mirror of
https://github.com/basecamp/once-campfire.git
synced 2026-09-26 18:24:55 +09:00
Keep an unsent message as a draft while switching rooms
The composer stores what's being written in localStorage per room and restores it when the room is opened again. Sending clears it.
This commit is contained in:
@@ -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() {
|
||||
|
||||
@@ -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 %>
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user