mediawiki-extensions-Echo/modules/mobile/notifications.js
jdlrobson d3c0494a17 Dormant mobile notifications overlay lives in Echo
This code will be enabled when Iba1d7863171268066bf7597182c57a0a2041497f
relinquishes the responsibility for rendering the Echo notification badge
and wiring up of the related JS.

It makes 3 assumptions:
1) Minerva will expose a VERSION property on the skins.minerva.scripts module
to tell Echo it can begin control of the functionality
2) A new hook `SkinMinervaReplaceNotificationsBadge` will run on the server side
allowing Echo extension to render the Notifications badge in Minerva.
3) A new client side hook (echo.mobile) will fire whenever the Echo dialog is opened or
closed.

All code relating to Echo inside MobileFrontend and Minerva is
moved here.
CSS for the modules is kept in Minerva as skinStyles

This code remains dormant until Iba1d7863171268066bf7597182c57a0a2041497f lands.
It pre-registers a "to-be-created" hook SkinMinervaReplaceNotificationsBadge that
substitutes the Minerva badge.

It also watches the export value of skins.minerva.scripts for a VERSION value - when
this appears it will take the signal that it should manage the frontend code.

In the new system the mobile specific code is limited to the mobile version of
Minerva. The desktop version of Echo loads on Minerva desktop - presenting an
opportunity in future to consolidate both implementations to use the same component.
The mobile version of Vector and Timeless for example will load the mobile overlay
(with existing styling issues that we don't need to worry about right now given
we don't officially support skins other than Minerva as mobile)

Testers:
* Check require( 'ext.echo.mobile' )(); inside initMobile
inside ext.echo.init does not fire until
Iba1d7863171268066bf7597182c57a0a2041497f is checked out.

Depends-On:  I1a66939d2b596094b419de40b370e79f09c85581
Bug: T221007
Change-Id: I09c27a084100b223662f84de6cbe01bebe1fe774
2019-10-09 12:36:11 -07:00

117 lines
4 KiB
JavaScript

var NOTIFICATIONS_PATH = '/notifications';
/**
* @fire echo.mobile every time the notifications overlay is opened
*/
function onOpenNotificationsOverlay() {
mw.hook( 'echo.mobile' ).fire( true );
}
/**
* @fire echo.mobile every time the notifications overlay is closed
*/
function onCloseNotificationsOverlay() {
mw.hook( 'echo.mobile' ).fire( false );
}
/*
* This code loads the necessary modules for the notifications overlay, not to be confused
* with the Toast notifications defined by common/toast.js.
*/
module.exports = function () {
var badge,
notificationsFilterOverlay = require( './notificationsFilterOverlay.js' ),
notificationsOverlay = require( './overlay.js' ),
router = require( 'mediawiki.router' ),
overlayManager = mw.mobileFrontend.require( 'mobile.startup' ).OverlayManager.getSingleton(),
NotificationBadge = require( './NotificationBadge.js' ),
initialized = false;
function showNotificationOverlay() {
var overlay = notificationsOverlay( badge.setCount.bind( badge ),
badge.markAsSeen.bind( badge ), function ( exit ) {
onCloseNotificationsOverlay();
exit();
} );
onOpenNotificationsOverlay();
return overlay;
}
// Once the DOM is loaded hijack the notifications button to display an overlay rather
// than linking to Special:Notifications.
$( function () {
badge = new NotificationBadge( {
onClick: function ( ev ) {
router.navigate( '#' + NOTIFICATIONS_PATH );
// prevent navigation to original Special:Notifications URL
// DO NOT USE stopPropagation or you'll break click tracking in WikimediaEvents
ev.preventDefault();
},
// eslint-disable-next-line no-jquery/no-global-selector
el: $( '#user-notifications.user-button' ).parent()
} );
overlayManager.add( /^\/notifications$/, showNotificationOverlay );
/**
* Adds a filter button to the UI inside notificationsInboxWidget
* @method
* @ignore
*/
function addFilterButton() {
// Create filter button once the notifications overlay has been loaded
var filterStatusButton = new OO.ui.ButtonWidget(
{
href: '#/notifications-filter',
classes: [ 'mw-echo-ui-notificationsInboxWidget-main-toolbar-nav-filter-placeholder' ],
icon: 'funnel',
label: mw.msg( 'echo-mobile-notifications-filter-title' )
} );
// eslint-disable-next-line no-jquery/no-global-selector
$( '.mw-echo-ui-notificationsInboxWidget-cell-placeholder' ).append(
$( '<div>' )
.addClass( 'mw-echo-ui-notificationsInboxWidget-main-toolbar-nav-filter' )
.addClass( 'mw-echo-ui-notificationsInboxWidget-cell' )
.append( filterStatusButton.$element )
);
}
// This code will currently only be invoked on Special:Notifications
// The code is bundled here since it makes use of loadModuleScript. This also allows
// the possibility of invoking the filter from outside the Special page in future.
// Once the 'ext.echo.special.onInitialize' hook has fired, load notification filter.
mw.hook( 'ext.echo.special.onInitialize' ).add( function () {
// eslint-disable-next-line no-jquery/no-global-selector
var $crossWikiUnreadFilter = $( '.mw-echo-ui-crossWikiUnreadFilterWidget' ),
// eslint-disable-next-line no-jquery/no-global-selector
$notifReadState = $( '.mw-echo-ui-notificationsInboxWidget-main-toolbar-readState' );
// The 'ext.echo.special.onInitialize' hook is fired whenever special page notification
// changes display on click of a filter.
// Hence the hook is restricted from firing more than once.
if ( initialized ) {
return;
}
// setup the filter button (now we have OOjs UI)
addFilterButton();
// setup route
overlayManager.add( /^\/notifications-filter$/, function () {
onOpenNotificationsOverlay();
return notificationsFilterOverlay( {
onBeforeExit: function ( exit ) {
onCloseNotificationsOverlay();
exit();
},
$notifReadState: $notifReadState,
$crossWikiUnreadFilter: $crossWikiUnreadFilter
} );
} );
initialized = true;
} );
} );
};