import $ from "jquery"; import _ from "lodash"; import * as channel from "./channel"; import * as compose from "./compose"; import * as compose_error from "./compose_error"; import * as hash_util from "./hash_util"; import {$t, $t_html} from "./i18n"; import * as message_lists from "./message_lists"; import * as notifications from "./notifications"; import {page_params} from "./page_params"; import * as people from "./people"; import * as transmit from "./transmit"; import * as util from "./util"; export const deferred_message_types = { scheduled: { delivery_type: "send_later", test: /^\/schedule/, slash_command: "/schedule", }, reminders: { delivery_type: "remind", test: /^\/remind/, slash_command: "/remind", }, }; export function is_deferred_delivery(message_content) { const reminders_test = deferred_message_types.reminders.test; const scheduled_test = deferred_message_types.scheduled.test; return reminders_test.test(message_content) || scheduled_test.test(message_content); } export function patch_request_for_scheduling(request, message_content, deliver_at, delivery_type) { if (request.type === "private") { request.to = JSON.stringify(request.to); } else { request.to = JSON.stringify([request.to]); } const new_request = request; new_request.content = message_content; new_request.deliver_at = deliver_at; new_request.delivery_type = delivery_type; new_request.tz_guess = new Intl.DateTimeFormat().resolvedOptions().timeZone; return new_request; } export function schedule_message(request = compose.create_message_object()) { const raw_message = request.content.split("\n"); const command_line = raw_message[0]; const message = raw_message.slice(1).join("\n"); const deferred_message_type = Object.values(deferred_message_types).find( (props) => command_line.match(props.test) !== null, ); const command = command_line.match(deferred_message_type.test)[0]; const deliver_at = command_line.slice(command.length + 1); let error_message; if (command_line.slice(command.length, command.length + 1) !== " ") { error_message = $t({ defaultMessage: "Invalid slash command. Check if you are missing a space after the command.", }); } else if (deliver_at.trim() === "") { error_message = $t({defaultMessage: "Please specify a date or time."}); } else if (message.trim() === "") { error_message = $t({defaultMessage: "You have nothing to send!"}); } if (error_message) { compose_error.show(error_message, $("#compose-textarea")); $("#compose-textarea").prop("disabled", false); return; } request = patch_request_for_scheduling( request, message, deliver_at, deferred_message_type.delivery_type, ); const success = function (data) { if (request.delivery_type === deferred_message_types.scheduled.delivery_type) { const deliver_at = data.deliver_at; notifications.notify_above_composebox( $t_html({defaultMessage: `Message scheduled for {deliver_at}`}, {deliver_at}), ); } $("#compose-textarea").prop("disabled", false); compose.clear_compose_box(); }; const error = function (response) { $("#compose-textarea").prop("disabled", false); compose_error.show(_.escape(response), $("#compose-textarea")); }; /* We are adding a disable on compose under this block because we want slash commands to be blocking in nature. */ $("#compose-textarea").prop("disabled", true); const future_message = true; transmit.send_message(request, success, error, future_message); } export function do_set_reminder_for_message(message_id, timestamp) { const row = $(`[zid='${CSS.escape(message_id)}']`); function error() { row.find(".alert-msg") .text($t({defaultMessage: "Reminder not set!"})) .css("display", "block") .css("color", "#b94a48") .delay(1000) .fadeOut(300, function () { $(this).css("color", ""); }); } const message = message_lists.current.get(message_id); if (!message.raw_content) { const msg_list = message_lists.current; channel.get({ url: "/json/messages/" + message.id, idempotent: true, success(data) { if (message_lists.current === msg_list) { message.raw_content = data.raw_content; do_set_reminder_for_message(message_id, timestamp); } }, error, }); return; } const link_to_msg = hash_util.by_conversation_and_time_url(message); const reminder_msg_content = message.raw_content + "\n\n[Link to conversation](" + link_to_msg + ")"; let reminder_message = { type: "private", sender_id: page_params.user_id, stream: "", }; reminder_message.topic = ""; const recipient = page_params.email; const emails = util.extract_pm_recipients(recipient); reminder_message.to = emails; reminder_message.reply_to = recipient; reminder_message.private_message_recipient = recipient; reminder_message.to_user_ids = people.email_list_to_user_ids_string(emails); function success() { row.find(".alert-msg") .text($t({defaultMessage: "Reminder set!"})) .css("display", "block") .delay(1000) .fadeOut(300); } reminder_message = patch_request_for_scheduling( reminder_message, reminder_msg_content, timestamp, deferred_message_types.reminders.delivery_type, ); transmit.send_message(reminder_message, success, error); }