Show confirmation prompt if trying to submit a new topic without a title

Bug: T334163
Change-Id: Ib961632636d5b7134219cddde1638c6962209001
This commit is contained in:
Ed Sanders 2024-05-02 16:24:20 +01:00 committed by David Lynch
parent 6a17f6121c
commit d8f564fe71
5 changed files with 36 additions and 14 deletions

View file

@ -125,6 +125,7 @@
"discussiontools-ledesection-title", "discussiontools-ledesection-title",
"discussiontools-newtopic-placeholder-title", "discussiontools-newtopic-placeholder-title",
"discussiontools-newtopic-missing-title", "discussiontools-newtopic-missing-title",
"discussiontools-newtopic-missing-title-prompt",
"discussiontools-newtopicssubscription-button-subscribe-label", "discussiontools-newtopicssubscription-button-subscribe-label",
"discussiontools-newtopicssubscription-button-subscribe-tooltip", "discussiontools-newtopicssubscription-button-subscribe-tooltip",
"discussiontools-newtopicssubscription-button-unsubscribe-label", "discussiontools-newtopicssubscription-button-unsubscribe-label",

View file

@ -57,7 +57,8 @@
"discussiontools-limitreport-errorreqid": "DiscussionTools error request ID", "discussiontools-limitreport-errorreqid": "DiscussionTools error request ID",
"discussiontools-limitreport-timeusage": "DiscussionTools time usage", "discussiontools-limitreport-timeusage": "DiscussionTools time usage",
"discussiontools-limitreport-timeusage-value": "$1 {{PLURAL:$1|second|seconds}}", "discussiontools-limitreport-timeusage-value": "$1 {{PLURAL:$1|second|seconds}}",
"discussiontools-newtopic-missing-title": "Please provide a title for {{GENDER:|your}} discussion topic. If you click \"{{int:discussiontools-replywidget-newtopic}}\", your topic will be added without a title.", "discussiontools-newtopic-missing-title": "Please provide a title for {{GENDER:|your}} discussion topic.",
"discussiontools-newtopic-missing-title-prompt": "{{GENDER:|You}} have not provided a title for {{GENDER:|your}} discussion topic. Are {{GENDER:|you}} sure you want to add this topic without a title?",
"discussiontools-newtopic-placeholder-title": "Subject", "discussiontools-newtopic-placeholder-title": "Subject",
"discussiontools-newtopicssubscription-button-subscribe-label": "Subscribe", "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-subscribe-tooltip": "Subscribe to receive notifications when new topics are started on this page.",

View file

@ -71,7 +71,8 @@
"discussiontools-limitreport-errorreqid": "Label for the ID of the web request in which a DiscussionTools error has occurred.", "discussiontools-limitreport-errorreqid": "Label for the ID of the web request in which a DiscussionTools error has occurred.",
"discussiontools-limitreport-timeusage": "Label for the time usage (duration) of DiscussionTools in the parser limit report. Followed by {{msg-mw|discussiontools-limitreport-timeusage-value}}.\n\nSimilar to:\n* {{msg-mw|limitreport-cputime}}\n* {{msg-mw|limitreport-walltime}}\n* {{msg-mw|scribunto-limitreport-timeusage}}", "discussiontools-limitreport-timeusage": "Label for the time usage (duration) of DiscussionTools in the parser limit report. Followed by {{msg-mw|discussiontools-limitreport-timeusage-value}}.\n\nSimilar to:\n* {{msg-mw|limitreport-cputime}}\n* {{msg-mw|limitreport-walltime}}\n* {{msg-mw|scribunto-limitreport-timeusage}}",
"discussiontools-limitreport-timeusage-value": "Follows {{msg-mw|discussiontools-limitreport-timeusage}}.\n\nParameters:\n* $1 - the usage in seconds\n{{Identical|Second}}", "discussiontools-limitreport-timeusage-value": "Follows {{msg-mw|discussiontools-limitreport-timeusage}}.\n\nParameters:\n* $1 - the usage in seconds\n{{Identical|Second}}",
"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-missing-title": "Warning message shown when leaving the title field empty while adding a new topic to the page.",
"discussiontools-newtopic-missing-title-prompt": "Confirmation prompt shown when trying to submit a new topic with the title field empty.",
"discussiontools-newtopic-placeholder-title": "Placeholder describing the heading field of a new topic\n{{identical|Subject}}", "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-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-subscribe-tooltip": "Tooltip for the button to subscribe to notifications about new topics on this page.",

View file

@ -408,9 +408,10 @@ CommentController.prototype.onReplyWidgetTeardown = function ( mode ) {
* *
* @param {string} pageName Title of the page to post on * @param {string} pageName Title of the page to post on
* @param {Object} checkboxes Value of the promise returned by controller#getCheckboxesPromise * @param {Object} checkboxes Value of the promise returned by controller#getCheckboxesPromise
* @param {Object} extraParams Extra params to pass to the API
* @return {Object.<string,string>} API query data * @return {Object.<string,string>} API query data
*/ */
CommentController.prototype.getApiQuery = function ( pageName, checkboxes ) { CommentController.prototype.getApiQuery = function ( pageName, checkboxes, extraParams ) {
const threadItem = this.getThreadItem(); const threadItem = this.getThreadItem();
const replyWidget = this.replyWidget; const replyWidget = this.replyWidget;
const sameNameComments = this.threadItemSet.findCommentsByName( threadItem.name ); const sameNameComments = this.threadItemSet.findCommentsByName( threadItem.name );
@ -426,7 +427,7 @@ CommentController.prototype.getApiQuery = function ( pageName, checkboxes ) {
tags.push( 'discussiontools-source-enhanced' ); tags.push( 'discussiontools-source-enhanced' );
} }
const data = { const data = Object.assign( {
action: 'discussiontoolsedit', action: 'discussiontoolsedit',
paction: 'addcomment', paction: 'addcomment',
page: pageName, page: pageName,
@ -441,7 +442,7 @@ CommentController.prototype.getApiQuery = function ( pageName, checkboxes ) {
// Pass through dtenable query string param from original request // Pass through dtenable query string param from original request
dtenable: new URLSearchParams( location.search ).get( 'dtenable' ) ? '1' : undefined, dtenable: new URLSearchParams( location.search ).get( 'dtenable' ) ? '1' : undefined,
dttags: tags.join( ',' ) dttags: tags.join( ',' )
}; }, extraParams );
if ( replyWidget.getMode() === 'source' ) { if ( replyWidget.getMode() === 'source' ) {
data.wikitext = replyWidget.getValue(); data.wikitext = replyWidget.getValue();
@ -466,8 +467,10 @@ CommentController.prototype.getApiQuery = function ( pageName, checkboxes ) {
/** /**
* Handle the reply widget being submitted * Handle the reply widget being submitted
*
* @param {Object} extraParams Extra params to pass to the API
*/ */
CommentController.prototype.onReplySubmit = function () { CommentController.prototype.onReplySubmit = function ( extraParams ) {
if ( !this.replyWidget ) { if ( !this.replyWidget ) {
return; return;
} }
@ -481,7 +484,7 @@ CommentController.prototype.onReplySubmit = function () {
mw.track( 'editAttemptStep', { action: 'saveAttempt' } ); mw.track( 'editAttemptStep', { action: 'saveAttempt' } );
// TODO: When editing a transcluded page, VE API returning the page HTML is a waste, since we won't use it // TODO: When editing a transcluded page, VE API returning the page HTML is a waste, since we won't use it
this.save( this.replyWidget.pageName ) this.save( this.replyWidget.pageName, extraParams )
.then( null, this.saveFail.bind( this ) ) .then( null, this.saveFail.bind( this ) )
.always( () => { .always( () => {
this.replyWidget.setPending( false ); this.replyWidget.setPending( false );
@ -543,14 +546,15 @@ CommentController.prototype.saveFail = function ( code, data ) {
* Save the comment in the comment controller * Save the comment in the comment controller
* *
* @param {string} pageName Page title * @param {string} pageName Page title
* @param {Object} extraParams Extra params to pass to the API
* @return {jQuery.Promise} Promise which resolves when the save is complete * @return {jQuery.Promise} Promise which resolves when the save is complete
*/ */
CommentController.prototype.save = function ( pageName ) { CommentController.prototype.save = function ( pageName, extraParams ) {
const replyWidget = this.replyWidget, const replyWidget = this.replyWidget,
threadItem = this.getThreadItem(); threadItem = this.getThreadItem();
return this.replyWidget.checkboxesPromise.then( ( checkboxes ) => { return this.replyWidget.checkboxesPromise.then( ( checkboxes ) => {
const data = this.getApiQuery( pageName, checkboxes ); const data = this.getApiQuery( pageName, checkboxes, extraParams );
if ( if (
// We're saving the first comment on a page that previously didn't exist. // We're saving the first comment on a page that previously didn't exist.

View file

@ -243,8 +243,8 @@ NewTopicController.prototype.getUnsupportedNodeSelectors = function () {
/** /**
* @inheritdoc * @inheritdoc
*/ */
NewTopicController.prototype.getApiQuery = function ( pageName, checkboxes ) { NewTopicController.prototype.getApiQuery = function ( pageName, checkboxes, extraParams ) {
let data = NewTopicController.super.prototype.getApiQuery.call( this, pageName, checkboxes ); let data = NewTopicController.super.prototype.getApiQuery.call( this, pageName, checkboxes, extraParams );
// Rebuild the tags array and remove the reply tag // Rebuild the tags array and remove the reply tag
const tags = ( data.dttags || '' ).split( ',' ); const tags = ( data.dttags || '' ).split( ',' );
@ -258,9 +258,6 @@ NewTopicController.prototype.getApiQuery = function ( pageName, checkboxes ) {
data = Object.assign( {}, data, { data = Object.assign( {}, data, {
paction: 'addtopic', paction: 'addtopic',
sectiontitle: this.sectionTitle.getValue(), sectiontitle: this.sectionTitle.getValue(),
// TODO: Make the user somehow confirm that they really want to post a topic with no subject
// before sending this parameter (T334163)
allownosectiontitle: true,
dttags: tags.join( ',' ) dttags: tags.join( ',' )
} ); } );
@ -274,6 +271,24 @@ NewTopicController.prototype.getApiQuery = function ( pageName, checkboxes ) {
return data; return data;
}; };
/**
* @inheritdoc
*/
NewTopicController.prototype.saveFail = function ( code ) {
if ( code === 'discussiontools-newtopic-missing-title' ) {
OO.ui.confirm( mw.msg( 'discussiontools-newtopic-missing-title-prompt' ) ).then( ( confirmed ) => {
if ( confirmed ) {
this.onReplySubmit( { allownosectiontitle: true } );
} else {
this.sectionTitle.focus();
}
} );
return;
}
NewTopicController.super.prototype.saveFail.apply( this, arguments );
};
/** /**
* Generate a default edit summary based on the section title. * Generate a default edit summary based on the section title.
* *