From 3ef4e80dff22cdbc1fd1421662ec0800650cd48a Mon Sep 17 00:00:00 2001 From: evykassirer Date: Fri, 19 Jan 2024 14:12:26 -0800 Subject: [PATCH] compose: Add button to save draft and start a new message. --- web/src/compose_actions.ts | 1 + web/src/compose_state.ts | 18 ++++++++++++++++++ web/src/drafts.ts | 5 ++++- web/src/narrow.js | 2 ++ web/src/scheduled_messages_popover.js | 18 ++++++++++++++++++ web/templates/popovers/send_later_popover.hbs | 8 +++++++- 6 files changed, 50 insertions(+), 2 deletions(-) diff --git a/web/src/compose_actions.ts b/web/src/compose_actions.ts index 3b4dae39b6..96d36d1eea 100644 --- a/web/src/compose_actions.ts +++ b/web/src/compose_actions.ts @@ -305,6 +305,7 @@ export function start(raw_opts: ComposeActionsStartOpts): void { // If we're not explicitly opening a different draft, restore the last // saved draft (if it exists). if ( + compose_state.can_restore_drafts() && !opts.content && opts.draft_id === undefined && compose_state.message_content().length === 0 diff --git a/web/src/compose_state.ts b/web/src/compose_state.ts index c09608a475..df9fd6c3ed 100644 --- a/web/src/compose_state.ts +++ b/web/src/compose_state.ts @@ -190,6 +190,11 @@ export function has_message_content(): boolean { return message_content() !== ""; } +export const MINIMUM_MESSAGE_LENGTH_TO_SAVE_DRAFT = 2; +export function has_savable_message_content(): boolean { + return message_content().length > MINIMUM_MESSAGE_LENGTH_TO_SAVE_DRAFT; +} + export function has_full_recipient(): boolean { if (message_type === "stream") { return stream_id() !== undefined && topic() !== ""; @@ -208,3 +213,16 @@ export function update_email(user_id: number, new_email: string): void { private_message_recipient(reply_to); } + +let _can_restore_drafts = true; +export function prevent_draft_restoring(): void { + _can_restore_drafts = false; +} + +export function allow_draft_restoring(): void { + _can_restore_drafts = true; +} + +export function can_restore_drafts(): boolean { + return _can_restore_drafts; +} diff --git a/web/src/drafts.ts b/web/src/drafts.ts index 51a8f2802a..d790e3cb04 100644 --- a/web/src/drafts.ts +++ b/web/src/drafts.ts @@ -281,7 +281,10 @@ export function rename_stream_recipient( } export function snapshot_message(): LocalStorageDraft | undefined { - if (!compose_state.composing() || compose_state.message_content().length <= 2) { + if ( + !compose_state.composing() || + compose_state.message_content().length <= compose_state.MINIMUM_MESSAGE_LENGTH_TO_SAVE_DRAFT + ) { // If you aren't in the middle of composing the body of a // message or the message is shorter than 2 characters long, don't try to snapshot. return undefined; diff --git a/web/src/narrow.js b/web/src/narrow.js index 38a0ebe0e2..a577184126 100644 --- a/web/src/narrow.js +++ b/web/src/narrow.js @@ -68,6 +68,8 @@ export function reset_ui_state() { message_feed_top_notices.hide_top_of_narrow_notices(); message_feed_loading.hide_indicators(); unread_ui.reset_unread_banner(); + // We sometimes prevent draft restoring until the narrow resets. + compose_state.allow_draft_restoring(); } export function changehash(newhash) { diff --git a/web/src/scheduled_messages_popover.js b/web/src/scheduled_messages_popover.js index 68b151cf2d..ebe0b38aac 100644 --- a/web/src/scheduled_messages_popover.js +++ b/web/src/scheduled_messages_popover.js @@ -9,6 +9,7 @@ import * as blueslip from "./blueslip"; import * as channel from "./channel"; import * as common from "./common"; import * as compose from "./compose"; +import * as compose_state from "./compose_state"; import * as compose_validate from "./compose_validate"; import * as drafts from "./drafts"; import * as flatpickr from "./flatpickr"; @@ -151,11 +152,15 @@ export function initialize() { onShow(instance) { const formatted_send_later_time = scheduled_messages.get_formatted_selected_send_later_time(); + // If there's existing text in the composebox, show an option + // to keep/save the current draft and start a new message. + const show_compose_new_message = compose_state.has_savable_message_content(); instance.setContent( parse_html( render_send_later_popover({ enter_sends_true: user_settings.enter_sends, formatted_send_later_time, + show_compose_new_message, }), ), ); @@ -203,6 +208,19 @@ export function initialize() { open_send_later_menu(); popover_menus.hide_current_popover_if_visible(instance); }); + $popper.one("click", ".compose_new_message", () => { + drafts.update_draft(); + // If they want to compose a new message instead + // of seeing the draft, remember this and don't + // restore drafts in this narrow until the user + // switches narrows. This allows a user to send + // a bunch of messages in a conversation without + // clicking the "start a new draft" button every + // time. + compose_state.prevent_draft_restoring(); + compose.clear_compose_box(); + popover_menus.hide_current_popover_if_visible(instance); + }); }, onHidden(instance) { instance.destroy(); diff --git a/web/templates/popovers/send_later_popover.hbs b/web/templates/popovers/send_later_popover.hbs index a7cdd01e44..882127d769 100644 --- a/web/templates/popovers/send_later_popover.hbs +++ b/web/templates/popovers/send_later_popover.hbs @@ -51,6 +51,12 @@
  • - {{t "Drafts"}} () + {{t "Drafts" }} ()
  • + {{#if show_compose_new_message}} +
    +
  • + {{t "Save draft and start a new message" }} +
  • + {{/if}}