mirror of https://github.com/zulip/zulip.git
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:
parent
eb5f679121
commit
7d373c54a9
|
@ -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() {
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -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();
|
||||||
});
|
});
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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();
|
||||||
|
|
||||||
|
|
|
@ -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.'}}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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",
|
||||||
|
|
Loading…
Reference in New Issue