Add new topic subscription button to page actions

Bug: T263821
Change-Id: Iab7f7d5fd1f7c229c2e0cda9369676cfd401a24e
This commit is contained in:
Ed Sanders 2023-02-17 15:14:44 -08:00
parent 2bae1864bd
commit 80dd6e2d7c
6 changed files with 102 additions and 6 deletions

View file

@ -123,6 +123,10 @@
"discussiontools-newtopic-legacy-hint",
"discussiontools-newtopic-placeholder-title",
"discussiontools-newtopic-missing-title",
"discussiontools-newtopicssubscription-button-subscribe-label",
"discussiontools-newtopicssubscription-button-subscribe-tooltip",
"discussiontools-newtopicssubscription-button-unsubscribe-label",
"discussiontools-newtopicssubscription-button-unsubscribe-tooltip",
"discussiontools-newtopicssubscription-notify-subscribed-body",
"discussiontools-newtopicssubscription-notify-subscribed-title",
"discussiontools-newtopicssubscription-notify-unsubscribed-body",
@ -408,6 +412,7 @@
"GetActionName": "page",
"OutputPageBeforeHTML": "page",
"OutputPageParserOutput": "page",
"SkinTemplateNavigation::Universal": "page",
"TitleGetEditNotices": "page",
"ResourceLoaderGetConfigVars": "resourceloader",
"GetBetaFeaturePreferences": "\\MediaWiki\\Extension\\DiscussionTools\\Hooks\\PreferenceHooks::onGetBetaFeaturePreferences",

View file

@ -53,6 +53,10 @@
"discussiontools-newtopic-legacy-hint-return": "<strong>You are now viewing the legacy experience.</strong> You can [$1 return to the new experience] or visit preferences to [$2 set the legacy experience as your default].",
"discussiontools-newtopic-missing-title": "Please provide a title for your discussion topic. If you click \"{{int:discussiontools-replywidget-newtopic}}\", your topic will be added without a title.",
"discussiontools-newtopic-placeholder-title": "Subject",
"discussiontools-newtopicssubscription-button-subscribe-label": "Subscribe",
"discussiontools-newtopicssubscription-button-subscribe-tooltip": "Subscribe to receive notifications when new topics are started on this page.",
"discussiontools-newtopicssubscription-button-unsubscribe-label": "Unsubscribe",
"discussiontools-newtopicssubscription-button-unsubscribe-tooltip": "Unsubscribe to stop receiving notifications when new topics are started on this page.",
"discussiontools-newtopicssubscription-notify-subscribed-body": "You will receive notifications when new topics are started on this page.",
"discussiontools-newtopicssubscription-notify-subscribed-title": "You have subscribed!",
"discussiontools-newtopicssubscription-notify-unsubscribed-body": "You will no longer receive notifications when new topics are started on this page.",

View file

@ -67,6 +67,10 @@
"discussiontools-newtopic-legacy-hint-return": "Message shown on the legacy section adding tool",
"discussiontools-newtopic-missing-title": "Warning message shown when leaving the title field empty while adding a new topic to the page.\n\nCopy <nowiki>{{int:discussiontools-replywidget-newtopic}}</nowiki> into your translation. It will be shown as {{msg-mw|discussiontools-replywidget-newtopic}}",
"discussiontools-newtopic-placeholder-title": "Placeholder describing the heading field of a new topic\n{{identical|Subject}}",
"discussiontools-newtopicssubscription-button-subscribe-label": "Label for the button to subscribe to notifications about new topics on this page.",
"discussiontools-newtopicssubscription-button-subscribe-tooltip": "Tooltip for the button to subscribe to notifications about new topics on this page.",
"discussiontools-newtopicssubscription-button-unsubscribe-label": "Label for the button to unsubscribe from notifications about new topics on this page.",
"discussiontools-newtopicssubscription-button-unsubscribe-tooltip": "Tooltip for the button to unsubscribe from notifications about new topics on this page.",
"discussiontools-newtopicssubscription-notify-subscribed-body": "Body of notification shown when a user subscribes to notifications about new topics on this page.",
"discussiontools-newtopicssubscription-notify-subscribed-title": "Title of notification shown when a user subscribes to notifications about new topics on this page.",
"discussiontools-newtopicssubscription-notify-unsubscribed-body": "Body of notification shown when a user unsubscribes from notifications about new topics on this page.",

View file

@ -17,11 +17,13 @@ use Html;
use IContextSource;
use MediaWiki\Actions\Hook\GetActionNameHook;
use MediaWiki\Extension\DiscussionTools\CommentFormatter;
use MediaWiki\Extension\DiscussionTools\CommentUtils;
use MediaWiki\Extension\DiscussionTools\SubscriptionStore;
use MediaWiki\Extension\VisualEditor\Hooks as VisualEditorHooks;
use MediaWiki\Hook\BeforePageDisplayHook;
use MediaWiki\Hook\OutputPageBeforeHTMLHook;
use MediaWiki\Hook\OutputPageParserOutputHook;
use MediaWiki\Hook\SkinTemplateNavigation__UniversalHook;
use MediaWiki\Hook\TitleGetEditNoticesHook;
use MediaWiki\MediaWikiServices;
use MediaWiki\Page\Hook\BeforeDisplayNoArticleTextHook;
@ -34,6 +36,7 @@ use OutputPage;
use ParserOutput;
use RequestContext;
use Skin;
use SkinTemplate;
use SpecialPage;
use Title;
@ -43,6 +46,7 @@ class PageHooks implements
GetActionNameHook,
OutputPageBeforeHTMLHook,
OutputPageParserOutputHook,
SkinTemplateNavigation__UniversalHook,
TitleGetEditNoticesHook
{
@ -527,6 +531,41 @@ class PageHooks implements
return $wrapped;
}
/**
* @param SkinTemplate $sktemplate
* @param array &$links
* @return void
* @phpcs:disable MediaWiki.NamingConventions.LowerCamelFunctionsName.FunctionName
*/
public function onSkinTemplateNavigation__Universal( $sktemplate, &$links ): void {
$output = $sktemplate->getOutput();
if ( HookUtils::isFeatureEnabledForOutput( $output, HookUtils::TOPICSUBSCRIPTION ) ) {
$user = $sktemplate->getUser();
$title = $sktemplate->getTitle();
$items = $this->subscriptionStore->getSubscriptionItemsForUser(
$user,
[ CommentUtils::getNewTopicsSubscriptionId( $title ) ]
);
$subscriptionItem = count( $items ) ? $items[ 0 ] : null;
$isSubscribed = $subscriptionItem && !$subscriptionItem->isMuted();
$context = $sktemplate->getContext();
$links['actions']['dt-page-subscribe'] = [
'text' => $context->msg( $isSubscribed ?
'discussiontools-newtopicssubscription-button-unsubscribe-label' :
'discussiontools-newtopicssubscription-button-subscribe-label'
),
'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' => '#',
];
}
}
/**
* @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)

View file

@ -16,24 +16,37 @@ var
*
* @param {HTMLElement} element Subscribe link
* @param {number|null} state State constant (STATE_UNSUBSCRIBED, STATE_SUBSCRIBED or STATE_AUTOSUBSCRIBED)
* @param {HTMLElement|null} labelElement Subscribe link, if different to element
* @param {boolean} isNewTopics Is a subscribe link for new topics subscriptions
*/
function updateSubscribeLink( element, state ) {
function updateSubscribeLink( element, state, labelElement, isNewTopics ) {
labelElement = labelElement || element;
if ( state !== null ) {
element.setAttribute( 'data-mw-subscribed', String( state ) );
}
if ( state ) {
element.textContent = mw.msg( 'discussiontools-topicsubscription-button-unsubscribe' );
element.setAttribute( 'title', mw.msg( 'discussiontools-topicsubscription-button-unsubscribe-tooltip' ) );
labelElement.textContent = mw.msg( isNewTopics ?
'discussiontools-newtopicssubscription-button-unsubscribe-label' :
'discussiontools-topicsubscription-button-unsubscribe' );
element.setAttribute( 'title', mw.msg( isNewTopics ?
'discussiontools-newtopicssubscription-button-unsubscribe-tooltip' :
'discussiontools-topicsubscription-button-unsubscribe-tooltip' )
);
} else {
element.textContent = mw.msg( 'discussiontools-topicsubscription-button-subscribe' );
element.setAttribute( 'title', mw.msg( 'discussiontools-topicsubscription-button-subscribe-tooltip' ) );
labelElement.textContent = mw.msg( isNewTopics ?
'discussiontools-newtopicssubscription-button-subscribe-label' :
'discussiontools-topicsubscription-button-subscribe' );
element.setAttribute( 'title', mw.msg( isNewTopics ?
'discussiontools-newtopicssubscription-button-subscribe-tooltip' :
'discussiontools-topicsubscription-button-subscribe-tooltip' )
);
}
}
/**
* Update a subscribe button
*
* @param {OO.ui.ButtonWidget} button Button Subscribe button
* @param {OO.ui.ButtonWidget} button Subscribe button
* @param {number|null} state State constant (STATE_UNSUBSCRIBED, STATE_SUBSCRIBED or STATE_AUTOSUBSCRIBED)
*/
function updateSubscribeButton( button, state ) {
@ -206,6 +219,26 @@ function initTopicSubscriptions( $container, threadItemSet ) {
} );
} );
} );
// New topics subscription button
( function () {
// eslint-disable-next-line no-jquery/no-global-selector
var $button = $( '#ca-dt-page-subscribe > a' );
var $label = $button.find( 'span' );
var titleObj = mw.Title.newFromText( mw.config.get( 'wgRelevantPageName' ) );
var name = utils.getNewTopicsSubscriptionId( titleObj );
$button.on( 'click', function ( e ) {
e.preventDefault();
// Get latest subscribedState
var subscribedState = getSubscribedStateFromElement( $button[ 0 ] );
changeSubscription( titleObj.getPrefixedText(), name, !subscribedState, true )
.then( function ( result ) {
updateSubscribeLink( $button[ 0 ], result.subscribe ? STATE_SUBSCRIBED : STATE_UNSUBSCRIBED, $label[ 0 ], true );
} );
} );
}() );
}
function initSpecialTopicSubscriptions() {

View file

@ -626,6 +626,16 @@ function compareRangesAlmostEqualBoundaries( a, b, boundary ) {
return !foundContent;
}
/**
* Get the ID for a new topics subscription from a page title
*
* @param {mw.Title} title Page title
* @return {string} ID for a new topics subscription
*/
function getNewTopicsSubscriptionId( title ) {
return 'p-topics-' + title.getNamespaceId() + ':' + title.getMain();
}
/**
* Check whether a jQuery event represents a plain left click, without any modifiers
*
@ -655,5 +665,6 @@ module.exports = {
linearWalk: linearWalk,
linearWalkBackwards: linearWalkBackwards,
compareRanges: compareRanges,
getNewTopicsSubscriptionId: getNewTopicsSubscriptionId,
isUnmodifiedLeftClick: isUnmodifiedLeftClick
};