Skip to content

Commit d707a4b

Browse files
committed
fix: refactor actions
- handleJoinCall - setCallViewMode - startPresentation - stopPresentation Signed-off-by: Maksim Sukharev <[email protected]> (cherry picked from commit d203d1f)
1 parent 684a983 commit d707a4b

File tree

9 files changed

+59
-78
lines changed

9 files changed

+59
-78
lines changed

src/components/CallView/CallView.vue

+8-8
Original file line numberDiff line numberDiff line change
@@ -425,19 +425,19 @@ export default {
425425
callParticipantModelsWithScreen(newValue, previousValue) {
426426
// Everytime a new screen is shared, switch to promoted view
427427
if (newValue.length > previousValue.length) {
428-
this.$store.dispatch('startPresentation')
428+
this.callViewStore.startPresentation()
429429
} else if (newValue.length === 0 && previousValue.length > 0 && !this.hasLocalScreen && !this.selectedVideoPeerId) {
430430
// last screen share stopped and no selected video, restoring previous state
431-
this.$store.dispatch('stopPresentation')
431+
this.callViewStore.stopPresentation()
432432
}
433433
},
434434
showLocalScreen(showLocalScreen) {
435435
// Everytime the local screen is shared, switch to promoted view
436436
if (showLocalScreen) {
437-
this.$store.dispatch('startPresentation')
437+
this.callViewStore.startPresentation()
438438
} else if (this.callParticipantModelsWithScreen.length === 0 && !this.selectedVideoPeerId) {
439439
// last screen share stopped and no selected video, restoring previous state
440-
this.$store.dispatch('stopPresentation')
440+
this.callViewStore.stopPresentation()
441441
}
442442
},
443443
hasLocalVideo(newValue) {
@@ -656,13 +656,13 @@ export default {
656656
}
657657

658658
if (this.callViewStore.presentationStarted) {
659-
this.$store.dispatch('setCallViewMode', {
659+
this.callViewStore.setCallViewMode({
660660
isGrid: false,
661661
isStripeOpen: false,
662662
clearLast: false,
663663
})
664664
} else {
665-
this.$store.dispatch('startPresentation')
665+
this.callViewStore.startPresentation()
666666
}
667667
this.callViewStore.setSelectedVideoPeerId(null)
668668
this.screens.splice(index, 1)
@@ -694,7 +694,7 @@ export default {
694694
return
695695
}
696696
this.callViewStore.setSelectedVideoPeerId(peerId)
697-
this.$store.dispatch('startPresentation')
697+
this.callViewStore.startPresentation()
698698
},
699699
handleClickLocalVideo() {
700700
// DO nothing if no video
@@ -703,7 +703,7 @@ export default {
703703
}
704704
// Deselect possible selected video
705705
this.callViewStore.setSelectedVideoPeerId('local')
706-
this.$store.dispatch('startPresentation')
706+
this.callViewStore.startPresentation()
707707
},
708708

709709
async fetchPeers() {

src/components/CallView/Grid/Grid.vue

+2-2
Original file line numberDiff line numberDiff line change
@@ -558,7 +558,7 @@ export default {
558558
return this.isStripe
559559
},
560560
set(value) {
561-
this.$store.dispatch('setCallViewMode', { isGrid: !value, clearLast: false })
561+
this.callViewStore.setCallViewMode({ isGrid: !value, clearLast: false })
562562
},
563563
},
564564
},
@@ -853,7 +853,7 @@ export default {
853853
},
854854

855855
handleClickStripeCollapse() {
856-
this.$store.dispatch('setCallViewMode', { isStripeOpen: !this.stripeOpen, clearLast: false })
856+
this.callViewStore.setCallViewMode({ isStripeOpen: !this.stripeOpen, clearLast: false })
857857
},
858858

859859
handleMovement() {

src/components/CallView/shared/LocalVideo.vue

+1-1
Original file line numberDiff line numberDiff line change
@@ -339,7 +339,7 @@ export default {
339339

340340
handleStopFollowing() {
341341
this.callViewStore.setSelectedVideoPeerId(null)
342-
this.$store.dispatch('stopPresentation')
342+
this.callViewStore.stopPresentation()
343343
},
344344

345345
updateContainerAspectRatio([{ target }]) {

src/components/CallView/shared/VideoBottomBar.spec.js

+12-17
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
*/
55
import { createLocalVue, shallowMount } from '@vue/test-utils'
66
import { cloneDeep } from 'lodash'
7+
import { createPinia, setActivePinia } from 'pinia'
78
import Vuex, { Store } from 'vuex'
89

910
import AlertCircle from 'vue-material-design-icons/AlertCircle.vue'
@@ -20,6 +21,7 @@ import VideoBottomBar from './VideoBottomBar.vue'
2021

2122
import { CONVERSATION, PARTICIPANT } from '../../../constants.js'
2223
import storeConfig from '../../../store/storeConfig.js'
24+
import { useCallViewStore } from '../../../stores/callView.js'
2325
import { findNcButton } from '../../../test-helpers.js'
2426
import { ConnectionState } from '../../../utils/webrtc/models/CallParticipantModel.js'
2527

@@ -35,10 +37,10 @@ describe('VideoBottomBar.vue', () => {
3537
const USER_ID = 'user-id-1'
3638
let localVue
3739
let store
40+
let callViewStore
3841
let testStoreConfig
3942
let componentProps
4043
let conversationProps
41-
let selectedVideoPeerIdMock
4244

4345
const audioIndicatorAriaLabels = [t('spreed', 'Mute'), t('spreed', 'Muted')]
4446
const videoIndicatorAriaLabels = [t('spreed', 'Disable video'), t('spreed', 'Enable video')]
@@ -48,6 +50,8 @@ describe('VideoBottomBar.vue', () => {
4850
beforeEach(() => {
4951
localVue = createLocalVue()
5052
localVue.use(Vuex)
53+
setActivePinia(createPinia())
54+
callViewStore = useCallViewStore()
5155

5256
conversationProps = {
5357
token: TOKEN,
@@ -85,12 +89,6 @@ describe('VideoBottomBar.vue', () => {
8589
testStoreConfig = cloneDeep(storeConfig)
8690
testStoreConfig.modules.conversationsStore.getters.conversation = jest.fn().mockReturnValue((token) => conversationProps)
8791
testStoreConfig.modules.actorStore.getters.getUserId = jest.fn().mockReturnValue(() => USER_ID)
88-
89-
selectedVideoPeerIdMock = jest.fn().mockReturnValue(() => null)
90-
testStoreConfig.modules.callViewStore.getters.selectedVideoPeerId = selectedVideoPeerIdMock()
91-
testStoreConfig.modules.callViewStore.actions.stopPresentation = jest.fn()
92-
testStoreConfig.modules.callViewStore.actions.selectedVideoPeerId = jest.fn()
93-
9492
store = new Store(testStoreConfig)
9593
})
9694

@@ -515,10 +513,7 @@ describe('VideoBottomBar.vue', () => {
515513
})
516514

517515
test('button is rendered when source is selected', () => {
518-
selectedVideoPeerIdMock = jest.fn().mockReturnValue(() => PEER_ID)
519-
testStoreConfig.modules.callViewStore.getters.selectedVideoPeerId = selectedVideoPeerIdMock()
520-
store = new Store(testStoreConfig)
521-
516+
callViewStore.setSelectedVideoPeerId(PEER_ID)
522517
componentProps.isBig = true
523518
const wrapper = shallowMount(VideoBottomBar, {
524519
localVue,
@@ -531,9 +526,10 @@ describe('VideoBottomBar.vue', () => {
531526
})
532527

533528
test('method is called after click', async () => {
534-
selectedVideoPeerIdMock = jest.fn().mockReturnValue(() => PEER_ID)
535-
testStoreConfig.modules.callViewStore.getters.selectedVideoPeerId = selectedVideoPeerIdMock()
536-
store = new Store(testStoreConfig)
529+
callViewStore.setSelectedVideoPeerId(PEER_ID)
530+
callViewStore.startPresentation()
531+
expect(callViewStore.selectedVideoPeerId).toBe(PEER_ID)
532+
expect(callViewStore.presentationStarted).toBeTruthy()
537533

538534
componentProps.isBig = true
539535
const wrapper = shallowMount(VideoBottomBar, {
@@ -548,9 +544,8 @@ describe('VideoBottomBar.vue', () => {
548544
const followingButton = findNcButton(wrapper, followingButtonAriaLabel)
549545
await followingButton.trigger('click')
550546

551-
expect(testStoreConfig.modules.callViewStore.actions.stopPresentation).toHaveBeenCalled()
552-
expect(testStoreConfig.modules.callViewStore.actions.selectedVideoPeerId).toHaveBeenCalled()
553-
expect(testStoreConfig.modules.callViewStore.actions.selectedVideoPeerId).toHaveBeenCalledWith(expect.anything(), null)
547+
expect(callViewStore.selectedVideoPeerId).toBe(null)
548+
expect(callViewStore.presentationStarted).toBeFalsy()
554549
})
555550
})
556551
})

src/components/CallView/shared/VideoBottomBar.vue

+1-1
Original file line numberDiff line numberDiff line change
@@ -286,7 +286,7 @@ export default {
286286
},
287287

288288
handleStopFollowing() {
289-
this.$store.dispatch('stopPresentation')
289+
this.callViewStore.stopPresentation()
290290
this.callViewStore.setSelectedVideoPeerId(null)
291291
},
292292
},

src/components/TopBar/TopBarMenu.vue

+1-1
Original file line numberDiff line numberDiff line change
@@ -437,7 +437,7 @@ export default {
437437
},
438438

439439
changeView() {
440-
this.$store.dispatch('setCallViewMode', { isGrid: !this.isGrid, clearLast: false })
440+
this.callViewStore.setCallViewMode({ isGrid: !this.isGrid, clearLast: false })
441441
this.callViewStore.setSelectedVideoPeerId(null)
442442
},
443443

src/store/participantsStore.js

+4
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ import {
3636
} from '../services/participantsService.js'
3737
import SessionStorage from '../services/SessionStorage.js'
3838
import { talkBroadcastChannel } from '../services/talkBroadcastChannel.js'
39+
import { useCallViewStore } from '../stores/callView.js'
3940
import { useGuestNameStore } from '../stores/guestName.js'
4041
import CancelableRequest from '../utils/cancelableRequest.js'
4142

@@ -842,6 +843,9 @@ const actions = {
842843
// "Waiting for others to join the call …" after some seconds.
843844
commit('finishedConnecting', { token, sessionId: participantIdentifier.sessionId })
844845
}, 10000)
846+
847+
const callViewStore = useCallViewStore()
848+
callViewStore.handleJoinCall({ token })
845849
},
846850

847851
async leaveCall({ commit, getters }, { token, participantIdentifier, all = false }) {

src/store/participantsStore.spec.js

+5
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,11 @@ jest.mock('../services/callsService', () => ({
5656
jest.mock('../services/conversationsService', () => ({
5757
fetchConversation: jest.fn(),
5858
}))
59+
jest.mock('../stores/callView', () => ({
60+
useCallViewStore: jest.fn(() => ({
61+
handleJoinCall: jest.fn(),
62+
})),
63+
}))
5964

6065
jest.mock('@nextcloud/event-bus', () => ({
6166
emit: jest.fn(),

src/stores/callView.js

+25-48
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { defineStore } from 'pinia'
77

88
import { CONVERSATION } from '../constants.js'
99
import BrowserStorage from '../services/BrowserStorage.js'
10+
import store from '../store/index.js'
1011

1112
export const useCallViewStore = defineStore('callView', {
1213
state: () => ({
@@ -27,8 +28,6 @@ export const useCallViewStore = defineStore('callView', {
2728
},
2829

2930
actions: {
30-
// Mutations
31-
// Actions
3231
setForceCallView(value) {
3332
this.forceCallView = value
3433
},
@@ -37,43 +36,41 @@ export const useCallViewStore = defineStore('callView', {
3736
this.isViewerOverlay = value
3837
},
3938

39+
setIsEmptyCallView(value) {
40+
this.isEmptyCallView = value
41+
},
42+
4043
setSelectedVideoPeerId(value) {
4144
this.selectedVideoPeerId = value
4245
},
4346

44-
joinCall(context, { token }) {
45-
let isGrid = BrowserStorage.getItem('callprefs-' + token + '-isgrid')
46-
if (isGrid === null) {
47-
const conversationType = context.getters.conversations[token].type
48-
// default to grid view for group/public calls, otherwise speaker view
49-
isGrid = (conversationType === CONVERSATION.TYPE.GROUP
50-
|| conversationType === CONVERSATION.TYPE.PUBLIC)
51-
} else {
52-
// BrowserStorage.getItem returns a string instead of a boolean
53-
isGrid = (isGrid === 'true')
54-
}
55-
context.dispatch('setCallViewMode', { isGrid, isStripeOpen: true })
47+
handleJoinCall({ token }) {
48+
const gridPreference = BrowserStorage.getItem(`callprefs-${token}-isgrid`)
49+
const isGrid = gridPreference === null
50+
// not defined yet, default to grid view for group/public calls, otherwise speaker view
51+
? [CONVERSATION.TYPE.GROUP, CONVERSATION.TYPE.PUBLIC].includes(store.getters.conversations[token].type)
52+
: gridPreference === 'true'
53+
this.setCallViewMode({ isGrid, isStripeOpen: true })
5654
},
5755

5856
/**
5957
* Sets the current call view mode and saves it in preferences.
6058
* If clearLast is false, also remembers it in separate properties.
6159
*
62-
* @param {object} context default store context;
6360
* @param {object} data the wrapping object;
6461
* @param {boolean|null} [data.isGrid=null] true for enabled grid mode, false for speaker view;
6562
* @param {boolean|null} [data.isStripeOpen=null] true for visible striped mode, false for speaker view;
6663
* @param {boolean} [data.clearLast=true] set false to not reset last temporary remembered state;
6764
*/
68-
setCallViewMode(context, { isGrid = null, isStripeOpen = null, clearLast = true }) {
65+
setCallViewMode({ isGrid = null, isStripeOpen = null, clearLast = true }) {
6966
if (clearLast) {
7067
this.lastIsGrid = null
7168
this.lastIsStripeOpen = null
7269
}
7370

7471
if (isGrid !== null) {
7572
this.lastIsGrid = this.isGrid
76-
BrowserStorage.setItem('callprefs-' + context.getters.getToken() + '-isgrid', isGrid)
73+
BrowserStorage.setItem(`callprefs-${store.getters.getToken()}-isgrid`, isGrid)
7774
this.isGrid = isGrid
7875
}
7976

@@ -88,53 +85,33 @@ export const useCallViewStore = defineStore('callView', {
8885
*
8986
* Switches off grid mode and closes the stripe.
9087
* Remembers the call view state for after the end of the presentation.
91-
*
92-
* @param {object} context default store context;
9388
*/
94-
startPresentation(context) {
95-
// don't start twice, this would prevent multiple
96-
// screen shares to clear the last call view state
89+
startPresentation() {
90+
// don't start twice, this would prevent multiple screen shares to clear the last call view state
9791
if (this.presentationStarted) {
9892
return
9993
}
100-
10194
this.presentationStarted = true
102-
// switch off grid mode during presentation and collapse
103-
// the stripe to focus on the screen share, but continue remembering
104-
// the last state
105-
context.dispatch('setCallViewMode', {
106-
isGrid: false,
107-
isStripeOpen: false,
108-
clearLast: false,
109-
})
95+
96+
this.setCallViewMode({ isGrid: false, isStripeOpen: false, clearLast: false })
11097
},
11198

11299
/**
113100
* Stops presentation mode.
114101
*
115-
* Restores call view state from before starting the presentation, given
116-
* that the last state was not cleared manually.
117-
*
118-
* @param {object} context default store context;
102+
* Restores call view state from before starting the presentation,
103+
* given that the last state was not cleared manually.
119104
*/
120-
stopPresentation(context) {
105+
stopPresentation() {
121106
if (!this.presentationStarted) {
122107
return
123108
}
124-
if (!this.isGrid && !this.isStripeOpen) {
125-
// User didn't pick grid view during presentation
126-
// restore previous state
127-
context.dispatch('setCallViewMode', {
128-
isGrid: this.lastIsGrid,
129-
isStripeOpen: this.lastIsStripeOpen,
130-
clearLast: false,
131-
})
132-
}
133109
this.presentationStarted = false
134-
},
135110

136-
setIsEmptyCallView(value) {
137-
this.isEmptyCallView = value
111+
if (!this.isGrid && !this.isStripeOpen) {
112+
// User didn't pick grid view during presentation, restore previous state
113+
this.setCallViewMode({ isGrid: this.lastIsGrid, isStripeOpen: this.lastIsStripeOpen, clearLast: false })
114+
}
138115
},
139116

140117
/**

0 commit comments

Comments
 (0)