diff --git a/src/components/CallView/CallView.vue b/src/components/CallView/CallView.vue
index 916952fbcb2..3cac3e1018a 100644
--- a/src/components/CallView/CallView.vue
+++ b/src/components/CallView/CallView.vue
@@ -138,6 +138,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'
@@ -173,6 +174,12 @@ export default {
},
setup() {
+ const settingsStore = useSettingsStore()
+ const startWithoutMediaEnabled = settingsStore.startWithoutMedia
+ if (startWithoutMediaEnabled) {
+ localMediaModel.disableAudio()
+ localMediaModel.disableVideo()
+ }
return {
localMediaModel,
localCallParticipantModel,
diff --git a/src/components/SettingsDialog/SettingsDialog.vue b/src/components/SettingsDialog/SettingsDialog.vue
index cc5a6ba5795..2d423d03cd9 100644
--- a/src/components/SettingsDialog/SettingsDialog.vue
+++ b/src/components/SettingsDialog/SettingsDialog.vue
@@ -20,6 +20,14 @@
:name="t('spreed', 'Choose devices')"
class="app-settings-section">
+
+ {{ t('spreed', 'Turn off camera and microphone by default when joining a call') }}
+
diff --git a/src/services/settingsService.js b/src/services/settingsService.js
index 9d6f768d042..684e8a8babe 100644
--- a/src/services/settingsService.js
+++ b/src/services/settingsService.js
@@ -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,
}
diff --git a/src/stores/__tests__/settings.spec.js b/src/stores/__tests__/settings.spec.js
index c8f1cf2574d..baa9cbb8ba2 100644
--- a/src/stores/__tests__/settings.spec.js
+++ b/src/stores/__tests__/settings.spec.js
@@ -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', () => {
@@ -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 () => {
@@ -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')
diff --git a/src/stores/settings.js b/src/stores/settings.js
index bfbfa416f20..5eb93f533ef 100644
--- a/src/stores/settings.js
+++ b/src/stores/settings.js
@@ -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
@@ -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: {
@@ -96,5 +102,10 @@ export const useSettingsStore = defineStore('settings', {
}
Vue.set(this.showMediaSettings, token, value)
},
+
+ async setStartWithoutMedia(value) {
+ await setStartWithoutMedia(value)
+ this.startWithoutMedia = value
+ },
},
})