scheduled_messages: Don't offer to reschedule in the past.

This introduces a function that checks for both the existence and the
expiration of the `selected_send_later_timestamp`.

The logic it supports prevents users from scheduling a message to send
in the past or less than five minutes into the future at the level of
the UI (specifically the popover on the \vdots component of the Send
button). That can happen if a user attempts to edit a previously
scheduled message.

Fixes #25439.
This commit is contained in:
Karl Stolley
2023-05-08 10:55:34 -05:00
committed by Tim Abbott
parent 90bf36887a
commit a318e7cbf4
3 changed files with 91 additions and 45 deletions

View File

@@ -89,7 +89,13 @@ export function get_selected_send_later_timestamp() {
} }
export function get_formatted_selected_send_later_time() { export function get_formatted_selected_send_later_time() {
if (!selected_send_later_timestamp) { const current_time = Date.now() / 1000; // seconds, like selected_send_later_timestamp
if (
scheduled_messages.is_send_later_timestamp_missing_or_expired(
selected_send_later_timestamp,
current_time,
)
) {
return undefined; return undefined;
} }
return timerender.get_full_datetime(new Date(selected_send_later_timestamp * 1000), "time"); return timerender.get_full_datetime(new Date(selected_send_later_timestamp * 1000), "time");

View File

@@ -15,6 +15,7 @@ import * as popover_menus from "./popover_menus";
import * as stream_data from "./stream_data"; import * as stream_data from "./stream_data";
import * as timerender from "./timerender"; import * as timerender from "./timerender";
export const MINIMUM_SCHEDULED_MESSAGE_DELAY_SECONDS = 5 * 60;
export let scheduled_messages_data = []; export let scheduled_messages_data = [];
function compute_send_times(now = new Date()) { function compute_send_times(now = new Date()) {
@@ -41,6 +42,21 @@ function compute_send_times(now = new Date()) {
return send_times; return send_times;
} }
export function is_send_later_timestamp_missing_or_expired(
timestamp_in_seconds,
current_time_in_seconds,
) {
if (!timestamp_in_seconds) {
return true;
}
// Determine if the selected timestamp is less than the minimum
// scheduled message delay
if (timestamp_in_seconds - current_time_in_seconds < MINIMUM_SCHEDULED_MESSAGE_DELAY_SECONDS) {
return true;
}
return false;
}
function sort_scheduled_messages_data() { function sort_scheduled_messages_data() {
scheduled_messages_data.sort( scheduled_messages_data.sort(
(msg1, msg2) => msg1.scheduled_delivery_timestamp - msg2.scheduled_delivery_timestamp, (msg1, msg2) => msg1.scheduled_delivery_timestamp - msg2.scheduled_delivery_timestamp,

View File

@@ -7,8 +7,7 @@ const {run_test} = require("./lib/test");
const scheduled_messages = zrequire("scheduled_messages"); const scheduled_messages = zrequire("scheduled_messages");
function get_expected_send_opts(day, expecteds) { const per_day_stamps = {
const per_day_stamps = {
"2023-04-30": { "2023-04-30": {
today_nine_am: 1682845200000, today_nine_am: 1682845200000,
today_four_pm: 1682870400000, today_four_pm: 1682870400000,
@@ -51,7 +50,9 @@ function get_expected_send_opts(day, expecteds) {
tomorrow_nine_am: 1683450000000, tomorrow_nine_am: 1683450000000,
tomorrow_four_pm: 1683475200000, tomorrow_four_pm: 1683475200000,
}, },
}; };
function get_expected_send_opts(day, expecteds) {
const modal_opts = { const modal_opts = {
send_later_tomorrow: { send_later_tomorrow: {
tomorrow_nine_am: { tomorrow_nine_am: {
@@ -117,7 +118,11 @@ run_test("scheduled_modal_opts", () => {
// Extra options change based on the hour of day // Extra options change based on the hour of day
const options_by_hour = [ const options_by_hour = [
{hour: "T06:00:00", extras: ["today_nine_am", "today_four_pm"]}, {hour: "T06:00:00", extras: ["today_nine_am", "today_four_pm"]},
{hour: "T08:54:00", extras: ["today_nine_am", "today_four_pm"]},
{hour: "T08:57:00", extras: ["today_four_pm"]},
{hour: "T11:00:00", extras: ["today_four_pm"]}, {hour: "T11:00:00", extras: ["today_four_pm"]},
{hour: "T13:54:00", extras: ["today_four_pm"]},
{hour: "T13:57:00", extras: []},
{hour: "T17:00:00", extras: []}, {hour: "T17:00:00", extras: []},
]; ];
@@ -135,3 +140,22 @@ run_test("scheduled_modal_opts", () => {
} }
} }
}); });
run_test("missing_or_expired_timestamps", () => {
let now_in_seconds = new Date("2023-05-03T08:54:00").getTime();
// The today at 9am option is not expired as of 8:54am (false)
assert.ok(
!scheduled_messages.is_send_later_timestamp_missing_or_expired(
per_day_stamps["2023-05-03"].today_nine_am / 1000,
now_in_seconds / 1000,
),
);
// The today at 9am option is expired as of 8:57am (true)
now_in_seconds = new Date("2023-05-03T08:57:00").getTime();
assert.ok(
scheduled_messages.is_send_later_timestamp_missing_or_expired(
per_day_stamps["2023-05-03"].today_nine_am / 1000,
now_in_seconds / 1000,
),
);
});