Adding dismiss functionality to flyout overlay.

Change-Id: Ibfbdb2a9f170e1d9b30b50e8639aee25101e71d6
This commit is contained in:
Kaldari 2013-02-12 18:08:36 -08:00
parent e7dc85c6d1
commit 16331eab92
8 changed files with 194 additions and 156 deletions

View file

@ -29,7 +29,7 @@ $messages['en'] = array(
// Dismiss interface // Dismiss interface
'echo-dismiss-button' => 'Dismiss', 'echo-dismiss-button' => 'Dismiss',
'echo-dismiss-message' => 'Turn off all <b>$1</b> notifications', 'echo-dismiss-message' => 'Turn off all $1 notifications',
'echo-dismiss-title-edit-user-talk' => 'Talk page post', 'echo-dismiss-title-edit-user-talk' => 'Talk page post',
'echo-dismiss-title-article-linked' => 'Page linked', 'echo-dismiss-title-article-linked' => 'Page linked',
'echo-dismiss-title-reverted' => 'Edit reverted', 'echo-dismiss-title-reverted' => 'Edit reverted',
@ -38,8 +38,8 @@ $messages['en'] = array(
'echo-no-agent' => '[Nobody]', 'echo-no-agent' => '[Nobody]',
'echo-no-title' => '[No page]', 'echo-no-title' => '[No page]',
'echo-error-no-formatter' => 'No formatting defined for notification', 'echo-error-no-formatter' => 'No formatting defined for notification',
'echo-error-preference' => '<b>Error:</b> Could not set $1.', 'echo-error-preference' => 'Error: Could not set user preference',
'echo-error-token' => "<b>Error</b> '''Error''' {{SITENAME}} $1.", 'echo-error-token' => 'Error: Could not retrieve user token',
// Special:Notifications // Special:Notifications
'notifications' => 'Notifications', 'notifications' => 'Notifications',

View file

@ -168,6 +168,11 @@ class EchoBasicFormatter extends EchoNotificationFormatter {
$output .= Xml::tags( 'div', array( 'class' => 'mw-echo-content' ), $content ) . "\n"; $output .= Xml::tags( 'div', array( 'class' => 'mw-echo-content' ), $content ) . "\n";
// The state div is used to visually indicate read or unread status. This is
// handled in a separate element than the notification element so that things
// like the close box won't inherit the greyed out opacity (which can't be reset).
$output = Xml::tags( 'div', array( 'class' => 'mw-echo-state' ), $output ) . "\n";
return $output; return $output;
} }

View file

@ -52,7 +52,6 @@
background-color: #EDEDEE; background-color: #EDEDEE;
position: absolute; position: absolute;
top: 0; top: 0;
left: 0;
z-index: 1; z-index: 1;
} }
.mw-echo-dismiss-message {
}

View file

@ -1,5 +1,165 @@
( function ( $, mw ) { ( function ( $, mw ) {
'use strict'; 'use strict';
mw.echo = {}; mw.echo = {
'optionsToken': '',
/**
* Change the user's preferences related to this notification type and
* reload the page.
*/
'dismiss': function( notification ) {
var _this = this,
$notification = $( notification ),
eventType = $notification.attr( 'data-notification-type' ),
change = 'echo-web-notifications' + eventType + '=0',
prefRequest = {
'action': 'options',
'change': change,
'token': mw.echo.optionsToken,
'format': 'json'
};
$.ajax( {
type: 'post',
url: mw.util.wikiScript( 'api' ),
data: prefRequest,
dataType: 'json',
success: function( data ) {
// If we're on the Notifications archive page, just refresh the page
if ( mw.config.get( 'wgCanonicalNamespace' ) === 'Special'
&& mw.config.get( 'wgCanonicalSpecialPageName' ) === 'Notifications' )
{
window.location.reload();
} else {
eventType = $notification.attr( 'data-notification-type' );
$( '.mw-echo-overlay li[data-notification-type="' + eventType + '"]' ).hide();
$notification.data( 'dismiss', false );
}
},
error: function() {
alert( mw.msg( 'echo-error-preference' ) );
}
} );
},
/**
* Handle clicking the Dismiss button.
* First we have to retrieve the options token.
*/
'setOptionsToken': function( callback, notification ) {
var _this = this;
var tokenRequest = {
'action': 'tokens',
'type' : 'options',
'format': 'json'
};
if ( this.optionsToken ) {
callback( notification );
} else {
$.ajax( {
type: 'get',
url: mw.util.wikiScript( 'api' ),
data: tokenRequest,
dataType: 'json',
success: function( data ) {
if ( typeof data.tokens.optionstoken === 'undefined' ) {
alert( mw.msg( 'echo-error-token' ) );
} else {
_this.optionsToken = data.tokens.optionstoken;
callback( notification );
}
},
error: function() {
alert( mw.msg( 'echo-error-token' ) );
}
} );
}
},
/**
* Show the dismiss interface (Dismiss and Cancel buttons).
*/
'showDismissOption': function( closeBox ) {
var $notification = $( closeBox ).parent();
$( closeBox ).hide();
$notification.data( 'dismiss', true );
$notification.find( '.mw-echo-dismiss' )
// Make sure the dismiss interface exactly covers the notification
.height( $notification.height() )
// Icon adds 45px to the notification
.width( $notification.width() - 45 )
.css( 'padding-top', $notification.css( 'padding-top' ) )
.css( 'padding-bottom', $notification.css( 'padding-bottom' ) )
.css( 'padding-right', $notification.css( 'padding-right' ) )
.css( 'padding-left', parseInt( $notification.css( 'padding-left' ) ) + 45 )
.show();
// Temprorarily ungrey-out read notifications
if ( !$notification.hasClass( 'mw-echo-unread' ) ) {
$notification.find( '.mw-echo-state' ).css( 'filter', 'alpha(opacity=100)' );
$notification.find( '.mw-echo-state' ).css( 'opacity', '1.0' );
}
},
'setUpDismissability' : function( notification ) {
var $dismissButton,
$cancelButton,
_this = this,
$notification = $( notification );
// Add dismiss box
var $closebox = $( '<div/>' )
.addClass( 'mw-echo-close-box' )
.css( 'display', 'none' )
.click( function() {
_this.showDismissOption( this );
} );
$notification.append( $closebox );
// Add dismiss and cancel buttons
$dismissButton = $( '<button/>' )
.text( mw.msg( 'echo-dismiss-button' ) )
.addClass( 'mw-echo-dismiss-button' )
.addClass( 'ui-button-blue' )
.button( {
icons: { primary: "ui-icon-closethick" }
} )
.click( function () {
_this.setOptionsToken( _this.dismiss, $notification );
} );
$cancelButton = $( '<button/>' )
.text( mw.msg( 'cancel' ) )
.addClass( 'mw-echo-cancel-button' )
.addClass( 'ui-button-red' )
.button()
.click( function () {
$notification.data( 'dismiss', false );
$notification.find( '.mw-echo-dismiss' ).hide();
$closebox.show();
// Restore greyed-out state for read notifications
if ( !$notification.hasClass( 'mw-echo-unread' ) ) {
$notification.find( '.mw-echo-state' ).css( 'filter', 'alpha(opacity=50)' );
$notification.find( '.mw-echo-state' ).css( 'opacity', '0.5' );
}
} );
$notification.find( '.mw-echo-dismiss' )
.append( $dismissButton )
.append( $cancelButton );
// Make each notification hot for dismissability
$notification.hover(
function() {
if ( !$( this ).data( 'dismiss' ) ) {
$( this ).find( '.mw-echo-close-box' ).show();
}
},
function() {
if ( !$( this ).data( 'dismiss' ) ) {
$( this ).find( '.mw-echo-close-box' ).hide();
}
}
);
},
};
} )( jQuery, mediaWiki ); } )( jQuery, mediaWiki );

View file

@ -33,18 +33,20 @@
display: block; display: block;
float: none; float: none;
border-bottom: 1px solid #DDDDDD; border-bottom: 1px solid #DDDDDD;
padding: 15px 15px 10px 15px; padding: 15px 40px 10px 15px;
margin: 0; margin: 0;
white-space: normal; white-space: normal;
font-size: 13px; font-size: 13px;
line-height: 16px; line-height: 16px;
filter: alpha(opacity=50);
opacity: 0.5;
} }
#p-personal .mw-echo-overlay li.mw-echo-notification:last-child { #p-personal .mw-echo-overlay li.mw-echo-notification:last-child {
border-bottom: none; border-bottom: none;
} }
#p-personal .mw-echo-overlay li.mw-echo-notification.mw-echo-unread { #p-personal .mw-echo-overlay li.mw-echo-notification .mw-echo-state {
filter: alpha(opacity=50);
opacity: 0.5;
}
#p-personal .mw-echo-overlay li.mw-echo-notification.mw-echo-unread .mw-echo-state {
filter: alpha(opacity=100); filter: alpha(opacity=100);
opacity: 1.0; opacity: 1.0;
} }

View file

@ -61,6 +61,7 @@
var $li = $( '<li></li>' ) var $li = $( '<li></li>' )
.data( 'details', data ) .data( 'details', data )
.data( 'id', id ) .data( 'id', id )
.attr( 'data-notification-type', data.type )
.addClass( 'mw-echo-notification' ) .addClass( 'mw-echo-notification' )
.append( data['*'] ) .append( data['*'] )
.appendTo( $ul ); .appendTo( $ul );
@ -69,6 +70,12 @@
$li.addClass( 'mw-echo-unread' ); $li.addClass( 'mw-echo-unread' );
unread.push( id ); unread.push( id );
} }
// Set up each individual notification with a close box and dismiss
// interface if it is dismissable.
if ( $li.find( '.mw-echo-dismiss' ).length ) {
mw.echo.setUpDismissability( $li );
}
} ); } );
if ( notifications.index.length > 0 ) { if ( notifications.index.length > 0 ) {

View file

@ -65,5 +65,13 @@ ul#mw-echo-special-container {
max-width: 600px; max-width: 600px;
} }
.mw-echo-notification { .mw-echo-notification {
padding: 15px 0 10px 0; padding: 15px 35px 10px 0;
}
#mw-echo-special-container .mw-echo-notification .mw-echo-state {
filter: alpha(opacity=50);
opacity: 0.5;
}
#mw-echo-special-container .mw-echo-notification.mw-echo-unread .mw-echo-state {
filter: alpha(opacity=100);
opacity: 1.0;
} }

View file

@ -8,149 +8,6 @@
'header': '', 'header': '',
'processing': false, 'processing': false,
'moreData': '0', 'moreData': '0',
'optionsToken': '',
/**
* Show the dismiss interface (Dismiss and Cancel buttons).
*/
'showDismissOption': function( closeBox ) {
var $notification = $( closeBox ).parent();
$( closeBox ).hide();
$notification.data( 'dismiss', true );
$notification.find( '.mw-echo-dismiss' ).show();
},
/**
* Handle clicking the Dismiss button.
* First we have to retrieve the options token.
*/
'dismiss': function( notification ) {
var eventType,
_this = this,
$notification = $( notification );
var tokenRequest = {
'action': 'tokens',
'type' : 'options',
'format': 'json'
};
if ( this.optionsToken ) {
this.finishDismiss( notification );
} else {
$.ajax( {
type: 'get',
url: mw.util.wikiScript( 'api' ),
data: tokenRequest,
dataType: 'json',
success: function( data ) {
if ( typeof data.tokens.optionstoken === 'undefined' ) {
alert( mw.msg( 'echo-error-token' ) );
} else {
_this.optionsToken = data.tokens.optionstoken;
_this.finishDismiss( notification );
}
/*
// TODO: Use something like this for the flyout to immediately
// hide the notifications without reloading the page. We reload
// the page in the archive interface since we're also dealing
// with date headers.
eventType = $notification.attr( 'data-notification-type' );
$( 'li[data-notification-type="' + eventType + '"]' ).hide();
*/
},
error: function() {
alert( mw.msg( 'echo-error-token' ) );
}
} );
}
},
/**
* Change the user's preferences related to this notification type and
* reload the page.
*/
'finishDismiss': function( notification ) {
var _this = this,
$notification = $( notification ),
eventType = $notification.attr( 'data-notification-type' ),
change = 'echo-web-notifications' + eventType + '=0',
prefRequest = {
'action': 'options',
'change': change,
'token': this.optionsToken,
'format': 'json'
};
$.ajax( {
type: 'post',
url: mw.util.wikiScript( 'api' ),
data: prefRequest,
dataType: 'json',
success: function( data ) {
window.location.reload();
},
error: function() {
alert( mw.msg( 'echo-error-preference' ) );
}
} );
},
'setUpDismissability' : function( notification ) {
var $dismissButton,
$cancelButton,
_this = this,
$notification = $( notification );
// Add dismiss box
var $closebox = $( '<div/>' )
.addClass( 'mw-echo-close-box' )
.css( 'display', 'none' )
.click( function() {
_this.showDismissOption( this );
} );
$notification.append( $closebox );
// Add dismiss and cancel buttons
$dismissButton = $( '<button/>' )
.text( mw.msg( 'echo-dismiss-button' ) )
.addClass( 'mw-echo-dismiss-button' )
.addClass( 'ui-button-blue' )
.button( {
icons: { primary: "ui-icon-closethick" }
} )
.click( function () {
_this.dismiss( $notification );
} );
$cancelButton = $( '<button/>' )
.text( mw.msg( 'cancel' ) )
.addClass( 'mw-echo-cancel-button' )
.addClass( 'ui-button-red' )
.button()
.click( function () {
$notification.data( 'dismiss', false );
$notification.find( '.mw-echo-dismiss' ).hide();
$closebox.show();
} );
$notification.find( '.mw-echo-dismiss' )
.height( $notification.height() )
.width( $notification.width() - 45 )
.css( 'padding-top', $notification.css( 'padding-top' ) )
.css( 'padding-bottom', $notification.css( 'padding-bottom' ) )
.append( $dismissButton )
.append( $cancelButton );
// Make each notification hot for dismissability
$notification.hover(
function() {
if ( !$( this ).data( 'dismiss' ) ) {
$( this ).find( '.mw-echo-close-box' ).show();
}
},
function() {
if ( !$( this ).data( 'dismiss' ) ) {
$( this ).find( '.mw-echo-close-box' ).hide();
}
}
);
},
/** /**
* Initialize the property in special notification page. * Initialize the property in special notification page.
@ -174,7 +31,7 @@
// interface if it is dismissable. // interface if it is dismissable.
$( '.mw-echo-notification' ).each( function() { $( '.mw-echo-notification' ).each( function() {
if ( $( this ).find( '.mw-echo-dismiss' ).length ) { if ( $( this ).find( '.mw-echo-dismiss' ).length ) {
_this.setUpDismissability( this ); mw.echo.setUpDismissability( this );
} }
} ); } );
@ -233,7 +90,7 @@
} }
if ( $li.find( '.mw-echo-dismiss' ).length ) { if ( $li.find( '.mw-echo-dismiss' ).length ) {
_this.setUpDismissability( $li ); mw.echo.setUpDismissability( $li );
} }
// update the timestamp and offset to get data from // update the timestamp and offset to get data from