Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

follow-up(ChatView) - align scroll button position with mobile clients #9861

Merged
merged 2 commits into from
Jun 30, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 49 additions & 0 deletions src/components/ChatView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -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>
<ChevronDoubleDown :size="20" />
</template>
</NcButton>
</transition>
</div>
</template>

<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 NewMessage from './NewMessage/NewMessage.vue'

import { CONVERSATION } from '../constants.js'
import { EventBus } from '../services/EventBus.js'

export default {

name: 'ChatView',

components: {
NcButton,
ChevronDoubleDown,
MessagesList,
NewMessage,
},
Expand All @@ -75,6 +96,8 @@ export default {

data() {
return {
isChatScrolledToBottom: true,
scrollButtonOffset: undefined,
isDraggingOver: false,
containerId: undefined,
}
Expand Down Expand Up @@ -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(() => {
// offset from NewMessage component by 8px, with 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()
Expand Down Expand Up @@ -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')
},
},

}
Expand Down Expand Up @@ -183,6 +227,11 @@ export default {
}
}

.scroll-to-bottom {
position: absolute !important;
right: 24px;
}

.slide {
&-enter {
transform: translateY(-50%);
Expand Down
44 changes: 12 additions & 32 deletions src/components/MessagesList/MessagesList.vue
Original file line number Diff line number Diff line change
Expand Up @@ -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>

Expand All @@ -75,15 +64,13 @@ 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'
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'
Expand All @@ -99,9 +86,7 @@ export default {
components: {
LoadingPlaceholder,
MessagesGroup,
ChevronDown,
Message,
NcButton,
NcEmptyContent,
},

Expand All @@ -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 }
Expand Down Expand Up @@ -156,7 +148,6 @@ export default {

isFocusingMessage: false,

isChatScrolledToBottom: true,
/**
* Quick edit option to fall back to the loading history and then new messages
*/
Expand Down Expand Up @@ -258,10 +249,6 @@ export default {
chatIdentifier() {
return this.token + ':' + this.isParticipant + ':' + this.isInLobby + ':' + this.viewId
},

scrollToBottomAriaLabel() {
return t('spreed', 'Scroll to bottom')
},
},

watch: {
Expand All @@ -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
Expand Down Expand Up @@ -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
}

Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -1073,11 +1060,4 @@ export default {
}
}

.scroll-to-bottom {
position: absolute !important;
bottom: 140px;
right: 24px;
z-index: 2;
}

</style>
Loading