Skip to content

Commit 92722c5

Browse files
committed
feat: stop polling when chat relat is present. Process incoming messages from chat relay
Signed-off-by: Dorra Jaouad <[email protected]>
1 parent ae2b48d commit 92722c5

File tree

3 files changed

+82
-3
lines changed

3 files changed

+82
-3
lines changed

src/composables/useGetMessages.ts

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,8 @@ export function useGetMessagesProvider() {
7474
const loadingNewMessages = ref(false)
7575
const isInitialisingMessages = ref(true)
7676
const stopFetchingOldMessages = ref(false)
77+
let chatRelayEnabled = false
78+
let chatRelaySupported = false
7779

7880
/**
7981
* Returns whether the current participant is a participant of current conversation.
@@ -144,6 +146,7 @@ export function useGetMessagesProvider() {
144146
}
145147
if (oldToken && oldToken !== newToken) {
146148
store.dispatch('cancelPollNewMessages', { requestId: oldToken })
149+
stopChatRelay()
147150
}
148151

149152
if (newToken && canGetMessages) {
@@ -162,6 +165,7 @@ export function useGetMessagesProvider() {
162165
subscribe('networkOnline', handleNetworkOnline)
163166
EventBus.on('route-change', onRouteChange)
164167
EventBus.on('set-context-id-to-bottom', setContextIdToBottom)
168+
EventBus.on('signaling-supported-features', checkChatRelaySupport)
165169

166170
/** Every 30 seconds we remove expired messages from the store */
167171
expirationInterval = setInterval(() => {
@@ -173,6 +177,8 @@ export function useGetMessagesProvider() {
173177
unsubscribe('networkOnline', handleNetworkOnline)
174178
EventBus.off('route-change', onRouteChange)
175179
EventBus.off('set-context-id-to-bottom', setContextIdToBottom)
180+
EventBus.off('chat-relay-message-received', addMessageFromChatRelay)
181+
EventBus.off('signaling-supported-features', checkChatRelaySupport)
176182

177183
store.dispatch('cancelPollNewMessages', { requestId: currentToken.value })
178184
clearInterval(pollingTimeout)
@@ -482,6 +488,10 @@ export function useGetMessagesProvider() {
482488
* @param token token of conversation where a method was called
483489
*/
484490
async function pollNewMessages(token: string) {
491+
if (chatRelayEnabled) {
492+
// Stop polling if chat relay is supported
493+
return
494+
}
485495
// Check that the token has not changed
486496
if (currentToken.value !== token) {
487497
console.debug(`token has changed to ${currentToken.value}, breaking the loop for ${token}`)
@@ -499,6 +509,7 @@ export function useGetMessagesProvider() {
499509
requestId: token,
500510
})
501511
debugTimer.end(`${token} | long polling`, 'status 200')
512+
tryChatRelay()
502513
} catch (exception) {
503514
if (Axios.isCancel(exception)) {
504515
debugTimer.end(`${token} | long polling`, 'cancelled')
@@ -512,6 +523,7 @@ export function useGetMessagesProvider() {
512523
// This is not an error, so reset error timeout and poll again
513524
pollingErrorTimeout = 1_000
514525
clearTimeout(pollingTimeout)
526+
tryChatRelay()
515527
pollingTimeout = setTimeout(() => {
516528
pollNewMessages(token)
517529
}, 500)
@@ -539,6 +551,66 @@ export function useGetMessagesProvider() {
539551
}, 500)
540552
}
541553

554+
/**
555+
* Try to start chat relay
556+
*/
557+
function tryChatRelay() {
558+
if (chatRelaySupported && isChatEndReached.value) {
559+
startChatRelay()
560+
}
561+
}
562+
563+
/**
564+
* Check whether chat relay is supported
565+
*
566+
* @param features
567+
*/
568+
function checkChatRelaySupport(features: string[]) {
569+
if (features.includes('chat-relay')) {
570+
chatRelaySupported = true
571+
}
572+
}
573+
574+
/**
575+
* Initialize chat relay support by stopping polling and listening to chat relay messages
576+
*/
577+
function startChatRelay() {
578+
if (currentToken.value) {
579+
// it might have been set already, ensure we cancel it
580+
store.dispatch('cancelPollNewMessages', { requestId: currentToken.value })
581+
}
582+
chatRelayEnabled = true
583+
EventBus.on('chat-relay-message-received', addMessageFromChatRelay)
584+
}
585+
586+
/**
587+
*
588+
* Chat relay sends one message at a time, we update our stores directly
589+
*
590+
* @param payload
591+
* @param payload.token
592+
* @param payload.message
593+
*/
594+
function addMessageFromChatRelay(payload: { token: string, message: ChatMessage }) {
595+
const { token, message } = payload
596+
if (token !== currentToken.value) {
597+
// Guard: Message is for another conversation
598+
// e.g., user switched conversation while messages were in-flight
599+
return
600+
}
601+
602+
chatStore.processChatBlocks(token, [message], { mergeBy: conversationLastMessageId.value })
603+
store.dispatch('processMessage', { token, message })
604+
}
605+
606+
/**
607+
* Stop chat relay and remove listener
608+
*/
609+
function stopChatRelay() {
610+
chatRelayEnabled = false
611+
EventBus.off('chat-relay-message-received', addMessageFromChatRelay)
612+
}
613+
542614
provide(GET_MESSAGES_CONTEXT_KEY, {
543615
contextMessageId,
544616
loadingOldMessages,

src/services/EventBus.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ import mitt from 'mitt'
2121
export type Events = {
2222
[key: EventType]: unknown
2323
'audio-player-ended': number
24+
'chat-relay-message-received': { token: string, message: ChatMessage }
25+
'chat-relay-supported': void
2426
'conversations-received': { singleConversation?: Conversation, fromBrowserStorage?: boolean }
2527
'session-conflict-confirmation': string
2628
'deleted-session-detected': void
@@ -39,7 +41,6 @@ export type Events = {
3941
'route-change': { from: RouteLocation, to: RouteLocation }
4042
'set-context-id-to-bottom': void
4143
'scroll-chat-to-bottom': { smooth?: boolean, force?: boolean }
42-
'should-refresh-chat-messages': void
4344
'should-refresh-conversations': { token: string, properties: Partial<Conversation> } | { all: true } | void
4445
'signaling-join-call': [string, number]
4546
'signaling-join-call-failed': [string, { meta: components['schemas']['OCSMeta'], data: { error: string } }]
@@ -53,6 +54,7 @@ export type Events = {
5354
'signaling-users-joined': [StandaloneSignalingJoinSession[]]
5455
'signaling-users-left': [string[]]
5556
'signaling-all-users-changed-in-call-to-disconnected': void
57+
'signaling-supported-features': string[]
5658
'smart-picker-open': void
5759
'switch-to-conversation': { token: string }
5860
'talk:poll-added': { token: string, message: ChatMessage }

src/utils/signaling.js

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1113,6 +1113,7 @@ Signaling.Standalone.prototype.helloResponseReceived = function(data) {
11131113
for (i = 0; i < features.length; i++) {
11141114
this.features[features[i]] = true
11151115
}
1116+
this._trigger('supportedFeatures', Object.keys(this.features))
11161117
}
11171118

11181119
if (!this.settings.helloAuthParams.internal
@@ -1430,8 +1431,12 @@ Signaling.Standalone.prototype.processRoomEvent = function(data) {
14301431
Signaling.Standalone.prototype.processRoomMessageEvent = function(token, data) {
14311432
switch (data.type) {
14321433
case 'chat':
1433-
// FIXME this is not listened to
1434-
EventBus.emit('should-refresh-chat-messages')
1434+
if ('comment' in data.chat) {
1435+
EventBus.emit('chat-relay-message-received', { token, message: data.chat.comment })
1436+
} else {
1437+
// FIXME this is not listened to
1438+
EventBus.emit('should-refresh-chat-messages')
1439+
}
14351440
break
14361441
case 'recording':
14371442
EventBus.emit('signaling-recording-status-changed', [token, data.recording.status])

0 commit comments

Comments
 (0)