Lewis Cawte has submitted this change and it was merged.

Change subject: Initial Echo integration, based on ikasty's code
......................................................................


Initial Echo integration, based on ikasty's code

Original diff can be found at https://git.io/v1W5n
Some cleanup, (copypasted) "brand new" code, etc. by me.

The new notifications-*.svg images are from WikiFont:
* notifications-award.svg was originally named "uniE023 - ribbonPrize.svg"
* notifications-gift-sent.svg was originally named "uniE022 - upload.svg"
* notifications-gift-received.svg was originally named "uniE023 - download.svg"
* notifications-added.svg was originally named "uniE022 - check.svg"
* notifications-level-up.svg was originally named "uniE027 - betaLaunch.svg"
Some of them have had their color changed to green as per Echo design
guidelines by giving the <svg> element a fill attribute.

Bug: T64520
Change-Id: I0c610c2bd33955c7f36619df9a3ce6b61b3c134f
---
M SocialProfile.php
A SystemGifts/EchoUserSystemGiftPresentationModel.php
M SystemGifts/SystemGifts.php
M SystemGifts/SystemGiftsClass.php
M SystemGifts/UserSystemGiftsClass.php
A SystemGifts/UserSystemGiftsHooks.php
M SystemGifts/i18n/en.json
M SystemGifts/i18n/fi.json
A UserBoard/EchoUserBoardMessagePresentationModel.php
M UserBoard/UserBoardClass.php
A UserBoard/UserBoardHooks.php
M UserBoard/i18n/en.json
M UserBoard/i18n/fi.json
A UserGifts/EchoUserGiftPresentationModel.php
M UserGifts/Gifts.php
M UserGifts/UserGiftsClass.php
A UserGifts/UserGiftsHooks.php
M UserGifts/i18n/en.json
M UserGifts/i18n/fi.json
M UserProfile/SpecialUpdateProfile.php
A UserRelationship/EchoUserRelationshipPresentationModel.php
M UserRelationship/UserRelationshipClass.php
A UserRelationship/UserRelationshipHooks.php
M UserRelationship/i18n/en.json
M UserRelationship/i18n/fi.json
A UserStats/EchoUserLevelAdvancePresentationModel.php
M UserStats/UserStatsClass.php
A UserStats/UserStatsHooks.php
M UserStats/i18n/en.json
M UserStats/i18n/fi.json
M UserSystemMessages/UserSystemMessagesClass.php
A images/notifications-added.svg
A images/notifications-award.svg
A images/notifications-gift-received.svg
A images/notifications-gift-sent.svg
A images/notifications-level-up.svg
36 files changed, 907 insertions(+), 19 deletions(-)

Approvals:
  Lewis Cawte: Verified; Looks good to me, approved



diff --git a/SocialProfile.php b/SocialProfile.php
index f4b722a..c2b4098 100644
--- a/SocialProfile.php
+++ b/SocialProfile.php
@@ -121,7 +121,7 @@
        'path' => __FILE__,
        'name' => 'SocialProfile',
        'author' => array( 'Aaron Wright', 'David Pean', 'Jack Phoenix' ),
-       'version' => '1.9',
+       'version' => '1.10',
        'url' => 'https://www.mediawiki.org/wiki/Extension:SocialProfile',
        'descriptionmsg' => 'socialprofile-desc',
 );
diff --git a/SystemGifts/EchoUserSystemGiftPresentationModel.php 
b/SystemGifts/EchoUserSystemGiftPresentationModel.php
new file mode 100644
index 0000000..5e46807
--- /dev/null
+++ b/SystemGifts/EchoUserSystemGiftPresentationModel.php
@@ -0,0 +1,31 @@
+<?php
+
+/**
+ * Formatter for award notifications ('social-award')
+ */
+class EchoUserSystemGiftPresentationModel extends EchoEventPresentationModel {
+
+       public function getIconType() {
+               return 'social-award';
+       }
+
+       public function getHeaderMessage() {
+               if ( $this->isBundled() ) {
+                       return $this->msg( 
'notification-social-award-rec-bundle', $this->getBundleCount() );
+               } else {
+                       return $this->msg( 'notification-social-award-rec', 
$this->event->getExtraParam( 'giftname' ) );
+               }
+       }
+
+       public function getBodyMessage() {
+               return false;
+       }
+
+       public function getPrimaryLink() {
+               return array(
+                       'url' => SpecialPage::getTitleFor( 'ViewSystemGift' 
)->getLocalURL( array( 'gift_id' => $this->event->getExtraParam( 'giftid' ) ) ),
+                       'label' => $this->msg( 'echo-learn-more' )->text()
+               );
+       }
+
+}
\ No newline at end of file
diff --git a/SystemGifts/SystemGifts.php b/SystemGifts/SystemGifts.php
index 06555f0..3d906e1 100644
--- a/SystemGifts/SystemGifts.php
+++ b/SystemGifts/SystemGifts.php
@@ -15,6 +15,7 @@
 
 $wgAutoloadClasses['SystemGifts'] = 
"{$wgSystemGiftsDirectory}/SystemGiftsClass.php";
 $wgAutoloadClasses['UserSystemGifts'] = 
"{$wgSystemGiftsDirectory}/UserSystemGiftsClass.php";
+$wgAutoloadClasses['UserSystemGiftsHooks'] = 
"{$wgSystemGiftsDirectory}/UserSystemGiftsHooks.php";
 
 // Special Pages
 $wgAutoloadClasses['TopAwards'] = "{$wgSystemGiftsDirectory}/TopAwards.php";
@@ -48,3 +49,13 @@
        'remoteExtPath' => 'SocialProfile/SystemGifts',
        'position' => 'top'
 );
+
+// Echo (Notifications) stuff
+$wgAutoloadClasses['EchoUserSystemGiftPresentationModel'] = 
"{$wgSystemGiftsDirectory}/EchoUserSystemGiftPresentationModel.php";
+
+$wgHooks['BeforeCreateEchoEvent'][] = 
'UserSystemGiftsHooks::onBeforeCreateEchoEvent';
+$wgHooks['EchoGetDefaultNotifiedUsers'][] = 
'UserSystemGiftsHooks::onEchoGetDefaultNotifiedUsers';
+$wgHooks['EchoGetBundleRules'][] = 
'UserSystemGiftsHooks::onEchoGetBundleRules';
+
+$wgDefaultUserOptions['echo-subscriptions-web-social-award'] = true;
+$wgDefaultUserOptions['echo-subscriptions-email-social-award'] = false;
\ No newline at end of file
diff --git a/SystemGifts/SystemGiftsClass.php b/SystemGifts/SystemGiftsClass.php
index 252702a..0d1a013 100644
--- a/SystemGifts/SystemGiftsClass.php
+++ b/SystemGifts/SystemGiftsClass.php
@@ -68,6 +68,7 @@
                                );
 
                                foreach ( $res2 as $row2 ) {
+                                       // @todo FIXME: this needs refactoring 
and badly (see T131016 for details)
                                        if ( $this->doesUserHaveGift( 
$row2->stats_user_id, $row->gift_id ) == false ) {
                                                $dbw->insert(
                                                        'user_system_gift',
@@ -84,7 +85,7 @@
                                                $sg_key = wfMemcKey( 'user', 
'profile', 'system_gifts', "{$row2->stats_user_id}" );
                                                $wgMemc->delete( $sg_key );
 
-                                               // Update counters (bug #27981)
+                                               // Update counters 
(https://phabricator.wikimedia.org/T29981)
                                                
UserSystemGifts::incGiftGivenCount( $row->gift_id );
 
                                                $wgOut->addHTML( wfMessage(
diff --git a/SystemGifts/UserSystemGiftsClass.php 
b/SystemGifts/UserSystemGiftsClass.php
index e213adf..f689128 100644
--- a/SystemGifts/UserSystemGiftsClass.php
+++ b/SystemGifts/UserSystemGiftsClass.php
@@ -52,7 +52,26 @@
                if ( $email && !empty( $sg_gift_id ) ) {
                        $this->sendGiftNotificationEmail( $this->user_id, 
$gift_id );
                }
+
+               if ( class_exists( 'EchoEvent' ) ) {
+                       $userFrom = User::newFromId( $this->user_id );
+
+                       $giftObj = SystemGifts::getGift( $gift_id );
+                       EchoEvent::create( array(
+                               'type' => 'social-award-rec',
+                               'agent' => $userFrom,
+                               'extra' => array(
+                                       'notifyAgent' => true,
+                                       'target' => $this->user_id,
+                                       'mastergiftid' => $gift_id,
+                                       'giftid' => $sg_gift_id,
+                                       'giftname' => $giftObj['gift_name']
+                               )
+                       ) );
+               }
+
                $wgMemc->delete( wfMemcKey( 'user', 'profile', 'system_gifts', 
$this->user_id ) );
+
                return $sg_gift_id;
        }
 
@@ -69,7 +88,9 @@
                $gift = SystemGifts::getGift( $gift_id );
                $user = User::newFromId( $user_id_to );
                $user->loadFromDatabase();
-               if ( $user->isEmailConfirmed() && $user->getIntOption( 
'notifygift', 1 ) ) {
+
+               $wantsEmail = class_exists( 'EchoEvent' ) ? 
$user->getBoolOption( 'echo-subscriptions-email-social-award' ) : 
$user->getIntOption( 'notifygift', 1 );
+               if ( $user->isEmailConfirmed() && $wantsEmail ) {
                        $gifts_link = SpecialPage::getTitleFor( 
'ViewSystemGifts' );
                        $update_profile_link = SpecialPage::getTitleFor( 
'UpdateProfile' );
                        $subject = wfMessage( 'system_gift_received_subject',
diff --git a/SystemGifts/UserSystemGiftsHooks.php 
b/SystemGifts/UserSystemGiftsHooks.php
new file mode 100644
index 0000000..d171671
--- /dev/null
+++ b/SystemGifts/UserSystemGiftsHooks.php
@@ -0,0 +1,75 @@
+<?php
+
+class UserSystemGiftsHooks {
+       /**
+        * For the Echo extension.
+        *
+        * @param array $notifications Echo notifications
+        * @param array $notificationCategories Echo notification categories
+        * @param array $icons Icon details
+        * @return bool
+        */
+       public static function onBeforeCreateEchoEvent( &$notifications, 
&$notificationCategories, &$icons ) {
+               $notificationCategories['social-award'] = array(
+                       'priority' => 3,
+                       'tooltip' => 'echo-pref-tooltip-social-award',
+               );
+
+               $notifications['social-award-rec'] = array(
+                       'category' => 'social-award',
+                       'group' => 'interactive',
+                       'presentation-model' => 
'EchoUserSystemGiftPresentationModel',
+                       EchoAttributeManager::ATTR_LOCATORS => array(
+                               'EchoUserLocator::locateEventAgent'
+                       ),
+
+                       'payload' => array( 'award-rec' ),
+
+                       'icon' => 'social-award',
+
+                       'bundle' => array( 'web' => true, 'email' => true ),
+                       'bundle-message' => 
'notification-social-award-rec-bundle',
+                       'bundle-params' => array( 'bundle-user-count', 
'bundle-noti-count' ) // @todo FIXME: 100% incorrect & bad copypasta
+               );
+
+               $icons['social-award'] = array(
+                       'path' => 'SocialProfile/images/notifications-award.svg'
+               );
+
+               return true;
+       }
+
+       /**
+        * Add user to be notified on Echo event
+        *
+        * @param EchoEvent $event
+        * @param array $users
+        * @return bool
+        */
+       public static function onEchoGetDefaultNotifiedUsers( $event, &$users ) 
{
+               switch ( $event->getType() ) {
+                       case 'social-award-rec':
+                               $extra = $event->getExtra();
+                               $targetId = $extra['target'];
+                               $users[] = User::newFromId( $targetId );
+                               break;
+               }
+               return true;
+       }
+
+       /**
+        * Set bundle for message
+        *
+        * @param EchoEvent $event
+        * @param string $bundleString
+        * @return bool
+        */
+       public static function onEchoGetBundleRules( $event, &$bundleString ) {
+               switch ( $event->getType() ) {
+                       case 'social-award-rec':
+                               $bundleString = 'social-award-rec';
+                               break;
+               }
+               return true;
+       }
+}
\ No newline at end of file
diff --git a/SystemGifts/i18n/en.json b/SystemGifts/i18n/en.json
index 487c9ac..a05241a 100644
--- a/SystemGifts/i18n/en.json
+++ b/SystemGifts/i18n/en.json
@@ -71,5 +71,9 @@
        "system_gift_received_subject": "You have received the $1 award on 
{{SITENAME}}!",
        "system_gift_received_body_html": "Hi $1.\n\nYou have just received the 
$2 award on {{SITENAME}}!\n\n\"$3\"\n\nClick below to check out your trophy 
case!\n\n[[Special:ViewSystemGifts]]\n\nWe hope you like 
it!\n\nThanks,\n\n\nThe {{SITENAME}} team\n\n---\n\nHey, want to stop getting 
emails from us?\n\nClick [[Special:UpdateProfile]]\nand change your settings to 
disable email notifications.",
        "system_gift_received_body": "Hi $1.\n\nYou have just received the $2 
award on {{SITENAME}}!\n\n\"$3\"\n\nClick below to check out your trophy 
case!\n\n$4\n\nWe hope you like it!\n\nThanks,\n\n\nThe {{SITENAME}} 
team\n\n---\n\nHey, want to stop getting emails from us?\n\nClick $5\nand 
change your settings to disable email notifications.",
+       "echo-category-title-social-award": "Awards",
+       "echo-pref-tooltip-social-award": "Notify me when I receive an award.",
+       "notification-social-award-rec": "You have received a new award: $1.",
+       "notification-social-award-rec-bundle": "You have received 
{{PLURAL:$1|one new award|$1 new awards}}.",
        "right-awardsmanage": "Create new and edit existing awards"
 }
diff --git a/SystemGifts/i18n/fi.json b/SystemGifts/i18n/fi.json
index 7d9b0c7..e75f227 100644
--- a/SystemGifts/i18n/fi.json
+++ b/SystemGifts/i18n/fi.json
@@ -53,5 +53,9 @@
        "system_gift_received_subject": "Olet saanut palkinnon $1 
{{GRAMMAR:inessive|{{SITENAME}}}}!",
        "system_gift_received_body_html": "Hei $1:\n\nOlet juuri saanut 
$2-palkinnon {{GRAMMAR:inessive|{{SITENAME}}}}!\n\n\"$3\"\n\nNapsauta 
alapuolella olevaa linkkiä tarkistaaksesi 
palkintorasiasi!\n\n[[Special:ViewSystemGifts]]\n\nToivomme, että pidät 
siitä!\n\nKiittäen,\n\n\n{{GRAMMAR:genitive|{{SITENAME}}}} tiimi\n\n---\n\nHei, 
etkö halua enää saada sähköposteja meiltä?\n\nNapsauta 
[[Special:UpdateProfile]]\nja muuta asetuksiasi poistaaksesi 
sähköpostitoiminnot käytöstä.",
        "system_gift_received_body": "Hei $1:\n\nOlet juuri saanut $2-palkinnon 
{{GRAMMAR:inessive|{{SITENAME}}}}!\n\n\"$3\"\n\nNapsauta alapuolella olevaa 
linkkiä tarkistaaksesi palkintorasiasi!\n\n$4\n\nToivomme, että pidät 
siitä!\n\nKiittäen,\n\n\n{{GRAMMAR:genitive|{{SITENAME}}}} tiimi\n\n---\n\nHei, 
etkö halua enää saada sähköposteja meiltä?\n\nNapsauta $5\nja muuta asetuksiasi 
poistaaksesi sähköpostitoiminnot käytöstä.",
+       "echo-category-title-social-award": "Palkinnot",
+       "echo-pref-tooltip-social-award": "Ilmoita minulle, kun saan 
palkinnon.",
+       "notification-social-award-rec": "Olet saanut uuden palkinnon: $1.",
+       "notification-social-award-rec-bundle": "Olet saanut {{PLURAL:$1|yhden 
uuden palkinnon|$1 uutta palkintoa}}.",
        "right-awardsmanage": "Luoda uusia ja muokata olemassaolevia palkintoja"
 }
diff --git a/UserBoard/EchoUserBoardMessagePresentationModel.php 
b/UserBoard/EchoUserBoardMessagePresentationModel.php
new file mode 100644
index 0000000..7679fcc
--- /dev/null
+++ b/UserBoard/EchoUserBoardMessagePresentationModel.php
@@ -0,0 +1,38 @@
+<?php
+
+/**
+ * Formatter for user board message notifications ('social-msg-send')
+ */
+class EchoUserBoardMessagePresentationModel extends EchoEventPresentationModel 
{
+
+       public function getIconType() {
+               return 'emailuser'; // per discussion with Cody on 27 March 2016
+       }
+
+       public function getHeaderMessage() {
+               if ( $this->isBundled() ) {
+                       return $this->msg(
+                               'notification-social-msg-send-bundle',
+                               $this->getBundleCount()
+                       );
+               } else {
+                       return $this->msg(
+                               'notification-social-msg-send',
+                               $this->event->getAgent()->getName(),
+                               $this->language->truncate( 
$this->event->getExtraParam( 'message' ), 100 )
+                       );
+               }
+       }
+
+       public function getBodyMessage() {
+               return false;
+       }
+
+       public function getPrimaryLink() {
+               return array(
+                       'url' => SpecialPage::getTitleFor( 'UserBoard' 
)->getLocalURL(),
+                       'label' => $this->msg( 'echo-learn-more' )->text()
+               );
+       }
+
+}
\ No newline at end of file
diff --git a/UserBoard/UserBoardClass.php b/UserBoard/UserBoardClass.php
index d2a5aa0..8b962a4 100644
--- a/UserBoard/UserBoardClass.php
+++ b/UserBoard/UserBoardClass.php
@@ -60,6 +60,21 @@
                $stats = new UserStatsTrack( $user_id_from, $user_name_from );
                $stats->incStatField( 'user_board_sent' );
 
+               if ( class_exists( 'EchoEvent' ) ) {
+                       $userFrom = User::newFromId( $user_id_from );
+
+                       EchoEvent::create( array(
+                               'type' => 'social-msg-send',
+                               'agent' => $userFrom,
+                               'extra' => array(
+                                       'target' => $user_id_to,
+                                       'from' => $user_id_from,
+                                       'type' => $message_type,
+                                       'message' => $message
+                               )
+                       ) );
+               }
+
                return $dbw->insertId();
        }
 
@@ -74,7 +89,8 @@
                $user->loadFromId();
 
                // Send email if user's email is confirmed and s/he's opted in 
to recieving social notifications
-               if ( $user->isEmailConfirmed() && $user->getIntOption( 
'notifymessage', 1 ) ) {
+               $wantsEmail = class_exists( 'EchoEvent' ) ? 
$user->getBoolOption( 'echo-subscriptions-email-social-rel' ) : 
$user->getIntOption( 'notifymessage', 1 );
+               if ( $user->isEmailConfirmed() && $wantsEmail ) {
                        $board_link = SpecialPage::getTitleFor( 'UserBoard' );
                        $update_profile_link = SpecialPage::getTitleFor( 
'UpdateProfile' );
                        $subject = wfMessage( 'message_received_subject', 
$user_from )->parse();
diff --git a/UserBoard/UserBoardHooks.php b/UserBoard/UserBoardHooks.php
new file mode 100644
index 0000000..bf497a2
--- /dev/null
+++ b/UserBoard/UserBoardHooks.php
@@ -0,0 +1,71 @@
+<?php
+
+class UserBoardHooks {
+       /**
+        * For the Echo extension.
+        *
+        * @param array $notifications Echo notifications
+        * @param array $notificationCategories Echo notification categories
+        * @param array $icons Icon details
+        * @return bool
+        */
+       public static function onBeforeCreateEchoEvent( &$notifications, 
&$notificationCategories, &$icons ) {
+               $notificationCategories['social-msg'] = array(
+                       'priority' => 3,
+                       'tooltip' => 'echo-pref-tooltip-social-msg',
+               );
+
+               $notifications['social-msg-send'] = array(
+                       'category' => 'social-msg',
+                       'group' => 'interactive',
+                       'presentation-model' => 
'EchoUserBoardMessagePresentationModel',
+                       EchoAttributeManager::ATTR_LOCATORS => array(
+                               'EchoUserLocator::locateEventAgent'
+                       ),
+
+                       'payload' => array( 'send-message' ),
+
+                       'icon' => 'emailuser', // per discussion with Cody on 
27 March 2016
+
+                       'bundle' => array( 'web' => true, 'email' => true ),
+                       'bundle-message' => 
'notification-social-msg-send-bundle',
+                       'bundle-params' => array( 'bundle-user-count', 
'bundle-noti-count' )
+               );
+
+               return true;
+       }
+
+       /**
+        * Add user to be notified on Echo event
+        *
+        * @param EchoEvent $event
+        * @param array $users
+        * @return bool
+        */
+       public static function onEchoGetDefaultNotifiedUsers( $event, &$users ) 
{
+               switch ( $event->getType() ) {
+                       case 'social-msg-send':
+                               $extra = $event->getExtra();
+                               $targetId = $extra['target'];
+                               $users[] = User::newFromId( $targetId );
+                               break;
+               }
+               return true;
+       }
+
+       /**
+        * Set bundle for message
+        *
+        * @param EchoEvent $event
+        * @param string $bundleString
+        * @return bool
+        */
+       public static function onEchoGetBundleRules( $event, &$bundleString ) {
+               switch ( $event->getType() ) {
+                       case 'social-msg-send':
+                               $bundleString = 'social-msg-send';
+                               break;
+               }
+               return true;
+       }
+}
\ No newline at end of file
diff --git a/UserBoard/i18n/en.json b/UserBoard/i18n/en.json
index b04486b..f487c29 100644
--- a/UserBoard/i18n/en.json
+++ b/UserBoard/i18n/en.json
@@ -56,5 +56,9 @@
        "userboard-time-seconds": "{{PLURAL:$1|one second|$1 seconds}}",
        "message_received_subject": "$1 wrote on your board on {{SITENAME}}",
        "message_received_body_html": "Hi $1.\n\n$2 just wrote on your board on 
{{SITENAME}}!\n\nClick below to check out your 
board!\n\n[[Special:UserBoard]]\n\n---\n\nHey, want to stop getting e-mails 
from us?\n\nClick [[Special:UpdateProfile]]\nand change your settings to 
disable email notifications.",
-       "message_received_body": "Hi $1.\n\n$2 just wrote on your board on 
{{SITENAME}}!\n\nClick below to check out your board!\n\n$3\n\n---\n\nHey, want 
to stop getting e-mails from us?\n\nClick $4\nand change your settings to 
disable email notifications."
+       "message_received_body": "Hi $1.\n\n$2 just wrote on your board on 
{{SITENAME}}!\n\nClick below to check out your board!\n\n$3\n\n---\n\nHey, want 
to stop getting e-mails from us?\n\nClick $4\nand change your settings to 
disable email notifications.",
+       "echo-category-title-social-msg": "User board messages",
+       "echo-pref-tooltip-social-msg": "Notify me when someone leaves a 
message on my user board.",
+       "notification-social-msg-send": "$1 just left a message for you.<br 
/><br />''$2''",
+       "notification-social-msg-send-bundle": "{{PLURAL:$1|One person|$1 
people|100=99+ people}} left messages for you."
 }
diff --git a/UserBoard/i18n/fi.json b/UserBoard/i18n/fi.json
index a3c4a0b..a7d524f 100644
--- a/UserBoard/i18n/fi.json
+++ b/UserBoard/i18n/fi.json
@@ -57,5 +57,9 @@
        "userboard-time-seconds": "{{PLURAL:$1|sekunti|$1 sekuntia}}",
        "message_received_subject": "$1 kirjoitti keskustelualueellesi 
{{GRAMMAR:inessive|{{SITENAME}}}}",
        "message_received_body_html": "Hei $1:\n\n$2 juuri kirjoitti 
keskustelualueellesi {{GRAMMAR:inessive|{{SITENAME}}}}!\n\nNapsauta alapuolella 
olevaa linkki tarkistaaksesi 
keskustelualueesi!\n\n[[Special:UserBoard]]\n\n---\n\nHei, etkö halua enää 
saada sähköposteja meiltä?\n\nNapsauta [[Special:UpdateProfile]]\nja muuta 
asetuksiasi poistaaksesi sähköpostitoiminnot käytöstä.",
-       "message_received_body": "Hei $1:\n\n$2 juuri kirjoitti 
keskustelualueellesi {{GRAMMAR:inessive|{{SITENAME}}}}!\n\nNapsauta alapuolella 
olevaa linkki tarkistaaksesi keskustelualueesi!\n\n$3\n\n---\n\nHei, etkö halua 
enää saada sähköposteja meiltä?\n\nNapsauta $4\nja muuta asetuksiasi 
poistaaksesi sähköpostitoiminnot käytöstä."
+       "message_received_body": "Hei $1:\n\n$2 juuri kirjoitti 
keskustelualueellesi {{GRAMMAR:inessive|{{SITENAME}}}}!\n\nNapsauta alapuolella 
olevaa linkki tarkistaaksesi keskustelualueesi!\n\n$3\n\n---\n\nHei, etkö halua 
enää saada sähköposteja meiltä?\n\nNapsauta $4\nja muuta asetuksiasi 
poistaaksesi sähköpostitoiminnot käytöstä.",
+       "echo-category-title-social-msg": "Keskustelualueen viestit",
+       "echo-pref-tooltip-social-msg": "Ilmoita minulle, kun joku jättää 
viestin keskustelualueelleni.",
+       "notification-social-msg-send": "$1 jätti juuri sinulle viestin.<br 
/><br />''$2''",
+       "notification-social-msg-send-bundle": "{{PLURAL:$1|Yksi henkilö 
jätti|$1 henkilöä jättivät|100=99+ henkilöä jättivät}} sinulle viestejä."
 }
diff --git a/UserGifts/EchoUserGiftPresentationModel.php 
b/UserGifts/EchoUserGiftPresentationModel.php
new file mode 100644
index 0000000..227c03f
--- /dev/null
+++ b/UserGifts/EchoUserGiftPresentationModel.php
@@ -0,0 +1,87 @@
+<?php
+
+/**
+ * Formatter for user gift notifications ('social-gift-send')
+ */
+class EchoUserGiftPresentationModel extends EchoEventPresentationModel {
+
+       public function getIconType() {
+               return 'social-gift-send';
+       }
+
+       public function getHeaderMessage() {
+               $g = Gifts::getGift( $this->event->getExtraParam( 
'mastergiftid' ) );
+               $giftName = '';
+               if ( isset( $g['gift_name'] ) ) {
+                       // It damn well *should* be set, but Gifts::getGift() 
can theoretically
+                       // return an empty array
+                       $giftName = $g['gift_name'];
+               }
+               if ( $this->isBundled() ) {
+                       return $this->msg(
+                               'notification-social-gift-send-bundle',
+                               $this->getBundleCount()
+                       );
+               } else {
+                       if ( !empty( $this->event->getExtraParam( 'message' ) ) 
) {
+                               return $this->msg(
+                                       
'notification-social-gift-send-with-message',
+                                       $this->event->getAgent()->getName(),
+                                       $giftName,
+                                       $this->event->getExtraParam( 'message' )
+                               );
+                       } else {
+                               return $this->msg(
+                                       
'notification-social-gift-send-no-message',
+                                       $this->event->getAgent()->getName(),
+                                       $giftName
+                               );
+                       }
+               }
+       }
+
+       public function getBodyMessage() {
+               return false;
+       }
+
+       public function getPrimaryLink() {
+               return array(
+                       'url' => $this->getGiftLink(),
+                       'label' => $this->msg( 'echo-learn-more' )->text()
+               );
+       }
+
+       public function getSecondaryLinks() {
+               $g = Gifts::getGift( $this->event->getExtraParam( 
'mastergiftid' ) );
+               $label = '';
+               if ( isset( $g['gift_name'] ) ) {
+                       // It damn well *should* be set, but Gifts::getGift() 
can theoretically
+                       // return an empty array
+                       $label = $g['gift_name'];
+               }
+               return array(
+                       $this->getMyProfileLink(),
+                       array(
+                               'url' => $this->getGiftLink(),
+                               'label' => $label
+                       )
+               );
+       }
+
+       private function getMyProfileLink() {
+               return array(
+                       'label' => $this->msg( 'g-your-profile' )->text(),
+                       'url' => Title::makeTitle( NS_USER, 
$this->getViewingUserForGender() )->getFullURL(),
+                       'description' => '',
+                       'icon' => 'userAvatar',
+                       'prioritized' => true,
+               );
+       }
+
+       private function getGiftLink() {
+               return SpecialPage::getTitleFor( 'ViewGift' )->getLocalURL( 
array(
+                       'gift_id' => $this->event->getExtraParam( 'giftid' )
+               ) );
+       }
+
+}
\ No newline at end of file
diff --git a/UserGifts/Gifts.php b/UserGifts/Gifts.php
index 9696517..3975139 100644
--- a/UserGifts/Gifts.php
+++ b/UserGifts/Gifts.php
@@ -12,6 +12,7 @@
 // Special Pages etc.
 $wgAutoloadClasses['Gifts'] = "{$wgUserGiftsDirectory}/GiftsClass.php";
 $wgAutoloadClasses['UserGifts'] = "{$wgUserGiftsDirectory}/UserGiftsClass.php";
+$wgAutoloadClasses['UserGiftsHooks'] = 
"{$wgUserGiftsDirectory}/UserGiftsHooks.php";
 
 $wgAutoloadClasses['GiveGift'] = "{$wgUserGiftsDirectory}/SpecialGiveGift.php";
 $wgSpecialPages['GiveGift'] = 'GiveGift';
@@ -50,6 +51,16 @@
        'remoteExtPath' => 'SocialProfile/UserGifts',
 );
 
+// Echo (Notifications) stuff
+$wgAutoloadClasses['EchoUserGiftPresentationModel'] = 
"{$wgUserGiftsDirectory}/EchoUserGiftPresentationModel.php";
+
+$wgHooks['BeforeCreateEchoEvent'][] = 
'UserGiftsHooks::onBeforeCreateEchoEvent';
+$wgHooks['EchoGetDefaultNotifiedUsers'][] = 
'UserGiftsHooks::onEchoGetDefaultNotifiedUsers';
+$wgHooks['EchoGetBundleRules'][] = 'UserGiftsHooks::onEchoGetBundleRules';
+
+$wgDefaultUserOptions['echo-subscriptions-web-social-gift'] = true;
+$wgDefaultUserOptions['echo-subscriptions-email-social-gift'] = false;
+
 // Credits
 $wgExtensionCredits['specialpage'][] = array(
        'name' => 'GiftManager',
diff --git a/UserGifts/UserGiftsClass.php b/UserGifts/UserGiftsClass.php
index b910b6d..075cac7 100644
--- a/UserGifts/UserGiftsClass.php
+++ b/UserGifts/UserGiftsClass.php
@@ -55,6 +55,24 @@
 
                $stats = new UserStatsTrack( $this->user_id, $this->user_name );
                $stats->incStatField( 'gift_sent' );
+
+               if ( class_exists( 'EchoEvent' ) ) {
+                       $userFrom = User::newFromId( $this->user_id );
+
+                       EchoEvent::create( array(
+                               'type' => 'social-gift-send',
+                               'agent' => $userFrom,
+                               'extra' => array(
+                                       'target' => $user_id_to,
+                                       'from' => $this->user_id,
+                                       'mastergiftid' => $gift_id,
+                                       'giftid' => $ug_gift_id,
+                                       'type' => $type,
+                                       'message' => $message
+                               )
+                       ) );
+               }
+
                return $ug_gift_id;
        }
 
@@ -73,7 +91,8 @@
                $user = User::newFromId( $user_id_to );
                $user->loadFromDatabase();
 
-               if ( $user->isEmailConfirmed() && $user->getIntOption( 
'notifygift', 1 ) ) {
+               $wantsEmail = class_exists( 'EchoEvent' ) ? 
$user->getBoolOption( 'echo-subscriptions-email-social-gift' ) : 
$user->getIntOption( 'notifygift', 1 );
+               if ( $user->isEmailConfirmed() && $wantsEmail ) {
                        $giftsLink = SpecialPage::getTitleFor( 'ViewGifts' );
                        $updateProfileLink = SpecialPage::getTitleFor( 
'UpdateProfile' );
 
diff --git a/UserGifts/UserGiftsHooks.php b/UserGifts/UserGiftsHooks.php
new file mode 100644
index 0000000..1be3525
--- /dev/null
+++ b/UserGifts/UserGiftsHooks.php
@@ -0,0 +1,76 @@
+<?php
+
+class UserGiftsHooks {
+       /**
+        * For the Echo extension.
+        *
+        * @param array $notifications Echo notifications
+        * @param array $notificationCategories Echo notification categories
+        * @param array $icons Icon details
+        * @return bool
+        */
+       public static function onBeforeCreateEchoEvent( &$notifications, 
&$notificationCategories, &$icons ) {
+               $notificationCategories['social-gift'] = array(
+                       'priority' => 3,
+                       'tooltip' => 'echo-pref-tooltip-social-gift',
+               );
+
+               $notifications['social-gift-send'] = array(
+                       'category' => 'social-gift',
+                       'group' => 'interactive',
+                       'presentation-model' => 'EchoUserGiftPresentationModel',
+                       EchoAttributeManager::ATTR_LOCATORS => array(
+                               'EchoUserLocator::locateEventAgent'
+                       ),
+
+                       'payload' => array( 'send-message' ), // @todo FIXME
+
+                       'icon' => 'social-gift-send',
+
+                       'bundle' => array( 'web' => true, 'email' => true ),
+                       'bundle-message' => 
'notification-social-gift-send-bundle'
+               );
+
+               // You just were *sent* a gift, thus you *received* it, ergo 
you should
+               // be seeing the *received* icon
+               $icons['social-gift-send'] = array(
+                       'path' => 
'SocialProfile/images/notifications-gift-received.svg'
+               );
+
+               return true;
+       }
+
+       /**
+        * Add user to be notified on Echo event
+        *
+        * @param EchoEvent $event
+        * @param array $users
+        * @return bool
+        */
+       public static function onEchoGetDefaultNotifiedUsers( $event, &$users ) 
{
+               switch ( $event->getType() ) {
+                       case 'social-gift-send':
+                               $extra = $event->getExtra();
+                               $targetId = $extra['target'];
+                               $users[] = User::newFromId( $targetId );
+                               break;
+               }
+               return true;
+       }
+
+       /**
+        * Set bundle for message
+        *
+        * @param EchoEvent $event
+        * @param string $bundleString
+        * @return bool
+        */
+       public static function onEchoGetBundleRules( $event, &$bundleString ) {
+               switch ( $event->getType() ) {
+                       case 'social-gift-send':
+                               $bundleString = 'social-gift-send';
+                               break;
+               }
+               return true;
+       }
+}
\ No newline at end of file
diff --git a/UserGifts/i18n/en.json b/UserGifts/i18n/en.json
index fc4ee85..0e6bf7e 100644
--- a/UserGifts/i18n/en.json
+++ b/UserGifts/i18n/en.json
@@ -81,5 +81,10 @@
        "gift_received_subject": "$1 has sent you the $2 gift on {{SITENAME}}!",
        "gift_received_body_html": "Hi $1.\n\n$2 just sent you the $3 gift on 
{{SITENAME}}.\n\nWant to read the note $2 left you and see your gift? Click the 
link below:\n\n[[Special:ViewGifts]]\n\nWe hope you like 
it!\n\nThanks,\n\n\nThe {{SITENAME}} team\n\n---\n\nHey, want to stop getting 
emails from us?\n\nClick [[Special:UpdateProfile]]\nand change your settings to 
disable email notifications.",
        "gift_received_body": "Hi $1.\n\n$2 just sent you the $3 gift on 
{{SITENAME}}.\n\nWant to read the note $2 left you and see your gift? Click the 
link below:\n\n$4\n\nWe hope you like it!\n\nThanks,\n\n\nThe {{SITENAME}} 
team\n\n---\n\nHey, want to stop getting emails from us?\n\nClick $5\nand 
change your settings to disable email notifications.",
+       "echo-category-title-social-gift": "Gifts",
+       "echo-pref-tooltip-social-gift": "Notify me when someone sends me a 
gift.",
+       "notification-social-gift-send-no-message": "$1 just sent a gift to 
you: $2.",
+       "notification-social-gift-send-with-message": "$1 just sent a gift to 
you: $2.<br /><br />''$3''",
+       "notification-social-gift-send-bundle": "{{PLURAL:$1|One person|$1 
people}} sent you gifts.",
        "right-giftadmin": "Create new and edit existing gifts"
 }
diff --git a/UserGifts/i18n/fi.json b/UserGifts/i18n/fi.json
index c6d2122..12c54ee 100644
--- a/UserGifts/i18n/fi.json
+++ b/UserGifts/i18n/fi.json
@@ -81,5 +81,10 @@
        "gift_received_subject": "$1 on lähettänyt sinulle lahjan $2 
{{GRAMMAR:inessive|{{SITENAME}}}}!",
        "gift_received_body_html": "Hei $1:\n\n$2 juuri lähetti sinulle 
$3-lahjan {{GRAMMAR:inessive|{{SITENAME}}}}.\n\nHaluatko lukea viestin, jonka 
$2 jätti sinulle ja nähdä lahjasi? Napsauta linkkiä 
alapuolella:\n\n[[Special:ViewGifts]]\n\nToivomme, että pidät 
siitä!\n\nKiittäen,\n\n\n{{GRAMMAR:genitive|{{SITENAME}}}} tiimi\n\n---\n\nHei, 
etkö halua enää saada sähköposteja meiltä?\n\nNapsauta 
[[Special:UpdateProfile]]\nja muuta asetuksiasi poistaaksesi 
sähköpostitoiminnot käytöstä.",
        "gift_received_body": "Hei $1:\n\n$2 juuri lähetti sinulle $3-lahjan 
{{GRAMMAR:inessive|{{SITENAME}}}}.\n\nHaluatko lukea viestin, jonka $2 jätti 
sinulle ja nähdä lahjasi? Napsauta linkkiä alapuolella:\n\n$4\n\nToivomme, että 
pidät siitä!\n\nKiittäen,\n\n\n{{GRAMMAR:genitive|{{SITENAME}}}} 
tiimi\n\n---\n\nHei, etkö halua enää saada sähköposteja meiltä?\n\nNapsauta 
$5\nja muuta asetuksiasi poistaaksesi sähköpostitoiminnot käytöstä.",
+       "echo-category-title-social-gift": "Lahjat",
+       "echo-pref-tooltip-social-gift": "Ilmoita minulle, kun joku lähettää 
minulle lahjan.",
+       "notification-social-gift-send-no-message": "$1 lähetti juuri sinulle 
lahjan: $2.",
+       "notification-social-gift-send-with-message": "$1 lähetti juuri sinulle 
lahjan: $2.<br /><br />''$2''",
+       "notification-social-gift-send-bundle": "{{PLURAL:$1|Yksi henkilö 
lähetti|$1 henkilöä lähettivät}} sinulle lahjoja.",
        "right-giftadmin": "Luoda uusia ja muokata olemassa olevia lahjoja"
 }
diff --git a/UserProfile/SpecialUpdateProfile.php 
b/UserProfile/SpecialUpdateProfile.php
index 20ef761..50da25d 100644
--- a/UserProfile/SpecialUpdateProfile.php
+++ b/UserProfile/SpecialUpdateProfile.php
@@ -783,8 +783,13 @@
                $form .= '<form action="" method="post" 
enctype="multipart/form-data" name="profile">';
                $form .= '<div class="profile-info clearfix">
                        <div class="profile-update">
-                               <p class="profile-update-title">' . $this->msg( 
'user-profile-preferences-emails' )->plain() . '</p>
-                               <p class="profile-update-row">'
+                               <p class="profile-update-title">' . $this->msg( 
'user-profile-preferences-emails' )->plain() . '</p>';
+               if ( class_exists( 'EchoEvent' ) ) {
+                       $form .= '<p class="profile-update-row">' .
+                               $this->msg( 
'user-profile-preferences-emails-manage' )->parse() .
+                               '</p>';
+               } else {
+                       $form .= '<p class="profile-update-row">'
                                        . $this->msg( 
'user-profile-preferences-emails-personalmessage' )->plain() .
                                        ' <input type="checkbox" size="25" 
name="notify_message" id="notify_message" value="1"' . ( ( $user->getIntOption( 
'notifymessage', 1 ) == 1 ) ? 'checked' : '' ) . '/>
                                </p>
@@ -801,6 +806,7 @@
                                        . $this->msg( 
'user-profile-preferences-emails-level' )->plain() .
                                        ' <input type="checkbox" size="25" 
name="notify_honorifics" id="notify_honorifics" value="1"' . ( ( 
$user->getIntOption( 'notifyhonorifics', 1 ) == 1 ) ? 'checked' : '' ) . '/>
                                </p>';
+               }
 
                $form .= '<p class="profile-update-title">' .
                        $this->msg( 'user-profile-preferences-miscellaneous' 
)->plain() .
diff --git a/UserRelationship/EchoUserRelationshipPresentationModel.php 
b/UserRelationship/EchoUserRelationshipPresentationModel.php
new file mode 100644
index 0000000..eba3725
--- /dev/null
+++ b/UserRelationship/EchoUserRelationshipPresentationModel.php
@@ -0,0 +1,94 @@
+<?php
+
+/**
+ * Formatter for user relationship (friend/foe) notifications ('social-rel-*')
+ */
+class EchoUserRelationshipPresentationModel extends EchoEventPresentationModel 
{
+
+       public function getIconType() {
+               $eventType = $this->event->getType();
+               $relType = $this->event->getExtraParam( 'rel_type' );
+
+               if ( $relType == 1 ) { // friend added/pending friend request
+                       return 'gratitude';
+               } elseif ( $eventType == 'social-rel-accept' && $relType != 1 ) 
{ // foe added
+                       return 'social-added';
+               } else { // pending friend or foe request
+                       // @todo FIXME: better icon
+                       return 'placeholder';
+               }
+       }
+
+       public function getHeaderMessage() {
+               $eventType = $this->event->getType();
+               $message = $this->event->getExtraParam( 'message' );
+               $relType = $this->event->getExtraParam( 'rel_type' );
+
+               if ( $eventType == 'social-rel-add' ) { // pending request
+                       if ( $relType == 1 && $message ) {
+                               $msg = 
'notification-social-rel-add-friend-message';
+                       } elseif ( $relType == 1 ) {
+                               $msg = 
'notification-social-rel-add-friend-no-message';
+                       } elseif ( $relType !== 1 && $message ) {
+                               $msg = 
'notification-social-rel-add-foe-message';
+                       } else {
+                               $msg = 
'notification-social-rel-add-foe-no-message';
+                       }
+                       return $this->msg(
+                               $msg,
+                               $this->event->getAgent()->getName(),
+                               $message
+                       );
+               } elseif ( $eventType == 'social-rel-accept' ) { // accepted 
request
+                       $msg = ( $relType == 1 ? 
'notification-social-rel-accept-friend' : 'notification-social-rel-accept-foe' 
);
+                       return $this->msg(
+                               $msg,
+                               $this->event->getAgent()->getName()
+                       );
+               }
+       }
+
+       public function getBodyMessage() {
+               return false;
+       }
+
+       public function getPrimaryLink() {
+               $eventType = $this->event->getType();
+               $relType = $this->event->getExtraParam( 'rel_type' );
+               if ( $eventType == 'social-rel-add' ) { // pending request
+                       $url = SpecialPage::getTitleFor( 
'ViewRelationshipRequests' )->getLocalURL();
+               } elseif ( $eventType == 'social-rel-accept' ) { // accepted 
request
+                       $url = SpecialPage::getTitleFor( 'ViewRelationships' 
)->getLocalURL();
+               }
+               return array(
+                       'url' => $url,
+                       'label' => $this->msg( 'echo-learn-more' )->text()
+               );
+       }
+
+       public function getSecondaryLinks() {
+               // Apparently these two can't be the other way around 'cause 
it'll look
+               // stupid. Who knew?
+               return array( $this->getAgentLink(), 
$this->getSpecialPageLink() );
+       }
+
+       private function getSpecialPageLink() {
+               $eventType = $this->event->getType();
+               $relType = $this->event->getExtraParam( 'rel_type' );
+               if ( $eventType == 'social-rel-add' ) { // pending request
+                       $label = $this->msg( 'viewrelationshiprequests' 
)->text();
+                       $url = SpecialPage::getTitleFor( 
'ViewRelationshipRequests' )->getLocalURL();
+               } elseif ( $eventType == 'social-rel-accept' ) { // accepted 
request
+                       $label = $this->msg( ( $relType == 1 ) ? 
'ur-title-friend' : 'ur-title-foe' )->params( $this->getViewingUserForGender() 
)->text();
+                       $url = SpecialPage::getTitleFor( 'ViewRelationships' 
)->getLocalURL();
+               }
+               return array(
+                       'label' => $label,
+                       'url' => $url,
+                       'description' => '',
+                       'icon' => false,
+                       'prioritized' => true,
+               );
+       }
+
+}
\ No newline at end of file
diff --git a/UserRelationship/UserRelationshipClass.php 
b/UserRelationship/UserRelationshipClass.php
index 546a06d..188e7e6 100644
--- a/UserRelationship/UserRelationshipClass.php
+++ b/UserRelationship/UserRelationshipClass.php
@@ -51,6 +51,22 @@
                        $this->sendRelationshipRequestEmail( $userIdTo, 
$this->user_name, $type );
                }
 
+               if ( class_exists( 'EchoEvent' ) ) {
+                       $userFrom = User::newFromId( $this->user_id );
+
+                       EchoEvent::create( array(
+                               'type' => 'social-rel-add',
+                               'agent' => $userFrom,
+                               'title' => $userFrom->getUserPage(),
+                               'extra' => array(
+                                       'target' => $userIdTo,
+                                       'from' => $this->user_id,
+                                       'rel_type' => $type,
+                                       'message' => $message
+                               )
+                       ) );
+               }
+
                return $requestId;
        }
 
@@ -67,7 +83,8 @@
                $user = User::newFromId( $userIdTo );
                $user->loadFromDatabase();
 
-               if ( $user->getEmail() && $user->getIntOption( 
'notifyfriendrequest', 1 ) ) {
+               $wantsEmail = class_exists( 'EchoEvent' ) ? 
$user->getBoolOption( 'echo-subscriptions-email-social-rel' ) : 
$user->getIntOption( 'notifyfriendrequest', 1 );
+               if ( $user->getEmail() && $wantsEmail ) {
                        $requestLink = SpecialPage::getTitleFor( 
'ViewRelationshipRequests' );
                        $updateProfileLink = SpecialPage::getTitleFor( 
'UpdateProfile' );
 
@@ -123,7 +140,8 @@
                $user = User::newFromId( $userIdTo );
                $user->loadFromDatabase();
 
-               if ( $user->getEmail() && $user->getIntOption( 
'notifyfriendrequest', 1 ) ) {
+               $wantsEmail = class_exists( 'EchoEvent' ) ? 
$user->getBoolOption( 'echo-subscriptions-email-social-rel' ) : 
$user->getIntOption( 'notifyfriendrequest', 1 );
+               if ( $user->getEmail() && $wantsEmail ) {
                        $userLink = Title::makeTitle( NS_USER, $userFrom );
                        $updateProfileLink = SpecialPage::getTitleFor( 
'UpdateProfile' );
 
@@ -179,7 +197,8 @@
                $user = User::newFromId( $userIdTo );
                $user->loadFromDatabase();
 
-               if ( $user->isEmailConfirmed() && $user->getIntOption( 
'notifyfriendrequest', 1 ) ) {
+               $wantsEmail = class_exists( 'EchoEvent' ) ? 
$user->getBoolOption( 'echo-subscriptions-email-social-rel' ) : 
$user->getIntOption( 'notifyfriendrequest', 1 );
+               if ( $user->isEmailConfirmed() && $wantsEmail ) {
                        $userLink = Title::makeTitle( NS_USER, $userFrom );
                        $updateProfileLink = SpecialPage::getTitleFor( 
'UpdateProfile' );
 
@@ -298,6 +317,21 @@
                        $wgMemc->delete( wfMemcKey( 'relationship', 'profile', 
"{$this->user_id}-{$ur_type}" ) );
                        $wgMemc->delete( wfMemcKey( 'relationship', 'profile', 
"{$ur_user_id_from}-{$ur_type}" ) );
 
+                       if ( class_exists( 'EchoEvent' ) ) {
+                               $userFrom = User::newFromId( $this->user_id );
+
+                               EchoEvent::create( array(
+                                       'type' => 'social-rel-accept',
+                                       'agent' => $userFrom,
+                                       'title' => $userFrom->getUserPage(),
+                                       'extra' => array(
+                                               'target' => $ur_user_id_from,
+                                               'from' => $this->user_id,
+                                               'rel_type' => $ur_type
+                                       )
+                               ) );
+                       }
+
                        // Hooks (for Semantic SocialProfile mostly)
                        if ( $ur_type == 1 ) {
                                Hooks::run( 'NewFriendAccepted', array( 
$ur_user_name_from, $this->user_name ) );
diff --git a/UserRelationship/UserRelationshipHooks.php 
b/UserRelationship/UserRelationshipHooks.php
new file mode 100644
index 0000000..c3d5419
--- /dev/null
+++ b/UserRelationship/UserRelationshipHooks.php
@@ -0,0 +1,74 @@
+<?php
+
+class UserRelationshipHooks {
+       /**
+        * For the Echo extension.
+        *
+        * @param array $notifications Echo notifications
+        * @param array $notificationCategories Echo notification categories
+        * @param array $icons Icon details
+        * @return bool
+        */
+       public static function onBeforeCreateEchoEvent( &$notifications, 
&$notificationCategories, &$icons ) {
+               $notificationCategories['social-rel'] = array(
+                       'priority' => 2,
+                       'tooltip' => 'echo-pref-tooltip-social-rel',
+               );
+
+               $notifications['social-rel-add'] = array(
+                       'primary-link' => array( 'message' => 
'notification-link-text-view-edit', 'destination' => 'diff' ),
+                       'category' => 'social-rel',
+                       'group' => 'interactive',
+                       'presentation-model' => 
'EchoUserRelationshipPresentationModel',
+                       EchoAttributeManager::ATTR_LOCATORS => array(
+                               'EchoUserLocator::locateEventAgent'
+                       ),
+                       'payload' => array( 'relationship-add' ),
+                       'email-subject-message' => 
'notification-social-rel-add-email-subject',
+                       'email-subject-params' => array( 'user' ),
+                       'email-body-batch-message' => 
'notification-social-rel-add-email-batch-body',
+                       'email-body-batch-params' => array( 'user', 
'relationship' ),
+                       'icon' => 'gratitude',
+               );
+
+               $notifications['social-rel-accept'] = array(
+                       'primary-link' => array( 'message' => 
'notification-link-text-view-edit', 'destination' => 'diff' ),
+                       'category' => 'social-rel',
+                       'group' => 'interactive',
+                       'presentation-model' => 
'EchoUserRelationshipPresentationModel',
+                       EchoAttributeManager::ATTR_LOCATORS => array(
+                               'EchoUserLocator::locateEventAgent'
+                       ),
+                       'email-subject-message' => 
'notification-social-rel-accept-email-subject',
+                       'email-subject-params' => array( 'user' ),
+                       'email-body-batch-message' => 
'notification-social-rel-accept-email-batch-body',
+                       'email-body-batch-params' => array( 'user' ),
+                       'icon' => 'gratitude',
+               );
+
+               $icons['social-added'] = array(
+                       'path' => 'SocialProfile/images/notifications-added.svg'
+               );
+
+               return true;
+       }
+
+       /**
+        * Add user to be notified on Echo event
+        *
+        * @param EchoEvent $event
+        * @param array $users
+        * @return bool
+        */
+       public static function onEchoGetDefaultNotifiedUsers( $event, &$users ) 
{
+               switch ( $event->getType() ) {
+                       case 'social-rel-add':
+                       case 'social-rel-accept':
+                               $extra = $event->getExtra();
+                               $targetId = $extra['target'];
+                               $users[] = User::newFromId( $targetId );
+                               break;
+               }
+               return true;
+       }
+}
\ No newline at end of file
diff --git a/UserRelationship/i18n/en.json b/UserRelationship/i18n/en.json
index ae28825..70eb860 100644
--- a/UserRelationship/i18n/en.json
+++ b/UserRelationship/i18n/en.json
@@ -49,8 +49,8 @@
        "ur-add-button-friend": "Add as friend",
        "ur-add-sent-title-foe": "We have sent your foe request to $1!",
        "ur-add-sent-title-friend": "We have sent your friend request to $1!",
-       "ur-add-sent-message-foe": "Your foe request has been sent to $1 for 
confirmation.\nIf $1 confirms your request, you will receive a follow-up 
e-mail",
-       "ur-add-sent-message-friend": "Your friend request has been sent to $1 
for confirmation.\nIf $1 confirms your request, you will receive a follow-up 
e-mail",
+       "ur-add-sent-message-foe": "Your foe request has been sent to $1 for 
confirmation.\nIf $1 confirms your request, you will receive a follow-up 
notification.",
+       "ur-add-sent-message-friend": "Your friend request has been sent to $1 
for confirmation.\nIf $1 confirms your request, you will receive a follow-up 
notification.",
        "ur-add-error-message-no-user": "The user you are trying to add does 
not exist.",
        "ur-add-error-message-blocked": "You are currently blocked and cannot 
add friends or foes.",
        "ur-add-error-message-yourself": "You cannot add yourself as a friend 
or foe.",
@@ -90,5 +90,16 @@
        "friend_removed_body": "Hi $1.\n\n$2 has removed you as a friend on 
{{SITENAME}}!\n\nThanks,\n\n\nThe {{SITENAME}} team\n\n---\n\nHey, want to stop 
getting e-mails from us?\n\nClick $4\nand change your settings to disable 
e-mail notifications.",
        "foe_removed_subject": "Woohoo! $1 has removed you as a foe on 
{{SITENAME}}!",
        "foe_removed_body_html": "Hi $1.\n\n\t$2 has removed you as a foe on 
{{SITENAME}}!\n\nPerhaps you two are on your way to becoming 
friends?\n\nThanks,\n\n\nThe {{SITENAME}} team\n\n---\n\nHey, want to stop 
getting e-mails from us?\n\nClick [[Special:UpdateProfile]]\nand change your 
settings to disable e-mail notifications.",
-       "foe_removed_body": "Hi $1.\n\n\t$2 has removed you as a foe on 
{{SITENAME}}!\n\nPerhaps you two are on your way to becoming 
friends?\n\nThanks,\n\n\nThe {{SITENAME}} team\n\n---\n\nHey, want to stop 
getting e-mails from us?\n\nClick $4\nand change your settings to disable 
e-mail notifications."
+       "foe_removed_body": "Hi $1.\n\n\t$2 has removed you as a foe on 
{{SITENAME}}!\n\nPerhaps you two are on your way to becoming 
friends?\n\nThanks,\n\n\nThe {{SITENAME}} team\n\n---\n\nHey, want to stop 
getting e-mails from us?\n\nClick $4\nand change your settings to disable 
e-mail notifications.",
+       "echo-category-title-social-rel": "User relationship changes",
+       "echo-pref-tooltip-social-rel": "Notify me when someone sends me a user 
relationship request (friend or foe request).",
+       "echo-show-social-rel-add-link": "(Friend/Foe request)",
+       "notification-social-rel-add-friend-message": "$1 wants to be your 
friend.<br /><br />''$2''",
+       "notification-social-rel-add-foe-message": "$1 wants to be your foe.<br 
/><br />''$2''",
+       "notification-social-rel-add-friend-no-message": "$1 wants to be your 
friend.",
+       "notification-social-rel-add-foe-no-message": "$1 wants to be your 
foe.",
+       "notification-social-rel-accept-friend": "You became friends with $1.",
+       "notification-social-rel-accept-foe": "You became foes with $1.",
+       "notification-social-rel-accept-email-subject": "$1 has accepted your 
relationship request!",
+       "notification-social-rel-accept-email-batch-body": "$1 has accepted 
your relationship request."
 }
diff --git a/UserRelationship/i18n/fi.json b/UserRelationship/i18n/fi.json
index b6708fa..c55b7df 100644
--- a/UserRelationship/i18n/fi.json
+++ b/UserRelationship/i18n/fi.json
@@ -49,8 +49,8 @@
        "ur-add-button-friend": "Lisää ystäväksi",
        "ur-add-sent-title-foe": "Olemme lähettäneet vihollisuuspyyntösi 
käyttäjälle $1!",
        "ur-add-sent-title-friend": "Olemme lähettäneet ystävyyspyyntösi 
käyttäjälle $1!",
-       "ur-add-sent-message-foe": "Vihollisuuspyyntösi on lähetetty 
käyttäjälle $1 vahvistusta varten.\nJos $1 vahvistaa pyyntösi, saat sähköpostia 
aiheesta",
-       "ur-add-sent-message-friend": "Ystävyyspyyntösi on lähetetty 
käyttäjälle $1 vahvistusta varten.\nJos $1 vahvistaa pyyntösi, saat sähköpostia 
aiheesta",
+       "ur-add-sent-message-foe": "Vihollisuuspyyntösi on lähetetty 
käyttäjälle $1 vahvistusta varten.\nJos $1 vahvistaa pyyntösi, saat ilmoituksen 
aiheesta.",
+       "ur-add-sent-message-friend": "Ystävyyspyyntösi on lähetetty 
käyttäjälle $1 vahvistusta varten.\nJos $1 vahvistaa pyyntösi, saat ilmoituksen 
aiheesta.",
        "ur-add-error-message-no-user": "Käyttäjää, jota koitat lisätä ei ole 
olemassa.",
        "ur-add-error-message-blocked": "Olet muokkauseston alaisena etkä voi 
lisätä ystäviä tai vihollisia.",
        "ur-add-error-message-yourself": "Et voi lisätä itseäsi ystäväksesi tai 
viholliseksesi.",
@@ -90,5 +90,14 @@
        "friend_removed_body": "Hei $1:\n\n$2 on poistanut sinut 
ystävälistaltaan 
{{GRAMMAR:inessive|{{SITENAME}}}}!\n\nKiittäen,\n\n\n{{GRAMMAR:genitive|{{SITENAME}}}}
 tiimi\n\n---\n\nHei, etkö enää halua saada sähköpostia meiltä?\n\nNapsauta 
$4\nja muuta asetuksiasi poistaaksesi sähköposti-ilmoitukset käytöstä.",
        "foe_removed_subject": "Jippii! $1 on poistanut sinut 
vihollislistaltaan {{GRAMMAR:inessive|{{SITENAME}}}}!",
        "foe_removed_body_html": "Hei $1:\n\n$2 on poistanut sinut 
vihollislistaltaan {{GRAMMAR:inessive|{{SITENAME}}}}!\n\nEhkäpä teistä tulee 
vielä ystävät?\n\nKiittäen,\n\n\n{{GRAMMAR:genitive|{{SITENAME}}}} 
tiimi\n\n---\n\nHei, etkö enää halua saada sähköpostia meiltä?\n\nNapsauta 
[[Special:UpdateProfile]]\nja muuta asetuksiasi poistaaksesi 
sähköposti-ilmoitukset käytöstä.",
-       "foe_removed_body": "Hei $1:\n\n$2 on poistanut sinut 
vihollislistaltaan {{GRAMMAR:inessive|{{SITENAME}}}}!\n\nEhkäpä teistä tulee 
vielä ystävät?\n\nKiittäen,\n\n\n{{GRAMMAR:genitive|{{SITENAME}}}} 
tiimi\n\n---\n\nHei, etkö enää halua saada sähköpostia meiltä?\n\nNapsauta 
$4\nja muuta asetuksiasi poistaaksesi sähköposti-ilmoitukset käytöstä."
+       "foe_removed_body": "Hei $1:\n\n$2 on poistanut sinut 
vihollislistaltaan {{GRAMMAR:inessive|{{SITENAME}}}}!\n\nEhkäpä teistä tulee 
vielä ystävät?\n\nKiittäen,\n\n\n{{GRAMMAR:genitive|{{SITENAME}}}} 
tiimi\n\n---\n\nHei, etkö enää halua saada sähköpostia meiltä?\n\nNapsauta 
$4\nja muuta asetuksiasi poistaaksesi sähköposti-ilmoitukset käytöstä.",
+       "echo-category-title-social-rel": "Käyttäjäsuhteiden muutokset",
+       "echo-pref-tooltip-social-rel": "Ilmoita minulle, kun joku lähettää 
minulle käyttäjäsuhdepyynnön (ystävyyspyyntö tai vihollisuuspyyntö).",
+       "echo-show-social-rel-add-link": "(Ystävyys-/vihollisuuspyyntö)",
+       "notification-social-rel-add-friend": "$1 haluaa olla ystäväsi.<br 
/><br />''$2''",
+       "notification-social-rel-add-foe": "$1 haluaa olla vihollisesi.<br 
/><br />''$2''",
+       "notification-social-rel-accept-friend": "Sinusta tuli ystävä 
käyttäjälle $1.",
+       "notification-social-rel-accept-foe": "Sinusta tuli vihollinen 
käyttäjälle $1.",
+       "notification-social-rel-accept-email-subject": "$1 on hyväksynyt 
käyttäjäsuhdepyyntösi!",
+       "notification-social-rel-accept-email-batch-body": "$1 on hyväksynyt 
käyttäjäsuhdepyyntösi."
 }
diff --git a/UserStats/EchoUserLevelAdvancePresentationModel.php 
b/UserStats/EchoUserLevelAdvancePresentationModel.php
new file mode 100644
index 0000000..e5b955e
--- /dev/null
+++ b/UserStats/EchoUserLevelAdvancePresentationModel.php
@@ -0,0 +1,35 @@
+<?php
+
+/**
+ * Formatter for user's level up notifications ('social-level-up')
+ */
+class EchoUserLevelAdvancePresentationModel extends EchoEventPresentationModel 
{
+
+       public function getIconType() {
+               return 'social-level-up';
+       }
+
+       public function getHeaderMessage() {
+               if ( $this->isBundled() ) {
+                       return $this->msg(
+                               'notification-social-level-up-bundle',
+                               $this->getBundleCount(),
+                               $this->event->getExtraParam( 'new-level' )
+                       );
+               } else {
+                       return $this->msg( 'notification-social-level-up', 
$this->event->getExtraParam( 'new-level' ) );
+               }
+       }
+
+       public function getBodyMessage() {
+               return false;
+       }
+
+       public function getPrimaryLink() {
+               return array(
+                       'url' => Title::makeTitle( NS_USER, 
$this->event->getAgent()->getName() )->getLocalURL(),
+                       'label' => $this->msg( 'echo-learn-more' )->text()
+               );
+       }
+
+}
\ No newline at end of file
diff --git a/UserStats/UserStatsClass.php b/UserStats/UserStatsClass.php
index aa6ca28..a2c2fff 100644
--- a/UserStats/UserStatsClass.php
+++ b/UserStats/UserStatsClass.php
@@ -629,6 +629,7 @@
                                        }
                                }
                        }
+
                        if ( $wgEnableFacebook ) {
                                $s = $dbw->selectRow(
                                        'fb_link_view_opinions',
@@ -666,10 +667,25 @@
                                                $this->user_id,
                                                $user_level->getLevelName()
                                        );
+
+                                       if ( class_exists( 'EchoEvent' ) ) {
+                                               $userFrom = User::newFromId( 
$this->user_id );
+
+                                               EchoEvent::create( array(
+                                                       'type' => 
'social-level-up',
+                                                       'agent' => $userFrom,
+                                                       'extra' => array(
+                                                               'notifyAgent' 
=> true,
+                                                               'new-level' => 
$user_level->getLevelName()
+                                                       )
+                                               ) );
+                                       }
                                }
                        }
+
                        $this->clearCache();
                }
+
                return $stats_data;
        }
 }
diff --git a/UserStats/UserStatsHooks.php b/UserStats/UserStatsHooks.php
new file mode 100644
index 0000000..f819f19
--- /dev/null
+++ b/UserStats/UserStatsHooks.php
@@ -0,0 +1,58 @@
+<?php
+
+class UserStatsHooks {
+       /**
+        * For the Echo extension.
+        *
+        * @param array $notifications Echo notifications
+        * @param array $notificationCategories Echo notification categories
+        * @param array $icons Icon details
+        * @return bool
+        */
+       public static function onBeforeCreateEchoEvent( &$notifications, 
&$notificationCategories, &$icons ) {
+               $notificationCategories['social-level-up'] = array(
+                       'priority' => 3,
+                       'tooltip' => 'echo-pref-tooltip-social-level-up',
+               );
+
+               $notifications['social-level-up'] = array(
+                       'category' => 'social-level-up',
+                       'group' => 'interactive',
+                       'presentation-model' => 
'EchoUserLevelAdvancePresentationModel',
+                       EchoAttributeManager::ATTR_LOCATORS => array(
+                               'EchoUserLocator::locateEventAgent'
+                       ),
+
+                       'title-message' => 'notification-social-level-up',
+                       'title-params' => array( 'new-level' ),
+                       'payload' => array( 'level-up' ),
+
+                       'icon' => 'social-level-up',
+
+                       'bundle' => array( 'web' => true, 'email' => true ),
+                       'bundle-message' => 
'notification-social-level-up-bundle'
+               );
+
+               $icons['social-level-up'] = array(
+                       'path' => 
'SocialProfile/images/notifications-level-up.svg'
+               );
+
+               return true;
+       }
+
+       /**
+        * Set bundle for message
+        *
+        * @param EchoEvent $event
+        * @param string $bundleString
+        * @return bool
+        */
+       public static function onEchoGetBundleRules( $event, &$bundleString ) {
+               switch ( $event->getType() ) {
+                       case 'social-level-up':
+                               $bundleString = 'social-level-up';
+                               break;
+               }
+               return true;
+       }
+}
\ No newline at end of file
diff --git a/UserStats/i18n/en.json b/UserStats/i18n/en.json
index 44c0ee5..77bffb8 100644
--- a/UserStats/i18n/en.json
+++ b/UserStats/i18n/en.json
@@ -53,6 +53,10 @@
        "level-advance-subject": "You are now a \"$1\" on {{SITENAME}}!",
        "level-advance-body-html": "Hi $1.\n\nYou are now a \"$2\" on 
{{SITENAME}}!\n\nCongratulations,\n\nThe {{SITENAME}} team\n\n---\nHey, want to 
stop getting e-mails from us?\n\nClick [[Special:UpdateProfile]]\nand change 
your settings to disable e-mail notifications.",
        "level-advance-body": "Hi $1.\n\nYou are now a \"$2\" on 
{{SITENAME}}!\n\nCongratulations,\n\nThe {{SITENAME}} team\n\n---\nHey, want to 
stop getting e-mails from us?\n\nClick $3\nand change your settings to disable 
e-mail notifications.",
+       "echo-category-title-social-level-up": "Level up",
+       "echo-pref-tooltip-social-level-up": "Notify me when I advance to a new 
level.",
+       "notification-social-level-up": "You have leveled up to \"$1\"!",
+       "notification-social-level-up-bundle": "You have leveled up 
{{PLURAL:$1|one level|$1 levels}} to $2!",
        "updateeditcounts": "Update Edit Counts",
        "updateeditcounts-updated": "Updated stats for '''$1''' 
{{PLURAL:$1|user|users}}",
        "updateeditcounts-updating": "Updating $1 with $2 
{{PLURAL:$2|edit|edits}}",
diff --git a/UserStats/i18n/fi.json b/UserStats/i18n/fi.json
index dc36d69..f4574fd 100644
--- a/UserStats/i18n/fi.json
+++ b/UserStats/i18n/fi.json
@@ -55,6 +55,10 @@
        "level-advance-subject": "Olet nyt \"$1\" 
{{GRAMMAR:inessive|{{SITENAME}}}}!",
        "level-advance-body-html": "Hei $1:\n\nOlet nyt \"$2\" 
{{GRAMMAR:inessive|{{SITENAME}}}}!\n\nOnneksi 
olkoon,\n\n{{GRAMMAR:genitive|{{SITENAME}}}} tiimi\n\n---\nHei, etkö enää halua 
saada sähköpostia meiltä?\n\nNapsauta [[Special:UpdateProfile]]\nja muuta 
asetuksiasi poistaaksesi sähköposti-ilmoitukset käytöstä.",
        "level-advance-body": "Hei $1:\n\nOlet nyt \"$2\" 
{{GRAMMAR:inessive|{{SITENAME}}}}!\n\nOnneksi 
olkoon,\n\n{{GRAMMAR:genitive|{{SITENAME}}}} tiimi\n\n---\nHei, etkö enää halua 
saada sähköpostia meiltä?\n\nNapsauta $3\nja muuta asetuksiasi poistaaksesi 
sähköposti-ilmoitukset käytöstä.",
+       "echo-category-title-social-level-up": "Käyttäjätason muutos",
+       "echo-pref-tooltip-social-level-up": "Ilmoita minulle, kun pääsen 
uudelle tasolle.",
+       "notification-social-level-up": "Olet saavuttanut tason \"$1\"!",
+       "notification-social-level-up-bundle": "Olet päässyt {{PLURAL:$1|yhden 
tason|$1 tasoa}} eteenpäin tasolle $2!",
        "generatetopusersreport": "Luo raportti huippukäyttäjistä",
        "user-stats-weekly-winners": "Viikon {{PLURAL:$1|voittaja|voittajat}}",
        "user-stats-monthly-winners": "Kuukauden 
{{PLURAL:$1|voittaja|voittajat}}",
diff --git a/UserSystemMessages/UserSystemMessagesClass.php 
b/UserSystemMessages/UserSystemMessagesClass.php
index 5010bd2..f400034 100644
--- a/UserSystemMessages/UserSystemMessagesClass.php
+++ b/UserSystemMessages/UserSystemMessagesClass.php
@@ -106,7 +106,9 @@
        public function sendAdvancementNotificationEmail( $userIdTo, $level ) {
                $user = User::newFromId( $userIdTo );
                $user->loadFromDatabase();
-               if ( $user->isEmailConfirmed() && $user->getIntOption( 
'notifyhonorifics', 1 ) ) {
+
+               $wantsEmail = class_exists( 'EchoEvent' ) ? 
$user->getBoolOption( 'echo-subscriptions-email-social-level-up' ) : 
$user->getIntOption( 'notifyhonorifics', 1 );
+               if ( $user->isEmailConfirmed() && $wantsEmail ) {
                        $updateProfileLink = SpecialPage::getTitleFor( 
'UpdateProfile' );
                        $subject = wfMessage( 'level-advance-subject', $level 
)->text();
                        if ( trim( $user->getRealName() ) ) {
diff --git a/images/notifications-added.svg b/images/notifications-added.svg
new file mode 100644
index 0000000..81cbc26
--- /dev/null
+++ b/images/notifications-added.svg
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 16.0.4, SVG Export Plug-In . SVG Version: 
6.00 Build 0)  -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" 
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd";>
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg"; 
xmlns:xlink="http://www.w3.org/1999/xlink"; x="0px" y="0px"
+        width="24px" height="24px" viewBox="0 0 24 24" enable-background="new 
0 0 24 24" xml:space="preserve">
+<g transform="matrix(1 0 0 -1 0 1638)">
+       <path 
d="M18.574,1632.199c0.469,0,0.867-0.164,1.195-0.492l0.68-0.703l-11.238-11.238l-5.824,5.824l1.887,1.887l3.938-3.926
+               l8.156,8.156C17.703,1632.035,18.105,1632.199,18.574,1632.199z"/>
+</g>
+</svg>
diff --git a/images/notifications-award.svg b/images/notifications-award.svg
new file mode 100644
index 0000000..546be32
--- /dev/null
+++ b/images/notifications-award.svg
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 18.1.1, SVG Export Plug-In . SVG Version: 
6.00 Build 0)  -->
+<svg version="1.1" xmlns="http://www.w3.org/2000/svg"; 
xmlns:xlink="http://www.w3.org/1999/xlink"; x="0px" y="0px"
+        viewBox="0 0 24 24" enable-background="new 0 0 24 24" 
xml:space="preserve" fill="#14B18A">
+<g id="Layer_1">
+       <g>
+               <circle cx="11.5" cy="8.5" r="2.5"/>
+               <path 
d="M16.3,8.7L17,8l-0.8-0.8l0.4-0.8l-1.1-0.5l0.1-0.9l-1.2-0.2l-0.1-0.9l-1.2,0.2l-0.4-0.8l-1.1,0.5L11,3l-0.8,0.8L9.3,3.4
+                       
L8.8,4.5L7.9,4.3L7.7,5.5L6.8,5.7l0.2,1.2L6.1,7.3l0.5,1.1L6,9l0.8,0.8l-0.4,0.8l1.1,0.5l-0.1,0.9l1.2,0.2l0.1,0.9l1.2-0.2
+                       
l0.4,0.8l1.1-0.5L12,14l0.8-0.8l0.8,0.4l0.5-1.1l0.9,0.1l0.2-1.2l0.9-0.1l-0.2-1.2l0.8-0.4L16.3,8.7z
 M11.5,12
+                       
C9.6,12,8,10.4,8,8.5S9.6,5,11.5,5S15,6.6,15,8.5S13.4,12,11.5,12z"/>
+               <polygon points="12,15 11.3,14.3 10.2,14.9 9.8,14.2 9,14.5 9,23 
11.5,20 14,23 14,14.5 13,14             "/>
+       </g>
+</g>
+<g id="Layer_2">
+</g>
+</svg>
diff --git a/images/notifications-gift-received.svg 
b/images/notifications-gift-received.svg
new file mode 100644
index 0000000..8834e1c
--- /dev/null
+++ b/images/notifications-gift-received.svg
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 16.0.4, SVG Export Plug-In . SVG Version: 
6.00 Build 0)  -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" 
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd";>
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg"; 
xmlns:xlink="http://www.w3.org/1999/xlink"; x="0px" y="0px"
+        width="24px" height="24px" viewBox="0 0 24 24" enable-background="new 
0 0 24 24" xml:space="preserve" fill="#14B18A">
+<g transform="matrix(1 0 0 -1 0 1638)">
+       <path 
d="M12.293,1635.211h1.02v-6.281h3.586l-4.723-5.59l-5.156,5.602h3.586v4.582c0.008,0.469,0.176,0.867,0.504,1.195
+               S11.832,1635.211,12.293,1635.211z 
M3.914,1626.234h2.754v-3.469c0-0.344,0.117-0.633,0.352-0.867s0.52-0.352,0.855-0.352h9.457
+               
v4.676h2.754v-7.418H5.602c-0.469,0-0.867,0.164-1.195,0.492s-0.492,0.723-0.492,1.184V1626.234z"/>
+</g>
+</svg>
diff --git a/images/notifications-gift-sent.svg 
b/images/notifications-gift-sent.svg
new file mode 100644
index 0000000..0a347b1
--- /dev/null
+++ b/images/notifications-gift-sent.svg
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 16.0.4, SVG Export Plug-In . SVG Version: 
6.00 Build 0)  -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" 
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd";>
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg"; 
xmlns:xlink="http://www.w3.org/1999/xlink"; x="0px" y="0px"
+        width="24px" height="24px" viewBox="0 0 24 24" enable-background="new 
0 0 24 24" xml:space="preserve" fill="#14B18A">
+<g transform="matrix(1 0 0 -1 0 1638)">
+       <path 
d="M16.617,1621.195v4.066h2.391v-6.457H6.41c-0.414,0-0.762,0.141-1.043,0.422s-0.422,0.629-0.422,1.043v4.992h2.391v-3.012
+               c0-0.297,0.102-0.547,0.305-0.75s0.453-0.305,0.75-0.305H16.617z 
M13.113,1628.719v-5.965h-0.879
+               
c-0.406,0.008-0.75,0.152-1.031,0.434s-0.426,0.625-0.434,1.031v4.5H7.629l4.5,4.875l4.125-4.875H13.113z"/>
+</g>
+</svg>
diff --git a/images/notifications-level-up.svg 
b/images/notifications-level-up.svg
new file mode 100644
index 0000000..16d4f90
--- /dev/null
+++ b/images/notifications-level-up.svg
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 18.1.1, SVG Export Plug-In . SVG Version: 
6.00 Build 0)  -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" 
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd";>
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg"; 
xmlns:xlink="http://www.w3.org/1999/xlink"; x="0px" y="0px"
+        viewBox="0 0 24 24" enable-background="new 0 0 24 24" 
xml:space="preserve" fill="#14B18A">
+<path 
d="M15.3,14.7C16.1,10.9,14.7,4,12,4c-2.7,0-4.2,6.7-3.4,10.5L7,18h2.7l0.3,1h4c0.2-0.3,0.1-0.5,0.3-1H17L15.3,14.7z
 M12,10
+       c-0.8,0-1.5-0.7-1.5-1.5S11.2,7,12,7s1.5,0.7,1.5,1.5S12.8,10,12,10z"/>
+<path d="M14,20c0,1.1-2,2-2,2s-2-0.9-2-2"/>
+</svg>

-- 
To view, visit https://gerrit.wikimedia.org/r/278868
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: merged
Gerrit-Change-Id: I0c610c2bd33955c7f36619df9a3ce6b61b3c134f
Gerrit-PatchSet: 29
Gerrit-Project: mediawiki/extensions/SocialProfile
Gerrit-Branch: master
Gerrit-Owner: Jack Phoenix <[email protected]>
Gerrit-Reviewer: GeorgeBarnick <[email protected]>
Gerrit-Reviewer: Jack Phoenix <[email protected]>
Gerrit-Reviewer: Lewis Cawte <[email protected]>

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to