Browse Source

Merge pull request #9861 from nextcloud/fix/9826/adjust-scroll-button

follow-up(ChatView) - restore scroll button position
pull/9872/head
Maksim Sukharev 2 years ago
committed by GitHub
parent
commit
80aafa63e1
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 49
      src/components/ChatView.vue
  2. 44
      src/components/MessagesList/MessagesList.vue

49
src/components/ChatView.vue

@ -41,27 +41,48 @@
<MessagesList role="region" <MessagesList role="region"
:aria-label="t('spreed', 'Conversation messages')" :aria-label="t('spreed', 'Conversation messages')"
:token="token" :token="token"
:is-chat-scrolled-to-bottom.sync="isChatScrolledToBottom"
:is-visible="isVisible" /> :is-visible="isVisible" />
<NewMessage v-if="containerId" <NewMessage v-if="containerId"
ref="newMessage"
role="region" role="region"
:token="token" :token="token"
:container="containerId" :container="containerId"
has-typing-indicator has-typing-indicator
:aria-label="t('spreed', 'Post message')" /> :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>
<ChevronDoubleDown :size="20" />
</template>
</NcButton>
</transition>
</div> </div>
</template> </template>
<script> <script>
import ChevronDoubleDown from 'vue-material-design-icons/ChevronDoubleDown.vue'
import NcButton from '@nextcloud/vue/dist/Components/NcButton.js'
import MessagesList from './MessagesList/MessagesList.vue' import MessagesList from './MessagesList/MessagesList.vue'
import NewMessage from './NewMessage/NewMessage.vue' import NewMessage from './NewMessage/NewMessage.vue'
import { CONVERSATION } from '../constants.js' import { CONVERSATION } from '../constants.js'
import { EventBus } from '../services/EventBus.js'
export default { export default {
name: 'ChatView', name: 'ChatView',
components: { components: {
NcButton,
ChevronDoubleDown,
MessagesList, MessagesList,
NewMessage, NewMessage,
}, },
@ -75,6 +96,8 @@ export default {
data() { data() {
return { return {
isChatScrolledToBottom: true,
scrollButtonOffset: undefined,
isDraggingOver: false, isDraggingOver: false,
containerId: undefined, containerId: undefined,
} }
@ -104,7 +127,24 @@ export default {
token() { token() {
return this.$store.getters.getToken() return this.$store.getters.getToken()
}, },
typingParticipants() {
return this.$store.getters.participantsListTyping(this.token)
},
}, },
watch: {
typingParticipants: {
immediate: true,
handler() {
this.$nextTick(() => {
// offset from NewMessage component by 8px, with its min-height: 69px as a fallback
this.scrollButtonOffset = (this.$refs.newMessage?.$el?.clientHeight ?? 69) + 8
})
},
},
},
mounted() { mounted() {
// Postpone render of NewMessage until application is mounted // Postpone render of NewMessage until application is mounted
this.containerId = this.$store.getters.getMainContainerSelector() this.containerId = this.$store.getters.getMainContainerSelector()
@ -142,6 +182,10 @@ export default {
// Uploads and shares the files // Uploads and shares the files
this.$store.dispatch('initialiseUpload', { files, token: this.token, uploadId }) 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 { .slide {
&-enter { &-enter {
transform: translateY(-50%); transform: translateY(-50%);

44
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" /> <Message :size="64" />
</template> </template>
</NcEmptyContent> </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> </div>
</template> </template>
@ -75,7 +64,6 @@ import debounce from 'debounce'
import uniqueId from 'lodash/uniqueId.js' import uniqueId from 'lodash/uniqueId.js'
import { computed } from 'vue' import { computed } from 'vue'
import ChevronDown from 'vue-material-design-icons/ChevronDown.vue'
import Message from 'vue-material-design-icons/Message.vue' import Message from 'vue-material-design-icons/Message.vue'
import Axios from '@nextcloud/axios' import Axios from '@nextcloud/axios'
@ -83,7 +71,6 @@ import { getCapabilities } from '@nextcloud/capabilities'
import { subscribe, unsubscribe } from '@nextcloud/event-bus' import { subscribe, unsubscribe } from '@nextcloud/event-bus'
import moment from '@nextcloud/moment' import moment from '@nextcloud/moment'
import NcButton from '@nextcloud/vue/dist/Components/NcButton.js'
import NcEmptyContent from '@nextcloud/vue/dist/Components/NcEmptyContent.js' import NcEmptyContent from '@nextcloud/vue/dist/Components/NcEmptyContent.js'
import LoadingPlaceholder from '../LoadingPlaceholder.vue' import LoadingPlaceholder from '../LoadingPlaceholder.vue'
@ -99,9 +86,7 @@ export default {
components: { components: {
LoadingPlaceholder, LoadingPlaceholder,
MessagesGroup, MessagesGroup,
ChevronDown,
Message, Message,
NcButton,
NcEmptyContent, NcEmptyContent,
}, },
@ -122,12 +107,19 @@ export default {
required: true, required: true,
}, },
isChatScrolledToBottom: {
type: Boolean,
default: true,
},
isVisible: { isVisible: {
type: Boolean, type: Boolean,
default: true, default: true,
}, },
}, },
emits: ['update:is-chat-scrolled-to-bottom'],
setup() { setup() {
const isInCall = useIsInCall() const isInCall = useIsInCall()
return { isInCall } return { isInCall }
@ -156,7 +148,6 @@ export default {
isFocusingMessage: false, isFocusingMessage: false,
isChatScrolledToBottom: true,
/** /**
* Quick edit option to fall back to the loading history and then new messages * Quick edit option to fall back to the loading history and then new messages
*/ */
@ -258,10 +249,6 @@ export default {
chatIdentifier() { chatIdentifier() {
return this.token + ':' + this.isParticipant + ':' + this.isInLobby + ':' + this.viewId return this.token + ':' + this.isParticipant + ':' + this.isInLobby + ':' + this.viewId
}, },
scrollToBottomAriaLabel() {
return t('spreed', 'Scroll to bottom')
},
}, },
watch: { watch: {
@ -276,7 +263,7 @@ export default {
if (oldValue) { if (oldValue) {
this.$store.dispatch('cancelLookForNewMessages', { requestId: oldValue }) this.$store.dispatch('cancelLookForNewMessages', { requestId: oldValue })
} }
this.isChatScrolledToBottom = true
this.$emit('update:is-chat-scrolled-to-bottom', true)
this.handleStartGettingMessagesPreconditions() this.handleStartGettingMessagesPreconditions()
// Remove expired messages when joining a room // Remove expired messages when joining a room
@ -374,9 +361,9 @@ export default {
if (!message1IsSystem // System messages are grouped independently of author if (!message1IsSystem // System messages are grouped independently of author
&& ((message1.actorType !== message2.actorType // Otherwise the type and id need to match && ((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 return false
} }
@ -1037,7 +1024,7 @@ export default {
}, },
setChatScrolledToBottom(boolean) { setChatScrolledToBottom(boolean) {
this.isChatScrolledToBottom = boolean
this.$emit('update:is-chat-scrolled-to-bottom', boolean)
if (boolean) { if (boolean) {
// mark as read if marker was seen // mark as read if marker was seen
// we have to do this early because unfocusing the window will remove the stickiness // 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> </style>
Loading…
Cancel
Save