diff --git a/locales/en-US.yml b/locales/en-US.yml index 6538c43ff..3f04adb67 100644 --- a/locales/en-US.yml +++ b/locales/en-US.yml @@ -1284,6 +1284,8 @@ noteOfThisUser: "Notes by this user" clipNoteLimitExceeded: "No more notes can be added to this clip." timeTravel: "Time Travel" timeTravelDescription: "Show posts before this date." +undoPostForm: "Undo" +clearPostForm: "Clear" pariPlusInfo: "Pari Plus! customized Misskey~!" pariPlusSystemSettings: "Pari Plus! system settings" pariPlusNoteSettings: "Pari Plus! note settings" diff --git a/packages/frontend/src/components/MkPostForm.vue b/packages/frontend/src/components/MkPostForm.vue index aca759dcb..435372f6a 100644 --- a/packages/frontend/src/components/MkPostForm.vue +++ b/packages/frontend/src/components/MkPostForm.vue @@ -90,6 +90,7 @@ SPDX-License-Identifier: AGPL-3.0-only
+
@@ -260,6 +261,44 @@ const canPost = computed((): boolean => { const withHashtags = computed(defaultStore.makeGetterSetter('postFormWithHashtags')); const hashtags = computed(defaultStore.makeGetterSetter('postFormHashtags')); +const textHistory = ref([]); +const currentHistoryIndex = ref(-1); +const showTextManageButton = computed(() => text.value !== '' || currentHistoryIndex.value >= 0); +const textManageButtonIcon = computed(() => { + if (currentHistoryIndex.value >= 0) return 'ti ti-arrow-back-up'; + return text.value !== '' ? 'ti ti-trash' : ''; +}); + +function clearText() { + if (text.value !== '') { + saveToHistory(); + text.value = ''; + nextTick(() => textareaEl.value && autosize.update(textareaEl.value)); + } +} + +function saveToHistory() { + textHistory.value = textHistory.value.slice(0, currentHistoryIndex.value + 1); + textHistory.value.push(text.value); + currentHistoryIndex.value = textHistory.value.length - 1; +} + +function undoTextChange() { + if (currentHistoryIndex.value >= 0) { + text.value = textHistory.value[currentHistoryIndex.value]; + currentHistoryIndex.value--; + nextTick(() => textareaEl.value && autosize.update(textareaEl.value)); + } +} + +function handleTextManageClick() { + if (currentHistoryIndex.value >= 0) { + undoTextChange(); + } else { + clearText(); + } +} + watch(text, () => { checkMissingMention(); }, { immediate: true }); @@ -576,6 +615,10 @@ function clear() { function onKeydown(ev: KeyboardEvent) { if (ev.key === 'Enter' && (ev.ctrlKey || ev.metaKey) && canPost.value) post(); + if (!ev.ctrlKey && !ev.metaKey && !ev.altKey && !justEndedComposition.value && !ev.isComposing) { + saveToHistory(); + } + // justEndedComposition.value is for Safari, which keyDown occurs after compositionend. // ev.isComposing is for another browsers. if (ev.key === 'Escape' && !justEndedComposition.value && !ev.isComposing) emit('esc');