FIX: Ensure slow mode duration is correctly edited and displayed. (#10945)

* FIX: Ensure slow mode duration is correctly edited and displayed.

This commit fixes a bug where you were forced to set hours, minutes, and seconds or you won't be able to set the slow mode. Also, the duration was not displayed correctly due to the seconds not being truncated.

Additionally, we'll always display the hours, minutes, and seconds inputs for clarity and remove the blue banner.

* Set slow mode modal tweaks.

Uses labels instead of placeholders.
Input fields only visible when custom option selected.
Replace "Custom Duration" with "Pick Duration".

Additionally, place the `Set slow mode` button at the bottom of the topic actions menu.

* Perform the slow_mode validation also on the client-side before saving trying to save the post. This way, the post won't be staged.
This commit is contained in:
Roman Rizzi 2020-10-20 06:52:03 -03:00 committed by GitHub
parent 1946fa3c53
commit fbb1fb9270
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 57 additions and 32 deletions

View File

@ -28,6 +28,7 @@ import { isTesting } from "discourse-common/config/environment";
import EmberObject, { computed, action } from "@ember/object";
import deprecated from "discourse-common/lib/deprecated";
import bootbox from "bootbox";
import { cannotPostAgain } from "discourse/helpers/slow-mode";
function loadDraft(store, opts) {
let promise = Promise.resolve();
@ -646,6 +647,17 @@ export default Controller.extend({
return;
}
const topic = composer.topic;
if (topic && topic.slow_mode_seconds && topic.user_last_posted_at) {
if (cannotPostAgain(topic.slow_mode_seconds, topic.user_last_posted_at)) {
const message = I18n.t("composer.slow_mode.error");
bootbox.alert(message);
return;
}
}
composer.set("disableDrafts", true);
// for now handle a very narrow use case

View File

@ -74,6 +74,10 @@ export default Controller.extend(ModalFunctionality, {
this.setProperties(fromSeconds(seconds));
},
_parseValue(value) {
return parseInt(value, 10) || 0;
},
@action
setSlowModeDuration(duration) {
if (duration !== "custom") {
@ -88,7 +92,13 @@ export default Controller.extend(ModalFunctionality, {
@action
enableSlowMode() {
this.set("saveDisabled", true);
const seconds = toSeconds(this.hours, this.minutes, this.seconds);
const seconds = toSeconds(
this._parseValue(this.hours),
this._parseValue(this.minutes),
this._parseValue(this.seconds)
);
Topic.setSlowMode(this.model.id, seconds)
.catch(popupAjaxError)
.then(() => {

View File

@ -1,14 +1,14 @@
export function fromSeconds(seconds) {
let initialSeconds = seconds;
let hours = initialSeconds / 3600;
let hours = Math.trunc(initialSeconds / 3600);
if (hours >= 1) {
initialSeconds = initialSeconds - 3600 * hours;
} else {
hours = 0;
}
let minutes = initialSeconds / 60;
let minutes = Math.trunc(initialSeconds / 60);
if (minutes >= 1) {
initialSeconds = initialSeconds - 60 * minutes;
} else {
@ -19,12 +19,19 @@ export function fromSeconds(seconds) {
}
export function toSeconds(hours, minutes, seconds) {
const hoursAsSeconds = parseInt(hours, 10) * 60 * 60;
const minutesAsSeconds = parseInt(minutes, 10) * 60;
const hoursAsSeconds = hours * 60 * 60;
const minutesAsSeconds = minutes * 60;
return parseInt(seconds, 10) + hoursAsSeconds + minutesAsSeconds;
return seconds + hoursAsSeconds + minutesAsSeconds;
}
export function durationTextFromSeconds(seconds) {
return moment.duration(seconds, "seconds").humanize();
}
export function cannotPostAgain(duration, last_posted_at) {
let threshold = new Date(last_posted_at);
threshold = new Date(threshold.getTime() + duration * 1000);
return new Date() < threshold;
}

View File

@ -15,18 +15,14 @@
{{#if showCustomSelect}}
<div class="control-group">
{{d-icon "hourglass-end"}}
{{input value=hours type="number" class="input-small" placeholder=(i18n "topic.slow_mode_update.hours")}}
{{input value=minutes type="number" class="input-small" placeholder=(i18n "topic.slow_mode_update.minutes")}}
{{input value=seconds type="number" class="input-small" placeholder=(i18n "topic.slow_mode_update.seconds")}}
</div>
{{/if}}
<label class="slow-mode-label">{{i18n "topic.slow_mode_update.hours"}}</label>
{{input value=hours type="number" class="input-small"}}
{{#if model.slow_mode_seconds}}
<div class="alert alert-info">
<b>
{{i18n "topic.slow_mode_update.current" hours=hours minutes=minutes seconds=seconds}}
</b>
<label class="slow-mode-label">{{i18n "topic.slow_mode_update.minutes"}}</label>
{{input value=minutes type="number" class="input-small"}}
<label class="slow-mode-label">{{i18n "topic.slow_mode_update.seconds"}}</label>
{{input value=seconds type="number" class="input-small"}}
</div>
{{/if}}
{{/d-modal-body}}

View File

@ -164,14 +164,6 @@ export default createWidget("topic-admin-menu", {
});
}
this.addActionButton({
className: "topic-admin-slow-mode",
buttonClass: "popup-menu-btn",
action: "showTopicSlowModeUpdate",
icon: "hourglass-end",
label: "actions.slow_mode",
});
if (topic.get("deleted") && details.get("can_recover")) {
this.addActionButton({
className: "topic-admin-recover",
@ -278,6 +270,14 @@ export default createWidget("topic-admin-menu", {
});
}
this.addActionButton({
className: "topic-admin-slow-mode",
buttonClass: "popup-menu-btn",
action: "showTopicSlowModeUpdate",
icon: "hourglass-end",
label: "actions.slow_mode",
});
if (this.currentUser.get("staff")) {
this.addActionButton({
icon: "list",

View File

@ -822,6 +822,6 @@
}
.input-small {
width: 15%;
width: 10%;
}
}

View File

@ -1925,6 +1925,7 @@ en:
slow_mode:
title: "This topic is in slow mode."
body: "After submitting a post, you'll need to wait %{duration} before being able to post again."
error: "You recently posted on this topic, which is in slow mode. Please wait so other users can have their chance to participate."
admin_options_title: "Optional staff settings for this topic"
@ -2320,19 +2321,18 @@ en:
title: "Slow Mode"
select: "Duration:"
description: "Users will have to wait to be able to post again."
current: "Current duration is %{hours} hours, %{minutes} minutes, and %{seconds} seconds."
save: "Save"
remove: "Disable"
hours: "Hours"
minutes: "Minutes"
seconds: "Seconds"
hours: "Hours:"
minutes: "Minutes:"
seconds: "Seconds:"
durations:
15_minutes: "15 Minutes"
1_hour: "1 Hour"
4_hours: "4 Hours"
1_day: "1 Day"
1_week: "1 Week"
custom: "Pick Duration"
custom: "Custom Duration"
slow_mode_notice:
duration: "You need to wait %{duration} between posts in this topic"
topic_status_update:

View File

@ -340,7 +340,7 @@ en:
removed_direct_reply_full_quotes: "Automatically removed quote of whole previous post."
secure_upload_not_allowed_in_public_topic: "Sorry, the following secure upload(s) cannot be used in a public topic: %{upload_filenames}."
create_pm_on_existing_topic: "Sorry, you can't create a PM on an existing topic."
slow_mode_enabled: "You recently posted on this topic, which is in slow mode. Please wait so other users can have their chance to participate."
slow_mode_enabled: "This topic is in slow mode."
just_posted_that: "is too similar to what you recently posted"
invalid_characters: "contains invalid characters"