diff --git a/app/javascript/controllers/composer_controller.js b/app/javascript/controllers/composer_controller.js index 3e1ff1c..104e319 100644 --- a/app/javascript/controllers/composer_controller.js +++ b/app/javascript/controllers/composer_controller.js @@ -12,11 +12,21 @@ export default class extends Controller { #files = [] connect() { + this.#restoreDraft() + if (!this.#usingTouchDevice) { onNextEventLoopTick(() => this.textTarget.focus()) } } + saveDraft() { + if (this.textTarget.isBlank) { + localStorage.removeItem(this.#draftKey) + } else { + localStorage.setItem(this.#draftKey, this.textTarget.value) + } + } + submit(event) { event.preventDefault() @@ -107,6 +117,19 @@ export default class extends Controller { this.fieldsTarget.disabled = true } + #restoreDraft() { + const draft = localStorage.getItem(this.#draftKey) + + if (draft) { + this.textTarget.value = draft + this.textTarget.selection.placeCursorAtTheEnd() + } + } + + get #draftKey() { + return `composer-draft-${this.roomIdValue}` + } + get #usingTouchDevice() { return 'ontouchstart' in window || navigator.maxTouchPoints > 0 || navigator.msMaxTouchPoints > 0; } @@ -158,6 +181,7 @@ export default class extends Controller { #reset() { this.textTarget.value = "" + localStorage.removeItem(this.#draftKey) } #updateFileList() { diff --git a/app/views/rooms/show/_composer.html.erb b/app/views/rooms/show/_composer.html.erb index 8d9e3c5..43f961c 100644 --- a/app/views/rooms/show/_composer.html.erb +++ b/app/views/rooms/show/_composer.html.erb @@ -25,7 +25,7 @@ "permitted-attachment-types": "application/vnd.campfire.mention application/vnd.actiontext.opengraph-embed", data: { controller: "unfurl", - action: "#{rich_text_data_actions} lexxy:insert-link->unfurl#unfurl", + action: "#{rich_text_data_actions} lexxy:change->composer#saveDraft lexxy:insert-link->unfurl#unfurl", composer_target: "text" } do %> <%= mention_prompt_tag room %> <% end %> diff --git a/test/system/composer_test.rb b/test/system/composer_test.rb index c63c028..24ccd12 100644 --- a/test/system/composer_test.rb +++ b/test/system/composer_test.rb @@ -29,6 +29,27 @@ class ComposerTest < ApplicationSystemTestCase assert_composer_empty end + test "an unsent message is kept as a draft while hopping between rooms" do + type_in_composer "Still writing this" + + join_room rooms(:hq) + assert_composer_empty + + type_in_composer "And this one too" + + join_room rooms(:designers) + assert_composer_text "Still writing this" + + press_in_composer :enter + assert_message_text "Still writing this" + + join_room rooms(:hq) + assert_composer_text "And this one too" + + join_room rooms(:designers) + assert_composer_empty + end + test "markdown strikethrough survives sanitization" do type_in_composer "Hello ~~Claude~~ World" press_in_composer :enter