Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(callView): move store to Pinia 🍍 #13432

Merged
merged 5 commits into from
Oct 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ import Router from './router/router.js'
import BrowserStorage from './services/BrowserStorage.js'
import { EventBus } from './services/EventBus.js'
import { leaveConversationSync } from './services/participantsService.js'
import { useCallViewStore } from './stores/callView.js'
import { useFederationStore } from './stores/federation.ts'
import { useSidebarStore } from './stores/sidebar.js'
import { checkBrowser } from './utils/browserCheck.js'
Expand Down Expand Up @@ -76,6 +77,7 @@ export default {
isDocumentVisible: useDocumentVisibility(),
supportSessionState: useActiveSession(),
federationStore: useFederationStore(),
callViewStore: useCallViewStore(),
sidebarStore: useSidebarStore(),
}
},
Expand Down Expand Up @@ -302,7 +304,7 @@ export default {

EventBus.on('switch-to-conversation', (params) => {
if (this.isInCall) {
this.$store.dispatch('setForceCallView', true)
this.callViewStore.setForceCallView(true)

const enableAudio = !BrowserStorage.getItem('audioDisabled_' + this.token)
const enableVideo = !BrowserStorage.getItem('videoDisabled_' + this.token)
Expand Down Expand Up @@ -365,7 +367,7 @@ export default {
recordingConsent: this.recordingConsentGiven,
})

this.$store.dispatch('setForceCallView', false)
this.callViewStore.setForceCallView(false)
})
}

Expand Down
40 changes: 21 additions & 19 deletions src/components/CallView/CallView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,7 @@ import { SIMULCAST } from '../../constants.js'
import { fetchPeers } from '../../services/callsService.js'
import { getTalkConfig } from '../../services/CapabilitiesManager.ts'
import { EventBus } from '../../services/EventBus.js'
import { useCallViewStore } from '../../stores/callView.js'
import { useSettingsStore } from '../../stores/settings.js'
import { localMediaModel, localCallParticipantModel, callParticipantCollection } from '../../utils/webrtc/index.js'
import RemoteVideoBlocker from '../../utils/webrtc/RemoteVideoBlocker.js'
Expand Down Expand Up @@ -208,6 +209,7 @@ export default {
localCallParticipantModel,
callParticipantCollection,
devMode,
callViewStore: useCallViewStore(),
}
},

Expand Down Expand Up @@ -250,15 +252,15 @@ export default {
},

isViewerOverlay() {
return this.$store.getters.isViewerOverlay
return this.callViewStore.isViewerOverlay
},

isGrid() {
return this.$store.getters.isGrid && !this.isSidebar
return this.callViewStore.isGrid && !this.isSidebar
},

selectedVideoPeerId() {
return this.$store.getters.selectedVideoPeerId
return this.callViewStore.selectedVideoPeerId
},

selectedCallParticipantModel() {
Expand Down Expand Up @@ -423,25 +425,25 @@ export default {
callParticipantModelsWithScreen(newValue, previousValue) {
// Everytime a new screen is shared, switch to promoted view
if (newValue.length > previousValue.length) {
this.$store.dispatch('startPresentation')
this.callViewStore.startPresentation()
} else if (newValue.length === 0 && previousValue.length > 0 && !this.hasLocalScreen && !this.selectedVideoPeerId) {
// last screen share stopped and no selected video, restoring previous state
this.$store.dispatch('stopPresentation')
this.callViewStore.stopPresentation()
}
},
showLocalScreen(showLocalScreen) {
// Everytime the local screen is shared, switch to promoted view
if (showLocalScreen) {
this.$store.dispatch('startPresentation')
this.callViewStore.startPresentation()
} else if (this.callParticipantModelsWithScreen.length === 0 && !this.selectedVideoPeerId) {
// last screen share stopped and no selected video, restoring previous state
this.$store.dispatch('stopPresentation')
this.callViewStore.stopPresentation()
}
},
hasLocalVideo(newValue) {
if (this.$store.getters.selectedVideoPeerId === 'local') {
if (this.selectedVideoPeerId === 'local') {
if (!newValue) {
this.$store.dispatch('selectedVideoPeerId', null)
this.callViewStore.setSelectedVideoPeerId(null)
}
}
},
Expand All @@ -451,7 +453,7 @@ export default {
},

showEmptyCallView(value) {
this.$store.dispatch('isEmptyCallView', value)
this.callViewStore.setIsEmptyCallView(value)
},
},

Expand All @@ -472,7 +474,7 @@ export default {

beforeDestroy() {
this.debounceFetchPeers.clear?.()
this.$store.dispatch('isEmptyCallView', true)
this.callViewStore.setIsEmptyCallView(true)
EventBus.off('refresh-peer-list', this.debounceFetchPeers)

callParticipantCollection.off('remove', this._lowerHandWhenParticipantLeaves)
Expand Down Expand Up @@ -653,16 +655,16 @@ export default {
return
}

if (this.$store.getters.presentationStarted) {
this.$store.dispatch('setCallViewMode', {
if (this.callViewStore.presentationStarted) {
this.callViewStore.setCallViewMode({
isGrid: false,
isStripeOpen: false,
clearLast: false,
})
} else {
this.$store.dispatch('startPresentation')
this.callViewStore.startPresentation()
}
this.$store.dispatch('selectedVideoPeerId', null)
this.callViewStore.setSelectedVideoPeerId(null)
this.screens.splice(index, 1)
this.screens.unshift(id)
},
Expand Down Expand Up @@ -691,17 +693,17 @@ export default {
if (this.isSidebar) {
return
}
this.$store.dispatch('selectedVideoPeerId', peerId)
this.$store.dispatch('startPresentation')
this.callViewStore.setSelectedVideoPeerId(peerId)
this.callViewStore.startPresentation()
},
handleClickLocalVideo() {
// DO nothing if no video
if (!this.hasLocalVideo || this.isSidebar) {
return
}
// Deselect possible selected video
this.$store.dispatch('selectedVideoPeerId', 'local')
this.$store.dispatch('startPresentation')
this.callViewStore.setSelectedVideoPeerId('local')
this.callViewStore.startPresentation()
},

async fetchPeers() {
Expand Down
10 changes: 6 additions & 4 deletions src/components/CallView/Grid/Grid.vue
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,7 @@ import VideoVue from '../shared/VideoVue.vue'

import { placeholderImage, placeholderModel, placeholderName, placeholderSharedData } from './gridPlaceholders.ts'
import { PARTICIPANT, ATTENDEE } from '../../../constants.js'
import { useCallViewStore } from '../../../stores/callView.js'
import { useSidebarStore } from '../../../stores/sidebar.js'

// Max number of videos per page. `0`, the default value, means no cap
Expand Down Expand Up @@ -252,6 +253,7 @@ export default {
screenshotMode,
videosCap,
videosCapEnforced,
callViewStore: useCallViewStore(),
sidebarStore: useSidebarStore(),
}
},
Expand Down Expand Up @@ -483,7 +485,7 @@ export default {
},

stripeOpen() {
return this.$store.getters.isStripeOpen && !this.isRecording
return this.callViewStore.isStripeOpen && !this.isRecording
},

participantsInitialised() {
Expand Down Expand Up @@ -555,7 +557,7 @@ export default {
return this.isStripe
},
set(value) {
this.$store.dispatch('setCallViewMode', { isGrid: !value, clearLast: false })
this.callViewStore.setCallViewMode({ isGrid: !value, clearLast: false })
},
},
},
Expand Down Expand Up @@ -850,7 +852,7 @@ export default {
},

handleClickStripeCollapse() {
this.$store.dispatch('setCallViewMode', { isStripeOpen: !this.stripeOpen, clearLast: false })
this.callViewStore.setCallViewMode({ isStripeOpen: !this.stripeOpen, clearLast: false })
},

handleMovement() {
Expand All @@ -877,7 +879,7 @@ export default {
},

isSelected(callParticipantModel) {
return callParticipantModel.attributes.peerId === this.$store.getters.selectedVideoPeerId
return callParticipantModel.attributes.peerId === this.callViewStore.selectedVideoPeerId
},

isModelWithVideo(callParticipantModel) {
Expand Down
10 changes: 6 additions & 4 deletions src/components/CallView/shared/LocalVideo.vue
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ import VideoBackground from './VideoBackground.vue'
import AvatarWrapper from '../../AvatarWrapper/AvatarWrapper.vue'

import { AVATAR } from '../../../constants.js'
import { useCallViewStore } from '../../../stores/callView.js'
import attachMediaStream from '../../../utils/attachmediastream.js'
import { ConnectionState } from '../../../utils/webrtc/models/CallParticipantModel.js'
import { placeholderImage } from '../Grid/gridPlaceholders.ts'
Expand Down Expand Up @@ -150,6 +151,7 @@ export default {
return {
devMode,
screenshotMode,
callViewStore: useCallViewStore(),
}
},

Expand Down Expand Up @@ -230,11 +232,11 @@ export default {
},

isSelected() {
return this.$store.getters.selectedVideoPeerId === 'local'
return this.callViewStore.selectedVideoPeerId === 'local'
},

isSelectable() {
return !this.unSelectable && !this.isSidebar && this.hasLocalVideo && this.$store.getters.selectedVideoPeerId !== 'local'
return !this.unSelectable && !this.isSidebar && this.hasLocalVideo && this.callViewStore.selectedVideoPeerId !== 'local'
},

screenshotModeUrl() {
Expand Down Expand Up @@ -336,8 +338,8 @@ export default {
},

handleStopFollowing() {
this.$store.dispatch('selectedVideoPeerId', null)
this.$store.dispatch('stopPresentation')
this.callViewStore.setSelectedVideoPeerId(null)
this.callViewStore.stopPresentation()
},

updateContainerAspectRatio([{ target }]) {
Expand Down
29 changes: 12 additions & 17 deletions src/components/CallView/shared/VideoBottomBar.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
*/
import { createLocalVue, shallowMount } from '@vue/test-utils'
import { cloneDeep } from 'lodash'
import { createPinia, setActivePinia } from 'pinia'
import Vuex, { Store } from 'vuex'

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

import { CONVERSATION, PARTICIPANT } from '../../../constants.js'
import storeConfig from '../../../store/storeConfig.js'
import { useCallViewStore } from '../../../stores/callView.js'
import { findNcButton } from '../../../test-helpers.js'
import { ConnectionState } from '../../../utils/webrtc/models/CallParticipantModel.js'

Expand All @@ -35,10 +37,10 @@ describe('VideoBottomBar.vue', () => {
const USER_ID = 'user-id-1'
let localVue
let store
let callViewStore
let testStoreConfig
let componentProps
let conversationProps
let selectedVideoPeerIdMock

const audioIndicatorAriaLabels = [t('spreed', 'Mute'), t('spreed', 'Muted')]
const videoIndicatorAriaLabels = [t('spreed', 'Disable video'), t('spreed', 'Enable video')]
Expand All @@ -48,6 +50,8 @@ describe('VideoBottomBar.vue', () => {
beforeEach(() => {
localVue = createLocalVue()
localVue.use(Vuex)
setActivePinia(createPinia())
callViewStore = useCallViewStore()

conversationProps = {
token: TOKEN,
Expand Down Expand Up @@ -85,12 +89,6 @@ describe('VideoBottomBar.vue', () => {
testStoreConfig = cloneDeep(storeConfig)
testStoreConfig.modules.conversationsStore.getters.conversation = jest.fn().mockReturnValue((token) => conversationProps)
testStoreConfig.modules.actorStore.getters.getUserId = jest.fn().mockReturnValue(() => USER_ID)

selectedVideoPeerIdMock = jest.fn().mockReturnValue(() => null)
testStoreConfig.modules.callViewStore.getters.selectedVideoPeerId = selectedVideoPeerIdMock()
testStoreConfig.modules.callViewStore.actions.stopPresentation = jest.fn()
testStoreConfig.modules.callViewStore.actions.selectedVideoPeerId = jest.fn()

store = new Store(testStoreConfig)
})

Expand Down Expand Up @@ -515,10 +513,7 @@ describe('VideoBottomBar.vue', () => {
})

test('button is rendered when source is selected', () => {
selectedVideoPeerIdMock = jest.fn().mockReturnValue(() => PEER_ID)
testStoreConfig.modules.callViewStore.getters.selectedVideoPeerId = selectedVideoPeerIdMock()
store = new Store(testStoreConfig)

callViewStore.setSelectedVideoPeerId(PEER_ID)
componentProps.isBig = true
const wrapper = shallowMount(VideoBottomBar, {
localVue,
Expand All @@ -531,9 +526,10 @@ describe('VideoBottomBar.vue', () => {
})

test('method is called after click', async () => {
selectedVideoPeerIdMock = jest.fn().mockReturnValue(() => PEER_ID)
testStoreConfig.modules.callViewStore.getters.selectedVideoPeerId = selectedVideoPeerIdMock()
store = new Store(testStoreConfig)
callViewStore.setSelectedVideoPeerId(PEER_ID)
callViewStore.startPresentation()
expect(callViewStore.selectedVideoPeerId).toBe(PEER_ID)
expect(callViewStore.presentationStarted).toBeTruthy()

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

expect(testStoreConfig.modules.callViewStore.actions.stopPresentation).toHaveBeenCalled()
expect(testStoreConfig.modules.callViewStore.actions.selectedVideoPeerId).toHaveBeenCalled()
expect(testStoreConfig.modules.callViewStore.actions.selectedVideoPeerId).toHaveBeenCalledWith(expect.anything(), null)
expect(callViewStore.selectedVideoPeerId).toBe(null)
expect(callViewStore.presentationStarted).toBeFalsy()
})
})
})
Expand Down
13 changes: 10 additions & 3 deletions src/components/CallView/shared/VideoBottomBar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ import NcButton from '@nextcloud/vue/dist/Components/NcButton.js'
import TransitionWrapper from '../../UIShared/TransitionWrapper.vue'

import { PARTICIPANT } from '../../../constants.js'
import { useCallViewStore } from '../../../stores/callView.js'
import { ConnectionState } from '../../../utils/webrtc/models/CallParticipantModel.js'

export default {
Expand Down Expand Up @@ -176,6 +177,12 @@ export default {

emits: ['bottom-bar-hover'],

setup() {
return {
callViewStore: useCallViewStore(),
}
},

data() {
return {
mouseover: false,
Expand All @@ -192,7 +199,7 @@ export default {
return !this.connectionStateFailedNoRestart && this.model.attributes.raisedHand.state
},
showStopFollowingButton() {
return this.isBig && this.$store.getters.selectedVideoPeerId !== null
return this.isBig && this.callViewStore.selectedVideoPeerId !== null
},

// Audio indicator
Expand Down Expand Up @@ -279,8 +286,8 @@ export default {
},

handleStopFollowing() {
this.$store.dispatch('stopPresentation')
this.$store.dispatch('selectedVideoPeerId', null)
this.callViewStore.stopPresentation()
this.callViewStore.setSelectedVideoPeerId(null)
},
},
}
Expand Down
Loading
Loading