Skip to content

Commit e54c037

Browse files
authored
Merge pull request #4375 from traPtitech/feat/stretch-message-input-text-area
💄 feat: MessageInputTextAreaに縦の伸長を追加
2 parents 3c28399 + 8fedd31 commit e54c037

File tree

6 files changed

+173
-80
lines changed

6 files changed

+173
-80
lines changed

src/assets/mdi.ts

+2
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ import {
4141
mdiChevronDoubleLeft,
4242
mdiChevronDoubleUp,
4343
mdiChevronDoubleDown,
44+
mdiChevronDown,
4445
mdiChevronLeft,
4546
mdiChevronRight,
4647
mdiBookmark,
@@ -142,6 +143,7 @@ const mdi: MdiIconsMapping = {
142143
'chevron-double': mdiChevronDoubleLeft,
143144
'chevron-double-up': mdiChevronDoubleUp,
144145
'chevron-double-down': mdiChevronDoubleDown,
146+
'chevron-down': mdiChevronDown,
145147
'chevron-left': mdiChevronLeft,
146148
'chevron-right': mdiChevronRight,
147149
'chevron-up': mdiChevronUp,

src/components/Main/MainView/MessageElement/MessageEditor.vue

+10-9
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
:class="$style.inputTextArea"
1313
:is-posting="isPostingAttachment"
1414
simple-padding
15+
is-max-height-none
1516
@add-attachments="onAddAttachments"
1617
@modifier-key-down="onModifierKeyDown"
1718
@modifier-key-up="onModifierKeyUp"
@@ -43,17 +44,17 @@
4344
</template>
4445

4546
<script lang="ts">
47+
import type { AxiosProgressEvent } from 'axios'
4648
import type { Ref } from 'vue'
4749
import { computed, onMounted, ref } from 'vue'
48-
import apis, { buildFilePathForPost, formatResizeError } from '/@/lib/apis'
49-
import useModifierKey from '/@/components/Main/MainView/MessageInput/composables/useModifierKey'
5050
import useTextStampPickerInvoker from '../composables/useTextStampPickerInvoker'
51-
import { MESSAGE_MAX_LENGTH } from '/@/lib/validate'
51+
import useAttachments from '/@/components/Main/MainView/MessageInput/composables/useAttachments'
52+
import useModifierKey from '/@/components/Main/MainView/MessageInput/composables/useModifierKey'
53+
import apis, { buildFilePathForPost, formatResizeError } from '/@/lib/apis'
5254
import { countLength } from '/@/lib/basic/string'
53-
import { useToastStore } from '/@/store/ui/toast'
5455
import { getResizedFile } from '/@/lib/resize'
55-
import useAttachments from '/@/components/Main/MainView/MessageInput/composables/useAttachments'
56-
import type { AxiosProgressEvent } from 'axios'
56+
import { MESSAGE_MAX_LENGTH } from '/@/lib/validate'
57+
import { useToastStore } from '/@/store/ui/toast'
5758
5859
const useEditMessage = (
5960
props: { messageId: string },
@@ -135,12 +136,12 @@ const useAttachmentsEditor = (
135136
</script>
136137

137138
<script lang="ts" setup>
139+
import MessageInputInsertStampButton from '/@/components/Main/MainView/MessageInput/MessageInputInsertStampButton.vue'
138140
import MessageInputKeyGuide from '/@/components/Main/MainView/MessageInput/MessageInputKeyGuide.vue'
139141
import MessageInputTextArea from '/@/components/Main/MainView/MessageInput/MessageInputTextArea.vue'
140-
import FormButton from '/@/components/UI/FormButton.vue'
141-
import MessageInputInsertStampButton from '/@/components/Main/MainView/MessageInput/MessageInputInsertStampButton.vue'
142-
import MessageInputUploadProgress from '/@/components/Main/MainView/MessageInput/MessageInputUploadProgress.vue'
143142
import MessageInputUploadButton from '/@/components/Main/MainView/MessageInput/MessageInputUploadButton.vue'
143+
import MessageInputUploadProgress from '/@/components/Main/MainView/MessageInput/MessageInputUploadProgress.vue'
144+
import FormButton from '/@/components/UI/FormButton.vue'
144145
145146
const props = defineProps<{
146147
rawContent: string

src/components/Main/MainView/MessageInput/MessageInput.vue

+27-21
Original file line numberDiff line numberDiff line change
@@ -26,19 +26,26 @@
2626
</div>
2727
<div v-else :class="$style.inputContainer">
2828
<message-input-left-controls
29-
v-model:is-expanded="isLeftControlsExpanded"
29+
v-model:is-left-controls-expanded="isLeftControlsExpanded"
3030
v-model:is-preview-shown="isPreviewShown"
31+
v-model:is-input-text-area-expanded="isInputTextAreaExpanded"
32+
:show-text-area-expand-button="showTextAreaExpandButton"
3133
:class="$style.leftControls"
3234
@click-add-attachment="addAttachment"
35+
@toggle-left-controls-expanded="
36+
textareaComponentRef?.textareaAutosizeRef?.autosizeUpdateTextarea
37+
"
3338
/>
3439
<message-input-text-area
3540
ref="textareaComponentRef"
3641
v-model="state.text"
42+
v-model:show-text-area-expand-button="showTextAreaExpandButton"
3743
:channel-id="channelId"
3844
:is-posting="isPosting"
3945
:shrink-to-one-line="
4046
(forceMobileStyle || isMobile) && isLeftControlsExpanded
4147
"
48+
:is-input-text-area-expanded="isInputTextAreaExpanded"
4249
@focus="onFocus"
4350
@blur="onBlur"
4451
@add-attachments="onAddAttachments"
@@ -58,30 +65,30 @@
5865
</template>
5966

6067
<script lang="ts" setup>
61-
import MessageInputLeftControls from './MessageInputLeftControls.vue'
62-
import MessageInputPreview from './MessageInputPreview.vue'
63-
import MessageInputTypingUsers from './MessageInputTypingUsers.vue'
64-
import MessageInputKeyGuide from './MessageInputKeyGuide.vue'
65-
import MessageInputTextArea from './MessageInputTextArea.vue'
66-
import MessageInputRightControls from './MessageInputRightControls.vue'
67-
import MessageInputFileList from './MessageInputFileList.vue'
68-
import MessageInputUploadProgress from './MessageInputUploadProgress.vue'
69-
import AIcon from '/@/components/UI/AIcon.vue'
7068
import { computed, ref, toRef, watch, watchEffect } from 'vue'
71-
import type { ChannelId, DMChannelId, UserId } from '/@/types/entity-ids'
72-
import { useResponsiveStore } from '/@/store/ui/responsive'
7369
import useTextStampPickerInvoker from '../composables/useTextStampPickerInvoker'
7470
import useAttachments from './composables/useAttachments'
7571
import useModifierKey from './composables/useModifierKey'
7672
import usePostMessage from './composables/usePostMessage'
73+
import MessageInputFileList from './MessageInputFileList.vue'
74+
import MessageInputKeyGuide from './MessageInputKeyGuide.vue'
75+
import MessageInputLeftControls from './MessageInputLeftControls.vue'
76+
import MessageInputPreview from './MessageInputPreview.vue'
77+
import MessageInputRightControls from './MessageInputRightControls.vue'
78+
import MessageInputTextArea from './MessageInputTextArea.vue'
79+
import MessageInputTypingUsers from './MessageInputTypingUsers.vue'
80+
import MessageInputUploadProgress from './MessageInputUploadProgress.vue'
81+
import { $boolAttr } from '/@/bool-attr'
82+
import AIcon from '/@/components/UI/AIcon.vue'
7783
import useFocus from '/@/composables/dom/useFocus'
78-
import { useToastStore } from '/@/store/ui/toast'
7984
import useMessageInputState from '/@/composables/messageInputState/useMessageInputState'
8085
import useMessageInputStateAttachment from '/@/composables/messageInputState/useMessageInputStateAttachment'
8186
import { useBrowserSettings } from '/@/store/app/browserSettings'
82-
import { useChannelsStore } from '/@/store/entities/channels'
8387
import { useViewStateSenderStore } from '/@/store/domain/viewStateSenderStore'
84-
import { $boolAttr } from '/@/bool-attr'
88+
import { useChannelsStore } from '/@/store/entities/channels'
89+
import { useResponsiveStore } from '/@/store/ui/responsive'
90+
import { useToastStore } from '/@/store/ui/toast'
91+
import type { ChannelId, DMChannelId, UserId } from '/@/types/entity-ids'
8592
8693
const props = defineProps<{
8794
channelId: ChannelId | DMChannelId
@@ -108,6 +115,8 @@ const { sendWithModifierKey } = useBrowserSettings()
108115
const { channelsMap } = useChannelsStore()
109116
const isLeftControlsExpanded = ref(false)
110117
const isPreviewShown = ref(false)
118+
const isInputTextAreaExpanded = ref(true)
119+
const showTextAreaExpandButton = ref(false)
111120
112121
const isArchived = computed(
113122
() => channelsMap.value.get(props.channelId)?.archived ?? false
@@ -147,13 +156,11 @@ const showKeyGuide = computed(
147156
(sendWithModifierKey.value !== 'modifier' || canPostMessage.value)
148157
)
149158
150-
const textareaComponentRef = ref<{
151-
textareaAutosizeRef: { $el: HTMLTextAreaElement }
152-
}>()
159+
const textareaComponentRef = ref<InstanceType<typeof MessageInputTextArea>>()
153160
const containerEle = ref<HTMLDivElement>()
154161
const { toggleStampPicker } = useTextStampPickerInvoker(
155162
toRef(state, 'text'),
156-
computed(() => textareaComponentRef.value?.textareaAutosizeRef.$el),
163+
computed(() => textareaComponentRef.value?.textareaAutosizeRef?.$el),
157164
containerEle
158165
)
159166
@@ -194,7 +201,6 @@ $radius: 4px;
194201
display: flex;
195202
flex-direction: row;
196203
justify-content: space-between;
197-
align-items: flex-end;
198204
199205
&[data-is-archived] {
200206
@include color-ui-secondary-inactive;
@@ -219,7 +225,7 @@ $radius: 4px;
219225
}
220226
}
221227
.leftControls {
222-
margin: 8px 8px 8px 0;
228+
margin: 2px 8px 8px 0;
223229
}
224230
.rightControls {
225231
position: absolute;
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,63 @@
11
<template>
2-
<div :class="$style.container" :data-is-mobile="$boolAttr(isMobile)">
3-
<template v-if="!isMobile || isExpanded">
4-
<message-input-upload-button
5-
:class="$style.button"
6-
@click="emit('clickAddAttachment')"
7-
/>
8-
<message-input-preview-button
9-
v-model="isPreviewShownValue"
10-
:class="$style.button"
11-
/>
12-
</template>
2+
<div :class="$style.outerContainer" :style="outerContainerStyle">
133
<icon-button
14-
v-if="isMobile"
15-
:class="$style.button"
16-
:icon-name="isExpanded ? 'chevron-left' : 'chevron-right'"
4+
v-if="showTextAreaExpandButton"
5+
:class="$style.textAreaExpandButton"
6+
:icon-name="isInputTextAreaExpanded ? 'chevron-down' : 'chevron-up'"
177
icon-mdi
18-
@click="toggleExpanded"
8+
@click="toggleIsInputTextAreaExpanded"
199
/>
10+
<div :class="$style.innerContainer" :data-is-mobile="$boolAttr(isMobile)">
11+
<template v-if="!isMobile || isLeftControlsExpanded">
12+
<message-input-upload-button
13+
:class="$style.button"
14+
@click="emit('clickAddAttachment')"
15+
/>
16+
<message-input-preview-button
17+
v-model="isPreviewShownValue"
18+
:class="$style.button"
19+
/>
20+
</template>
21+
<icon-button
22+
v-if="isMobile"
23+
:class="$style.button"
24+
:icon-name="isLeftControlsExpanded ? 'chevron-left' : 'chevron-right'"
25+
icon-mdi
26+
@click="toggleLeftControlsExpanded"
27+
/>
28+
</div>
2029
</div>
2130
</template>
2231

2332
<script lang="ts" setup>
24-
import MessageInputUploadButton from './MessageInputUploadButton.vue'
33+
import { computed } from 'vue'
2534
import MessageInputPreviewButton from './MessageInputPreviewButton.vue'
35+
import MessageInputUploadButton from './MessageInputUploadButton.vue'
2636
import IconButton from '/@/components/UI/IconButton.vue'
27-
import { computed } from 'vue'
2837
import { useResponsiveStore } from '/@/store/ui/responsive'
2938
3039
const props = defineProps<{
31-
isExpanded: boolean
40+
isLeftControlsExpanded: boolean
3241
isPreviewShown: boolean
42+
isInputTextAreaExpanded: boolean
43+
showTextAreaExpandButton: boolean
3344
}>()
3445
3546
const emit = defineEmits<{
36-
(e: 'update:isExpanded', _v: boolean): void
47+
(e: 'update:isLeftControlsExpanded', _v: boolean): void
3748
(e: 'update:isPreviewShown', _v: boolean): void
3849
(e: 'clickAddAttachment'): void
50+
(e: 'update:isInputTextAreaExpanded', _v: boolean): void
51+
(e: 'toggleLeftControlsExpanded'): void
3952
}>()
4053
4154
const { isMobile } = useResponsiveStore()
42-
const toggleExpanded = () => {
43-
emit('update:isExpanded', !props.isExpanded)
55+
const toggleLeftControlsExpanded = () => {
56+
emit('update:isLeftControlsExpanded', !props.isLeftControlsExpanded)
57+
emit('toggleLeftControlsExpanded')
58+
}
59+
const toggleIsInputTextAreaExpanded = () => {
60+
emit('update:isInputTextAreaExpanded', !props.isInputTextAreaExpanded)
4461
}
4562
4663
const isPreviewShownValue = computed<boolean>({
@@ -49,17 +66,32 @@ const isPreviewShownValue = computed<boolean>({
4966
},
5067
set(v) {
5168
emit('update:isPreviewShown', v)
52-
emit('update:isExpanded', false)
69+
emit('update:isLeftControlsExpanded', false)
70+
emit('toggleLeftControlsExpanded')
5371
}
5472
})
73+
74+
const outerContainerStyle = computed(() => ({
75+
'--justify-content': props.showTextAreaExpandButton
76+
? 'space-between'
77+
: 'flex-end'
78+
}))
5579
</script>
5680

5781
<style lang="scss" module>
58-
.container {
82+
.outerContainer {
83+
@include color-ui-secondary;
84+
display: flex;
85+
flex-direction: column;
86+
align-items: end;
87+
justify-content: var(--justify-content);
88+
}
89+
.innerContainer {
5990
@include color-ui-secondary;
6091
display: flex;
6192
}
6293
.button {
94+
@include color-ui-secondary;
6395
margin: 0 4px;
6496
6597
&:first-child:first-child {
@@ -69,4 +101,7 @@ const isPreviewShownValue = computed<boolean>({
69101
margin-right: 0;
70102
}
71103
}
104+
.textAreaExpandButton {
105+
@include color-ui-secondary;
106+
}
72107
</style>

0 commit comments

Comments
 (0)