fix(useGetMessages): introduce composable, extract shared data

Signed-off-by: Maksim Sukharev <antreesy.web@gmail.com>
This commit is contained in:
Maksim Sukharev
2025-07-16 16:04:27 +02:00
parent a0aab04226
commit e30e7afce7
6 changed files with 106 additions and 38 deletions

View File

@ -40,6 +40,7 @@ import SettingsDialog from './components/SettingsDialog/SettingsDialog.vue'
import ConfirmDialog from './components/UIShared/ConfirmDialog.vue'
import { useActiveSession } from './composables/useActiveSession.js'
import { useDocumentTitle } from './composables/useDocumentTitle.ts'
import { useGetMessagesProvider } from './composables/useGetMessages.ts'
import { useGetToken } from './composables/useGetToken.ts'
import { useHashCheck } from './composables/useHashCheck.js'
import { useIsInCall } from './composables/useIsInCall.js'
@ -72,6 +73,8 @@ export default {
setup() {
useDocumentTitle()
// Provide context for MessagesList mounted in different places
useGetMessagesProvider()
// Add provided value to check if we're in the main app or plugin
provide('Talk:isMainApp', true)

View File

@ -36,6 +36,7 @@ import PollViewer from './components/PollViewer/PollViewer.vue'
import InternalSignalingHint from './components/RightSidebar/InternalSignalingHint.vue'
import TopBar from './components/TopBar/TopBar.vue'
import TransitionWrapper from './components/UIShared/TransitionWrapper.vue'
import { useGetMessagesProvider } from './composables/useGetMessages.ts'
import { useGetToken } from './composables/useGetToken.ts'
import { useHashCheck } from './composables/useHashCheck.js'
import { useSessionIssueHandler } from './composables/useSessionIssueHandler.ts'
@ -65,6 +66,7 @@ export default {
setup() {
useHashCheck()
useGetMessagesProvider()
return {
isLeavingAfterSessionIssue: useSessionIssueHandler(),

View File

@ -50,6 +50,7 @@ import InternalSignalingHint from './components/RightSidebar/InternalSignalingHi
import CallButton from './components/TopBar/CallButton.vue'
import TopBar from './components/TopBar/TopBar.vue'
import TransitionWrapper from './components/UIShared/TransitionWrapper.vue'
import { useGetMessagesProvider } from './composables/useGetMessages.ts'
import { useGetToken } from './composables/useGetToken.ts'
import { useHashCheck } from './composables/useHashCheck.js'
import { useIsInCall } from './composables/useIsInCall.js'
@ -96,6 +97,7 @@ export default {
setup() {
useHashCheck()
useGetMessagesProvider()
return {
isInCall: useIsInCall(),

View File

@ -82,6 +82,7 @@ import TransitionWrapper from '../UIShared/TransitionWrapper.vue'
import MessagesGroup from './MessagesGroup/MessagesGroup.vue'
import MessagesSystemGroup from './MessagesGroup/MessagesSystemGroup.vue'
import { useDocumentVisibility } from '../../composables/useDocumentVisibility.ts'
import { useGetMessages } from '../../composables/useGetMessages.ts'
import { useGetThreadId } from '../../composables/useGetThreadId.ts'
import { useIsInCall } from '../../composables/useIsInCall.js'
import { ATTENDEE, CHAT, CONVERSATION, MESSAGE } from '../../constants.ts'
@ -133,6 +134,18 @@ export default {
emits: ['update:isChatScrolledToBottom'],
setup(props) {
const {
pollingErrorTimeout,
loadingOldMessages,
isInitialisingMessages,
destroying,
stopFetchingOldMessages,
isParticipant,
isInLobby,
chatIdentifier,
isChatBeginningReached,
} = useGetMessages()
const isDocumentVisible = useDocumentVisibility()
const isChatVisible = computed(() => isDocumentVisible.value && props.isVisible)
const threadId = useGetThreadId()
@ -142,6 +155,16 @@ export default {
chatExtrasStore: useChatExtrasStore(),
isChatVisible,
threadId,
pollingErrorTimeout,
loadingOldMessages,
isInitialisingMessages,
destroying,
stopFetchingOldMessages,
isParticipant,
isInLobby,
chatIdentifier,
isChatBeginningReached,
}
},
@ -163,24 +186,14 @@ export default {
*/
previousScrollTopValue: null,
pollingErrorTimeout: 1,
loadingOldMessages: false,
isInitialisingMessages: false,
isFocusingMessage: false,
destroying: false,
expirationInterval: null,
debounceUpdateReadMarkerPosition: () => {},
debounceHandleScroll: () => {},
stopFetchingOldMessages: false,
isScrolling: null,
stickyDate: null,
@ -242,41 +255,13 @@ export default {
return this.$store.getters.hasMoreMessagesToLoad(this.token)
},
/**
* Returns whether the current participant is a participant of the
* current conversation or not.
*
* @return {boolean} true if it is already a participant, false
* otherwise.
*/
isParticipant() {
if (!this.conversation) {
return false
}
return !!this.$store.getters.findParticipant(this.token, this.conversation)?.attendeeId
},
isInLobby() {
return this.$store.getters.isInLobby
},
conversation() {
return this.$store.getters.conversation(this.token)
},
chatIdentifier() {
return this.token + ':' + this.isParticipant
},
currentDay() {
return convertToUnix(new Date().setHours(0, 0, 0, 0))
},
isChatBeginningReached() {
return this.stopFetchingOldMessages || (this.messagesList?.[0]?.messageType === MESSAGE.TYPE.SYSTEM
&& ['conversation_created', 'history_cleared'].includes(this.messagesList[0].systemMessage))
},
},
watch: {

View File

@ -0,0 +1,73 @@
/**
* SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
import type {
ChatMessage,
Conversation,
} from '../types/index.ts'
import { computed, ref } from 'vue'
import { useStore } from 'vuex'
import { MESSAGE } from '../constants.ts'
import { useGetToken } from './useGetToken.ts'
/**
* Composable to provide control logic for fetching messages list
*/
export function useGetMessagesProvider() {
const store = useStore()
const currentToken = useGetToken()
const conversation = computed<Conversation | undefined>(() => store.getters.conversation(currentToken.value))
const isInLobby = computed<boolean>(() => store.getters.isInLobby)
const pollingErrorTimeout = ref(1)
const destroying = ref(false)
const loadingOldMessages = ref(false)
const isInitialisingMessages = ref(false)
const stopFetchingOldMessages = ref(false)
/**
* Returns whether the current participant is a participant of current conversation.
*/
const isParticipant = computed<boolean>(() => {
if (!conversation.value) {
return false
}
return !!store.getters.findParticipant(currentToken.value, conversation.value)?.attendeeId
})
const chatIdentifier = computed(() => currentToken.value + ':' + isParticipant.value)
const firstKnownMessage = computed<ChatMessage | undefined>(() => {
return store.getters.message(currentToken.value, store.getters.getFirstKnownMessageId(currentToken.value))
})
const isChatBeginningReached = computed(() => {
return stopFetchingOldMessages.value || (!!firstKnownMessage.value
&& firstKnownMessage.value.messageType === MESSAGE.TYPE.SYSTEM
&& ['conversation_created', 'history_cleared'].includes(firstKnownMessage.value.systemMessage))
})
return {
pollingErrorTimeout,
loadingOldMessages,
isInitialisingMessages,
destroying,
stopFetchingOldMessages,
isParticipant,
isInLobby,
chatIdentifier,
isChatBeginningReached,
}
}
/**
* Composable to inject control logic for fetching messages list in the component
*/
export function useGetMessages() {
// FIXME
return useGetMessagesProvider()
}

View File

@ -24,6 +24,7 @@ import PollManager from '../components/PollViewer/PollManager.vue'
import PollViewer from '../components/PollViewer/PollViewer.vue'
import InternalSignalingHint from '../components/RightSidebar/InternalSignalingHint.vue'
import CallButton from '../components/TopBar/CallButton.vue'
import { useGetMessagesProvider } from '../composables/useGetMessages.ts'
import { useGetToken } from '../composables/useGetToken.ts'
import { useIsInCall } from '../composables/useIsInCall.js'
@ -42,6 +43,8 @@ export default {
},
setup() {
useGetMessagesProvider()
return {
isInCall: useIsInCall(),
token: useGetToken(),