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 12, 2024
1 parent 264ddc1 commit 868bf5b
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 36 deletions.
42 changes: 12 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,20 @@ 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) {
return null
}
if (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 +1008,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
74 changes: 71 additions & 3 deletions src/store/participantsStore.js
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,8 @@ const state = {
},
speaking: {
},
speakingInterval: {
},
initialised: {
},
/**
Expand Down Expand Up @@ -414,7 +416,7 @@ const mutations = {
* @param {string} data.attendeeId - the attendee ID of the participant in conversation.
* @param {boolean} data.speaking - whether the participant is speaking or not
*/
setSpeaking(state, { token, attendeeId, speaking }) {
setSpeakingTime(state, { token, attendeeId, speaking }) {
// create a dummy object for current call
if (!state.speaking[token]) {
Vue.set(state.speaking, token, {})
Expand All @@ -433,9 +435,56 @@ const mutations = {
// when speaking has stopped, update the total talking time
state.speaking[token][attendeeId].speaking = false
state.speaking[token][attendeeId].totalCountedTime += (currentTimestamp - state.speaking[token][attendeeId].lastTimestamp)
clearInterval(state.speakingInterval[token][attendeeId])
state.speakingInterval[token][attendeeId] = null
}
},

/**
* Sets the speaking interval of a participant in a conversation / call.
*
* @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.interval - interval id for participant update
*/
setSpeakingInterval(state, { token, attendeeId, interval }) {
// create a dummy object for current call
if (!state.speakingInterval[token]) {
Vue.set(state.speakingInterval, token, {})
}
if (!state.speakingInterval[token][attendeeId]) {
Vue.set(state.speakingInterval[token], attendeeId, interval)
} else if (!interval) {
clearInterval(state.speakingInterval[token][attendeeId])
state.speakingInterval[token][attendeeId] = interval
}
},

/**
* Update the total time of speaking 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.
*/
updateTimeSpeaking(state, { token, attendeeId }) {
if (!state.speaking[token]?.[attendeeId]) {
return
}
if (!state.speaking[token][attendeeId].speaking) {
clearInterval(state.speakingInterval[token][attendeeId])
state.speakingInterval[token][attendeeId] = null
return
}

const currentTimestamp = Date.now()
state.speaking[token][attendeeId].totalCountedTime += (currentTimestamp - state.speaking[token][attendeeId].lastTimestamp)
state.speaking[token][attendeeId].lastTimestamp = currentTimestamp
},

/**
* Purge the speaking information for recent call when local participant leaves call
* (including cases when the call ends for everyone).
Expand All @@ -445,7 +494,15 @@ const mutations = {
* @param {string} data.token - the conversation token.
*/
purgeSpeakingStore(state, { token }) {
if (!state.speaking[token]) {
return
}

for (const attendeeId in state.speakingInterval[token]) {
clearInterval(state.speakingInterval[token][attendeeId])
}
Vue.delete(state.speaking, token)
Vue.delete(state.speakingInterval, token)
},

/**
Expand Down Expand Up @@ -1036,8 +1093,19 @@ const actions = {
}
},

setSpeaking(context, { token, attendeeId, speaking }) {
context.commit('setSpeaking', { token, attendeeId, speaking })
setSpeakingTime(context, { token, attendeeId, speaking }) {
let interval

if (speaking) {
interval = setInterval(() => {
context.commit('updateTimeSpeaking', { token, attendeeId })
}, 1000)
} else {
interval = null
}

context.commit('setSpeakingTime', { token, attendeeId, speaking })
context.commit('setSpeakingInterval', { token, attendeeId, interval })
},

purgeSpeakingStore(context, { token }) {
Expand Down
6 changes: 3 additions & 3 deletions src/utils/webrtc/SpeakingStatusHandler.js
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ export default class SpeakingStatusHandler {
* @param {boolean} speaking whether the participant is speaking or not
*/
#handleLocalSpeaking(localMediaModel, speaking) {
this.#store.dispatch('setSpeaking', {
this.#store.dispatch('setSpeakingTime', {
token: this.#store.getters.getToken(),
attendeeId: this.#store.getters.getAttendeeId(),
speaking,
Expand All @@ -125,7 +125,7 @@ export default class SpeakingStatusHandler {
* changes.
*/
#handleLocalPeerId() {
this.#store.dispatch('setSpeaking', {
this.#store.dispatch('setSpeakingTime', {
token: this.#store.getters.getToken(),
attendeeId: this.#store.getters.getAttendeeId(),
speaking: this.#localMediaModel.attributes.speaking,
Expand All @@ -148,7 +148,7 @@ export default class SpeakingStatusHandler {
return
}

this.#store.dispatch('setSpeaking', {
this.#store.dispatch('setSpeakingTime', {
token: this.#store.getters.getToken(),
attendeeId,
speaking,
Expand Down

0 comments on commit 868bf5b

Please sign in to comment.