mirror of https://github.com/jitsi/jitsi-meet
parent
ab7e572162
commit
959db3a665
@ -1,191 +0,0 @@ |
||||
/* global JitsiMeetJS */ |
||||
const logger = require('jitsi-meet-logger').getLogger(__filename); |
||||
|
||||
import UIUtil from '../UI/util/UIUtil'; |
||||
import jitsiLocalStorage from '../util/JitsiLocalStorage'; |
||||
import { randomHexString } from '../../react/features/base/util'; |
||||
|
||||
let avatarUrl = ''; |
||||
|
||||
let email = UIUtil.unescapeHtml(jitsiLocalStorage.getItem('email') || ''); |
||||
let avatarId = UIUtil.unescapeHtml(jitsiLocalStorage.getItem('avatarId') || ''); |
||||
|
||||
if (!avatarId) { |
||||
// if there is no avatar id, we generate a unique one and use it forever
|
||||
avatarId = randomHexString(32); |
||||
jitsiLocalStorage.setItem('avatarId', avatarId); |
||||
} |
||||
|
||||
let localFlipX = JSON.parse(jitsiLocalStorage.getItem('localFlipX') || true); |
||||
let displayName = UIUtil.unescapeHtml( |
||||
jitsiLocalStorage.getItem('displayname') || ''); |
||||
let cameraDeviceId = jitsiLocalStorage.getItem('cameraDeviceId') || ''; |
||||
let micDeviceId = jitsiLocalStorage.getItem('micDeviceId') || ''; |
||||
|
||||
// Currently audio output device change is supported only in Chrome and
|
||||
// default output always has 'default' device ID
|
||||
const audioOutputDeviceId = jitsiLocalStorage.getItem('audioOutputDeviceId') |
||||
|| 'default'; |
||||
|
||||
if (audioOutputDeviceId |
||||
!== JitsiMeetJS.mediaDevices.getAudioOutputDevice()) { |
||||
JitsiMeetJS.mediaDevices.setAudioOutputDevice(audioOutputDeviceId) |
||||
.catch(ex => { |
||||
logger.warn('Failed to set audio output device from local ' |
||||
+ 'storage. Default audio output device will be used' |
||||
+ 'instead.', ex); |
||||
}); |
||||
} |
||||
|
||||
export default { |
||||
|
||||
/** |
||||
* Sets the local user display name and saves it to local storage |
||||
* |
||||
* @param {string} newDisplayName unescaped display name for the local user |
||||
* @param {boolean} disableLocalStore disables local store the display name |
||||
*/ |
||||
setDisplayName(newDisplayName, disableLocalStore) { |
||||
displayName = newDisplayName; |
||||
|
||||
if (!disableLocalStore) { |
||||
jitsiLocalStorage.setItem('displayname', |
||||
UIUtil.escapeHtml(displayName)); |
||||
} |
||||
}, |
||||
|
||||
/** |
||||
* Returns the escaped display name currently used by the user |
||||
* @returns {string} currently valid user display name. |
||||
*/ |
||||
getDisplayName() { |
||||
return displayName; |
||||
}, |
||||
|
||||
/** |
||||
* Sets new email for local user and saves it to the local storage. |
||||
* @param {string} newEmail new email for the local user |
||||
* @param {boolean} disableLocalStore disables local store the email |
||||
*/ |
||||
setEmail(newEmail, disableLocalStore) { |
||||
email = newEmail; |
||||
|
||||
if (!disableLocalStore) { |
||||
jitsiLocalStorage.setItem('email', UIUtil.escapeHtml(newEmail)); |
||||
} |
||||
}, |
||||
|
||||
/** |
||||
* Returns email address of the local user. |
||||
* @returns {string} email |
||||
*/ |
||||
getEmail() { |
||||
return email; |
||||
}, |
||||
|
||||
/** |
||||
* Returns avatar id of the local user. |
||||
* @returns {string} avatar id |
||||
*/ |
||||
getAvatarId() { |
||||
return avatarId; |
||||
}, |
||||
|
||||
/** |
||||
* Sets new avatarUrl for local user and saves it to the local storage. |
||||
* @param {string} newAvatarUrl new avatarUrl for the local user |
||||
*/ |
||||
setAvatarUrl(newAvatarUrl) { |
||||
avatarUrl = newAvatarUrl; |
||||
}, |
||||
|
||||
/** |
||||
* Returns avatarUrl address of the local user. |
||||
* @returns {string} avatarUrl |
||||
*/ |
||||
getAvatarUrl() { |
||||
return avatarUrl; |
||||
}, |
||||
|
||||
/** |
||||
* Sets new flipX state of local video and saves it to the local storage. |
||||
* @param {string} val flipX state of local video |
||||
*/ |
||||
setLocalFlipX(val) { |
||||
localFlipX = val; |
||||
jitsiLocalStorage.setItem('localFlipX', val); |
||||
}, |
||||
|
||||
/** |
||||
* Returns flipX state of local video. |
||||
* @returns {string} flipX |
||||
*/ |
||||
getLocalFlipX() { |
||||
return localFlipX; |
||||
}, |
||||
|
||||
/** |
||||
* Get device id of the camera which is currently in use. |
||||
* Empty string stands for default device. |
||||
* @returns {String} |
||||
*/ |
||||
getCameraDeviceId() { |
||||
return cameraDeviceId; |
||||
}, |
||||
|
||||
/** |
||||
* Set device id of the camera which is currently in use. |
||||
* Empty string stands for default device. |
||||
* @param {string} newId new camera device id |
||||
* @param {boolean} whether we need to store the value |
||||
*/ |
||||
setCameraDeviceId(newId, store) { |
||||
cameraDeviceId = newId; |
||||
if (store) { |
||||
jitsiLocalStorage.setItem('cameraDeviceId', newId); |
||||
} |
||||
}, |
||||
|
||||
/** |
||||
* Get device id of the microphone which is currently in use. |
||||
* Empty string stands for default device. |
||||
* @returns {String} |
||||
*/ |
||||
getMicDeviceId() { |
||||
return micDeviceId; |
||||
}, |
||||
|
||||
/** |
||||
* Set device id of the microphone which is currently in use. |
||||
* Empty string stands for default device. |
||||
* @param {string} newId new microphone device id |
||||
* @param {boolean} whether we need to store the value |
||||
*/ |
||||
setMicDeviceId(newId, store) { |
||||
micDeviceId = newId; |
||||
if (store) { |
||||
jitsiLocalStorage.setItem('micDeviceId', newId); |
||||
} |
||||
}, |
||||
|
||||
/** |
||||
* Get device id of the audio output device which is currently in use. |
||||
* Empty string stands for default device. |
||||
* @returns {String} |
||||
*/ |
||||
getAudioOutputDeviceId() { |
||||
return JitsiMeetJS.mediaDevices.getAudioOutputDevice(); |
||||
}, |
||||
|
||||
/** |
||||
* Set device id of the audio output device which is currently in use. |
||||
* Empty string stands for default device. |
||||
* @param {string} newId='default' - new audio output device id |
||||
* @returns {Promise} |
||||
*/ |
||||
setAudioOutputDeviceId(newId = 'default') { |
||||
return JitsiMeetJS.mediaDevices.setAudioOutputDevice(newId) |
||||
.then(() => |
||||
jitsiLocalStorage.setItem('audioOutputDeviceId', newId)); |
||||
} |
||||
}; |
@ -0,0 +1,32 @@ |
||||
// @flow
|
||||
|
||||
import JitsiMeetJS from '../lib-jitsi-meet'; |
||||
import { updateSettings } from '../settings'; |
||||
|
||||
/** |
||||
* Get device id of the audio output device which is currently in use. |
||||
* Empty string stands for default device. |
||||
* |
||||
* @returns {string} |
||||
*/ |
||||
export function getAudioOutputDeviceId() { |
||||
return JitsiMeetJS.mediaDevices.getAudioOutputDevice(); |
||||
} |
||||
|
||||
/** |
||||
* Set device id of the audio output device which is currently in use. |
||||
* Empty string stands for default device. |
||||
* |
||||
* @param {string} newId - New audio output device id. |
||||
* @param {Function} dispatch - The Redux dispatch function. |
||||
* @returns {Promise} |
||||
*/ |
||||
export function setAudioOutputDeviceId( |
||||
newId: string = 'default', |
||||
dispatch: Function): Promise<*> { |
||||
return JitsiMeetJS.mediaDevices.setAudioOutputDevice(newId) |
||||
.then(() => |
||||
dispatch(updateSettings({ |
||||
audioOutputDeviceId: newId |
||||
}))); |
||||
} |
@ -1,5 +1,6 @@ |
||||
export * from './actions'; |
||||
export * from './actionTypes'; |
||||
export * from './functions'; |
||||
|
||||
import './middleware'; |
||||
import './reducer'; |
||||
|
@ -1,15 +0,0 @@ |
||||
/** |
||||
* Create an action for when the local profile is updated. |
||||
* |
||||
* { |
||||
* type: PROFILE_UPDATED, |
||||
* profile: { |
||||
* displayName: string, |
||||
* defaultURL: URL, |
||||
* email: string, |
||||
* startWithAudioMuted: boolean, |
||||
* startWithVideoMuted: boolean |
||||
* } |
||||
* } |
||||
*/ |
||||
export const PROFILE_UPDATED = Symbol('PROFILE_UPDATED'); |
@ -1,23 +0,0 @@ |
||||
import { PROFILE_UPDATED } from './actionTypes'; |
||||
|
||||
/** |
||||
* Create an action for when the local profile is updated. |
||||
* |
||||
* @param {Object} profile - The new profile data. |
||||
* @returns {{ |
||||
* type: UPDATE_PROFILE, |
||||
* profile: { |
||||
* displayName: string, |
||||
* defaultURL: URL, |
||||
* email: string, |
||||
* startWithAudioMuted: boolean, |
||||
* startWithVideoMuted: boolean |
||||
* } |
||||
* }} |
||||
*/ |
||||
export function updateProfile(profile) { |
||||
return { |
||||
type: PROFILE_UPDATED, |
||||
profile |
||||
}; |
||||
} |
@ -1,53 +0,0 @@ |
||||
// @flow
|
||||
|
||||
import { APP_WILL_MOUNT } from '../../app'; |
||||
import { ReducerRegistry } from '../redux'; |
||||
import { PersistenceRegistry } from '../storage'; |
||||
|
||||
import { PROFILE_UPDATED } from './actionTypes'; |
||||
|
||||
/** |
||||
* The default/initial redux state of the feature {@code base/profile}. |
||||
* |
||||
* @type Object |
||||
*/ |
||||
const DEFAULT_STATE = {}; |
||||
|
||||
const STORE_NAME = 'features/base/profile'; |
||||
|
||||
/** |
||||
* Sets up the persistence of the feature {@code base/profile}. |
||||
*/ |
||||
PersistenceRegistry.register(STORE_NAME); |
||||
|
||||
ReducerRegistry.register(STORE_NAME, (state = DEFAULT_STATE, action) => { |
||||
switch (action.type) { |
||||
case APP_WILL_MOUNT: |
||||
// XXX APP_WILL_MOUNT is the earliest redux action of ours dispatched in
|
||||
// the store. For the purposes of legacy support, make sure that the
|
||||
// deserialized base/profile's state is in the format deemed current by
|
||||
// the current app revision.
|
||||
if (state && typeof state === 'object') { |
||||
// In an enterprise/internal build of Jitsi Meet for Android and iOS
|
||||
// we had base/profile's state as an object with property profile.
|
||||
const { profile } = state; |
||||
|
||||
if (profile && typeof profile === 'object') { |
||||
return { ...profile }; |
||||
} |
||||
} else { |
||||
// In the weird case that we have previously persisted/serialized
|
||||
// null.
|
||||
return DEFAULT_STATE; |
||||
} |
||||
break; |
||||
|
||||
case PROFILE_UPDATED: |
||||
return { |
||||
...state, |
||||
...action.profile |
||||
}; |
||||
} |
||||
|
||||
return state; |
||||
}); |
@ -0,0 +1,22 @@ |
||||
/** |
||||
* Create an action for when the settings are updated. |
||||
* |
||||
* { |
||||
* type: SETTINGS_UPDATED, |
||||
* settings: { |
||||
* audioOutputDeviceId: string, |
||||
* avatarID: string, |
||||
* avatarURL: string, |
||||
* cameraDeviceId: string, |
||||
* displayName: string, |
||||
* email: string, |
||||
* localFlipX: boolean, |
||||
* micDeviceId: string, |
||||
* serverURL: string, |
||||
* startAudioOnly: boolean, |
||||
* startWithAudioMuted: boolean, |
||||
* startWithVideoMuted: boolean |
||||
* } |
||||
* } |
||||
*/ |
||||
export const SETTINGS_UPDATED = Symbol('SETTINGS_UPDATED'); |
@ -0,0 +1,30 @@ |
||||
import { SETTINGS_UPDATED } from './actionTypes'; |
||||
|
||||
/** |
||||
* Create an action for when the settings are updated. |
||||
* |
||||
* @param {Object} settings - The new (partial) settings properties. |
||||
* @returns {{ |
||||
* type: SETTINGS_UPDATED, |
||||
* settings: { |
||||
* audioOutputDeviceId: string, |
||||
* avatarID: string, |
||||
* avatarURL: string, |
||||
* cameraDeviceId: string, |
||||
* displayName: string, |
||||
* email: string, |
||||
* localFlipX: boolean, |
||||
* micDeviceId: string, |
||||
* serverURL: string, |
||||
* startAudioOnly: boolean, |
||||
* startWithAudioMuted: boolean, |
||||
* startWithVideoMuted: boolean |
||||
* } |
||||
* }} |
||||
*/ |
||||
export function updateSettings(settings) { |
||||
return { |
||||
type: SETTINGS_UPDATED, |
||||
settings |
||||
}; |
||||
} |
@ -0,0 +1,157 @@ |
||||
// @flow
|
||||
import _ from 'lodash'; |
||||
|
||||
import { APP_WILL_MOUNT } from '../../app'; |
||||
|
||||
import JitsiMeetJS, { browser } from '../lib-jitsi-meet'; |
||||
import { ReducerRegistry } from '../redux'; |
||||
import { PersistenceRegistry } from '../storage'; |
||||
import { assignIfDefined, randomHexString } from '../util'; |
||||
|
||||
import { SETTINGS_UPDATED } from './actionTypes'; |
||||
|
||||
const logger = require('jitsi-meet-logger').getLogger(__filename); |
||||
|
||||
/** |
||||
* The default/initial redux state of the feature {@code base/settings}. |
||||
* |
||||
* @type Object |
||||
*/ |
||||
const DEFAULT_STATE = { |
||||
audioOutputDeviceId: undefined, |
||||
avatarID: undefined, |
||||
avatarURL: undefined, |
||||
cameraDeviceId: undefined, |
||||
displayName: undefined, |
||||
email: undefined, |
||||
localFlipX: true, |
||||
micDeviceId: undefined, |
||||
serverURL: undefined, |
||||
startAudioOnly: false, |
||||
startWithAudioMuted: false, |
||||
startWithVideoMuted: false |
||||
}; |
||||
|
||||
const STORE_NAME = 'features/base/settings'; |
||||
|
||||
/** |
||||
* Sets up the persistence of the feature {@code base/settings}. |
||||
*/ |
||||
PersistenceRegistry.register(STORE_NAME); |
||||
|
||||
ReducerRegistry.register(STORE_NAME, (state = DEFAULT_STATE, action) => { |
||||
switch (action.type) { |
||||
case APP_WILL_MOUNT: |
||||
return _initSettings(state); |
||||
|
||||
case SETTINGS_UPDATED: |
||||
return { |
||||
...state, |
||||
...action.settings |
||||
}; |
||||
} |
||||
|
||||
return state; |
||||
}); |
||||
|
||||
/** |
||||
* Retrieves the legacy profile values regardless of it's being in pre or |
||||
* post-flattening format. |
||||
* |
||||
* FIXME: Let's remove this after a predefined time (e.g. by July 2018) to avoid |
||||
* garbage in the source. |
||||
* |
||||
* @private |
||||
* @returns {Object} |
||||
*/ |
||||
function _getLegacyProfile() { |
||||
let persistedProfile |
||||
= window.localStorage.getItem('features/base/profile'); |
||||
|
||||
if (persistedProfile) { |
||||
try { |
||||
persistedProfile = JSON.parse(persistedProfile); |
||||
|
||||
if (persistedProfile && typeof persistedProfile === 'object') { |
||||
const preFlattenedProfile = persistedProfile.profile; |
||||
|
||||
return preFlattenedProfile || persistedProfile; |
||||
} |
||||
} catch (e) { |
||||
logger.warn('Error parsing persisted legacy profile', e); |
||||
} |
||||
} |
||||
|
||||
return {}; |
||||
} |
||||
|
||||
/** |
||||
* Inits the settings object based on what information we have available. |
||||
* Info taken into consideration: |
||||
* - Old Settings.js style data |
||||
* - Things that we stored in profile earlier but belong here. |
||||
* |
||||
* @private |
||||
* @param {Object} featureState - The current state of the feature. |
||||
* @returns {Object} |
||||
*/ |
||||
function _initSettings(featureState) { |
||||
let settings = featureState; |
||||
|
||||
// Old Settings.js values
|
||||
// FIXME: Let's remove this after a predefined time (e.g. by July 2018) to
|
||||
// avoid garbage in the source.
|
||||
const displayName = _.escape(window.localStorage.getItem('displayname')); |
||||
const email = _.escape(window.localStorage.getItem('email')); |
||||
let avatarID = _.escape(window.localStorage.getItem('avatarId')); |
||||
|
||||
if (!avatarID) { |
||||
// if there is no avatar id, we generate a unique one and use it forever
|
||||
avatarID = randomHexString(32); |
||||
} |
||||
|
||||
settings = assignIfDefined({ |
||||
avatarID, |
||||
displayName, |
||||
email |
||||
}, settings); |
||||
|
||||
if (!browser.isReactNative()) { |
||||
// Browser only
|
||||
const localFlipX |
||||
= JSON.parse(window.localStorage.getItem('localFlipX') || 'true'); |
||||
const cameraDeviceId |
||||
= window.localStorage.getItem('cameraDeviceId') || ''; |
||||
const micDeviceId = window.localStorage.getItem('micDeviceId') || ''; |
||||
|
||||
// Currently audio output device change is supported only in Chrome and
|
||||
// default output always has 'default' device ID
|
||||
const audioOutputDeviceId |
||||
= window.localStorage.getItem('audioOutputDeviceId') || 'default'; |
||||
|
||||
if (audioOutputDeviceId |
||||
!== JitsiMeetJS.mediaDevices.getAudioOutputDevice()) { |
||||
JitsiMeetJS.mediaDevices.setAudioOutputDevice( |
||||
audioOutputDeviceId |
||||
).catch(ex => { |
||||
logger.warn('Failed to set audio output device from local ' |
||||
+ 'storage. Default audio output device will be used' |
||||
+ 'instead.', ex); |
||||
}); |
||||
} |
||||
|
||||
settings = assignIfDefined({ |
||||
audioOutputDeviceId, |
||||
cameraDeviceId, |
||||
localFlipX, |
||||
micDeviceId |
||||
}, settings); |
||||
} |
||||
|
||||
// Things we stored in profile earlier
|
||||
const legacyProfile = _getLegacyProfile(); |
||||
|
||||
settings = assignIfDefined(legacyProfile, settings); |
||||
|
||||
return settings; |
||||
} |
Loading…
Reference in new issue