scheduled_mesages: Use events to update scheduled message data.

This also allows to display scheduled message overlay without
fetching any data.
This commit is contained in:
Aman Agrawal 2023-05-01 12:29:57 +00:00 committed by Tim Abbott
parent eb5f679121
commit 7d373c54a9
8 changed files with 178 additions and 65 deletions

View File

@ -95,8 +95,8 @@ export function get_formatted_selected_send_later_time() {
return timerender.get_full_datetime(new Date(selected_send_later_time), "time"); return timerender.get_full_datetime(new Date(selected_send_later_time), "time");
} }
export function set_selected_schedule_time(scheduled_time) { export function set_selected_schedule_time(raw_scheduled_time) {
selected_send_later_time = scheduled_time; selected_send_later_time = raw_scheduled_time;
} }
export function reset_selected_schedule_time() { export function reset_selected_schedule_time() {

View File

@ -8,28 +8,52 @@ import * as compose_ui from "./compose_ui";
import {$t} from "./i18n"; import {$t} from "./i18n";
import * as narrow from "./narrow"; import * as narrow from "./narrow";
import * as notifications from "./notifications"; import * as notifications from "./notifications";
import * as overlays from "./overlays"; import {page_params} from "./page_params";
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";
// This is only updated when user opens the scheduled messages overlay.
export let scheduled_messages_data = []; export let scheduled_messages_data = [];
export function override_scheduled_messages_data(data) { function sort_scheduled_messages_data() {
scheduled_messages_data = data; scheduled_messages_data.sort(
(msg1, msg2) => msg1.scheduled_delivery_timestamp - msg2.scheduled_delivery_timestamp,
);
} }
export function edit_scheduled_message(scheduled_msg_id) { export function add_scheduled_messages(scheduled_messages) {
const scheduled_msg = scheduled_messages_data.find( scheduled_messages_data.push(...scheduled_messages);
(msg) => msg.scheduled_message_id === scheduled_msg_id, sort_scheduled_messages_data();
}
export function remove_scheduled_message(scheduled_message_id) {
const msg_index = scheduled_messages_data.findIndex(
(msg) => msg.scheduled_message_id === scheduled_message_id,
);
if (msg_index !== undefined) {
scheduled_messages_data.splice(msg_index, 1);
}
}
export function update_scheduled_message(scheduled_message) {
const msg_index = scheduled_messages_data.findIndex(
(msg) => msg.scheduled_message_id === scheduled_message.scheduled_message_id,
); );
let compose_args; if (msg_index === undefined) {
return;
}
scheduled_messages_data[msg_index] = scheduled_message;
sort_scheduled_messages_data();
}
export function open_scheduled_message_in_compose(scheduled_msg) {
let compose_args;
if (scheduled_msg.type === "stream") { if (scheduled_msg.type === "stream") {
compose_args = { compose_args = {
type: "stream", type: "stream",
stream: scheduled_msg.stream_name, stream: stream_data.maybe_get_stream_name(scheduled_msg.to),
topic: scheduled_msg.topic, topic: scheduled_msg.topic,
content: scheduled_msg.content, content: scheduled_msg.content,
}; };
@ -61,11 +85,11 @@ export function edit_scheduled_message(scheduled_msg_id) {
}); });
} }
overlays.close_overlay("scheduled");
compose.clear_compose_box(); compose.clear_compose_box();
compose_banner.clear_message_sent_banners(false);
compose_actions.start(compose_args.type, compose_args); compose_actions.start(compose_args.type, compose_args);
compose_ui.autosize_textarea($("#compose-textarea")); compose_ui.autosize_textarea($("#compose-textarea"));
popover_menus.set_selected_schedule_time(scheduled_msg.formatted_send_at_time); popover_menus.set_selected_schedule_time(scheduled_msg.scheduled_delivery_timestamp * 1000);
} }
export function send_request_to_schedule_message(scheduled_message_data, deliver_at) { export function send_request_to_schedule_message(scheduled_message_data, deliver_at) {
@ -98,19 +122,26 @@ export function send_request_to_schedule_message(scheduled_message_data, deliver
}); });
} }
export function delete_scheduled_message(scheduled_msg_id, edit_if_delete_successs) { export function edit_scheduled_message(scheduled_message_id) {
const scheduled_msg = scheduled_messages_data.find(
(msg) => msg.scheduled_message_id === scheduled_message_id,
);
delete_scheduled_message(scheduled_message_id, () =>
open_scheduled_message_in_compose(scheduled_msg),
);
}
export function delete_scheduled_message(scheduled_msg_id, success = () => {}) {
channel.del({ channel.del({
url: "/json/scheduled_messages/" + scheduled_msg_id, url: "/json/scheduled_messages/" + scheduled_msg_id,
success() { success,
// TODO: Do this via events received from the server in server_events_dispatch.
if (overlays.scheduled_messages_open()) {
$(
`#scheduled_messages_overlay .scheduled-message-row[data-message-id=${scheduled_msg_id}]`,
).remove();
}
if (edit_if_delete_successs) {
edit_scheduled_message(scheduled_msg_id);
}
},
}); });
} }
export function initialize() {
if (scheduled_messages_data.length === 0) {
scheduled_messages_data = page_params.scheduled_messages;
} else {
add_scheduled_messages(page_params.scheduled_messages);
}
}

View File

@ -4,10 +4,7 @@ import $ from "jquery";
import render_scheduled_message from "../templates/scheduled_message.hbs"; import render_scheduled_message from "../templates/scheduled_message.hbs";
import render_scheduled_messages_overlay from "../templates/scheduled_messages_overlay.hbs"; import render_scheduled_messages_overlay from "../templates/scheduled_messages_overlay.hbs";
import * as blueslip from "./blueslip";
import * as browser_history from "./browser_history"; import * as browser_history from "./browser_history";
import * as channel from "./channel";
import * as loading from "./loading";
import * as overlays from "./overlays"; import * as overlays from "./overlays";
import * as people from "./people"; import * as people from "./people";
import * as scheduled_messages from "./scheduled_messages"; import * as scheduled_messages from "./scheduled_messages";
@ -15,11 +12,6 @@ import * as stream_color from "./stream_color";
import * as stream_data from "./stream_data"; import * as stream_data from "./stream_data";
import * as timerender from "./timerender"; import * as timerender from "./timerender";
function hide_loading_indicator() {
loading.destroy_indicator($("#scheduled_messages_overlay .loading-indicator"));
$(".scheduled-messages-loading").hide();
}
function format(scheduled_messages) { function format(scheduled_messages) {
const formatted_msgs = []; const formatted_msgs = [];
for (const msg of scheduled_messages) { for (const msg of scheduled_messages) {
@ -56,29 +48,32 @@ export function launch() {
browser_history.exit_overlay(); browser_history.exit_overlay();
}, },
}); });
loading.make_indicator($("#scheduled_messages_overlay .loading-indicator"), {
abs_positioned: true,
});
channel.get({ const rendered_list = render_scheduled_message({
url: "/json/scheduled_messages", scheduled_messages_data: format(scheduled_messages.scheduled_messages_data),
success(data) {
hide_loading_indicator();
// Saving formatted data is helpful when user is trying to edit a scheduled message.
scheduled_messages.override_scheduled_messages_data(
format(data.scheduled_messages),
);
const rendered_list = render_scheduled_message({
scheduled_messages_data: scheduled_messages.scheduled_messages_data,
});
const $messages_list = $("#scheduled_messages_overlay .overlay-messages-list");
$messages_list.append(rendered_list);
},
error(xhr) {
hide_loading_indicator();
blueslip.error(xhr);
},
}); });
const $messages_list = $("#scheduled_messages_overlay .overlay-messages-list");
$messages_list.append(rendered_list);
}
export function rerender() {
if (!overlays.scheduled_messages_open()) {
return;
}
const rendered_list = render_scheduled_message({
scheduled_messages_data: format(scheduled_messages.scheduled_messages_data),
});
const $messages_list = $("#scheduled_messages_overlay .overlay-messages-list");
$messages_list.find(".scheduled-message-row").remove();
$messages_list.append(rendered_list);
}
export function remove_scheduled_message_id(scheduled_msg_id) {
if (overlays.scheduled_messages_open()) {
$(
`#scheduled_messages_overlay .scheduled-message-row[data-message-id=${scheduled_msg_id}]`,
).remove();
}
} }
export function initialize() { export function initialize() {
@ -87,8 +82,8 @@ export function initialize() {
.closest(".scheduled-message-row") .closest(".scheduled-message-row")
.attr("data-message-id"); .attr("data-message-id");
scheduled_msg_id = Number.parseInt(scheduled_msg_id, 10); scheduled_msg_id = Number.parseInt(scheduled_msg_id, 10);
scheduled_messages.delete_scheduled_message(scheduled_msg_id, true); scheduled_messages.edit_scheduled_message(scheduled_msg_id);
overlays.close_overlay("scheduled");
e.stopPropagation(); e.stopPropagation();
e.preventDefault(); e.preventDefault();
}); });

View File

@ -39,6 +39,8 @@ import * as realm_logo from "./realm_logo";
import * as realm_playground from "./realm_playground"; import * as realm_playground from "./realm_playground";
import {realm_user_settings_defaults} from "./realm_user_settings_defaults"; import {realm_user_settings_defaults} from "./realm_user_settings_defaults";
import * as reload from "./reload"; import * as reload from "./reload";
import * as scheduled_messages from "./scheduled_messages";
import * as scheduled_messages_overlay_ui from "./scheduled_messages_overlay_ui";
import * as scroll_bar from "./scroll_bar"; import * as scroll_bar from "./scroll_bar";
import * as settings_account from "./settings_account"; import * as settings_account from "./settings_account";
import * as settings_bots from "./settings_bots"; import * as settings_bots from "./settings_bots";
@ -80,6 +82,29 @@ import * as user_status from "./user_status";
export function dispatch_normal_event(event) { export function dispatch_normal_event(event) {
const noop = function () {}; const noop = function () {};
switch (event.type) { switch (event.type) {
case "scheduled_messages":
switch (event.op) {
case "add": {
scheduled_messages.add_scheduled_messages(event.scheduled_messages);
scheduled_messages_overlay_ui.rerender();
break;
}
case "remove": {
scheduled_messages.remove_scheduled_message(event.scheduled_message_id);
scheduled_messages_overlay_ui.remove_scheduled_message_id(
event.scheduled_message_id,
);
break;
}
case "update": {
scheduled_messages.update_scheduled_message(event.scheduled_message);
scheduled_messages_overlay_ui.rerender();
break;
}
// No default
}
break;
case "alert_words": case "alert_words":
alert_words.set_words(event.alert_words); alert_words.set_words(event.alert_words);
alert_words_ui.rerender_alert_words_ui(); alert_words_ui.rerender_alert_words_ui();

View File

@ -74,6 +74,7 @@ import * as reload from "./reload";
import * as rendered_markdown from "./rendered_markdown"; import * as rendered_markdown from "./rendered_markdown";
import * as resize from "./resize"; import * as resize from "./resize";
import * as rows from "./rows"; import * as rows from "./rows";
import * as scheduled_messages from "./scheduled_messages";
import * as scheduled_messages_overlay_ui from "./scheduled_messages_overlay_ui"; import * as scheduled_messages_overlay_ui from "./scheduled_messages_overlay_ui";
import * as scroll_bar from "./scroll_bar"; import * as scroll_bar from "./scroll_bar";
import * as scroll_util from "./scroll_util"; import * as scroll_util from "./scroll_util";
@ -588,6 +589,8 @@ export function initialize_everything() {
i18n.initialize(i18n_params); i18n.initialize(i18n_params);
tippyjs.initialize(); tippyjs.initialize();
// This populates data for scheduled messages.
scheduled_messages.initialize();
popovers.initialize(); popovers.initialize();
popover_menus.initialize(); popover_menus.initialize();

View File

@ -13,15 +13,6 @@
{{/tr}} {{/tr}}
</div> </div>
</div> </div>
<div class="scheduled-messages-loading">
<div class="scheduled-messages-loading-logo">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 773.12 773.12">
<circle cx="386.56" cy="386.56" r="386.56"></circle>
<path d="M566.66 527.25c0 33.03-24.23 60.05-53.84 60.05H260.29c-29.61 0-53.84-27.02-53.84-60.05 0-20.22 9.09-38.2 22.93-49.09l134.37-120c2.5-2.14 5.74 1.31 3.94 4.19l-49.29 98.69c-1.38 2.76.41 6.16 3.25 6.16h191.18c29.61 0 53.83 27.03 53.83 60.05zm0-281.39c0 20.22-9.09 38.2-22.93 49.09l-134.37 120c-2.5 2.14-5.74-1.31-3.94-4.19l49.29-98.69c1.38-2.76-.41-6.16-3.25-6.16H260.29c-29.61 0-53.84-27.02-53.84-60.05s24.23-60.05 53.84-60.05h252.54c29.61 0 53.83 27.02 53.83 60.05z"></path>
</svg>
</div>
<div class="loading-indicator"></div>
</div>
<div class="overlay-messages-list"> <div class="overlay-messages-list">
<div class="no-overlay-messages"> <div class="no-overlay-messages">
{{t 'No scheduled messages.'}} {{t 'No scheduled messages.'}}

View File

@ -40,6 +40,8 @@ const realm_icon = mock_esm("../src/realm_icon");
const realm_logo = mock_esm("../src/realm_logo"); const realm_logo = mock_esm("../src/realm_logo");
const realm_playground = mock_esm("../src/realm_playground"); const realm_playground = mock_esm("../src/realm_playground");
const reload = mock_esm("../src/reload"); const reload = mock_esm("../src/reload");
const scheduled_messages = mock_esm("../src/scheduled_messages");
const scheduled_messages_overlay_ui = mock_esm("../src/scheduled_messages_overlay_ui");
const scroll_bar = mock_esm("../src/scroll_bar"); const scroll_bar = mock_esm("../src/scroll_bar");
const settings_account = mock_esm("../src/settings_account"); const settings_account = mock_esm("../src/settings_account");
const settings_bots = mock_esm("../src/settings_bots"); const settings_bots = mock_esm("../src/settings_bots");
@ -371,6 +373,38 @@ run_test("reaction", ({override}) => {
} }
}); });
run_test("scheduled_messages", ({override}) => {
override(scheduled_messages_overlay_ui, "rerender", noop);
override(scheduled_messages_overlay_ui, "remove_scheduled_message_id", noop);
let event = event_fixtures.scheduled_messages__add;
{
const stub = make_stub();
override(scheduled_messages, "add_scheduled_messages", stub.f);
dispatch(event);
assert.equal(stub.num_calls, 1);
const args = stub.get_args("scheduled_messages");
assert_same(args.scheduled_messages, event.scheduled_messages);
}
event = event_fixtures.scheduled_messages__update;
{
const stub = make_stub();
override(scheduled_messages, "update_scheduled_message", stub.f);
dispatch(event);
assert.equal(stub.num_calls, 1);
const args = stub.get_args("scheduled_message");
assert_same(args.scheduled_message, event.scheduled_message);
}
event = event_fixtures.scheduled_messages__remove;
{
const stub = make_stub();
override(scheduled_messages, "remove_scheduled_message", stub.f);
dispatch(event);
assert.equal(stub.num_calls, 1);
const args = stub.get_args("scheduled_message_id");
assert_same(args.scheduled_message_id, event.scheduled_message_id);
}
});
run_test("realm settings", ({override}) => { run_test("realm settings", ({override}) => {
page_params.is_admin = true; page_params.is_admin = true;

View File

@ -613,6 +613,40 @@ exports.fixtures = {
immediate: true, immediate: true,
}, },
scheduled_messages__add: {
type: "scheduled_messages",
op: "add",
scheduled_messages: [
{
scheduled_message_id: 17,
type: "private",
to: [6],
content: "Hello there!",
rendered_content: "<p>Hello there!</p>",
scheduled_delivery_timestamp: 1681662420,
},
],
},
scheduled_messages__remove: {
type: "scheduled_messages",
op: "remove",
scheduled_message_id: 17,
},
scheduled_messages__update: {
type: "scheduled_messages",
op: "update",
scheduled_message: {
scheduled_message_id: 17,
type: "private",
to: [6],
content: "Hello there!",
rendered_content: "<p>Hello there!</p>",
scheduled_delivery_timestamp: 1681662420,
},
},
stream__create: { stream__create: {
type: "stream", type: "stream",
op: "create", op: "create",