From 8e74baea7813530be35310aba76c62a40d1ff6f2 Mon Sep 17 00:00:00 2001 From: Valerian Saliou Date: Wed, 27 Nov 2024 17:49:23 +0100 Subject: [PATCH] feat: add preview area for message drafts, fixes #142 --- src/assemblies/inbox/InboxForm.vue | 36 +++- .../images/icons/character.cursor.ibeam.svg | 1 + src/assets/images/icons/text.viewfinder.svg | 1 + src/broker/index.ts | 3 + src/components/inbox/InboxFormFormatting.vue | 166 ++++++++++++++++-- src/components/inbox/InboxFormPreview.vue | 158 +++++++++++++++++ 6 files changed, 350 insertions(+), 15 deletions(-) create mode 100644 src/assets/images/icons/character.cursor.ibeam.svg create mode 100644 src/assets/images/icons/text.viewfinder.svg create mode 100644 src/components/inbox/InboxFormPreview.vue diff --git a/src/assemblies/inbox/InboxForm.vue b/src/assemblies/inbox/InboxForm.vue index 65a3a080..a52c2658 100644 --- a/src/assemblies/inbox/InboxForm.vue +++ b/src/assemblies/inbox/InboxForm.vue @@ -69,11 +69,20 @@ layout-toolbar( inbox-form-formatting( v-if="isActionFormatFormattingVisible" @action="onFormattingAction" + @mode="onFormattingMode" :disabled="isFormDisabled" + :mode="formattingMode" class="a-inbox-form__compose-formatting" ) + inbox-form-preview( + v-if="formattingMode === formattingModeOptions.Preview" + :message="message" + class="a-inbox-form__compose-preview" + ) + form.a-inbox-form__compose-form( + v-show="formattingMode === formattingModeOptions.Write" @submit.prevent="onSubmit" ) form-field( @@ -199,6 +208,7 @@ import { Suggestion as FormFieldSuggestSuggestion } from "@/components/form/Form import { default as InboxFormFormatting, FormattingAction, + FormattingMode, FormattingSyntax, TAG_TEXT as FORMATTING_TAG_TEXT, TAG_INDEX as FORMATTING_TAG_INDEX @@ -209,6 +219,7 @@ import { } from "@/components/inbox/InboxFormRecorder.vue"; import InboxFormAttach from "@/components/inbox/InboxFormAttach.vue"; import InboxFormChatstate from "@/components/inbox/InboxFormChatstate.vue"; +import InboxFormPreview from "@/components/inbox/InboxFormPreview.vue"; import InboxFormLoader from "@/components/inbox/InboxFormLoader.vue"; // PROJECT: STORES @@ -243,6 +254,7 @@ export default { InboxFormRecorder, InboxFormAttach, InboxFormChatstate, + InboxFormPreview, InboxFormLoader }, @@ -261,10 +273,14 @@ export default { actionIconSize: "18px", + formattingModeOptions: FormattingMode, + // --> STATE <-- message: "", + formattingMode: FormattingMode.Write, + mentionQuery: null as string | null, isMessageFieldFocused: false, @@ -539,6 +555,12 @@ export default { focusMessageField(): void { // Focus on input (this.$refs.message as typeof FormField)?.focusFieldFromParent(); + + // Force formatting mode to write + // Notice: this is important, as the user might be previewing a message \ + // when something requests to focus on the message field. We therefore \ + // need to force the mode to write. + this.formattingMode = FormattingMode.Write; }, clearMessageField(): void { @@ -742,6 +764,10 @@ export default { } }, + onFormattingMode(mode: FormattingMode): void { + this.formattingMode = mode; + }, + onRecorderAudio(audio: RecorderAudio) { // Close recorder this.isActionRecordRecorderVisible = false; @@ -1054,15 +1080,19 @@ $form-compose-send-button-size: ( width: 100%; } + #{$c}__compose-field textarea, + #{$c}__compose-preview { + min-height: $form-compose-field-height-minimum; + max-height: 220px; + border-radius: ($size-form-field-border-radius + 2px); + } + #{$c}__compose-field { textarea { - min-height: $form-compose-field-height-minimum; - max-height: 220px; padding-inline-end: ( $form-compose-send-button-size + $form-compose-send-position-edges + 2px ); - border-radius: ($size-base-button-border-radius + 2px); } } diff --git a/src/assets/images/icons/character.cursor.ibeam.svg b/src/assets/images/icons/character.cursor.ibeam.svg new file mode 100644 index 00000000..6a1301c0 --- /dev/null +++ b/src/assets/images/icons/character.cursor.ibeam.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/images/icons/text.viewfinder.svg b/src/assets/images/icons/text.viewfinder.svg new file mode 100644 index 00000000..ed552f4a --- /dev/null +++ b/src/assets/images/icons/text.viewfinder.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/broker/index.ts b/src/broker/index.ts index ce1c9a52..d3040095 100644 --- a/src/broker/index.ts +++ b/src/broker/index.ts @@ -14,6 +14,7 @@ import BrokerClient from "@/broker/client"; import BrokerModuleAccount from "@/broker/modules/account"; import BrokerModuleRoom from "@/broker/modules/room"; import BrokerModulePresence from "@/broker/modules/presence"; +import BrokerModuleMessage from "@/broker/modules/message"; import BrokerModuleChannel from "@/broker/modules/channel"; import BrokerModuleProfile from "@/broker/modules/profile"; import BrokerModuleRoster from "@/broker/modules/roster"; @@ -32,6 +33,7 @@ class Broker { readonly $roster: BrokerModuleRoster; readonly $status: BrokerModuleStatus; readonly $presence: BrokerModulePresence; + readonly $message: BrokerModuleMessage; readonly $room: BrokerModuleRoom; readonly $channel: BrokerModuleChannel; readonly $data: BrokerModuleData; @@ -46,6 +48,7 @@ class Broker { this.$roster = new BrokerModuleRoster(this.client); this.$status = new BrokerModuleStatus(this.client); this.$presence = new BrokerModulePresence(this.client); + this.$message = new BrokerModuleMessage(this.client); this.$room = new BrokerModuleRoom(this.client); this.$channel = new BrokerModuleChannel(this.client); this.$data = new BrokerModuleData(this.client); diff --git a/src/components/inbox/InboxFormFormatting.vue b/src/components/inbox/InboxFormFormatting.vue index d2dc60cb..9c03deae 100644 --- a/src/components/inbox/InboxFormFormatting.vue +++ b/src/components/inbox/InboxFormFormatting.vue @@ -10,24 +10,59 @@ + + + +