Merge "Add new topics subscription button in Minerva"

This commit is contained in:
jenkins-bot 2023-03-27 23:04:55 +00:00 committed by Gerrit Code Review
commit 9e51f11b8c
3 changed files with 100 additions and 22 deletions

View file

@ -90,6 +90,7 @@
], ],
"dependencies": [ "dependencies": [
"ext.discussionTools.init.styles", "ext.discussionTools.init.styles",
"ext.discussionTools.minervaicons",
"web2017-polyfills", "web2017-polyfills",
"moment", "moment",
"rangefix", "rangefix",
@ -159,6 +160,16 @@
"mobile" "mobile"
] ]
}, },
"ext.discussionTools.minervaicons": {
"selectorWithoutVariant": ".mw-ui-icon-minerva-{name}:before",
"useDataURI": false,
"defaultColor": "#54595d",
"class": "ResourceLoaderOOUIIconPackModule",
"icons": [
"bell",
"bellOutline"
]
},
"ext.discussionTools.debug": { "ext.discussionTools.debug": {
"packageFiles": [ "packageFiles": [
"dt.debug.js", "dt.debug.js",
@ -421,6 +432,7 @@
"GetActionName": "page", "GetActionName": "page",
"OutputPageBeforeHTML": "page", "OutputPageBeforeHTML": "page",
"OutputPageParserOutput": "page", "OutputPageParserOutput": "page",
"SidebarBeforeOutput": "page",
"SkinTemplateNavigation::Universal": "page", "SkinTemplateNavigation::Universal": "page",
"TitleGetEditNotices": "page", "TitleGetEditNotices": "page",
"ResourceLoaderGetConfigVars": "resourceloader", "ResourceLoaderGetConfigVars": "resourceloader",

View file

@ -23,10 +23,12 @@ use MediaWiki\Extension\VisualEditor\Hooks as VisualEditorHooks;
use MediaWiki\Hook\BeforePageDisplayHook; use MediaWiki\Hook\BeforePageDisplayHook;
use MediaWiki\Hook\OutputPageBeforeHTMLHook; use MediaWiki\Hook\OutputPageBeforeHTMLHook;
use MediaWiki\Hook\OutputPageParserOutputHook; use MediaWiki\Hook\OutputPageParserOutputHook;
use MediaWiki\Hook\SidebarBeforeOutputHook;
use MediaWiki\Hook\SkinTemplateNavigation__UniversalHook; use MediaWiki\Hook\SkinTemplateNavigation__UniversalHook;
use MediaWiki\Hook\TitleGetEditNoticesHook; use MediaWiki\Hook\TitleGetEditNoticesHook;
use MediaWiki\MediaWikiServices; use MediaWiki\MediaWikiServices;
use MediaWiki\Page\Hook\BeforeDisplayNoArticleTextHook; use MediaWiki\Page\Hook\BeforeDisplayNoArticleTextHook;
use MediaWiki\User\UserIdentity;
use MediaWiki\User\UserNameUtils; use MediaWiki\User\UserNameUtils;
use MediaWiki\User\UserOptionsLookup; use MediaWiki\User\UserOptionsLookup;
use OOUI\ButtonWidget; use OOUI\ButtonWidget;
@ -46,6 +48,7 @@ class PageHooks implements
GetActionNameHook, GetActionNameHook,
OutputPageBeforeHTMLHook, OutputPageBeforeHTMLHook,
OutputPageParserOutputHook, OutputPageParserOutputHook,
SidebarBeforeOutputHook,
SkinTemplateNavigation__UniversalHook, SkinTemplateNavigation__UniversalHook,
TitleGetEditNoticesHook TitleGetEditNoticesHook
{ {
@ -532,6 +535,29 @@ class PageHooks implements
return $wrapped; return $wrapped;
} }
/**
* @param Skin $skin
* @param array &$sidebar
*/
public function onSidebarBeforeOutput( $skin, &$sidebar ): void {
$output = $skin->getOutput();
if (
$skin->getSkinName() === 'minerva' &&
HookUtils::isFeatureEnabledForOutput( $output, HookUtils::TOPICSUBSCRIPTION )
) {
$button = $this->getNewTopicsSubscriptionButton(
$skin->getUser(),
$skin->getTitle(),
$skin->getContext()
);
$sidebar['TOOLBOX']['t-page-subscribe'] = [
'icon' => $button['icon'],
'text' => $button['label'],
'href' => '#',
];
}
}
/** /**
* @param SkinTemplate $sktemplate * @param SkinTemplate $sktemplate
* @param array &$links * @param array &$links
@ -541,32 +567,55 @@ class PageHooks implements
public function onSkinTemplateNavigation__Universal( $sktemplate, &$links ): void { public function onSkinTemplateNavigation__Universal( $sktemplate, &$links ): void {
$output = $sktemplate->getOutput(); $output = $sktemplate->getOutput();
if ( HookUtils::isFeatureEnabledForOutput( $output, HookUtils::TOPICSUBSCRIPTION ) ) { if ( HookUtils::isFeatureEnabledForOutput( $output, HookUtils::TOPICSUBSCRIPTION ) ) {
$user = $sktemplate->getUser(); $button = $this->getNewTopicsSubscriptionButton(
$title = $sktemplate->getTitle(); $sktemplate->getUser(),
$items = $this->subscriptionStore->getSubscriptionItemsForUser( $sktemplate->getTitle(),
$user, $sktemplate->getContext()
[ CommentUtils::getNewTopicsSubscriptionId( $title ) ]
); );
$subscriptionItem = count( $items ) ? $items[ 0 ] : null;
$isSubscribed = $subscriptionItem && !$subscriptionItem->isMuted();
$context = $sktemplate->getContext();
$links['actions']['dt-page-subscribe'] = [ $links['actions']['dt-page-subscribe'] = [
'text' => $context->msg( $isSubscribed ? 'text' => $button['label'],
'discussiontools-newtopicssubscription-button-unsubscribe-label' : 'title' => $button['tooltip'],
'discussiontools-newtopicssubscription-button-subscribe-label' 'data-mw-subscribed' => $button['isSubscribed'] ? '1' : '0',
), 'href' => $button['href'],
'title' => $context->msg( $isSubscribed ?
'discussiontools-newtopicssubscription-button-unsubscribe-tooltip' :
'discussiontools-newtopicssubscription-button-subscribe-tooltip'
),
'data-mw-subscribed' => $isSubscribed ? '1' : '0',
// TODO: Provide a no-JS action?
'href' => '#',
]; ];
} }
} }
/**
* Get data from a new topics subcription button
*
* @param UserIdentity $user User
* @param Title $title Title
* @param IContextSource $context Context
* @return array Array containing label, tooltip, icon, isSubscribed and href.
*/
private function getNewTopicsSubscriptionButton(
UserIdentity $user, Title $title, IContextSource $context
): array {
$items = $this->subscriptionStore->getSubscriptionItemsForUser(
$user,
[ CommentUtils::getNewTopicsSubscriptionId( $title ) ]
);
$subscriptionItem = count( $items ) ? $items[ 0 ] : null;
$isSubscribed = $subscriptionItem && !$subscriptionItem->isMuted();
return [
'label' => $context->msg( $isSubscribed ?
'discussiontools-newtopicssubscription-button-unsubscribe-label' :
'discussiontools-newtopicssubscription-button-subscribe-label'
)->text(),
'tooltip' => $context->msg( $isSubscribed ?
'discussiontools-newtopicssubscription-button-unsubscribe-tooltip' :
'discussiontools-newtopicssubscription-button-subscribe-tooltip'
)->text(),
'icon' => $isSubscribed ? 'bell' : 'bellOutline',
'isSubscribed' => $isSubscribed,
// TODO: Provide a no-JS action?
'href' => '#',
];
}
/** /**
* @param Title $title Title object for the page the edit notices are for * @param Title $title Title object for the page the edit notices are for
* @param int $oldid Revision ID that the edit notices are for (or 0 for latest) * @param int $oldid Revision ID that the edit notices are for (or 0 for latest)

View file

@ -222,9 +222,24 @@ function initTopicSubscriptions( $container, threadItemSet ) {
// New topics subscription button // New topics subscription button
( function () { ( function () {
// eslint-disable-next-line no-jquery/no-global-selector var $button, $label, $icon;
var $button = $( '#ca-dt-page-subscribe > a' );
var $label = $button.find( 'span' ); if ( mw.config.get( 'skin' ) === 'minerva' ) {
// eslint-disable-next-line no-jquery/no-global-selector
$button = $( '.menu__item--page-actions-overflow-t-page-subscribe' );
$label = $button.find( '.toggle-list-item__label' );
$icon = $button.find( '.mw-ui-icon' );
// HACK: We can't set data-mw-subscribed intially in Minerva, so work it out from the icon
// eslint-disable-next-line no-jquery/no-class-state
var initialState = $icon.hasClass( 'mw-ui-icon-minerva-bell' ) ? STATE_SUBSCRIBED : STATE_UNSUBSCRIBED;
$button.attr( 'data-mw-subscribed', String( initialState ) );
} else {
// eslint-disable-next-line no-jquery/no-global-selector
$button = $( '#ca-dt-page-subscribe > a' );
$label = $button.find( 'span' );
$icon = $( [] );
}
var titleObj = mw.Title.newFromText( mw.config.get( 'wgRelevantPageName' ) ); var titleObj = mw.Title.newFromText( mw.config.get( 'wgRelevantPageName' ) );
var name = utils.getNewTopicsSubscriptionId( titleObj ); var name = utils.getNewTopicsSubscriptionId( titleObj );
@ -236,6 +251,8 @@ function initTopicSubscriptions( $container, threadItemSet ) {
changeSubscription( titleObj.getPrefixedText(), name, !subscribedState, true ) changeSubscription( titleObj.getPrefixedText(), name, !subscribedState, true )
.then( function ( result ) { .then( function ( result ) {
updateSubscribeLink( $button[ 0 ], result.subscribe ? STATE_SUBSCRIBED : STATE_UNSUBSCRIBED, $label[ 0 ], true ); updateSubscribeLink( $button[ 0 ], result.subscribe ? STATE_SUBSCRIBED : STATE_UNSUBSCRIBED, $label[ 0 ], true );
$icon.toggleClass( 'mw-ui-icon-minerva-bell', !!result.subscribe );
$icon.toggleClass( 'mw-ui-icon-minerva-bellOutline', !result.subscribe );
} ); } );
} ); } );
}() ); }() );