mirror of
https://gerrit.wikimedia.org/r/mediawiki/extensions/DiscussionTools
synced 2024-11-23 16:06:53 +00:00
Comment thanking
Bug: T249893 Change-Id: I64f7abc26bfc3e7b226340934a637a555edf754f
This commit is contained in:
parent
d1bffdee70
commit
a86897f890
|
@ -10,6 +10,7 @@ $cfg['directory_list'] = array_merge(
|
|||
'../../extensions/EventLogging',
|
||||
'../../extensions/Gadgets',
|
||||
'../../extensions/BetaFeatures',
|
||||
'../../extensions/Thanks',
|
||||
]
|
||||
);
|
||||
|
||||
|
@ -21,6 +22,7 @@ $cfg['exclude_analysis_directory_list'] = array_merge(
|
|||
'../../extensions/EventLogging',
|
||||
'../../extensions/Gadgets',
|
||||
'../../extensions/BetaFeatures',
|
||||
'../../extensions/Thanks',
|
||||
]
|
||||
);
|
||||
|
||||
|
|
|
@ -44,6 +44,7 @@
|
|||
"topicsubscriptions.js",
|
||||
"mobile.js",
|
||||
"overflowMenu.js",
|
||||
"thanks.js",
|
||||
"LedeSectionDialog.js",
|
||||
{
|
||||
"name": "controller/contLangMessages.json",
|
||||
|
@ -154,7 +155,12 @@
|
|||
"discussiontools-topicsubscription-notify-unsubscribed-body",
|
||||
"discussiontools-topicsubscription-notify-unsubscribed-title",
|
||||
"pagetitle",
|
||||
"skin-view-edit"
|
||||
"skin-view-edit",
|
||||
"cancel",
|
||||
"thanks-button-thank",
|
||||
"thanks-button-thanked",
|
||||
"thanks-confirmation2",
|
||||
"thanks-thanked-notice"
|
||||
]
|
||||
},
|
||||
"ext.discussionTools.minervaicons": {
|
||||
|
@ -418,6 +424,7 @@
|
|||
"RevisionDataUpdates": "dataupdates",
|
||||
"LoadExtensionSchemaUpdates": "installer",
|
||||
"GetDoubleUnderscoreIDs": "parser",
|
||||
"ApiMain::moduleManager": "api",
|
||||
"ParserAfterTidy": "parser",
|
||||
"ParserOutputPostCacheTransform": "parser",
|
||||
"BeforeDisplayNoArticleText": "page",
|
||||
|
@ -446,6 +453,9 @@
|
|||
"installer": {
|
||||
"class": "MediaWiki\\Extension\\DiscussionTools\\Hooks\\InstallerHooks"
|
||||
},
|
||||
"api": {
|
||||
"class": "MediaWiki\\Extension\\DiscussionTools\\Hooks\\ApiHooks"
|
||||
},
|
||||
"page": {
|
||||
"class": "MediaWiki\\Extension\\DiscussionTools\\Hooks\\PageHooks",
|
||||
"services": [
|
||||
|
@ -561,6 +571,10 @@
|
|||
"value": true,
|
||||
"description": "Enable permalinks frontend features: 1. Convert signature timestamps to comment links. 2. Show notification when the target comment is found on another page."
|
||||
},
|
||||
"DiscussionToolsEnableThanks": {
|
||||
"value": true,
|
||||
"description": "Show a button to thank individual comments. Requires the 'Thanks' extension."
|
||||
},
|
||||
"DiscussionToolsAutoTopicSubEditor": {
|
||||
"value": "any",
|
||||
"description": "Editor which triggers automatic topic subscriptions. Either 'discussiontoolsapi' for edits made using DiscussionTools' API (e.g. reply and new topic tools), or 'any' for any editor."
|
||||
|
|
|
@ -38,5 +38,7 @@
|
|||
"apihelp-discussiontoolssubscribe-param-commentname": "Name of the topic to subscribe to (or unsubscribe from)",
|
||||
"apihelp-discussiontoolssubscribe-param-page": "A page on which the topic appears",
|
||||
"apihelp-discussiontoolssubscribe-param-subscribe": "True to subscribe, false to unsubscribe",
|
||||
"apihelp-discussiontoolssubscribe-summary": "Subscribe (or unsubscribe) to receive notifications about a topic."
|
||||
"apihelp-discussiontoolssubscribe-summary": "Subscribe (or unsubscribe) to receive notifications about a topic.",
|
||||
"apihelp-discussiontoolsthank-param-commentid": "ID of the comment to thank.",
|
||||
"apihelp-discussiontoolsthank-summary": "Send a public thank-you notification for a comment."
|
||||
}
|
||||
|
|
|
@ -40,5 +40,7 @@
|
|||
"apihelp-discussiontoolssubscribe-param-commentname": "{{doc-apihelp-param|discussiontoolssubscribe|commentname}}",
|
||||
"apihelp-discussiontoolssubscribe-param-page": "{{doc-apihelp-param|discussiontoolssubscribe|page}}",
|
||||
"apihelp-discussiontoolssubscribe-param-subscribe": "{{doc-apihelp-param|discussiontoolssubscribe|subscribe}}",
|
||||
"apihelp-discussiontoolssubscribe-summary": "{{doc-apihelp-summary|discussiontoolssubscribe}}"
|
||||
"apihelp-discussiontoolssubscribe-summary": "{{doc-apihelp-summary|discussiontoolssubscribe}}",
|
||||
"apihelp-discussiontoolsthank-param-commentid": "{{doc-apihelp-summary|discussiontoolsthank|commentid}}",
|
||||
"apihelp-discussiontoolsthank-summary": "{{doc-apihelp-summary|discussiontoolsthank}}"
|
||||
}
|
||||
|
|
|
@ -71,6 +71,9 @@
|
|||
"discussiontools-notification-added-topic-header-bundled": "{{PLURAL:$1|One new topic|$1 new topics|100=99+ new topics}} on \"<strong>$2</strong>\".",
|
||||
"discussiontools-notification-added-topic-header-compact": "$3: <em>$4</em>",
|
||||
"discussiontools-notification-added-topic-view": "View topic",
|
||||
"discussiontools-notification-comment-thank-header": "$1 {{GENDER:$2|thanked}} {{GENDER:$4|you}} for your comment in \"<strong>$3</strong>\".",
|
||||
"discussiontools-notification-comment-thank-header-bundled": "{{PLURAL:$1|One person|$1 people|100=99+ people}} thanked {{GENDER:$3|you}} for your comment in \"<strong>$2</strong>\".",
|
||||
"discussiontools-notification-comment-thank-header-compact": "$1 {{GENDER:$2|thanked}} {{GENDER:$3|you}}.",
|
||||
"discussiontools-notification-removed-topic-body": "{{GENDER:|You}} might no longer receive notifications about {{PLURAL:$1|this topic|these topics}}.",
|
||||
"discussiontools-notification-removed-topic-header": "Topic \"<strong>$4</strong>\" was archived or removed from $3.",
|
||||
"discussiontools-notification-removed-topic-header-bundled": "{{PLURAL:$1|One topic was|$1 topics were|100=99+ topics were}} archived or removed from $2.",
|
||||
|
|
|
@ -85,6 +85,9 @@
|
|||
"discussiontools-notification-added-topic-header-bundled": "Notification header for when multiple new topics have been started on a page.\n\n* $1 - number of new topics.\n* $2 - discussion page title.",
|
||||
"discussiontools-notification-added-topic-header-compact": "Notification compact header for when a new topic has been started on a page.",
|
||||
"discussiontools-notification-added-topic-view": "Label for button to view topic that was just posted.",
|
||||
"discussiontools-notification-comment-thank-header": "Notification header for when you have been thanked for a comment. Parameters:\n* $1 is the username of the user sending the thanks (not suitable for GENDER).\n* $2 is the thanking user's name for use in GENDER.\n* $3 is the topic in which the thanked comment was posted.\n* $4 is the username of the user being thanked, for use in GENDER.",
|
||||
"discussiontools-notification-comment-thank-header-bundled": "Notification header for when you have received multiple thanks for a comment. Parameters:\n* $1 is the number of users who sent thanks for the same comment. When used with PLURAL, the value 100 represents more than 99.\n* $2 is the topic in which the thanked comment was posted.\n* $3 is the username of the user being thanked, for use in GENDER.",
|
||||
"discussiontools-notification-comment-thank-header-compact": "Notification compact header for when you have been thanked for a comment. Parameters:\n* $1 is the username of the user sending the thanks (not suitable for GENDER).\n* $2 is the thanking user's name for use in GENDER.\n* $3 is the username of the user being thanked, for use in GENDER.",
|
||||
"discussiontools-notification-removed-topic-body": "Notification body text for when multiple topics were removed from a page.\n\nFollows {{msg-mw|discussiontools-notification-removed-topic-header}} or {{msg-mw|discussiontools-notification-removed-topic-header-bundled}}.\n\nParameters:\n* $1 - the number of topics removed",
|
||||
"discussiontools-notification-removed-topic-header": "Notification header text for when a topic was removed from a page. Parameters:\n* $1 - the formatted username of the user who replied to the topic (unused)\n* $2 - the username for gender purposes (unused)\n* $3 - title of the page\n* $4 - title of the topic",
|
||||
"discussiontools-notification-removed-topic-header-bundled": "Notification header text for when multiple topics were removed from a page. Parameters:\n* $1 - the number of topics removed\n* $2 - title of the page",
|
||||
|
|
158
includes/ApiDiscussionToolsThank.php
Normal file
158
includes/ApiDiscussionToolsThank.php
Normal file
|
@ -0,0 +1,158 @@
|
|||
<?php
|
||||
|
||||
namespace MediaWiki\Extension\DiscussionTools;
|
||||
|
||||
use ApiBase;
|
||||
use ApiMain;
|
||||
use ApiUsageException;
|
||||
use MediaWiki\Extension\DiscussionTools\Hooks\HookUtils;
|
||||
use MediaWiki\Extension\DiscussionTools\ThreadItem\ContentCommentItem;
|
||||
use MediaWiki\Extension\Notifications\Model\Event;
|
||||
use MediaWiki\Extension\Thanks\Api\ApiThank;
|
||||
use MediaWiki\Extension\Thanks\Storage\LogStore;
|
||||
use MediaWiki\Extension\VisualEditor\ApiParsoidTrait;
|
||||
use MediaWiki\Permissions\PermissionManager;
|
||||
use MediaWiki\Revision\RevisionLookup;
|
||||
use MediaWiki\User\UserFactory;
|
||||
use Title;
|
||||
use Wikimedia\ParamValidator\ParamValidator;
|
||||
use Wikimedia\Parsoid\Core\ResourceLimitExceededException;
|
||||
|
||||
/**
|
||||
* API module to send DiscussionTools comment thanks notifications
|
||||
*
|
||||
* @ingroup API
|
||||
* @ingroup Extensions
|
||||
*/
|
||||
|
||||
class ApiDiscussionToolsThank extends ApiThank {
|
||||
|
||||
use ApiDiscussionToolsTrait;
|
||||
use ApiParsoidTrait;
|
||||
|
||||
private RevisionLookup $revisionLookup;
|
||||
private UserFactory $userFactory;
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function __construct(
|
||||
ApiMain $main,
|
||||
$action,
|
||||
PermissionManager $permissionManager,
|
||||
LogStore $storage,
|
||||
RevisionLookup $revisionLookup,
|
||||
UserFactory $userFactory
|
||||
) {
|
||||
parent::__construct( $main, $action, $permissionManager, $storage );
|
||||
$this->revisionLookup = $revisionLookup;
|
||||
$this->userFactory = $userFactory;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
* @throws ApiUsageException
|
||||
* @throws ResourceLimitExceededException
|
||||
*/
|
||||
public function execute() {
|
||||
$user = $this->getUser();
|
||||
$this->dieOnBadUser( $user );
|
||||
$this->dieOnUserBlockedFromThanks( $user );
|
||||
|
||||
$params = $this->extractRequestParams();
|
||||
|
||||
$title = Title::newFromText( $params['page'] );
|
||||
$commentId = $params['commentid'];
|
||||
|
||||
if ( !$title ) {
|
||||
$this->dieWithError( [ 'apierror-invalidtitle', wfEscapeWikiText( $params['page'] ) ] );
|
||||
}
|
||||
|
||||
// TODO: Using the data in the permalinks database would be much
|
||||
// faster, we just wouldn't have the comment content.
|
||||
|
||||
// Support oldid?
|
||||
$revision = $this->revisionLookup->getRevisionByTitle( $title );
|
||||
if ( !$revision ) {
|
||||
throw ApiUsageException::newWithMessage(
|
||||
$this,
|
||||
[ 'apierror-missingrev-title', wfEscapeWikiText( $title->getPrefixedText() ) ],
|
||||
'nosuchrevid'
|
||||
);
|
||||
}
|
||||
$threadItemSet = HookUtils::parseRevisionParsoidHtml( $revision, __METHOD__ );
|
||||
|
||||
$comment = $threadItemSet->findCommentById( $commentId );
|
||||
|
||||
if ( !$comment || !( $comment instanceof ContentCommentItem ) ) {
|
||||
$this->dieWithError( [ 'apierror-discussiontools-commentid-notfound', $commentId ] );
|
||||
}
|
||||
|
||||
if ( $user->getRequest()->getSessionData( "discussiontools-thanked-{$comment->getId()}" ) ) {
|
||||
$this->markResultSuccess( $comment->getAuthor() );
|
||||
return;
|
||||
}
|
||||
|
||||
$uniqueId = "discussiontools-{$comment->getId()}";
|
||||
// Do one last check to make sure we haven't sent Thanks before
|
||||
if ( $this->haveAlreadyThanked( $user, $uniqueId ) ) {
|
||||
// Pretend the thanks were sent
|
||||
$this->markResultSuccess( $comment->getAuthor() );
|
||||
return;
|
||||
}
|
||||
|
||||
$recipient = $this->userFactory->newFromName( $comment->getAuthor() );
|
||||
if ( !$recipient || !$recipient->getId() ) {
|
||||
$this->dieWithError( 'thanks-error-invalidrecipient', 'invalidrecipient' );
|
||||
}
|
||||
|
||||
$this->dieOnBadRecipient( $user, $recipient );
|
||||
|
||||
$heading = $comment->getSubscribableHeading();
|
||||
if ( !$heading ) {
|
||||
$heading = $comment->getHeading();
|
||||
}
|
||||
|
||||
// Create the notification via Echo extension
|
||||
Event::create( [
|
||||
'type' => 'dt-thank',
|
||||
'title' => $title,
|
||||
'extra' => [
|
||||
'comment-id' => $comment->getId(),
|
||||
'comment-name' => $comment->getName(),
|
||||
'content' => $comment->getBodyText( true ),
|
||||
'section-title' => $heading->getLinkableTitle(),
|
||||
'thanked-user-id' => $recipient->getId(),
|
||||
'revid' => $revision->getId(),
|
||||
],
|
||||
'agent' => $user,
|
||||
] );
|
||||
|
||||
// And mark the thank in session for a cheaper check to prevent duplicates (T48690).
|
||||
$user->getRequest()->setSessionData( "discussiontools-thanked-{$comment->getId()}", true );
|
||||
// Set success message.
|
||||
$this->markResultSuccess( $recipient->getName() );
|
||||
$this->logThanks( $user, $recipient, $uniqueId );
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function getAllowedParams() {
|
||||
return [
|
||||
'page' => [
|
||||
ParamValidator::PARAM_REQUIRED => true,
|
||||
// Message will exist if DiscussionTools is installed as VE is a dependency
|
||||
ApiBase::PARAM_HELP_MSG => 'apihelp-visualeditoredit-param-page',
|
||||
],
|
||||
'commentid' => [
|
||||
ParamValidator::PARAM_REQUIRED => true,
|
||||
ParamValidator::PARAM_TYPE => 'string',
|
||||
],
|
||||
'token' => [
|
||||
ParamValidator::PARAM_REQUIRED => true,
|
||||
ParamValidator::PARAM_TYPE => 'string',
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
43
includes/Hooks/ApiHooks.php
Normal file
43
includes/Hooks/ApiHooks.php
Normal file
|
@ -0,0 +1,43 @@
|
|||
<?php
|
||||
/**
|
||||
* DiscussionTools API hooks
|
||||
*
|
||||
* @file
|
||||
* @ingroup Extensions
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
namespace MediaWiki\Extension\DiscussionTools\Hooks;
|
||||
|
||||
use ApiModuleManager;
|
||||
use ExtensionRegistry;
|
||||
use MediaWiki\Api\Hook\ApiMain__moduleManagerHook;
|
||||
use MediaWiki\Extension\DiscussionTools\ApiDiscussionToolsThank;
|
||||
|
||||
// phpcs:disable MediaWiki.NamingConventions.LowerCamelFunctionsName.FunctionName
|
||||
|
||||
class ApiHooks implements
|
||||
ApiMain__moduleManagerHook
|
||||
{
|
||||
/**
|
||||
* @param ApiModuleManager $moduleManager
|
||||
* @return bool|void
|
||||
*/
|
||||
public function onApiMain__moduleManager( $moduleManager ) {
|
||||
if ( ExtensionRegistry::getInstance()->isLoaded( 'Thanks' ) ) {
|
||||
$moduleManager->addModule(
|
||||
'discussiontoolsthank',
|
||||
'action',
|
||||
[
|
||||
'class' => ApiDiscussionToolsThank::class,
|
||||
'services' => [
|
||||
'PermissionManager',
|
||||
'ThanksLogStore',
|
||||
'RevisionLookup',
|
||||
'UserFactory',
|
||||
]
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -9,8 +9,11 @@
|
|||
|
||||
namespace MediaWiki\Extension\DiscussionTools\Hooks;
|
||||
|
||||
use ExtensionRegistry;
|
||||
use IContextSource;
|
||||
use MediaWiki\Extension\DiscussionTools\OverflowMenuItem;
|
||||
use MediaWiki\MediaWikiServices;
|
||||
use MediaWiki\User\UserNameUtils;
|
||||
|
||||
class DiscussionToolsHooks implements
|
||||
DiscussionToolsAddOverflowMenuItemsHook
|
||||
|
@ -41,5 +44,26 @@ class DiscussionToolsHooks implements
|
|||
2
|
||||
);
|
||||
}
|
||||
|
||||
$dtConfig = MediaWikiServices::getInstance()->getConfigFactory()->makeConfig( 'discussiontools' );
|
||||
if ( $dtConfig->get( 'DiscussionToolsEnableThanks' ) ) {
|
||||
$user = $contextSource->getUser();
|
||||
$showThanks = ExtensionRegistry::getInstance()->isLoaded( 'Thanks' );
|
||||
if ( $showThanks && ( $threadItemData['type'] ?? null ) === 'comment' && $user->isNamed() ) {
|
||||
$userNameUtils = MediaWikiServices::getInstance()->getUserNameUtils();
|
||||
$recipient = $userNameUtils->getCanonical( $threadItemData['author'], UserNameUtils::RIGOR_NONE );
|
||||
|
||||
if (
|
||||
$recipient !== $user->getName() &&
|
||||
!$userNameUtils->isIP( $recipient )
|
||||
) {
|
||||
$overflowMenuItems[] = new OverflowMenuItem(
|
||||
'thank',
|
||||
'heart',
|
||||
$contextSource->msg( 'thanks-button-thank' ),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,7 +9,9 @@
|
|||
|
||||
namespace MediaWiki\Extension\DiscussionTools\Hooks;
|
||||
|
||||
use ExtensionRegistry;
|
||||
use MediaWiki\Extension\DiscussionTools\Notifications\AddedTopicPresentationModel;
|
||||
use MediaWiki\Extension\DiscussionTools\Notifications\CommentThanksPresentationModel;
|
||||
use MediaWiki\Extension\DiscussionTools\Notifications\EnhancedEchoEditUserTalkPresentationModel;
|
||||
use MediaWiki\Extension\DiscussionTools\Notifications\EnhancedEchoMentionPresentationModel;
|
||||
use MediaWiki\Extension\DiscussionTools\Notifications\EventDispatcher;
|
||||
|
@ -101,6 +103,25 @@ class EchoHooks implements
|
|||
],
|
||||
];
|
||||
|
||||
if ( ExtensionRegistry::getInstance()->isLoaded( 'Thanks' ) ) {
|
||||
$notifications['dt-thank'] = [
|
||||
'category' => 'edit-thank',
|
||||
'group' => 'positive',
|
||||
'section' => 'message',
|
||||
'user-locators' => [
|
||||
[
|
||||
[ UserLocator::class, 'locateFromEventExtra' ],
|
||||
[ 'thanked-user-id' ]
|
||||
]
|
||||
],
|
||||
'presentation-model' => CommentThanksPresentationModel::class,
|
||||
'bundle' => [
|
||||
'web' => true,
|
||||
'expandable' => true,
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
// Override default handlers
|
||||
$notifications['edit-user-talk']['presentation-model'] = EnhancedEchoEditUserTalkPresentationModel::class;
|
||||
$notifications['mention']['presentation-model'] = EnhancedEchoMentionPresentationModel::class;
|
||||
|
@ -116,6 +137,9 @@ class EchoHooks implements
|
|||
$bundleString = $event->getType() . '-' . $event->getTitle()->getNamespace()
|
||||
. '-' . $event->getTitle()->getDBkey();
|
||||
break;
|
||||
case 'dt-thank':
|
||||
$bundleString = $event->getType() . '-' . $event->getExtraParam( 'comment-name' );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -304,12 +304,13 @@ class PageHooks implements
|
|||
// Reply button: share
|
||||
$output->addModuleStyles( 'oojs-ui.styles.icons-content' );
|
||||
}
|
||||
$output->addModuleStyles( [
|
||||
// Overflow menu ('ellipsis' icon)
|
||||
'oojs-ui.styles.icons-interactions',
|
||||
] );
|
||||
if ( $isMobile ) {
|
||||
$output->addModuleStyles( [
|
||||
// Mobile overflow menu:
|
||||
// ellipsis
|
||||
'oojs-ui.styles.icons-interactions',
|
||||
// edit
|
||||
// Edit button in overflow menu ('edit' icon)
|
||||
'oojs-ui.styles.icons-editing-core',
|
||||
] );
|
||||
}
|
||||
|
|
150
includes/Notifications/CommentThanksPresentationModel.php
Normal file
150
includes/Notifications/CommentThanksPresentationModel.php
Normal file
|
@ -0,0 +1,150 @@
|
|||
<?php
|
||||
/**
|
||||
* EchoEventPresentationModel for comment thanks notifications
|
||||
*
|
||||
* @file
|
||||
* @ingroup Extensions
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
namespace MediaWiki\Extension\DiscussionTools\Notifications;
|
||||
|
||||
use Language;
|
||||
use MediaWiki\Extension\Notifications\Formatters\EchoEventPresentationModel;
|
||||
use MediaWiki\Extension\Notifications\Formatters\EchoPresentationModelSection;
|
||||
use MediaWiki\Extension\Notifications\Model\Event;
|
||||
use MediaWiki\Revision\RevisionRecord;
|
||||
use Message;
|
||||
use RawMessage;
|
||||
use User;
|
||||
|
||||
class CommentThanksPresentationModel extends EchoEventPresentationModel {
|
||||
|
||||
use DiscussionToolsEventTrait;
|
||||
|
||||
/**
|
||||
* @var EchoPresentationModelSection
|
||||
*/
|
||||
private $section;
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
protected function __construct( Event $event, Language $language, User $user, $distributionType ) {
|
||||
parent::__construct( $event, $language, $user, $distributionType );
|
||||
$this->section = new EchoPresentationModelSection( $event, $user, $language );
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function getIconType() {
|
||||
return 'thanks';
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function canRender() {
|
||||
return (bool)$this->event->getTitle();
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function getPrimaryLink() {
|
||||
return [
|
||||
'url' => $this->getCommentLink() ?: $this->event->getTitle()->getFullURL(),
|
||||
'label' => $this->msg( 'discussiontools-notification-subscribed-new-comment-view' )->text()
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a link to the individual comment, if available.
|
||||
*
|
||||
* @return string|null Full URL linking to the comment, null if not available
|
||||
*/
|
||||
protected function getCommentLink(): ?string {
|
||||
if ( !$this->userCan( RevisionRecord::DELETED_TEXT ) ) {
|
||||
return null;
|
||||
}
|
||||
// Thanks notifications are bundled by comment-id, so the link will always be to a single comment
|
||||
// (unlike in DiscussionToolsEventTrait)
|
||||
$commentId = $this->event->getExtraParam( 'comment-id' );
|
||||
if ( !$commentId ) {
|
||||
return null;
|
||||
}
|
||||
$title = $this->event->getTitle();
|
||||
return $title->createFragmentTarget( $commentId )->getFullURL();
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
protected function getHeaderMessageKey() {
|
||||
if ( $this->isBundled() ) {
|
||||
return 'discussiontools-notification-comment-thank-header-bundled';
|
||||
} else {
|
||||
return 'discussiontools-notification-comment-thank-header';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function getHeaderMessage() {
|
||||
$title = $this->section->getTruncatedSectionTitle();
|
||||
if ( !$title ) {
|
||||
// Comment could have been at the top of the page before
|
||||
// any section titles. Use the page title instead.
|
||||
$title = $this->event->getTitle()->getPrefixedText();
|
||||
}
|
||||
if ( $this->isBundled() ) {
|
||||
$count = $this->getNotificationCountForOutput();
|
||||
$msg = $this->msg( $this->getHeaderMessageKey() );
|
||||
|
||||
// Params 1, 2, 3:
|
||||
$msg->numParams( $count );
|
||||
$msg->plaintextParams( $title );
|
||||
$msg->params( $this->getViewingUserForGender() );
|
||||
return $msg;
|
||||
} else {
|
||||
$msg = parent::getHeaderMessage();
|
||||
// Params 3, 4:
|
||||
$msg->plaintextParams( $title );
|
||||
$msg->params( $this->getViewingUserForGender() );
|
||||
return $msg;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function getCompactHeaderMessage() {
|
||||
$msg = $this->getMessageWithAgent( 'discussiontools-notification-comment-thank-header-compact' );
|
||||
// Param 3:
|
||||
$msg->params( $this->getViewingUserForGender() );
|
||||
return $msg;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function getBodyMessage() {
|
||||
if ( !$this->isBundled() ) {
|
||||
return new RawMessage( '$1', [ Message::plaintextParam( $this->getContentSnippet() ) ] );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function getSecondaryLinks() {
|
||||
$pageLink = $this->getPageLink( $this->event->getTitle(), '', true );
|
||||
if ( $this->isBundled() ) {
|
||||
return [ $pageLink ];
|
||||
} else {
|
||||
return [ $this->getAgentLink(), $pageLink ];
|
||||
}
|
||||
}
|
||||
}
|
|
@ -27,6 +27,7 @@ let mobile = null;
|
|||
if ( OO.ui.isMobile() && mw.config.get( 'skin' ) === 'minerva' ) {
|
||||
mobile = require( './mobile.js' );
|
||||
}
|
||||
require( './thanks.js' );
|
||||
|
||||
mw.messages.set( require( './controller/contLangMessages.json' ) );
|
||||
|
||||
|
|
77
modules/thanks.js
Normal file
77
modules/thanks.js
Normal file
|
@ -0,0 +1,77 @@
|
|||
const cacheKey = 'dt-thanks';
|
||||
|
||||
/**
|
||||
* Thank a comment item
|
||||
*
|
||||
* @param {CommentItem} commentItem Comment item
|
||||
* @return {jQuery.Promise} Resolves when thanks successfully sent, rejects on error
|
||||
*/
|
||||
function thankComment( commentItem ) {
|
||||
// TODO: Add recipient gender for messages
|
||||
const recipientGender = 'unknown';
|
||||
return OO.ui.confirm( mw.msg( 'thanks-confirmation2', mw.user ), {
|
||||
actions: [
|
||||
{
|
||||
action: 'accept',
|
||||
label: mw.msg( 'thanks-button-thank', mw.user, recipientGender ),
|
||||
flags: [ 'primary', 'progressive' ]
|
||||
},
|
||||
{
|
||||
action: 'cancel',
|
||||
label: mw.msg( 'cancel' ),
|
||||
flags: 'safe'
|
||||
}
|
||||
]
|
||||
} ).then( ( confirmed ) => {
|
||||
if ( !confirmed ) {
|
||||
return $.Deferred().reject().promise();
|
||||
}
|
||||
|
||||
const api = require( './controller.js' ).getApi();
|
||||
|
||||
return api.postWithToken( 'csrf', {
|
||||
action: 'discussiontoolsthank',
|
||||
// We don't need to store the correct transcluded comment page
|
||||
// for a thank, any page the comment appears on will do.
|
||||
page: mw.config.get( 'wgRelevantPageName' ),
|
||||
commentid: commentItem.id
|
||||
} ).then( () => {
|
||||
mw.notify( mw.msg( 'thanks-thanked-notice', commentItem.author, recipientGender, mw.user ), { type: 'success' } );
|
||||
cacheThanked( commentItem );
|
||||
}, ( code, data ) => {
|
||||
mw.notify( api.getErrorMessage( data ), { type: 'error' } );
|
||||
return $.Deferred().reject().promise();
|
||||
} );
|
||||
} );
|
||||
}
|
||||
|
||||
function isThanked( threadItem ) {
|
||||
const cache = mw.storage.getObject( cacheKey ) || {};
|
||||
return cache[ threadItem.id ];
|
||||
}
|
||||
|
||||
function cacheThanked( threadItem ) {
|
||||
const cache = mw.storage.getObject( cacheKey ) || {};
|
||||
cache[ threadItem.id ] = true;
|
||||
mw.storage.setObject( cacheKey, cache );
|
||||
}
|
||||
|
||||
mw.hook( 'discussionToolsOverflowMenuOnChoose' ).add( ( id, menuItem, threadItem ) => {
|
||||
// TODO: Add recipient gender for messages
|
||||
const recipientGender = 'unknown';
|
||||
if ( id === 'thank' ) {
|
||||
thankComment( threadItem ).then( () => {
|
||||
menuItem.setLabel( mw.msg( 'thanks-button-thanked', mw.user, recipientGender ) );
|
||||
menuItem.setDisabled( true );
|
||||
} );
|
||||
}
|
||||
} );
|
||||
|
||||
mw.hook( 'discussionToolsOverflowMenuOnAddItem' ).add( ( id, menuItem, threadItem ) => {
|
||||
// TODO: Add recipient gender for messages
|
||||
const recipientGender = 'unknown';
|
||||
if ( id === 'thank' && isThanked( threadItem ) ) {
|
||||
menuItem.setLabel( mw.msg( 'thanks-button-thanked', mw.user, recipientGender ) );
|
||||
menuItem.setDisabled( true );
|
||||
}
|
||||
} );
|
Loading…
Reference in a new issue