Skip to content

Commit

Permalink
fix(participants): move interval update of talking time counter to th…
Browse files Browse the repository at this point in the history
…e store

Signed-off-by: Maksim Sukharev <antreesy.web@gmail.com>
  • Loading branch information
Antreesy committed Mar 13, 2024
1 parent b7c6b77 commit 31c9833
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 35 deletions.
39 changes: 9 additions & 30 deletions src/components/RightSidebar/Participants/Participant.vue
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@

<!-- Phone participant dial action -->
<div v-if="isInCall && canBeModerated && isPhoneActor"
id="participantNavigationId"
:id="participantNavigationId"
class="participant-row__dial-actions">
<NcButton v-if="!participant.inCall"
type="success"
Expand Down Expand Up @@ -464,8 +464,6 @@ export default {
isUserNameTooltipVisible: false,
isStatusTooltipVisible: false,
permissionsEditor: false,
speakingInterval: null,
timeSpeaking: null,
disabled: false,
}
},
Expand Down Expand Up @@ -864,22 +862,17 @@ export default {
}
return ''
},
},
watch: {
isParticipantSpeaking(speaking) {
if (speaking) {
if (!this.speakingInterval) {
this.speakingInterval = setInterval(this.computeElapsedTime, 1000)
}
} else {
if (speaking === undefined) {
this.timeSpeaking = 0
}
clearInterval(this.speakingInterval)
this.speakingInterval = null
timeSpeaking() {
if (!this.participantSpeakingInformation || this.isParticipantSpeaking === undefined) {
return 0
}
return this.participantSpeakingInformation.totalCountedTime
},
},
watch: {
phoneCallStatus(value) {
if (!value || !(value === 'ringing' || value === 'accepted')) {
this.disabled = false
Expand Down Expand Up @@ -1012,20 +1005,6 @@ export default {
}
},
computeElapsedTime() {
if (!this.participantSpeakingInformation) {
return null
}
const { speaking, lastTimestamp, totalCountedTime } = this.participantSpeakingInformation
if (!speaking) {
this.timeSpeaking = totalCountedTime
} else {
this.timeSpeaking = Date.now() - lastTimestamp + totalCountedTime
}
},
async dialOutPhoneNumber() {
try {
this.disabled = true
Expand Down
71 changes: 66 additions & 5 deletions src/store/participantsStore.js
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ const state = {
* when quickly switching to a new conversation.
*/
cancelFetchParticipants: null,
speakingInterval: null,
}

const getters = {
Expand Down Expand Up @@ -420,20 +421,53 @@ const mutations = {
Vue.set(state.speaking, token, {})
}
if (!state.speaking[token][attendeeId]) {
Vue.set(state.speaking[token], attendeeId, { speaking: null, lastTimestamp: 0, totalCountedTime: 0 })
Vue.set(state.speaking[token], attendeeId, { speaking, lastTimestamp: Date.now(), totalCountedTime: 0 })
}
},

/**
* Tracks the interval id to update speaking information for a current call.
*
* @param {object} state - current store state.
* @param {number} interval - interval id.
*/
setSpeakingInterval(state, interval) {
Vue.set(state, 'speakingInterval', interval)
},

/**
* Update speaking information for a participant.
*
* @param {object} state - current store state.
* @param {object} data - the wrapping object.
* @param {string} data.token - the conversation token participant is speaking in.
* @param {string} data.attendeeId - the attendee ID of the participant in conversation.
* @param {boolean} data.speaking - whether the participant is speaking or not
* @param {boolean} [data.interval=false] - whether update happens with interval or signal
*/
updateTimeSpeaking(state, { token, attendeeId, speaking, interval = false }) {
if (!state.speaking[token]?.[attendeeId]) {
return
}

const currentTimestamp = Date.now()
const currentSpeakingState = state.speaking[token][attendeeId].speaking

if (currentSpeakingState && speaking && interval) {
// true -> true, only currently speaking users are updated within interval
state.speaking[token][attendeeId].totalCountedTime += (currentTimestamp - state.speaking[token][attendeeId].lastTimestamp)
state.speaking[token][attendeeId].lastTimestamp = currentTimestamp
return
}

if (!currentSpeakingState && speaking) {
state.speaking[token][attendeeId].speaking = true
// false -> true, speaking has started, update last timestamp
state.speaking[token][attendeeId].lastTimestamp = currentTimestamp
} else if (currentSpeakingState && !speaking) {
// when speaking has stopped, update the total talking time
state.speaking[token][attendeeId].speaking = false
// true -> false, speaking has stopped, update total counted time
state.speaking[token][attendeeId].totalCountedTime += (currentTimestamp - state.speaking[token][attendeeId].lastTimestamp)
}
state.speaking[token][attendeeId].speaking = speaking
},

/**
Expand All @@ -445,7 +479,14 @@ const mutations = {
* @param {string} data.token - the conversation token.
*/
purgeSpeakingStore(state, { token }) {
Vue.delete(state.speaking, token)
if (state.speaking[token]) {
Vue.delete(state.speaking, token)
}

if (state.speakingInterval) {
clearInterval(state.speakingInterval)
Vue.set(state, 'speakingInterval', null)
}
},

/**
Expand Down Expand Up @@ -1038,6 +1079,26 @@ const actions = {

setSpeaking(context, { token, attendeeId, speaking }) {
context.commit('setSpeaking', { token, attendeeId, speaking })
context.commit('updateTimeSpeaking', { token, attendeeId, speaking, interval: false })

if (!context.state.speakingInterval) {
const interval = setInterval(() => {
context.dispatch('updateIntervalTimeSpeaking', { token })
}, 1000)
context.commit('setSpeakingInterval', interval)
}
},

updateIntervalTimeSpeaking(context, { token }) {
if (!context.state.speaking[token] || !context.state.speakingInterval) {
return
}

for (const attendeeId in context.state.speaking[token]) {
if (context.state.speaking[token][attendeeId].speaking) {
context.commit('updateTimeSpeaking', { token, attendeeId, speaking: true, interval: true })
}
}
},

purgeSpeakingStore(context, { token }) {
Expand Down

0 comments on commit 31c9833

Please sign in to comment.