No-JS special page: One-click mark as read

Bug: T136361
Change-Id: I7896dbdf25d2c1624f97777f4c8d0af41b195ef0
Depends-On: Ic31f857c749d62a32cafae68dc3f1cbd86e1e382
This commit is contained in:
Matthew Flaschen 2016-05-27 17:02:55 -07:00
parent 1bef12c3e7
commit 188e8d7395
8 changed files with 190 additions and 22 deletions

View file

@ -253,7 +253,8 @@ $wgResourceModules += array(
'ext.echo.styles.notifications' => $echoResourceTemplate + array(
'position' => 'top',
'styles' => array(
'nojs/mw.echo.notifications.less'
'nojs/mw.echo.notifications.less',
'styles/LabelIconWidget.less',
),
'targets' => array( 'desktop', 'mobile' ),
),

View file

@ -41,8 +41,8 @@ $wgAutoloadClasses += [
'EchoEmailFormat' => __DIR__ . '/includes/EmailFormat.php',
'EchoEmailFormatter' => __DIR__ . '/includes/EmailFormatter.php',
'EchoEmailFormatterTest' => __DIR__ . '/tests/phpunit/EmailFormatterTest.php',
'EchoEmailMode' => __DIR__ . '/includes/EmailFormatter.php',
'EchoEmailFrequency' => __DIR__ . '/includes/EmailFrequency.php',
'EchoEmailMode' => __DIR__ . '/includes/EmailFormatter.php',
'EchoEmailSingle' => __DIR__ . '/includes/EmailFormatter.php',
'EchoEmailUserPresentationModel' => __DIR__ . '/includes/formatters/EmailUserPresentationModel.php',
'EchoEvent' => __DIR__ . '/includes/model/Event.php',
@ -57,8 +57,9 @@ $wgAutoloadClasses += [
'EchoForeignNotifications' => __DIR__ . '/includes/ForeignNotifications.php',
'EchoForeignPresentationModel' => __DIR__ . '/includes/formatters/EchoForeignPresentationModel.php',
'EchoHTMLEmailDecorator' => __DIR__ . '/includes/EmailFormatter.php',
'LegacyEchoHTMLEmailFormatter' => __DIR__ . '/includes/EmailFormatter.php',
'EchoHooks' => __DIR__ . '/Hooks.php',
'EchoHtmlDigestEmailFormatter' => __DIR__ . '/includes/formatters/EchoHtmlDigestEmailFormatter.php',
'EchoHtmlEmailFormatter' => __DIR__ . '/includes/formatters/EchoHtmlEmailFormatter.php',
'EchoIteratorDecorator' => __DIR__ . '/includes/iterator/IteratorDecorator.php',
'EchoLocalCache' => __DIR__ . '/includes/cache/LocalCache.php',
'EchoMentionFormatter' => __DIR__ . '/includes/formatters/MentionFormatter.php',
@ -76,14 +77,13 @@ $wgAutoloadClasses += [
'EchoNotificationMapperTest' => __DIR__ . '/tests/phpunit/mapper/NotificationMapperTest.php',
'EchoNotificationTest' => __DIR__ . '/tests/phpunit/model/NotificationTest.php',
'EchoNotifier' => __DIR__ . '/includes/Notifier.php',
'EchoOOUI\\LabelIconWidget' => __DIR__ . '/includes/ooui/LabelIconWidget.php',
'EchoOnWikiList' => __DIR__ . '/includes/ContainmentSet.php',
'EchoPageLinkFormatter' => __DIR__ . '/includes/formatters/PageLinkFormatter.php',
'EchoPageLinkedPresentationModel' => __DIR__ . '/includes/formatters/PageLinkedPresentationModel.php',
'EchoPresentationModelSectionTrait' => __DIR__ . '/includes/formatters/PresentationModelSectionTrait.php',
'EchoPlainTextDigestEmailFormatter' => __DIR__ . '/includes/formatters/EchoPlainTextDigestEmailFormatter.php',
'EchoPlainTextEmailFormatter' => __DIR__ . '/includes/formatters/EchoPlainTextEmailFormatter.php',
'EchoHtmlEmailFormatter' => __DIR__ . '/includes/formatters/EchoHtmlEmailFormatter.php',
'EchoHtmlDigestEmailFormatter' => __DIR__ . '/includes/formatters/EchoHtmlDigestEmailFormatter.php',
'EchoPresentationModelSectionTrait' => __DIR__ . '/includes/formatters/PresentationModelSectionTrait.php',
'EchoRevertedPresentationModel' => __DIR__ . '/includes/formatters/RevertedPresentationModel.php',
'EchoRevisionLocalCache' => __DIR__ . '/includes/cache/RevisionLocalCache.php',
'EchoSeenTime' => __DIR__ . '/includes/SeenTime.php',
@ -106,6 +106,7 @@ $wgAutoloadClasses += [
'EchoUserRightsPresentationModel' => __DIR__ . '/includes/formatters/UserRightsPresentationModel.php',
'EchoWelcomePresentationModel' => __DIR__ . '/includes/formatters/WelcomePresentationModel.php',
'FilteredSequentialIteratorTest' => __DIR__ . '/tests/phpunit/iterator/FilteredSequentialIteratorTest.php',
'LegacyEchoHTMLEmailFormatter' => __DIR__ . '/includes/EmailFormatter.php',
'MWEchoDbFactory' => __DIR__ . '/includes/EchoDbFactory.php',
'MWEchoDbFactoryTest' => __DIR__ . '/tests/phpunit/EchoDbFactoryTest.php',
'MWEchoEmailBatch' => __DIR__ . '/includes/EmailBatch.php',

View file

@ -8,7 +8,7 @@
*/
class SpecialNotificationsFormatter extends EchoEventFormatter {
protected function formatModel( EchoEventPresentationModel $model ) {
$markReadSpecialPage = SpecialPage::getTitleFor( 'NotificationsMarkRead' );
$markReadSpecialPage = new SpecialNotificationsMarkRead();
$id = $model->getEventId();
$icon = Html::element(
@ -20,14 +20,25 @@ class SpecialNotificationsFormatter extends EchoEventFormatter {
);
OutputPage::setupOOUI();
$markAsReadButton = new OOUI\ButtonWidget( array(
$markAsReadIcon = new OOUI\IconWidget( array(
'icon' => 'close',
'framed' => false,
'href' => $markReadSpecialPage->getLocalUrl() . '/' . $id,
'classes' => array( 'mw-echo-markAsReadButton' ),
'title' => wfMessage( 'echo-notification-markasread' )
'title' => wfMessage( 'echo-notification-markasread' ),
) );
$markAsReadForm = $markReadSpecialPage->getMinimalForm(
$id,
$this->msg( 'echo-notification-markasread' )->text(),
false,
$markAsReadIcon->toString()
);
$markAsReadButton = Html::rawElement(
'div',
array( 'class' => 'mw-echo-markAsReadButton' ),
$markAsReadForm->prepareForm()->getHTML( /* First submission attempt */ false )
);
$html = Xml::tags(
'div',
array( 'class' => 'mw-echo-title' ),

View file

@ -0,0 +1,44 @@
<?php
namespace EchoOOUI;
use OOUI\IconElement;
use OOUI\LabelElement;
use OOUI\TitledElement;
use OOUI\Tag;
use OOUI\Widget;
/**
* Widget combining a label and icon
*/
class LabelIconWidget extends Widget {
use IconElement;
use LabelElement;
use TitledElement;
/**
* @param array $config Configuration options
* @param string|HtmlSnippet $config['label'] Label text
* @param string $config['title'] Title text
* @param string $config['icon'] Icon key
*/
public function __construct( $config ) {
parent::__construct( $config );
$this->tableRow = new Tag( 'div' );
$this->tableRow->setAttributes( array(
'class' => 'oo-ui-labelIconWidget-row',
) );
$this->icon = new Tag( 'div' );
$this->label = new Tag( 'div' );
$this->initializeIconElement( array_merge( $config, [ 'iconElement' => $this->icon ] ) );
$this->initializeLabelElement( array_merge( $config, [ 'labelElement' => $this->label ] ) );
$this->initializeTitledElement( $config );
$this->addClasses( [ 'oo-ui-labelIconWidget' ] );
$this->tableRow->appendContent( $this->icon, $this->label );
$this->appendContent( $this->tableRow );
}
}

View file

@ -102,18 +102,35 @@ class SpecialNotifications extends SpecialPage {
// Build the HTML
$notices = '';
$markReadSpecialPage = SpecialPage::getTitleFor( 'NotificationsMarkRead' );
$markReadSpecialPage = new SpecialNotificationsMarkRead();
foreach ( $notifArray as $section => $data ) {
$sectionTitle = Html::element( 'span', array( 'class' => 'mw-echo-date-section-text' ), $section );
$dateSectionText = Html::element( 'span', array( 'class' => 'mw-echo-date-section-text' ), $section );
$sectionTitle = $dateSectionText;
if ( count( $data[ 'unread' ] ) > 0 ) {
// There are unread notices. Add the 'mark section as read' button
$markSectionAsReadButton = new OOUI\ButtonWidget( array(
'label' => $this->msg( 'echo-specialpage-section-markread' )->text(),
'href' => $markReadSpecialPage->getLocalURL() . '/' . join( ',', $data[ 'unread' ] ),
'classes' => array( 'mw-echo-markAsReadSectionButton' ),
$markReadSectionText = $this->msg( 'echo-specialpage-section-markread' )->text();
$markAsReadLabelIcon = new EchoOOUI\LabelIconWidget( array(
'label' => $markReadSectionText,
'icon' => 'doubleCheck',
) );
$sectionTitle .= $markSectionAsReadButton;
// There are unread notices. Add the 'mark section as read' button
$markSectionAsReadForm = $markReadSpecialPage->getMinimalForm(
$data[ 'unread' ],
$markReadSectionText,
true,
$markAsReadLabelIcon->toString()
);
$formHtml = $markSectionAsReadForm->prepareForm()->getHTML( /* First submission attempt */ false );
$formWrapper = Html::rawElement(
'div',
array(
'class' => 'mw-echo-markAsReadSectionButton',
),
$formHtml
);
$sectionTitle .= $formWrapper;
}
// Heading

View file

@ -1,5 +1,13 @@
<?php
/**
* Form for marking notifications as read by ID.
*
* This uses the normal HTMLForm handling when receiving POSTs.
* However, for a better user no-JS user experience, we integrate
* a version of the form into Special:Notifications. Thus, this
* page should normally not need to be visited directly.
*/
class SpecialNotificationsMarkRead extends FormSpecialPage {
protected $eventId;
@ -25,6 +33,10 @@ class SpecialNotificationsMarkRead extends FormSpecialPage {
return false;
}
public function getDisplayFormat() {
return 'ooui';
}
/**
* Get an HTMLForm descriptor array
* @return array
@ -55,8 +67,59 @@ class SpecialNotificationsMarkRead extends FormSpecialPage {
);
}
/**
* Gets a pre-filled version of the form; this should not have a legend or anything
* visible, except the button.
*
* @param int|array $idValue ID or array of IDs
* @param string $submitButtonValue Value attribute for button
* @param boolean $framed Whether the button should be framed
* @param string Raw HTML to use for button label
*
* @return HTMLForm
*/
public function getMinimalForm( $idValue, $submitButtonValue, $framed, $submitLabelHtml ) {
if ( !is_array( $idValue ) ) {
$idValue = array( $idValue );
}
$idString = join( ',', $idValue );
$this->setParameter( $idString );
$form = HTMLForm::factory(
$this->getDisplayFormat(),
$this->getFormFields(),
$this->getContext(),
$this->getMessagePrefix()
);
// HTMLForm assumes that the main submit button is always 'primary',
// which means it is colored. Since this form is being embedded multiple
// places on the page, it has to be neutral, so we make the button
// manually.
$form->suppressDefaultSubmit();
$form->setAction( $this->getPageTitle()->getLocalURL() );
$form->addButton( array(
'name' => 'submit',
'value' => $submitButtonValue,
'label-raw' => $submitLabelHtml,
'framed' => $framed,
) );
return $form;
}
/**
* Sets a custom label
*
* This is only called when the form is actually visited directly, which is not the
* main intended use.
*/
protected function alterForm( HTMLForm $form ) {
$form->setSubmitText( $this->msg( 'echo-notification-markasread' ) );
$form->setSubmitText( $this->msg( 'echo-notification-markasread' )->text() );
}
/**

View file

@ -59,10 +59,15 @@
text-transform: uppercase;
font-size: 1.1em;
font-weight: 800;
display: inline-block;
}
ul.mw-echo-special-notifications {
max-width: 600px;
div.mw-htmlform-submit-buttons {
margin: 0;
}
list-style: none none;
padding: 0;
margin: 0;
@ -84,11 +89,20 @@ ul.mw-echo-special-notifications {
.mw-echo-markAsReadButton {
display: none;
button {
padding: 0;
}
}
}
.mw-echo-markAsReadSectionButton {
float: right;
display: inline-block;
button.oo-ui-buttonElement-button {
padding: 2px 12px 2px 12px;
}
// HACK: temporary workaround for T136024
line-height: normal;
@ -124,7 +138,7 @@ ul.mw-echo-special-notifications {
.mw-echo-markAsReadButton {
float: right;
display: inline-block;
margin-left: 1em;
margin: 0;
opacity: 0.5;
&:hover {
@ -134,3 +148,7 @@ ul.mw-echo-special-notifications {
}
}
}
div.mw-htmlform-ooui-wrapper {
margin: 0;
}

View file

@ -0,0 +1,13 @@
.oo-ui-labelIconWidget {
display: table;
}
.oo-ui-labelIconWidget-row {
display: table-row;
.oo-ui-iconElement-icon,
.oo-ui-labelElement-label {
display: table-cell;
vertical-align: middle;
}
}