Skip to content

Commit

Permalink
Merge pull request #13484 from nextcloud/feat/13446/disable-streams-b…
Browse files Browse the repository at this point in the history
…y-default

feat(devices): add an option to always disable streams by default befo…
  • Loading branch information
DorraJaouad authored Oct 11, 2024
2 parents 1b288b7 + 8c6d2f0 commit f18fe92
Show file tree
Hide file tree
Showing 5 changed files with 81 additions and 11 deletions.
7 changes: 7 additions & 0 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 { 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 @@ -195,6 +196,12 @@ export default {
provide('CallView:devModeEnabled', devMode)
const screenshotMode = ref(false)
provide('CallView:screenshotModeEnabled', screenshotMode)
const settingsStore = useSettingsStore()
const startWithoutMediaEnabled = settingsStore.startWithoutMedia
if (startWithoutMediaEnabled) {
localMediaModel.disableAudio()
localMediaModel.disableVideo()
}
return {
localMediaModel,
Expand Down
35 changes: 32 additions & 3 deletions src/components/SettingsDialog/SettingsDialog.vue
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,14 @@
:name="t('spreed', 'Choose devices')"
class="app-settings-section">
<MediaDevicesPreview />
<NcCheckboxRadioSwitch id="call-media"
:checked="startWithoutMediaEnabled"
:disabled="mediaLoading"
type="switch"
class="checkbox call-media"
@update:checked="toggleStartWithoutMedia">
{{ t('spreed', 'Turn off camera and microphone by default when joining a call') }}
</NcCheckboxRadioSwitch>
</NcAppSettingsSection>
<NcAppSettingsSection v-if="!isGuest"
id="attachments"
Expand Down Expand Up @@ -196,6 +204,7 @@ import { PRIVACY } from '../../constants.js'
import BrowserStorage from '../../services/BrowserStorage.js'
import { getTalkConfig } from '../../services/CapabilitiesManager.ts'
import { useCustomSettings } from '../../services/SettingsAPI.ts'
import { setUserConfig } from '../../services/settingsService.js'
import { useSettingsStore } from '../../stores/settings.js'
import { useSoundsStore } from '../../stores/sounds.js'
Expand Down Expand Up @@ -235,6 +244,7 @@ export default {
attachmentFolderLoading: true,
privacyLoading: false,
playSoundsLoading: false,
mediaLoading: false,
}
},
Expand Down Expand Up @@ -263,6 +273,10 @@ export default {
return this.settingsStore.typingStatusPrivacy === PRIVACY.PUBLIC
},
startWithoutMediaEnabled() {
return this.settingsStore.startWithoutMedia
},
settingsUrl() {
return generateUrl('/settings/user/notifications')
},
Expand All @@ -284,12 +298,11 @@ export default {
},
},
created() {
async created() {
const blurred = BrowserStorage.getItem('background-blurred')
if (blurred === 'false' && isBackgroundBlurred === '') {
console.debug('Blur was disabled intentionally, propagating last choice to server')
axios.post(generateOcsUrl('apps/provisioning_api/api/v1/config/users/theming/force_enable_blur_filter'),
{ configValue: 'no' })
await setUserConfig('theming', 'force_enable_blur_filter', 'no')
}
BrowserStorage.removeItem('background-blurred')
},
Expand Down Expand Up @@ -362,6 +375,18 @@ export default {
this.playSoundsLoading = false
},
async toggleStartWithoutMedia(value) {
this.mediaLoading = true
try {
await this.settingsStore.setStartWithoutMedia(value)
showSuccess(t('spreed', 'Your default media state has been saved'))
} catch (exception) {
showError(t('spreed', 'Error while setting default media state'))
} finally {
this.mediaLoading = false
}
},
handleShowSettings() {
this.showSettings = true
},
Expand Down Expand Up @@ -420,4 +445,8 @@ export default {
}
}
.call-media {
margin: calc(3 * var(--default-grid-baseline)) 0;
}
</style>
19 changes: 19 additions & 0 deletions src/services/settingsService.js
Original file line number Diff line number Diff line change
Expand Up @@ -74,10 +74,29 @@ const setPlaySounds = async function(hasUserAccount, value) {
}
}

const setStartWithoutMedia = async function(value) {
await setUserConfig('spreed', 'calls_start_without_media', value ? 'yes' : 'no')
}

/**
* Set user config using provisioning API
*
* @param {string} appId - app id
* @param {string} configKey - key of the config to set
* @param {string} configValue - value to set
*/
const setUserConfig = async function(appId, configKey, configValue) {
await axios.post(generateOcsUrl('apps/provisioning_api/api/v1/config/users/{appId}/{configKey}', { appId, configKey }), {
configValue,
})
}

export {
setAttachmentFolder,
setReadStatusPrivacy,
setTypingStatusPrivacy,
setSIPSettings,
setPlaySounds,
setStartWithoutMedia,
setUserConfig,
}
16 changes: 10 additions & 6 deletions src/stores/__tests__/settings.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,9 @@ describe('settingsStore', () => {

// Assert
expect(results).toEqual([true, false])
expect(BrowserStorage.getItem).not.toHaveBeenCalled()
// It's always called at least once : BrowserStorage.getItem('cachedConversations')
// +1
expect(BrowserStorage.getItem).toHaveBeenCalledTimes(1)
})

it('shows correct values received from BrowserStorage', () => {
Expand All @@ -87,10 +89,11 @@ describe('settingsStore', () => {

// Assert
expect(results).toEqual([true, true, false])
expect(BrowserStorage.getItem).toHaveBeenCalledTimes(3)
expect(BrowserStorage.getItem).toHaveBeenNthCalledWith(1, 'showMediaSettings_token-1')
expect(BrowserStorage.getItem).toHaveBeenNthCalledWith(2, 'showMediaSettings_token-2')
expect(BrowserStorage.getItem).toHaveBeenNthCalledWith(3, 'showMediaSettings_token-3')
// It's always called at least once : BrowserStorage.getItem('cachedConversations')
expect(BrowserStorage.getItem).toHaveBeenCalledTimes(4) // 1 + 3
expect(BrowserStorage.getItem).toHaveBeenNthCalledWith(2, 'showMediaSettings_token-1')
expect(BrowserStorage.getItem).toHaveBeenNthCalledWith(3, 'showMediaSettings_token-2')
expect(BrowserStorage.getItem).toHaveBeenNthCalledWith(4, 'showMediaSettings_token-3')
})

it('updates values correctly', async () => {
Expand All @@ -106,7 +109,8 @@ describe('settingsStore', () => {

// Assert
expect(results).toEqual([false, true])
expect(BrowserStorage.getItem).not.toHaveBeenCalled()
// It's always called at least once : BrowserStorage.getItem('cachedConversations')
expect(BrowserStorage.getItem).toHaveBeenCalledTimes(1)
expect(BrowserStorage.setItem).toHaveBeenCalledTimes(2)
expect(BrowserStorage.setItem).toHaveBeenNthCalledWith(1, 'showMediaSettings_token-1', 'false')
expect(BrowserStorage.setItem).toHaveBeenNthCalledWith(2, 'showMediaSettings_token-2', 'true')
Expand Down
15 changes: 13 additions & 2 deletions src/stores/settings.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,12 @@ import { loadState } from '@nextcloud/initial-state'

import { PRIVACY } from '../constants.js'
import BrowserStorage from '../services/BrowserStorage.js'
import { setReadStatusPrivacy, setTypingStatusPrivacy } from '../services/settingsService.js'
import { getTalkConfig } from '../services/CapabilitiesManager.ts'
import {
setReadStatusPrivacy,
setTypingStatusPrivacy,
setStartWithoutMedia
} from '../services/settingsService.js'

/**
* @typedef {string} Token
Expand All @@ -33,7 +38,8 @@ export const useSettingsStore = defineStore('settings', {
state: () => ({
readStatusPrivacy: loadState('spreed', 'read_status_privacy', PRIVACY.PRIVATE),
typingStatusPrivacy: loadState('spreed', 'typing_privacy', PRIVACY.PRIVATE),
showMediaSettings: {}
showMediaSettings: {},
startWithoutMedia: getTalkConfig('local', 'call', 'start-without-media'),
}),

getters: {
Expand Down Expand Up @@ -96,5 +102,10 @@ export const useSettingsStore = defineStore('settings', {
}
Vue.set(this.showMediaSettings, token, value)
},

async setStartWithoutMedia(value) {
await setStartWithoutMedia(value)
this.startWithoutMedia = value
},
},
})

0 comments on commit f18fe92

Please sign in to comment.