Lwelling has uploaded a new change for review.
https://gerrit.wikimedia.org/r/58312
Change subject: Add HTML email messages to echo notifications
......................................................................
Add HTML email messages to echo notifications
Talk page notifications are tested and the happy path works, but need more
error handling and care with escaping/encoding
Other notifications are not properly tested
Main todo is making sure wrapper functions are used to make sure dynamic or
translated content gets encoded properly
Change-Id: I0c0bd38f1e8c98a877bf40152ab544065dc23f77
---
M Echo.i18n.php
M Echo.php
M Notifier.php
M formatters/BasicFormatter.php
M formatters/NotificationFormatter.php
A modules/emailicons/chat.png
A modules/emailicons/linked.png
A modules/emailicons/placeholder.png
A modules/emailicons/revert.png
A modules/emailicons/review.png
A modules/emailicons/review_with_tags.png
A modules/emailicons/started.png
A modules/emailicons/thanks.png
A modules/emailicons/w.png
14 files changed, 290 insertions(+), 11 deletions(-)
git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/Echo
refs/changes/12/58312/1
diff --git a/Echo.i18n.php b/Echo.i18n.php
index 9df5fc5..41d76a2 100644
--- a/Echo.i18n.php
+++ b/Echo.i18n.php
@@ -87,6 +87,7 @@
$2
$4',
+ 'notification-edit-talk-page-email-html' => '{{SITENAME}} user $1
{{GENDER:$1|posted}} on your talk page:',
'notification-edit-talk-page-email-batch-body2' => '$1
{{GENDER:$1|posted}} on your talk page',
'notification-article-linked-email-subject2' => '{{PLURAL:$2|A
page|Pages}} you started {{PLURAL:$2|was|were}} linked on {{SITENAME}}',
'notification-article-linked-email-body2' => '$4 {{PLURAL:$5|was|were}}
{{GENDER:$1|linked}} by {{SITENAME}} user $1, from this page: $2
@@ -97,6 +98,10 @@
$6',
'notification-article-linked-email-batch-body2' => '$2
{{PLURAL:$3|was|were}} {{GENDER:$1|linked}} by $1',
+ 'notification-article-linked-email-button-label' => 'See all links',
+ 'notification-article-linked-email-html' => '<p>$2 was
{{GENDER:$1|linked}} from $4</p>
+<p>$3</p>',
+
'notification-reverted-email-subject2' => 'Your {{PLURAL:$3|edit on $2
was|edits on $2 were}} {{GENDER:$1|reverted}} by $1',
'notification-reverted-email-body2' => 'Your {{PLURAL:$7|edit on $2 has
been|edits on $2 have been}} {{GENDER:$1|reverted}} by $1.
@@ -107,6 +112,10 @@
$3
$6',
+ 'notification-reverted-email-html' => '<p>Your {{PLURAL:$7|edit on $2
has been|edits on $2 have been}} {{GENDER:$1|reverted}} by $1.</p>
+<p>$3</p>
+<p>$5</p>',
+
'notification-reverted-email-batch-body2' => 'Your {{PLURAL:$3|edit on
$2 was|edits on $2 were}} {{GENDER:$1|reverted}} by $1',
'notification-mention-email-subject' => '$1 {{GENDER:$1|mentioned}} you
on {{SITENAME}}',
'notification-mention-email-body' => '{{SITENAME}} user $1
{{GENDER:$1|mentioned}} you on $2.
@@ -127,6 +136,8 @@
{{canonicalurl:{{#special:ListGroupRights}}}}
$3',
+ 'notification-user-rights-email-html' => '<p>Your user rights were
{{GENDER:$1|changed}} by $1. $2</p>',
+
'notification-user-rights-email-batch-body' => 'Your user rights were
{{GENDER:$1|changed}} by $1. $2',
'echo-notification-count' => '$1+',
// Email notification
@@ -134,12 +145,23 @@
'echo-email-body-default' => 'You have a new notification at
{{SITENAME}}:
$1',
+<<<<<<< HEAD
+=======
+ 'echo-email-batch-body-default' => 'You have a new notification',
+
+ 'notification-email-html-default' => '<p>You have a new
notification<p>',
+ 'notification-email-button-label-default' => 'View More',
+
+>>>>>>> 1e584fe... Add HTML email messages to echo notifications
'echo-email-footer-default' => '$2
To control which emails we send you, visit:
{{canonicalurl:{{#special:Preferences}}#mw-prefsection-echo}}
$1',
+ 'echo-html-email-footer-default' => 'To control which emails we send
you, visit <a href =
"{{canonicalurl:{{#special:Preferences}}#mw-prefsection-echo}}" $2"><span
$2>account preferences</a><span><br />
+This email was sent by $1',
+
// Notifications overlay
'echo-link-new' => '$1 new {{PLURAL:$1|notification|notifications}}',
'echo-link' => 'Notifications',
diff --git a/Echo.php b/Echo.php
index d941487..92fa0ed 100644
--- a/Echo.php
+++ b/Echo.php
@@ -206,7 +206,7 @@
$wgEchoUseJobQueue = false;
// The organization address, the value should be defined in LocalSettings.php
-$wgEchoEmailFooterAddress = '';
+global $wgEchoEmailFooterAddress;
// The max notification count showed in badge
$wgEchoMaxNotificationCount = 99;
@@ -288,6 +288,8 @@
'email-subject-message' =>
'notification-edit-talk-page-email-subject2',
'email-body-message' =>
'notification-edit-talk-page-email-body2',
'email-body-params' => array( 'agent', 'titlelink', 'summary',
'email-footer' ),
+ 'email-html-message' =>
'notification-edit-talk-page-email-html',
+ 'email-html-params' => array( 'agent', 'titlelink', 'summary' ),
'email-body-batch-message' =>
'notification-edit-talk-page-email-batch-body2',
'email-body-batch-params' => array( 'agent', 'difflink',
'summary' ),
'icon' => 'chat',
@@ -305,6 +307,8 @@
'email-subject-params' => array( 'agent', 'title', 'number' ),
'email-body-message' => 'notification-reverted-email-body2',
'email-body-params' => array( 'agent', 'title', 'difflink',
'user', 'summary', 'email-footer', 'number' ),
+ 'email-html-message' => 'notification-reverted-email-html',
+ 'email-html-params' => array( 'agent', 'title', 'difflink',
'user', 'summary', 'number' ),
'email-body-batch-message' =>
'notification-reverted-email-batch-body2',
'email-body-batch-params' => array( 'agent', 'title', 'number'
),
'icon' => 'revert',
@@ -324,6 +328,8 @@
'email-body-params' => array( 'agent', 'title', 'titlelink',
'title-linked', 'email-footer' ),
'email-body-batch-message' =>
'notification-article-linked-email-batch-body2',
'email-body-batch-params' => array( 'agent', 'title-linked' ),
+ 'email-html-message' =>
'notification-article-linked-email-html',
+ 'email-html-params' => array( 'agent', 'title', 'titlelink',
'title-linked' ),
'icon' => 'linked',
),
'mention' => array(
@@ -339,6 +345,8 @@
'email-subject-params' => array( 'agent' ),
'email-body-message' => 'notification-mention-email-body',
'email-body-params' => array( 'agent', 'title', 'summary',
'subject-link', 'email-footer' ),
+ 'email-html-message' => 'notification-mention-email-html',
+ 'email-html-params' => array( 'agent', 'title', 'summary',
'subject-link' ),
'email-body-batch-message' =>
'notification-mention-email-batch-body',
'email-body-batch-params' => array( 'agent', 'title' ),
'content-message' => 'notification-talkpage-content',
@@ -358,6 +366,8 @@
'email-subject-params' => array(),
'email-body-message' => 'notification-user-rights-email-body',
'email-body-params' => array( 'agent', 'user-rights-list',
'email-footer' ),
+ 'email-html-message' => 'notification-user-rights-email-html',
+ 'email-html-params' => array( 'agent', 'user-rights-list' ),
'email-body-batch-message' =>
'notification-user-rights-email-batch-body',
'email-body-batch-params' => array( 'agent', 'user-rights-list'
),
'icon' => 'w',
diff --git a/Notifier.php b/Notifier.php
index e05de9a..0b25dda 100644
--- a/Notifier.php
+++ b/Notifier.php
@@ -82,9 +82,12 @@
$address = new MailAddress( $user );
$email =
EchoNotificationController::formatNotification( $event, $user, 'email' );
$subject = $email['subject'];
- $body = $email['body'];
-
- UserMailer::send( $address, $adminAddress, $subject,
$body );
+ $textBody = $email['textBody'];
+ $htmlBody = $email['htmlBody'];
+
+ UserMailer::send( $address, $adminAddress, $subject,
+ array( 'text' => $textBody, 'html' => $htmlBody
)
+ );
}
return true;
diff --git a/formatters/BasicFormatter.php b/formatters/BasicFormatter.php
index 25de60b..1510e9e 100644
--- a/formatters/BasicFormatter.php
+++ b/formatters/BasicFormatter.php
@@ -63,6 +63,32 @@
if ( isset( $params['email-body-message'] ) ) {
$this->email['body'] = array();
$this->email['body']['message'] =
$params['email-body-message'];
+ /**
+ * @Todo Check if this varaible can be removed
+ */
+
+ protected $email;
+
+ /**
+ * Notification icon name for each type (name must be same for UI and
email icons)
+ * @param string
+ */
+ protected $icon;
+
+ /**
+ * Label string for link button in html email version of notification
+ * @param string
+ */
+ protected $emailButtonLabel;
+
+ /**
+ * Data for constructing bundle message, data in this array
+ * should be used in function processParams()
+ * @var array
+ */
+ protected $bundleData = array (
+ 'use-bundle' => false
+ );
if ( isset( $params['email-body-params'] ) ) {
$this->email['body']['params'] =
$params['email-body-params'];
@@ -78,6 +104,7 @@
);
}
+<<<<<<< HEAD
$this->email['batch-body'] = array();
if ( isset( $params['email-body-batch-message'] ) ) {
$this->email['batch-body']['message'] =
$params['email-body-batch-message'];
@@ -94,6 +121,89 @@
$this->icon = $params['icon'];
}
+=======
+ // Title for archive page
+ $this->title = array(
+ 'message' => $params['title-message'],
+ 'params' => $params['title-params']
+ );
+
+ // Set up default params if one is missing
+ $params += $this->getDefaultParams();
+
+ // Title for the flyout
+ $this->flyoutTitle = array(
+ 'message' => $params['flyout-message'],
+ 'params' => $params['flyout-params']
+ );
+
+ // Bundle title for both archive page and flyout
+ $this->bundleTitle = array(
+ 'message' => $params['bundle-message'],
+ 'params' => $params['bundle-params']
+ );
+
+ // Notification payload data, eg, summary
+ $this->payload = $params['payload'];
+
+ // Notification email subject and body
+ $this->email = array(
+ 'subject' => array(
+ 'message' => $params['email-subject-message'],
+ 'params' => $params['email-subject-params']
+ ),
+ 'body' => array(
+ 'message' => $params['email-body-message'],
+ 'params' => $params['email-body-params']
+ ),
+ 'html' => array(
+ 'message' => $params['email-html-message'],
+ 'params' => $params['email-html-params']
+ ),
+ 'batch-body' => array(
+ 'message' =>
$params['email-body-batch-message'],
+ 'params' => $params['email-body-batch-params']
+ )
+ );
+
+ // Notification icon for the event type
+ $this->icon = $params['icon'];
+
+ // label for link button in HTML email version of notification
+ $this->emailButtonLabel = $params['email-button-label'];
+
+ }
+
+ /**
+ * Internal function that returns notification default params
+ *
+ * @return array
+ */
+ protected function getDefaultParams() {
+ return array(
+ 'flyout-message' => $this->title['message'],
+ 'flyout-params' => $this->title['params'],
+ 'bundle-message' => '',
+ 'bundle-params' => array(),
+ 'payload' => array(),
+ 'email-subject-message' => 'echo-email-subject-default',
+ 'email-subject-params' => array(),
+ 'email-body-message' => 'echo-email-body-default',
+ 'email-body-params' => array( 'text-notification' ),
+ 'email-body-batch-message' =>
'echo-email-batch-body-default',
+ 'email-body-batch-params' => array(),
+ 'icon' => 'placeholder',
+ 'email-html-message' =>
'notification-email-html-default',
+ 'email-html-params' => array( 'agent', 'titlelink',
'summary' ),
+ 'email-button-label' =>
'notification-email-button-label-default',
+ );
+
+ /**
+ * Notification email data
+ * @param array
+ */
+
+>>>>>>> 1e584fe... Add HTML email messages to echo notifications
}
/**
@@ -207,13 +317,103 @@
* @return string
*/
protected function formatEmail( $event, $user, $type ) {
+ global $wgServer, $wgExtensionAssetsPath, $wgEchoNotifications,
$wgScriptPath;
$subject = $this->formatFragment( $this->email['subject'],
$event, $user )->text();
$body = preg_replace( "/\n{3,}/", "\n\n",
$this->formatFragment( $this->email['body'], $event, $user )->text() );
$batchBody = preg_replace( "/\n{3,}/", "\n\n",
$this->formatFragment( $this->email['batch-body'], $event, $user )->text() );
+<<<<<<< HEAD
return array( 'subject' => $subject, 'body' => $body,
'batch-body' => $batchBody );
+=======
+ $this->setOutputFormat( 'htmlemail' );
+
+ // fully qualified url for icon to use
+ $htmlIcon = $wgServer. $wgScriptPath . $wgExtensionAssetsPath .
'/Echo/modules/emailicons/' . $this->icon . '.png';
+ $iconHeight = 61;
+ $iconWidth = 61;
+
+ $contentWidth = 500-35-35-$iconWidth; // border sizes hardcoded
as they should rarely change
+
+ $htmlMain = $this->formatFragment( $this->email['html'],
$event, $user )->text();
+
+ $htmlSummary = '';
+ foreach ( $this->payload as $payloadComponent ) {
+ $htmlSummary .= $this->formatPayload(
$payloadComponent, $event, $user ) . '<br/>';
+ }
+
+ $htmlButtonLabel = wfMessage( $this->emailButtonLabel )
+ ->inLanguage( $user->getOption( 'language' ) )
+ ->text();
+
+ $htmlButtonLink = $event->getTitle()->getCanonicalURL();
+
+ global $wgEchoEmailFooterAddress;
+ $htmlFooter = wfMessage( 'echo-html-email-footer-default' )
+ ->inLanguage( $user->getOption( 'language' ) )
+ ->params( $wgEchoEmailFooterAddress, 'style =
"color:#3366BB;text-decoration:none;"' )
+ ->text();
+
+ $this->setOutputFormat( 'email' );
+
+ // Note: this HTML is awful and looks like it escaped from 1996
+ // Sadly, for HTML to work in most email clients has to be very
+ // lowest common denominator with tables for layout and inline
CSS for presentation
+ // @TODO leave static formatting raw to deliberately generate
'bad' html but correctly use wrapper
+ // functions to make sure dynamic or translated content gets
encoded properly
+ $htmlBody = <<< EOT
+<html><head></head><body>
+<table cellspacing="0" cellpadding="0" border="0" width="100%" align="center">
+<tr>
+ <td bgcolor="#E6E7E8"><center>
+ <br /><br />
+ <table cellspacing="0" cellpadding="0" border="0" width="500">
+ <tr>
+ <td bgcolor="#FFFFFF" width = "35"> </td>
+ <td bgcolor="#FFFFFF" width =
"$iconWidth"> </td>
+ <td bgcolor="#FFFFFF" width = "$contentWidth"
style = "line-height:50px;"> </td>
+ <td bgcolor="#FFFFFF" width = "35"> </td>
+ </tr><tr>
+ <td bgcolor="#FFFFFF" width = "35"
rowspan="2"> </td>
+ <td bgcolor="#FFFFFF" width = "$iconWidth"
align = "center" valign="top" rowspan="2"><img src="$htmlIcon" alt = "" height
= "$iconHeight" width = "$iconWidth"></td>
+ <td bgcolor="#FFFFFF" width = "$contentWidth"
style = "font-family:Verdana, Geneva, sans-serif; font-size:15px;
line-height:19px; color:#C9C9C9;">$htmlMain</td>
+ <td bgcolor="#FFFFFF" width = "35" rowspan =
"2"> </td>
+ </tr><tr>
+ <td bgcolor="#FFFFFF" width = "$contentWidth"
style = "font-family:Verdana, Geneva, sans-serif; font-size:18px; line-height
24px; color:#252525;">$htmlSummary
+ <br /><br />
+ <table cellspacing="0" cellpadding="4"
border="0" >
+ <tr><td bgcolor="#3366BB"><a
href = "$htmlButtonLink" style = "color:#FFFFFF;text-decoration:none;"><span
style = "color:#FFFFFF;text-decoration:none;"> $htmlButtonLabel
</span></a></td></tr>
+ </table>
+ </td>
+ </tr><tr>
+ <td bgcolor="#FFFFFF" width = "35"> </td>
+ <td bgcolor="#FFFFFF" width =
"$iconWidth"> </td>
+ <td bgcolor="#FFFFFF" width = "$contentWidth"
style = "line-height:50px;"> </td>
+ <td bgcolor="#FFFFFF" width = "35"> </td>
+ </tr><tr>
+ <td bgcolor="#F1F1F1" width = "35"> </td>
+ <td bgcolor="#F1F1F1" width =
"$iconWidth"> </td>
+ <td bgcolor="#F1F1F1" width = "$contentWidth"
style = "font-family:Verdana, Geneva, sans-serif; font-size:12px;
line-height:15px; color:C9C9C9"><br />$htmlFooter
+<br /><br />
+ </td>
+ <td bgcolor="#F1F1F1" width = "35"> </td>
+ </tr>
+ </table>
+ <br><br></center>
+ </td>
+</tr>
+</table>
+</body></html>
+EOT;
+
+ if($htmlBody) {
+ return array( 'subject' => $subject, 'textBody' =>
$textBody, 'htmlBody' => $htmlBody, 'batch-body' => $batchBody );
+ }
+ else {
+ return array( 'subject' => $subject, 'textBody' =>
$textBody, 'batch-body' => $batchBody );
+ }
+>>>>>>> 1e584fe... Add HTML email messages to echo notifications
}
/**
@@ -295,7 +495,7 @@
}
$message->rawParams( Linker::link( $title, $linkText,
$class, $param ) );
- } elseif ( $this->outputFormat === 'email' ) {
+ } elseif ( $this->outputFormat === 'email' ||
$this->outputFormat === 'htmlemail' ) {
$message->params( $title->getCanonicalURL( $param ) );
} else {
$message->params( $title->getFullURL( $param ) );
@@ -327,12 +527,29 @@
*/
protected function processParam( $event, $param, $message, $user ) {
if ( $param === 'agent' ) {
+<<<<<<< HEAD
// Actually converts to two parameters for gender
support
if ( !$event->getAgent() ) {
$message->params( '', wfMessage(
'echo-no-agent' )->text() );
} else {
$agent = $event->getAgent();
$message->params( $agent->getName() );
+=======
+ $message->params( $this->formatAgent(
$event->getAgent() ) );
+ // example: {7} others, {99+} others
+ } elseif ( $param === 'agent-other-display') {
+ global $wgEchoMaxNotificationCount;
+
+ if ( $this->bundleData['agent-other-count'] >
$wgEchoMaxNotificationCount ) {
+ $message->params(
+ wfMessage( 'echo-notification-count' )
+ ->inLanguage( $user->getOption(
'language' ) )
+ ->params( $wgEchoMaxNotificationCount )
+ ->text()
+ );
+ } else {
+ $message->params(
$this->bundleData['agent-other-count'] );
+>>>>>>> 1e584fe... Add HTML email messages to echo notifications
}
} elseif ( $param === 'user' ) {
$message->params( $user->getName() );
@@ -358,6 +575,13 @@
->params( $wgEchoEmailFooterAddress, wfMessage(
'echo-email-batch-separator' )->text() )
->text()
);
+ } elseif ( $param === 'html-email-footer' ) {
+ global $wgEchoEmailFooterAddress;
+ $message->params(
+ wfMessage( 'echo-html-email-footer-default' )
+ ->inLanguage( $user->getOption( 'language' ) )
+ ->params( $wgEchoEmailFooterAddress, 'style =
"color:#3366BB; text-decoration:none;"' )->text()
+ );
} else {
throw new MWException( "Unrecognised parameter $param"
);
}
diff --git a/formatters/NotificationFormatter.php
b/formatters/NotificationFormatter.php
index eb2b06f..c1919d9 100644
--- a/formatters/NotificationFormatter.php
+++ b/formatters/NotificationFormatter.php
@@ -12,7 +12,7 @@
* List of valid output format
* @var array
*/
- protected $validOutputFormats = array( 'text', 'flyout', 'html',
'email' );
+ protected $validOutputFormats = array( 'text', 'flyout', 'html',
'email', 'htmlemail' );
/**
* Current output format, default is 'text'
@@ -121,6 +121,17 @@
}
}
+ protected function formatAgent( $agent, $style = '', $class = '' ) {
+ // for registered users present as a link to their user page
+ if (!$agent->isAnon() && $this->outputFormat === 'html' ) {
+ global $wgServer, $wgScriptPath, $wgScriptExtension;
+ $url = $wgServer . $wgScriptPath . '/index' .
$wgScriptExtension . '/';
+ return Xml::element( 'a', array( 'href' => $url .
$agent->getUserPage(), 'style' => $style, 'class' => $class ),
$agent->getName() );
+ } else {
+ return $agent->getName();
+ }
+ }
+
/**
* Formats an edit summary
* TODO: implement parsed option for notifications archive page (where
we can use all the html)
@@ -137,10 +148,15 @@
if ( $revision ) {
$summary = $revision->getComment(
Revision::FOR_THIS_USER, $user );
- if ( $this->outputFormat === 'html' ||
$this->outputFormat === 'flyout' ) {
+ if ( $this->outputFormat === 'html' ||
$this->outputFormat === 'flyout' || $this->outputFormat === 'htmlemail' ) {
if ( $this->outputFormat === 'html' ) {
- // Parse the edit summary
+ // Parse the edit summary
$summary = Linker::formatComment(
$summary, $revision->getTitle() );
+ } elseif ( $this->outputFormat === 'htmlemail'
) {
+ // Parse the edit summary and remove
arrow charcter that may be missing from destination machine
+ $summary = str_replace( '→', '',
Linker::formatComment( $summary, $revision->getTitle() ) );
+ // allow only a small set of
presentation tags
+ $summary = strip_tags( $summary,
'<p><b><i><font><br>' );
} else {
// Strip wikitext from the edit summary
and manually convert autocomments
$summary = FeedItem::stripComment(
$summary );
@@ -156,9 +172,13 @@
$summary = $matches[1] . "<span
class='autocomment'>" . $section . "</span>" . $matches[3];
}
}
- $summary = wfMessage( 'echo-quotation-marks',
$summary )->inContentLanguage()->plain();
- $summary = Xml::tags( 'span', array( 'class' =>
'comment' ), $summary );
- $summary = Xml::tags( 'div', array( 'class' =>
'mw-echo-summary' ), $summary );
+ if ( $summary ) {
+ $summary = wfMessage(
'echo-quotation-marks', $summary )->inContentLanguage()->plain();
+ if( $this->outputFormat !== 'htmlemail'
) {
+ $summary = Xml::tags( 'span',
array( 'class' => 'comment' ), $summary );
+ $summary = Xml::tags( 'div',
array( 'class' => 'mw-echo-summary' ), $summary );
+ }
+ }
}
return $summary;
diff --git a/modules/emailicons/chat.png b/modules/emailicons/chat.png
new file mode 100644
index 0000000..484c22f
--- /dev/null
+++ b/modules/emailicons/chat.png
Binary files differ
diff --git a/modules/emailicons/linked.png b/modules/emailicons/linked.png
new file mode 100644
index 0000000..59fcc46
--- /dev/null
+++ b/modules/emailicons/linked.png
Binary files differ
diff --git a/modules/emailicons/placeholder.png
b/modules/emailicons/placeholder.png
new file mode 100644
index 0000000..6253cf9
--- /dev/null
+++ b/modules/emailicons/placeholder.png
Binary files differ
diff --git a/modules/emailicons/revert.png b/modules/emailicons/revert.png
new file mode 100644
index 0000000..5c398cf
--- /dev/null
+++ b/modules/emailicons/revert.png
Binary files differ
diff --git a/modules/emailicons/review.png b/modules/emailicons/review.png
new file mode 100644
index 0000000..de52e02
--- /dev/null
+++ b/modules/emailicons/review.png
Binary files differ
diff --git a/modules/emailicons/review_with_tags.png
b/modules/emailicons/review_with_tags.png
new file mode 100644
index 0000000..eb62857
--- /dev/null
+++ b/modules/emailicons/review_with_tags.png
Binary files differ
diff --git a/modules/emailicons/started.png b/modules/emailicons/started.png
new file mode 100644
index 0000000..b63772a
--- /dev/null
+++ b/modules/emailicons/started.png
Binary files differ
diff --git a/modules/emailicons/thanks.png b/modules/emailicons/thanks.png
new file mode 100644
index 0000000..c2cdeb4
--- /dev/null
+++ b/modules/emailicons/thanks.png
Binary files differ
diff --git a/modules/emailicons/w.png b/modules/emailicons/w.png
new file mode 100644
index 0000000..6253cf9
--- /dev/null
+++ b/modules/emailicons/w.png
Binary files differ
--
To view, visit https://gerrit.wikimedia.org/r/58312
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I0c0bd38f1e8c98a877bf40152ab544065dc23f77
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/Echo
Gerrit-Branch: master
Gerrit-Owner: Lwelling <[email protected]>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits