summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMaksim Sukharev <antreesy.web@gmail.com>2023-06-26 12:03:48 +0200
committerbackportbot-nextcloud[bot] <backportbot-nextcloud[bot]@users.noreply.github.com>2023-06-30 09:34:44 +0000
commitf83560842bbc22b387a9a73f7fe2da748df3b7c7 (patch)
tree9e51f1b202193e267f8021f4dbdd48679e5a6c34 /src
parent0cc443aef90d8c72d0fb171208a16285f6eace61 (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.vue49
-rw-r--r--src/components/MessagesList/MessagesList.vue44
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>