mediawiki-extensions-Echo/modules/ui/mw.echo.ui.SingleNotificationItemWidget.js
Moriel Schottlender 951f146b54 Emit sortChange only for read/unread actions
Do not emit sortChange for toggleSeen, because every sortChange
creates a fake widget with a flipped 'read' state. There is no
reason to emit the sortChange event in toggleSeen anyways so it
is safer when only emitted in togglRead.

Also, make sure the controller always updates the correct seenTime
from the API when fetching local notifications. This was done for
the special page method but was overlooked for the fetching of local
notifications. For the most part, it shouldn't be affecting too much
because the SeenTimeModel is initialized with wgEchoSeenTime (which
is local) but updating the controller with the API response is the
safe thing to do, and will also cover cases where a tab was open,
notifications were seen in a different tab, and now the popup was
reopened in a "stale" tab again.

Bug: T143067
Change-Id: Ie261e32db28926d04fe14f7badd9d287ddc52749
2016-08-15 16:53:09 -07:00

101 lines
3 KiB
JavaScript

( function ( mw ) {
/**
* Single notification item widget for echo popup.
*
* @class
* @extends mw.echo.ui.NotificationItemWidget
* @mixins OO.ui.mixin.PendingElement
*
* @constructor
* @param {mw.echo.Controller} controller Echo notifications controller
* @param {mw.echo.dm.NotificationItem} model Notification item model
* @param {Object} [config] Configuration object
* @cfg {jQuery} [$overlay] A jQuery element functioning as an overlay
* for popups.
* @cfg {boolean} [bundle=false] This notification is part of a bundle
*/
mw.echo.ui.SingleNotificationItemWidget = function MwEchoUiSingleNotificationItemWidget( controller, model, config ) {
config = config || {};
// Parent constructor
mw.echo.ui.SingleNotificationItemWidget.parent.call( this, controller, model, config );
// Mixin constructors
OO.ui.mixin.PendingElement.call( this, config );
this.controller = controller;
this.model = model;
this.bundle = !!config.bundle;
this.$overlay = config.$overlay || this.$element;
// Toggle 'mark as read' functionality
this.toggleMarkAsReadButtons( !this.model.isRead() );
// Events
this.model.connect( this, { update: 'updateDataFromModel' } );
// Update read and seen states from the model
this.updateDataFromModel();
};
/* Initialization */
OO.inheritClass( mw.echo.ui.SingleNotificationItemWidget, mw.echo.ui.NotificationItemWidget );
OO.mixinClass( mw.echo.ui.SingleNotificationItemWidget, OO.ui.mixin.PendingElement );
/* Methods */
mw.echo.ui.SingleNotificationItemWidget.prototype.onPrimaryLinkClick = function () {
// Log notification click
mw.echo.logger.logInteraction(
mw.echo.Logger.static.actions.notificationClick,
mw.echo.Logger.static.context.popup,
this.getModel().getId(),
this.getModel().getCategory(),
false,
// Source of this notification if it is cross-wiki
// TODO: For notifications in local bundles, we need
// to consider changing this
this.bundle ? this.getModel().getSource() : ''
);
};
/**
* @inheritdoc
*/
mw.echo.ui.SingleNotificationItemWidget.prototype.markRead = function ( isRead ) {
isRead = isRead !== undefined ? !!isRead : true;
if ( this.model.isForeign() ) {
this.controller.markCrossWikiItemsRead( this.model.getId(), this.model.getSource() );
} else {
this.controller.markItemsRead( this.model.getId(), this.model.getModelName(), isRead );
}
};
/**
* Extend 'toggleRead' to emit sortChange so the item can be sorted
* when its read state was updated
*
* @fires sortChange
*/
mw.echo.ui.SingleNotificationItemWidget.prototype.toggleRead = function ( read ) {
var oldState = this.read;
// Parent
mw.echo.ui.SingleNotificationItemWidget.parent.prototype.toggleRead.call( this, read );
if ( oldState !== read ) {
this.emit( 'sortChange' );
}
};
/**
* Update item state when the item model changes.
*/
mw.echo.ui.SingleNotificationItemWidget.prototype.updateDataFromModel = function () {
this.toggleRead( this.model.isRead() );
this.toggleSeen( this.model.isSeen() );
};
} )( mediaWiki );