scheduled_messages: Render localized, streamlined modal opts.

This commit ensures that user-locale and 24-hour preferences are
respected in the message-scheduling modal. It also simplifies the
translation of text strings in the scheduling modal.

Available scheduling options and their time values, including whether
the options are allowed, are now calculated every time a user opens
the scheduling modal.

In order to achieve those things, additional interrelated fixes here
accomplish the following:

1. Modal-scheduling opts now have data- attributes containing
timestamps for the time a message will be scheduled to send.

2. With those timestamps in place, the logic for setting the
scheduled send-time is simplified.

3. There are no more `send_later_xxx` global variables in the
`schedule_send` module.

Fixes #25403.
This commit is contained in:
Karl Stolley
2023-05-05 10:12:30 -05:00
committed by Tim Abbott
parent 96680e95fb
commit 5113f4e2e9
4 changed files with 107 additions and 96 deletions

View File

@@ -790,14 +790,7 @@ export function initialize() {
}); });
function set_compose_box_schedule(element) { function set_compose_box_schedule(element) {
const send_later_in = element.id; const selected_send_at_time = element.dataset.sendStamp / 1000;
const send_later_class = element.classList[0];
const date = new Date();
const selected_send_at_time = scheduled_messages.get_send_at_time_from_opts(
send_later_in,
send_later_class,
date,
);
return selected_send_at_time; return selected_send_at_time;
} }

View File

@@ -1,9 +1,7 @@
import {format} from "date-fns";
import $ from "jquery"; import $ from "jquery";
import render_success_message_scheduled_banner from "../templates/compose_banner/success_message_scheduled_banner.hbs"; import render_success_message_scheduled_banner from "../templates/compose_banner/success_message_scheduled_banner.hbs";
import * as blueslip from "./blueslip";
import * as channel from "./channel"; import * as channel from "./channel";
import * as compose from "./compose"; import * as compose from "./compose";
import * as compose_actions from "./compose_actions"; import * as compose_actions from "./compose_actions";
@@ -15,41 +13,33 @@ import * as narrow from "./narrow";
import * as people from "./people"; import * as people from "./people";
import * as popover_menus from "./popover_menus"; 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";
export let scheduled_messages_data = []; export let scheduled_messages_data = [];
const send_later_today = { function compute_send_times(now = new Date()) {
today_nine_am: { const send_times = {};
text: $t({defaultMessage: "Today at 9:00 AM"}),
time: "9:00 am",
},
today_four_pm: {
text: $t({defaultMessage: "Today at 4:00 PM"}),
time: "4:00 pm",
},
};
const send_later_tomorrow = { const today = new Date(now);
tomorrow_nine_am: { const tomorrow = new Date(new Date(now).setDate(now.getDate() + 1));
text: $t({defaultMessage: "Tomorrow at 9:00 AM"}), // Find the next Monday by subtracting the current day (0-6) from 8
time: "9:00 am", const monday = new Date(new Date(now).setDate(now.getDate() + 8 - now.getDay()));
},
tomorrow_four_pm: {
text: $t({defaultMessage: "Tomorrow at 4:00 PM"}),
time: "4:00 pm",
},
};
const send_later_monday = { // Since setHours returns a timestamp, it's safe to mutate the
monday_nine_am: { // original date objects here.
text: $t({defaultMessage: "Monday at 9:00 AM"}), //
time: "9:00 am", // today at 9am
}, send_times.today_nine_am = today.setHours(9, 0, 0, 0);
}; // today at 4pm
send_times.today_four_pm = today.setHours(16, 0, 0, 0);
const send_later_custom = { // tomorrow at 9am
text: $t({defaultMessage: "Custom"}), send_times.tomorrow_nine_am = tomorrow.setHours(9, 0, 0, 0);
}; // tomorrow at 4pm
send_times.tomorrow_four_pm = tomorrow.setHours(16, 0, 0, 0);
// next Monday at 9am
send_times.monday_nine_am = monday.setHours(9, 0, 0, 0);
return send_times;
}
function sort_scheduled_messages_data() { function sort_scheduled_messages_data() {
scheduled_messages_data.sort( scheduled_messages_data.sort(
@@ -187,8 +177,84 @@ export function get_count() {
} }
export function get_filtered_send_opts(date) { export function get_filtered_send_opts(date) {
const send_times = compute_send_times();
const day = date.getDay(); // Starts with 0 for Sunday. const day = date.getDay(); // Starts with 0 for Sunday.
const hours = date.getHours(); const hours = date.getHours();
const send_later_today = {
today_nine_am: {
text: $t(
{defaultMessage: "Today at {time}"},
{
time: timerender.get_localized_date_or_time_for_format(
send_times.today_nine_am,
"time",
),
},
),
stamp: send_times.today_nine_am,
},
today_four_pm: {
text: $t(
{defaultMessage: "Today at {time}"},
{
time: timerender.get_localized_date_or_time_for_format(
send_times.today_four_pm,
"time",
),
},
),
stamp: send_times.today_four_pm,
},
};
const send_later_tomorrow = {
tomorrow_nine_am: {
text: $t(
{defaultMessage: "Tomorrow at {time}"},
{
time: timerender.get_localized_date_or_time_for_format(
send_times.tomorrow_nine_am,
"time",
),
},
),
stamp: send_times.tomorrow_nine_am,
},
tomorrow_four_pm: {
text: $t(
{defaultMessage: "Tomorrow at {time}"},
{
time: timerender.get_localized_date_or_time_for_format(
send_times.tomorrow_four_pm,
"time",
),
},
),
stamp: send_times.tomorrow_four_pm,
},
};
const send_later_monday = {
monday_nine_am: {
text: $t(
{defaultMessage: "Monday at {time}"},
{
time: timerender.get_localized_date_or_time_for_format(
send_times.monday_nine_am,
"time",
),
},
),
stamp: send_times.monday_nine_am,
},
};
const send_later_custom = {
text: $t({defaultMessage: "Custom"}),
};
let possible_send_later_today = {}; let possible_send_later_today = {};
let possible_send_later_monday = {}; let possible_send_later_monday = {};
if (hours <= 8) { if (hours <= 8) {
@@ -213,33 +279,6 @@ export function get_filtered_send_opts(date) {
}; };
} }
export function get_send_at_time_from_opts(send_later_in, send_later_class, date) {
switch (send_later_class) {
case "send_later_tomorrow": {
const send_time = send_later_tomorrow[send_later_in].time;
const scheduled_date = date.setDate(date.getDate() + 1);
const send_at_time = format(scheduled_date, "MMM d yyyy ") + send_time;
return send_at_time;
}
case "send_later_today": {
const send_time = send_later_today[send_later_in].time;
const send_at_time = format(date.setDate(date.getDate()), "MMM d yyyy ") + send_time;
return send_at_time;
}
case "send_later_monday": {
const send_time = send_later_monday[send_later_in].time;
// Subtract from 8 to find the next Monday.
const monday_offset = 8 - date.getDay();
const scheduled_date = date.setDate(date.getDate() + monday_offset);
const send_at_time = format(scheduled_date, "MMM d yyyy ") + send_time;
return send_at_time;
}
// No default
}
blueslip.error("Not a valid time.");
return false;
}
export function initialize(scheduled_messages_params) { export function initialize(scheduled_messages_params) {
scheduled_messages_data = scheduled_messages_params.scheduled_messages; scheduled_messages_data = scheduled_messages_params.scheduled_messages;

View File

@@ -13,19 +13,19 @@
{{#if possible_send_later_today}} {{#if possible_send_later_today}}
{{#each possible_send_later_today}} {{#each possible_send_later_today}}
<li> <li>
<a id="{{@key}}" class="send_later_today" tabindex="0">{{this.text}}</a> <a id="{{@key}}" class="send_later_today" data-send-stamp="{{this.stamp}}" tabindex="0">{{this.text}}</a>
</li> </li>
{{/each}} {{/each}}
{{/if}} {{/if}}
{{#each send_later_tomorrow}} {{#each send_later_tomorrow}}
<li> <li>
<a id="{{@key}}" class="send_later_tomorrow" tabindex="0">{{this.text}}</a> <a id="{{@key}}" class="send_later_tomorrow" data-send-stamp="{{this.stamp}}" tabindex="0">{{this.text}}</a>
</li> </li>
{{/each}} {{/each}}
{{#if possible_send_later_monday }} {{#if possible_send_later_monday }}
{{#each possible_send_later_monday}} {{#each possible_send_later_monday}}
<li> <li>
<a id="{{@key}}" class="send_later_monday" tabindex="0">{{this.text}}</a> <a id="{{@key}}" class="send_later_monday" data-send-stamp="{{this.stamp}}" tabindex="0">{{this.text}}</a>
</li> </li>
{{/each}} {{/each}}
{{/if}} {{/if}}

View File

@@ -12,11 +12,11 @@ function get_expected_send_opts(expecteds) {
send_later_tomorrow: { send_later_tomorrow: {
tomorrow_nine_am: { tomorrow_nine_am: {
text: "translated: Tomorrow at 9:00 AM", text: "translated: Tomorrow at 9:00 AM",
time: "9:00 am", stamp: 1683363600000,
}, },
tomorrow_four_pm: { tomorrow_four_pm: {
text: "translated: Tomorrow at 4:00 PM", text: "translated: Tomorrow at 4:00 PM",
time: "4:00 pm", stamp: 1683388800000,
}, },
}, },
send_later_custom: { send_later_custom: {
@@ -29,17 +29,17 @@ function get_expected_send_opts(expecteds) {
send_later_today: { send_later_today: {
today_nine_am: { today_nine_am: {
text: "translated: Today at 9:00 AM", text: "translated: Today at 9:00 AM",
time: "9:00 am", stamp: 1683277200000,
}, },
today_four_pm: { today_four_pm: {
text: "translated: Today at 4:00 PM", text: "translated: Today at 4:00 PM",
time: "4:00 pm", stamp: 1683302400000,
}, },
}, },
send_later_monday: { send_later_monday: {
monday_nine_am: { monday_nine_am: {
text: "translated: Monday at 9:00 AM", text: "translated: Monday at 9:00 AM",
time: "9:00 am", stamp: 1683536400000,
}, },
}, },
}; };
@@ -91,24 +91,3 @@ run_test("scheduled_modal_opts", () => {
} }
} }
}); });
run_test("scheduled_selected_times", () => {
// When scheduling a message on a Monday at 6:00am
// that will be sent tomorrow at 4pm
let date = new Date("2023-05-01T06:00:00");
let send_at_time = scheduled_messages.get_send_at_time_from_opts(
"tomorrow_four_pm",
"send_later_tomorrow",
date,
);
assert.equal(send_at_time, "May 2 2023 4:00 pm");
// When scheduling a message on a Friday at 5:00pm
// that will be sent Monday at 9am
date = new Date("2023-05-05T17:00:00");
send_at_time = scheduled_messages.get_send_at_time_from_opts(
"monday_nine_am",
"send_later_monday",
date,
);
assert.equal(send_at_time, "May 8 2023 9:00 am");
});