You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

reducer.ts 5.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. /* eslint-disable lines-around-comment */
  2. // @ts-ignore
  3. import { jitsiLocalStorage } from '@jitsi/js-utils';
  4. import _ from 'lodash';
  5. import { APP_WILL_MOUNT } from '../app/actionTypes';
  6. import PersistenceRegistry from '../redux/PersistenceRegistry';
  7. import ReducerRegistry from '../redux/ReducerRegistry';
  8. import { assignIfDefined } from '../util/helpers';
  9. import { SETTINGS_UPDATED } from './actionTypes';
  10. /**
  11. * The default/initial redux state of the feature {@code base/settings}.
  12. *
  13. * @type Object
  14. */
  15. const DEFAULT_STATE: ISettingsState = {
  16. audioOutputDeviceId: undefined,
  17. avatarURL: undefined,
  18. cameraDeviceId: undefined,
  19. disableCallIntegration: undefined,
  20. disableCrashReporting: undefined,
  21. disableP2P: undefined,
  22. disableSelfView: false,
  23. displayName: undefined,
  24. email: undefined,
  25. localFlipX: true,
  26. maxStageParticipants: 1,
  27. micDeviceId: undefined,
  28. serverURL: undefined,
  29. hideShareAudioHelper: false,
  30. soundsIncomingMessage: true,
  31. soundsParticipantJoined: true,
  32. soundsParticipantKnocking: true,
  33. soundsParticipantLeft: true,
  34. soundsTalkWhileMuted: true,
  35. soundsReactions: true,
  36. startAudioOnly: false,
  37. startWithAudioMuted: false,
  38. startWithVideoMuted: false,
  39. userSelectedAudioOutputDeviceId: undefined,
  40. userSelectedCameraDeviceId: undefined,
  41. userSelectedMicDeviceId: undefined,
  42. userSelectedAudioOutputDeviceLabel: undefined,
  43. userSelectedCameraDeviceLabel: undefined,
  44. userSelectedNotifications: {
  45. 'notify.chatMessages': true
  46. },
  47. userSelectedMicDeviceLabel: undefined,
  48. userSelectedSkipPrejoin: undefined
  49. };
  50. export interface ISettingsState {
  51. audioOutputDeviceId?: string | boolean;
  52. audioSettingsVisible?: boolean;
  53. avatarURL?: string;
  54. cameraDeviceId?: string | boolean;
  55. disableCallIntegration?: boolean;
  56. disableCrashReporting?: boolean;
  57. disableP2P?: boolean;
  58. disableSelfView?: boolean;
  59. displayName?: string;
  60. email?: string;
  61. hideShareAudioHelper?: boolean;
  62. localFlipX?: boolean;
  63. maxStageParticipants?: number;
  64. micDeviceId?: string | boolean;
  65. serverURL?: string;
  66. soundsIncomingMessage?: boolean;
  67. soundsParticipantJoined?: boolean;
  68. soundsParticipantKnocking?: boolean;
  69. soundsParticipantLeft?: boolean;
  70. soundsReactions?: boolean;
  71. soundsTalkWhileMuted?: boolean;
  72. startAudioOnly?: boolean;
  73. startWithAudioMuted?: boolean;
  74. startWithVideoMuted?: boolean;
  75. userSelectedAudioOutputDeviceId?: string;
  76. userSelectedAudioOutputDeviceLabel?: string;
  77. userSelectedCameraDeviceId?: string;
  78. userSelectedCameraDeviceLabel?: string;
  79. userSelectedMicDeviceId?: string;
  80. userSelectedMicDeviceLabel?: string;
  81. userSelectedNotifications?: {
  82. [key: string]: boolean;
  83. } | boolean;
  84. userSelectedSkipPrejoin?: boolean;
  85. videoSettingsVisible?: boolean;
  86. visible?: boolean;
  87. }
  88. const STORE_NAME = 'features/base/settings';
  89. /**
  90. * Sets up the persistence of the feature {@code base/settings}.
  91. */
  92. const filterSubtree: ISettingsState = {};
  93. // start with the default state
  94. Object.keys(DEFAULT_STATE).forEach(key => {
  95. const key1 = key as keyof typeof filterSubtree;
  96. // @ts-ignore
  97. filterSubtree[key1] = true;
  98. });
  99. // we want to filter these props, to not be stored as they represent
  100. // what is currently opened/used as devices
  101. filterSubtree.audioOutputDeviceId = false;
  102. filterSubtree.cameraDeviceId = false;
  103. filterSubtree.micDeviceId = false;
  104. PersistenceRegistry.register(STORE_NAME, filterSubtree, DEFAULT_STATE);
  105. ReducerRegistry.register<ISettingsState>(STORE_NAME, (state = DEFAULT_STATE, action): ISettingsState => {
  106. switch (action.type) {
  107. case APP_WILL_MOUNT:
  108. return _initSettings(state);
  109. case SETTINGS_UPDATED:
  110. return {
  111. ...state,
  112. ...action.settings
  113. };
  114. }
  115. return state;
  116. });
  117. /**
  118. * Inits the settings object based on what information we have available.
  119. * Info taken into consideration:
  120. * - Old Settings.js style data.
  121. *
  122. * @private
  123. * @param {ISettingsState} featureState - The current state of the feature.
  124. * @returns {Object}
  125. */
  126. function _initSettings(featureState: ISettingsState) {
  127. let settings = featureState;
  128. // Old Settings.js values
  129. // FIXME: jibri uses old settings.js local storage values to set its display
  130. // name and email. Provide another way for jibri to set these values, update
  131. // jibri, and remove the old settings.js values.
  132. const savedDisplayName = jitsiLocalStorage.getItem('displayname');
  133. const savedEmail = jitsiLocalStorage.getItem('email');
  134. // The helper _.escape will convert null to an empty strings. The empty
  135. // string will be saved in settings. On app re-load, because an empty string
  136. // is a defined value, it will override any value found in local storage.
  137. // The workaround is sidestepping _.escape when the value is not set in
  138. // local storage.
  139. const displayName = savedDisplayName === null ? undefined : _.escape(savedDisplayName);
  140. const email = savedEmail === null ? undefined : _.escape(savedEmail);
  141. settings = assignIfDefined({
  142. displayName,
  143. email
  144. }, settings);
  145. return settings;
  146. }