| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231 | 
							- /* @flow */
 - 
 - import _ from 'lodash';
 - import Logger from 'jitsi-meet-logger';
 - 
 - import persisterConfig from './persisterconfig.json';
 - 
 - const logger = Logger.getLogger(__filename);
 - const PERSISTED_STATE_NAME = 'jitsi-state';
 - 
 - /**
 -  * Sets specific properties of a specific state to specific values and prevents
 -  * unnecessary state changes.
 -  *
 -  * @param {Object} target - The state on which the specified properties are to
 -  * be set.
 -  * @param {Object} source - The map of properties to values which are to be set
 -  * on the specified target.
 -  * @returns {Object} The specified target if the values of the specified
 -  * properties equal the specified values; otherwise, a new state constructed
 -  * from the specified target by setting the specified properties to the
 -  * specified values.
 -  */
 - export function assign(target: Object, source: Object) {
 -     let t = target;
 - 
 -     for (const property in source) { // eslint-disable-line guard-for-in
 -         t = _set(t, property, source[property], t === target);
 -     }
 - 
 -     return t;
 - }
 - 
 - /**
 -  * Determines whether {@code a} equals {@code b} according to deep comparison
 -  * (which makes sense for Redux and its state definition).
 -  *
 -  * @param {*} a - The value to compare to {@code b}.
 -  * @param {*} b - The value to compare to {@code a}.
 -  * @returns {boolean} True if {@code a} equals {@code b} (according to deep
 -  * comparison); false, otherwise.
 -  */
 - export function equals(a: any, b: any) {
 -     return _.isEqual(a, b);
 - }
 - 
 - /**
 -  * Prepares a filtered state-slice (Redux term) based on the config for
 -  * persisting or for retreival.
 -  *
 -  * @private
 -  * @param {Object} persistedSlice - The redux state-slice.
 -  * @param {Object} persistedSliceConfig - The related config sub-tree.
 -  * @returns {Object}
 -  */
 - function _getFilteredSlice(persistedSlice, persistedSliceConfig) {
 -     const filteredpersistedSlice = {};
 - 
 -     for (const persistedKey of Object.keys(persistedSlice)) {
 -         if (persistedSliceConfig[persistedKey]) {
 -             filteredpersistedSlice[persistedKey] = persistedSlice[persistedKey];
 -         }
 -     }
 - 
 -     return filteredpersistedSlice;
 - }
 - 
 - /**
 -  * Prepares a filtered state from the actual or the
 -  * persisted Redux state, based on the config.
 -  *
 -  * @private
 -  * @param {Object} state - The actual or persisted redux state.
 -  * @returns {Object}
 -  */
 - function _getFilteredState(state: Object) {
 -     const filteredState = {};
 - 
 -     for (const slice of Object.keys(persisterConfig)) {
 -         filteredState[slice] = _getFilteredSlice(
 -             state[slice],
 -             persisterConfig[slice]
 -         );
 -     }
 - 
 -     return filteredState;
 - }
 - 
 - /**
 -  *  Returns the persisted redux state. This function takes
 -  * the persisterConfig into account as we may have persisted something
 -  * in the past that we don't want to retreive anymore. The next
 -  * {@link #persistState} will remove those values.
 -  *
 -  * @returns {Object}
 -  */
 - export function getPersistedState() {
 -     let persistedState = window.localStorage.getItem(PERSISTED_STATE_NAME);
 - 
 -     if (persistedState) {
 -         try {
 -             persistedState = JSON.parse(persistedState);
 -         } catch (error) {
 -             return {};
 -         }
 - 
 -         const filteredPersistedState = _getFilteredState(persistedState);
 - 
 -         logger.info('Redux state rehydrated', filteredPersistedState);
 - 
 -         return filteredPersistedState;
 -     }
 - 
 -     return {};
 - }
 - 
 - /**
 -  * Persists a filtered subtree of the redux state into {@code localStorage}.
 -  *
 -  * @param {Object} state - The redux state.
 -  * @returns {void}
 -  */
 - export function persistState(state: Object) {
 -     const filteredState = _getFilteredState(state);
 - 
 -     window.localStorage.setItem(
 -         PERSISTED_STATE_NAME,
 -         JSON.stringify(filteredState)
 -     );
 - 
 -     logger.info('Redux state persisted');
 - }
 - 
 - /**
 -  * Sets a specific property of a specific state to a specific value. Prevents
 -  * unnecessary state changes (when the specified {@code value} is equal to the
 -  * value of the specified {@code property} of the specified {@code state}).
 -  *
 -  * @param {Object} state - The (Redux) state from which a new state is to be
 -  * constructed by setting the specified {@code property} to the specified
 -  * {@code value}.
 -  * @param {string} property - The property of {@code state} which is to be
 -  * assigned the specified {@code value} (in the new state).
 -  * @param {*} value - The value to assign to the specified {@code property}.
 -  * @returns {Object} The specified {@code state} if the value of the specified
 -  * {@code property} equals the specified <tt>value/tt>; otherwise, a new state
 -  * constructed from the specified {@code state} by setting the specified
 -  * {@code property} to the specified {@code value}.
 -  */
 - export function set(state: Object, property: string, value: any) {
 -     return _set(state, property, value, /* copyOnWrite */ true);
 - }
 - 
 - /* eslint-disable max-params */
 - 
 - /**
 -  * Sets a specific property of a specific state to a specific value. Prevents
 -  * unnecessary state changes (when the specified {@code value} is equal to the
 -  * value of the specified {@code property} of the specified {@code state}).
 -  *
 -  * @param {Object} state - The (Redux) state from which a state is to be
 -  * constructed by setting the specified {@code property} to the specified
 -  * {@code value}.
 -  * @param {string} property - The property of {@code state} which is to be
 -  * assigned the specified {@code value}.
 -  * @param {*} value - The value to assign to the specified {@code property}.
 -  * @param {boolean} copyOnWrite - If the specified {@code state} is to not be
 -  * modified, {@code true}; otherwise, {@code false}.
 -  * @returns {Object} The specified {@code state} if the value of the specified
 -  * {@code property} equals the specified <tt>value/tt> or {@code copyOnWrite}
 -  * is truthy; otherwise, a new state constructed from the specified
 -  * {@code state} by setting the specified {@code property} to the specified
 -  * {@code value}.
 -  */
 - function _set(
 -         state: Object,
 -         property: string,
 -         value: any,
 -         copyOnWrite: boolean) {
 -     // Delete state properties that are to be set to undefined. (It is a matter
 -     // of personal preference, mostly.)
 -     if (typeof value === 'undefined'
 -             && Object.prototype.hasOwnProperty.call(state, property)) {
 -         const newState = copyOnWrite ? { ...state } : state;
 - 
 -         if (delete newState[property]) {
 -             return newState;
 -         }
 -     }
 - 
 -     if (state[property] !== value) {
 -         if (copyOnWrite) {
 -             return {
 -                 ...state,
 -                 [property]: value
 -             };
 -         }
 - 
 -         state[property] = value;
 -     }
 - 
 -     return state;
 - }
 - 
 - /* eslint-enable max-params */
 - 
 - /**
 -  * Returns redux state from the specified {@code stateful} which is presumed to
 -  * be related to the redux state (e.g. the redux store, the redux
 -  * {@code getState} function).
 -  *
 -  * @param {Function|Object} stateful - The entity such as the redux store or the
 -  * redux {@code getState} function from which the redux state is to be
 -  * returned.
 -  * @returns {Object} The redux state.
 -  */
 - export function toState(stateful: Function | Object) {
 -     if (stateful) {
 -         if (typeof stateful === 'function') {
 -             return stateful();
 -         }
 - 
 -         const { getState } = stateful;
 - 
 -         if (typeof getState === 'function') {
 -             return getState();
 -         }
 -     }
 - 
 -     return stateful;
 - }
 
 
  |