diff options
author | Maksim Sukharev <antreesy.web@gmail.com> | 2023-06-26 12:03:48 +0200 |
---|---|---|
committer | backportbot-nextcloud[bot] <backportbot-nextcloud[bot]@users.noreply.github.com> | 2023-06-30 09:34:44 +0000 |
commit | f83560842bbc22b387a9a73f7fe2da748df3b7c7 (patch) | |
tree | 9e51f1b202193e267f8021f4dbdd48679e5a6c34 /src | |
parent | 0cc443aef90d8c72d0fb171208a16285f6eace61 (diff) |
move scroll button out of list, update position on NewMessage resize
Signed-off-by: Maksim Sukharev <antreesy.web@gmail.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/components/ChatView.vue | 49 | ||||
-rw-r--r-- | src/components/MessagesList/MessagesList.vue | 44 |
2 files changed, 61 insertions, 32 deletions
diff --git a/src/components/ChatView.vue b/src/components/ChatView.vue index c0a2727ad..cd89f1635 100644 --- a/src/components/ChatView.vue +++ b/src/components/ChatView.vue @@ -41,27 +41,48 @@ <MessagesList role="region" :aria-label="t('spreed', 'Conversation messages')" :token="token" + :is-chat-scrolled-to-bottom.sync="isChatScrolledToBottom" :is-visible="isVisible" /> <NewMessage v-if="containerId" + ref="newMessage" role="region" :token="token" :container="containerId" has-typing-indicator :aria-label="t('spreed', 'Post message')" /> + <transition name="fade"> + <NcButton v-show="!isChatScrolledToBottom" + type="secondary" + :aria-label="t('spreed', 'Scroll to bottom')" + class="scroll-to-bottom" + :style="`bottom: ${scrollButtonOffset}px`" + @click="smoothScrollToBottom"> + <template #icon> + <ChevronDown :size="20" /> + </template> + </NcButton> + </transition> </div> </template> <script> +import ChevronDown from 'vue-material-design-icons/ChevronDown.vue' + +import NcButton from '@nextcloud/vue/dist/Components/NcButton.js' + import MessagesList from './MessagesList/MessagesList.vue' import NewMessage from './NewMessage/NewMessage.vue' import { CONVERSATION } from '../constants.js' +import { EventBus } from '../services/EventBus.js' export default { name: 'ChatView', components: { + NcButton, + ChevronDown, MessagesList, NewMessage, }, @@ -75,6 +96,8 @@ export default { data() { return { + isChatScrolledToBottom: true, + scrollButtonOffset: undefined, isDraggingOver: false, containerId: undefined, } @@ -104,7 +127,24 @@ export default { token() { return this.$store.getters.getToken() }, + + typingParticipants() { + return this.$store.getters.participantsListTyping(this.token) + }, }, + + watch: { + typingParticipants: { + immediate: true, + handler() { + this.$nextTick(() => { + // overlap NewMessage component by 8px, set its min-height: 69px as a fallback + this.scrollButtonOffset = (this.$refs.newMessage?.$el?.clientHeight ?? 69) - 8 + }) + }, + }, + }, + mounted() { // Postpone render of NewMessage until application is mounted this.containerId = this.$store.getters.getMainContainerSelector() @@ -142,6 +182,10 @@ export default { // Uploads and shares the files this.$store.dispatch('initialiseUpload', { files, token: this.token, uploadId }) }, + + smoothScrollToBottom() { + EventBus.$emit('smooth-scroll-chat-to-bottom') + }, }, } @@ -183,6 +227,11 @@ export default { } } +.scroll-to-bottom { + position: absolute !important; + right: 24px; +} + .slide { &-enter { transform: translateY(-50%); diff --git a/src/components/MessagesList/MessagesList.vue b/src/components/MessagesList/MessagesList.vue index 2638643be..152c389cc 100644 --- a/src/components/MessagesList/MessagesList.vue +++ b/src/components/MessagesList/MessagesList.vue @@ -56,17 +56,6 @@ get the messagesList array and loop through the list to generate the messages. <Message :size="64" /> </template> </NcEmptyContent> - <transition name="fade"> - <NcButton v-show="!isChatScrolledToBottom" - type="secondary" - :aria-label="scrollToBottomAriaLabel" - class="scroll-to-bottom" - @click="smoothScrollToBottom"> - <template #icon> - <ChevronDown :size="20" /> - </template> - </NcButton> - </transition> </div> </template> @@ -75,7 +64,6 @@ import debounce from 'debounce' import uniqueId from 'lodash/uniqueId.js' import { computed } from 'vue' -import ChevronDown from 'vue-material-design-icons/ChevronDown.vue' import Message from 'vue-material-design-icons/Message.vue' import Axios from '@nextcloud/axios' @@ -83,7 +71,6 @@ import { getCapabilities } from '@nextcloud/capabilities' import { subscribe, unsubscribe } from '@nextcloud/event-bus' import moment from '@nextcloud/moment' -import NcButton from '@nextcloud/vue/dist/Components/NcButton.js' import NcEmptyContent from '@nextcloud/vue/dist/Components/NcEmptyContent.js' import LoadingPlaceholder from '../LoadingPlaceholder.vue' @@ -99,9 +86,7 @@ export default { components: { LoadingPlaceholder, MessagesGroup, - ChevronDown, Message, - NcButton, NcEmptyContent, }, @@ -122,12 +107,19 @@ export default { required: true, }, + isChatScrolledToBottom: { + type: Boolean, + default: true, + }, + isVisible: { type: Boolean, default: true, }, }, + emits: ['update:is-chat-scrolled-to-bottom'], + setup() { const isInCall = useIsInCall() return { isInCall } @@ -156,7 +148,6 @@ export default { isFocusingMessage: false, - isChatScrolledToBottom: true, /** * Quick edit option to fall back to the loading history and then new messages */ @@ -258,10 +249,6 @@ export default { chatIdentifier() { return this.token + ':' + this.isParticipant + ':' + this.isInLobby + ':' + this.viewId }, - - scrollToBottomAriaLabel() { - return t('spreed', 'Scroll to bottom') - }, }, watch: { @@ -276,7 +263,7 @@ export default { if (oldValue) { this.$store.dispatch('cancelLookForNewMessages', { requestId: oldValue }) } - this.isChatScrolledToBottom = true + this.$emit('update:is-chat-scrolled-to-bottom', true) this.handleStartGettingMessagesPreconditions() // Remove expired messages when joining a room @@ -374,9 +361,9 @@ export default { if (!message1IsSystem // System messages are grouped independently of author && ((message1.actorType !== message2.actorType // Otherwise the type and id need to match - || message1.actorId !== message2.actorId) - || (message1.actorType === ATTENDEE.ACTOR_TYPE.BRIDGED // Or, if the message is bridged, display names also need to match - && message1.actorDisplayName !== message2.actorDisplayName))) { + || message1.actorId !== message2.actorId) + || (message1.actorType === ATTENDEE.ACTOR_TYPE.BRIDGED // Or, if the message is bridged, display names also need to match + && message1.actorDisplayName !== message2.actorDisplayName))) { return false } @@ -1037,7 +1024,7 @@ export default { }, setChatScrolledToBottom(boolean) { - this.isChatScrolledToBottom = boolean + this.$emit('update:is-chat-scrolled-to-bottom', boolean) if (boolean) { // mark as read if marker was seen // we have to do this early because unfocusing the window will remove the stickiness @@ -1073,11 +1060,4 @@ export default { } } -.scroll-to-bottom { - position: absolute !important; - bottom: 140px; - right: 24px; - z-index: 2; -} - </style> |