Change ephemeral settings to only persist in ephemeralConfig
This commit is contained in:
		
					parent
					
						
							
								07e2fb7f60
							
						
					
				
			
			
				commit
				
					
						73e8bec42f
					
				
			
		
					 18 changed files with 295 additions and 265 deletions
				
			
		| 
						 | 
					@ -8,7 +8,6 @@ import {
 | 
				
			||||||
  SystemTraySetting,
 | 
					  SystemTraySetting,
 | 
				
			||||||
} from '../ts/types/SystemTraySetting';
 | 
					} from '../ts/types/SystemTraySetting';
 | 
				
			||||||
import { isSystemTraySupported } from '../ts/types/Settings';
 | 
					import { isSystemTraySupported } from '../ts/types/Settings';
 | 
				
			||||||
import type { MainSQL } from '../ts/sql/main';
 | 
					 | 
				
			||||||
import type { ConfigType } from './base_config';
 | 
					import type { ConfigType } from './base_config';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
| 
						 | 
					@ -21,7 +20,6 @@ export class SystemTraySettingCache {
 | 
				
			||||||
  private getPromise: undefined | Promise<SystemTraySetting>;
 | 
					  private getPromise: undefined | Promise<SystemTraySetting>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  constructor(
 | 
					  constructor(
 | 
				
			||||||
    private readonly sql: Pick<MainSQL, 'sqlCall'>,
 | 
					 | 
				
			||||||
    private readonly ephemeralConfig: Pick<ConfigType, 'get' | 'set'>,
 | 
					    private readonly ephemeralConfig: Pick<ConfigType, 'get' | 'set'>,
 | 
				
			||||||
    private readonly argv: Array<string>,
 | 
					    private readonly argv: Array<string>,
 | 
				
			||||||
    private readonly appVersion: string
 | 
					    private readonly appVersion: string
 | 
				
			||||||
| 
						 | 
					@ -56,15 +54,11 @@ export class SystemTraySettingCache {
 | 
				
			||||||
        `getSystemTraySetting saw --use-tray-icon flag. Returning ${result}`
 | 
					        `getSystemTraySetting saw --use-tray-icon flag. Returning ${result}`
 | 
				
			||||||
      );
 | 
					      );
 | 
				
			||||||
    } else if (isSystemTraySupported(OS, this.appVersion)) {
 | 
					    } else if (isSystemTraySupported(OS, this.appVersion)) {
 | 
				
			||||||
      const fastValue = this.ephemeralConfig.get('system-tray-setting');
 | 
					      const value = this.ephemeralConfig.get('system-tray-setting');
 | 
				
			||||||
      if (fastValue !== undefined) {
 | 
					      if (value !== undefined) {
 | 
				
			||||||
        log.info('getSystemTraySetting got fast value', fastValue);
 | 
					        log.info('getSystemTraySetting got value', value);
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      const value =
 | 
					 | 
				
			||||||
        fastValue ??
 | 
					 | 
				
			||||||
        (await this.sql.sqlCall('getItemById', 'system-tray-setting'))?.value;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      if (value !== undefined) {
 | 
					      if (value !== undefined) {
 | 
				
			||||||
        result = parseSystemTraySetting(value);
 | 
					        result = parseSystemTraySetting(value);
 | 
				
			||||||
        log.info(`getSystemTraySetting returning ${result}`);
 | 
					        log.info(`getSystemTraySetting returning ${result}`);
 | 
				
			||||||
| 
						 | 
					@ -73,7 +67,7 @@ export class SystemTraySettingCache {
 | 
				
			||||||
        log.info(`getSystemTraySetting got no value, returning ${result}`);
 | 
					        log.info(`getSystemTraySetting got no value, returning ${result}`);
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      if (result !== fastValue) {
 | 
					      if (result !== value) {
 | 
				
			||||||
        this.ephemeralConfig.set('system-tray-setting', result);
 | 
					        this.ephemeralConfig.set('system-tray-setting', result);
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										118
									
								
								app/main.ts
									
										
									
									
									
								
							
							
						
						
									
										118
									
								
								app/main.ts
									
										
									
									
									
								
							| 
						 | 
					@ -292,22 +292,18 @@ const sql = new MainSQL();
 | 
				
			||||||
const heicConverter = getHeicConverter();
 | 
					const heicConverter = getHeicConverter();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
async function getSpellCheckSetting(): Promise<boolean> {
 | 
					async function getSpellCheckSetting(): Promise<boolean> {
 | 
				
			||||||
  const fastValue = ephemeralConfig.get('spell-check');
 | 
					  const value = ephemeralConfig.get('spell-check');
 | 
				
			||||||
  if (typeof fastValue === 'boolean') {
 | 
					  if (typeof value === 'boolean') {
 | 
				
			||||||
    getLogger().info('got fast spellcheck setting', fastValue);
 | 
					    getLogger().info('got fast spellcheck setting', value);
 | 
				
			||||||
    return fastValue;
 | 
					    return value;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const json = await sql.sqlCall('getItemById', 'spell-check');
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  // Default to `true` if setting doesn't exist yet
 | 
					  // Default to `true` if setting doesn't exist yet
 | 
				
			||||||
  const slowValue = typeof json?.value === 'boolean' ? json.value : true;
 | 
					  ephemeralConfig.set('spell-check', true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ephemeralConfig.set('spell-check', slowValue);
 | 
					  getLogger().info('initializing spellcheck setting', true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  getLogger().info('got slow spellcheck setting', slowValue);
 | 
					  return true;
 | 
				
			||||||
 | 
					 | 
				
			||||||
  return slowValue;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type GetThemeSettingOptionsType = Readonly<{
 | 
					type GetThemeSettingOptionsType = Readonly<{
 | 
				
			||||||
| 
						 | 
					@ -317,29 +313,22 @@ type GetThemeSettingOptionsType = Readonly<{
 | 
				
			||||||
async function getThemeSetting({
 | 
					async function getThemeSetting({
 | 
				
			||||||
  ephemeralOnly = false,
 | 
					  ephemeralOnly = false,
 | 
				
			||||||
}: GetThemeSettingOptionsType = {}): Promise<ThemeSettingType> {
 | 
					}: GetThemeSettingOptionsType = {}): Promise<ThemeSettingType> {
 | 
				
			||||||
  let result: unknown;
 | 
					  const value = ephemeralConfig.get('theme-setting');
 | 
				
			||||||
 | 
					  if (value !== undefined) {
 | 
				
			||||||
  const fastValue = ephemeralConfig.get('theme-setting');
 | 
					    getLogger().info('got fast theme-setting value', value);
 | 
				
			||||||
  if (fastValue !== undefined) {
 | 
					 | 
				
			||||||
    getLogger().info('got fast theme-setting value', fastValue);
 | 
					 | 
				
			||||||
    result = fastValue;
 | 
					 | 
				
			||||||
  } else if (ephemeralOnly) {
 | 
					  } else if (ephemeralOnly) {
 | 
				
			||||||
    return 'system';
 | 
					    return 'system';
 | 
				
			||||||
  } else {
 | 
					 | 
				
			||||||
    const json = await sql.sqlCall('getItemById', 'theme-setting');
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    result = json?.value;
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Default to `system` if setting doesn't exist or is invalid
 | 
					  // Default to `system` if setting doesn't exist or is invalid
 | 
				
			||||||
  const validatedResult =
 | 
					  const validatedResult =
 | 
				
			||||||
    result === 'light' || result === 'dark' || result === 'system'
 | 
					    value === 'light' || value === 'dark' || value === 'system'
 | 
				
			||||||
      ? result
 | 
					      ? value
 | 
				
			||||||
      : 'system';
 | 
					      : 'system';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (fastValue !== validatedResult) {
 | 
					  if (value !== validatedResult) {
 | 
				
			||||||
    ephemeralConfig.set('theme-setting', validatedResult);
 | 
					    ephemeralConfig.set('theme-setting', validatedResult);
 | 
				
			||||||
    getLogger().info('got slow theme-setting value', result);
 | 
					    getLogger().info('saving theme-setting value', validatedResult);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return validatedResult;
 | 
					  return validatedResult;
 | 
				
			||||||
| 
						 | 
					@ -372,23 +361,19 @@ async function getBackgroundColor(
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
async function getLocaleOverrideSetting(): Promise<string | null> {
 | 
					async function getLocaleOverrideSetting(): Promise<string | null> {
 | 
				
			||||||
  const fastValue = ephemeralConfig.get('localeOverride');
 | 
					  const value = ephemeralConfig.get('localeOverride');
 | 
				
			||||||
  // eslint-disable-next-line eqeqeq -- Checking for null explicitly
 | 
					  // eslint-disable-next-line eqeqeq -- Checking for null explicitly
 | 
				
			||||||
  if (typeof fastValue === 'string' || fastValue === null) {
 | 
					  if (typeof value === 'string' || value === null) {
 | 
				
			||||||
    getLogger().info('got fast localeOverride setting', fastValue);
 | 
					    getLogger().info('got fast localeOverride setting', value);
 | 
				
			||||||
    return fastValue;
 | 
					    return value;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const json = await sql.sqlCall('getItemById', 'localeOverride');
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  // Default to `null` if setting doesn't exist yet
 | 
					  // Default to `null` if setting doesn't exist yet
 | 
				
			||||||
  const slowValue = typeof json?.value === 'string' ? json.value : null;
 | 
					  ephemeralConfig.set('localeOverride', null);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ephemeralConfig.set('localeOverride', slowValue);
 | 
					  getLogger().info('initializing localeOverride setting', null);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  getLogger().info('got slow localeOverride setting', slowValue);
 | 
					  return null;
 | 
				
			||||||
 | 
					 | 
				
			||||||
  return slowValue;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const zoomFactorService = new ZoomFactorService({
 | 
					const zoomFactorService = new ZoomFactorService({
 | 
				
			||||||
| 
						 | 
					@ -409,7 +394,6 @@ const zoomFactorService = new ZoomFactorService({
 | 
				
			||||||
 | 
					
 | 
				
			||||||
let systemTrayService: SystemTrayService | undefined;
 | 
					let systemTrayService: SystemTrayService | undefined;
 | 
				
			||||||
const systemTraySettingCache = new SystemTraySettingCache(
 | 
					const systemTraySettingCache = new SystemTraySettingCache(
 | 
				
			||||||
  sql,
 | 
					 | 
				
			||||||
  ephemeralConfig,
 | 
					  ephemeralConfig,
 | 
				
			||||||
  process.argv,
 | 
					  process.argv,
 | 
				
			||||||
  app.getVersion()
 | 
					  app.getVersion()
 | 
				
			||||||
| 
						 | 
					@ -1811,12 +1795,7 @@ app.on('ready', async () => {
 | 
				
			||||||
    getLogger().info(`app.ready: setting system-tray-setting to ${newValue}`);
 | 
					    getLogger().info(`app.ready: setting system-tray-setting to ${newValue}`);
 | 
				
			||||||
    systemTraySettingCache.set(newValue);
 | 
					    systemTraySettingCache.set(newValue);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Update both stores
 | 
					 | 
				
			||||||
    ephemeralConfig.set('system-tray-setting', newValue);
 | 
					    ephemeralConfig.set('system-tray-setting', newValue);
 | 
				
			||||||
    await sql.sqlCall('createOrUpdateItem', {
 | 
					 | 
				
			||||||
      id: 'system-tray-setting',
 | 
					 | 
				
			||||||
      value: newValue,
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (OS.isWindows()) {
 | 
					    if (OS.isWindows()) {
 | 
				
			||||||
      getLogger().info('app.ready: enabling open at login');
 | 
					      getLogger().info('app.ready: enabling open at login');
 | 
				
			||||||
| 
						 | 
					@ -1832,6 +1811,32 @@ app.on('ready', async () => {
 | 
				
			||||||
  settingsChannel = new SettingsChannel();
 | 
					  settingsChannel = new SettingsChannel();
 | 
				
			||||||
  settingsChannel.install();
 | 
					  settingsChannel.install();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  settingsChannel.on('change:systemTraySetting', async rawSystemTraySetting => {
 | 
				
			||||||
 | 
					    const { openAtLogin } = app.getLoginItemSettings(
 | 
				
			||||||
 | 
					      await getDefaultLoginItemSettings()
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const systemTraySetting = parseSystemTraySetting(rawSystemTraySetting);
 | 
				
			||||||
 | 
					    systemTraySettingCache.set(systemTraySetting);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (systemTrayService) {
 | 
				
			||||||
 | 
					      const isEnabled = shouldMinimizeToSystemTray(systemTraySetting);
 | 
				
			||||||
 | 
					      systemTrayService.setEnabled(isEnabled);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Default login item settings might have changed, so update the object.
 | 
				
			||||||
 | 
					    getLogger().info('refresh-auto-launch: new value', openAtLogin);
 | 
				
			||||||
 | 
					    app.setLoginItemSettings({
 | 
				
			||||||
 | 
					      ...(await getDefaultLoginItemSettings()),
 | 
				
			||||||
 | 
					      openAtLogin,
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  settingsChannel.on(
 | 
				
			||||||
 | 
					    'ephemeral-setting-changed',
 | 
				
			||||||
 | 
					    sendPreferencesChangedEventToWindows
 | 
				
			||||||
 | 
					  );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // We use this event only a single time to log the startup time of the app
 | 
					  // We use this event only a single time to log the startup time of the app
 | 
				
			||||||
  // from when it's first ready until the loading screen disappears.
 | 
					  // from when it's first ready until the loading screen disappears.
 | 
				
			||||||
  ipc.once('signal-app-loaded', (event, info) => {
 | 
					  ipc.once('signal-app-loaded', (event, info) => {
 | 
				
			||||||
| 
						 | 
					@ -2318,30 +2323,6 @@ ipc.on(
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
);
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ipc.handle(
 | 
					 | 
				
			||||||
  'update-system-tray-setting',
 | 
					 | 
				
			||||||
  async (_event, rawSystemTraySetting /* : Readonly<unknown> */) => {
 | 
					 | 
				
			||||||
    const { openAtLogin } = app.getLoginItemSettings(
 | 
					 | 
				
			||||||
      await getDefaultLoginItemSettings()
 | 
					 | 
				
			||||||
    );
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    const systemTraySetting = parseSystemTraySetting(rawSystemTraySetting);
 | 
					 | 
				
			||||||
    systemTraySettingCache.set(systemTraySetting);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (systemTrayService) {
 | 
					 | 
				
			||||||
      const isEnabled = shouldMinimizeToSystemTray(systemTraySetting);
 | 
					 | 
				
			||||||
      systemTrayService.setEnabled(isEnabled);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // Default login item settings might have changed, so update the object.
 | 
					 | 
				
			||||||
    getLogger().info('refresh-auto-launch: new value', openAtLogin);
 | 
					 | 
				
			||||||
    app.setLoginItemSettings({
 | 
					 | 
				
			||||||
      ...(await getDefaultLoginItemSettings()),
 | 
					 | 
				
			||||||
      openAtLogin,
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
ipc.on('close-screen-share-controller', () => {
 | 
					ipc.on('close-screen-share-controller', () => {
 | 
				
			||||||
  if (screenShareWindow) {
 | 
					  if (screenShareWindow) {
 | 
				
			||||||
    screenShareWindow.close();
 | 
					    screenShareWindow.close();
 | 
				
			||||||
| 
						 | 
					@ -2564,13 +2545,14 @@ ipc.on('get-user-data-path', event => {
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Refresh the settings window whenever preferences change
 | 
					// Refresh the settings window whenever preferences change
 | 
				
			||||||
ipc.on('preferences-changed', () => {
 | 
					const sendPreferencesChangedEventToWindows = () => {
 | 
				
			||||||
  for (const window of activeWindows) {
 | 
					  for (const window of activeWindows) {
 | 
				
			||||||
    if (window.webContents) {
 | 
					    if (window.webContents) {
 | 
				
			||||||
      window.webContents.send('preferences-changed');
 | 
					      window.webContents.send('preferences-changed');
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
});
 | 
					};
 | 
				
			||||||
 | 
					ipc.on('preferences-changed', sendPreferencesChangedEventToWindows);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function maybeGetIncomingSignalRoute(argv: Array<string>) {
 | 
					function maybeGetIncomingSignalRoute(argv: Array<string>) {
 | 
				
			||||||
  for (const arg of argv) {
 | 
					  for (const arg of argv) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -190,6 +190,7 @@ import {
 | 
				
			||||||
  updateLocalGroupCallHistoryTimestamp,
 | 
					  updateLocalGroupCallHistoryTimestamp,
 | 
				
			||||||
} from './util/callDisposition';
 | 
					} from './util/callDisposition';
 | 
				
			||||||
import { deriveStorageServiceKey } from './Crypto';
 | 
					import { deriveStorageServiceKey } from './Crypto';
 | 
				
			||||||
 | 
					import { getThemeType } from './util/getThemeType';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export function isOverHourIntoPast(timestamp: number): boolean {
 | 
					export function isOverHourIntoPast(timestamp: number): boolean {
 | 
				
			||||||
  return isNumber(timestamp) && isOlderThan(timestamp, HOUR);
 | 
					  return isNumber(timestamp) && isOlderThan(timestamp, HOUR);
 | 
				
			||||||
| 
						 | 
					@ -697,25 +698,6 @@ export async function startApp(): Promise<void> {
 | 
				
			||||||
  log.info('Storage fetch');
 | 
					  log.info('Storage fetch');
 | 
				
			||||||
  drop(window.storage.fetch());
 | 
					  drop(window.storage.fetch());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  function mapOldThemeToNew(
 | 
					 | 
				
			||||||
    theme: Readonly<
 | 
					 | 
				
			||||||
      'system' | 'light' | 'dark' | 'android' | 'ios' | 'android-dark'
 | 
					 | 
				
			||||||
    >
 | 
					 | 
				
			||||||
  ): 'system' | 'light' | 'dark' {
 | 
					 | 
				
			||||||
    switch (theme) {
 | 
					 | 
				
			||||||
      case 'dark':
 | 
					 | 
				
			||||||
      case 'light':
 | 
					 | 
				
			||||||
      case 'system':
 | 
					 | 
				
			||||||
        return theme;
 | 
					 | 
				
			||||||
      case 'android-dark':
 | 
					 | 
				
			||||||
        return 'dark';
 | 
					 | 
				
			||||||
      case 'android':
 | 
					 | 
				
			||||||
      case 'ios':
 | 
					 | 
				
			||||||
      default:
 | 
					 | 
				
			||||||
        return 'light';
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  // We need this 'first' check because we don't want to start the app up any other time
 | 
					  // We need this 'first' check because we don't want to start the app up any other time
 | 
				
			||||||
  //   than the first time. And window.storage.fetch() will cause onready() to fire.
 | 
					  //   than the first time. And window.storage.fetch() will cause onready() to fire.
 | 
				
			||||||
  let first = true;
 | 
					  let first = true;
 | 
				
			||||||
| 
						 | 
					@ -925,16 +907,6 @@ export async function startApp(): Promise<void> {
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      const themeSetting = window.Events.getThemeSetting();
 | 
					 | 
				
			||||||
      const newThemeSetting = mapOldThemeToNew(themeSetting);
 | 
					 | 
				
			||||||
      if (window.isBeforeVersion(lastVersion, 'v1.25.0')) {
 | 
					 | 
				
			||||||
        if (newThemeSetting === window.systemTheme) {
 | 
					 | 
				
			||||||
          void window.Events.setThemeSetting('system');
 | 
					 | 
				
			||||||
        } else {
 | 
					 | 
				
			||||||
          void window.Events.setThemeSetting(newThemeSetting);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      if (
 | 
					      if (
 | 
				
			||||||
        window.isBeforeVersion(lastVersion, 'v1.36.0-beta.1') &&
 | 
					        window.isBeforeVersion(lastVersion, 'v1.36.0-beta.1') &&
 | 
				
			||||||
        window.isAfterVersion(lastVersion, 'v1.35.0-beta.1')
 | 
					        window.isAfterVersion(lastVersion, 'v1.35.0-beta.1')
 | 
				
			||||||
| 
						 | 
					@ -1133,6 +1105,8 @@ export async function startApp(): Promise<void> {
 | 
				
			||||||
      platform: 'unknown',
 | 
					      platform: 'unknown',
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let theme: ThemeType = window.systemTheme;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    try {
 | 
					    try {
 | 
				
			||||||
      // This needs to load before we prime the data because we expect
 | 
					      // This needs to load before we prime the data because we expect
 | 
				
			||||||
      // ConversationController to be loaded and ready to use by then.
 | 
					      // ConversationController to be loaded and ready to use by then.
 | 
				
			||||||
| 
						 | 
					@ -1153,6 +1127,9 @@ export async function startApp(): Promise<void> {
 | 
				
			||||||
        (async () => {
 | 
					        (async () => {
 | 
				
			||||||
          menuOptions = await window.SignalContext.getMenuOptions();
 | 
					          menuOptions = await window.SignalContext.getMenuOptions();
 | 
				
			||||||
        })(),
 | 
					        })(),
 | 
				
			||||||
 | 
					        (async () => {
 | 
				
			||||||
 | 
					          theme = await getThemeType();
 | 
				
			||||||
 | 
					        })(),
 | 
				
			||||||
      ]);
 | 
					      ]);
 | 
				
			||||||
      await window.ConversationController.checkForConflicts();
 | 
					      await window.ConversationController.checkForConflicts();
 | 
				
			||||||
    } catch (error) {
 | 
					    } catch (error) {
 | 
				
			||||||
| 
						 | 
					@ -1161,7 +1138,7 @@ export async function startApp(): Promise<void> {
 | 
				
			||||||
        Errors.toLogFormat(error)
 | 
					        Errors.toLogFormat(error)
 | 
				
			||||||
      );
 | 
					      );
 | 
				
			||||||
    } finally {
 | 
					    } finally {
 | 
				
			||||||
      setupAppState({ mainWindowStats, menuOptions });
 | 
					      setupAppState({ mainWindowStats, menuOptions, theme });
 | 
				
			||||||
      drop(start());
 | 
					      drop(start());
 | 
				
			||||||
      window.Signal.Services.initializeNetworkObserver(
 | 
					      window.Signal.Services.initializeNetworkObserver(
 | 
				
			||||||
        window.reduxActions.network
 | 
					        window.reduxActions.network
 | 
				
			||||||
| 
						 | 
					@ -1186,9 +1163,11 @@ export async function startApp(): Promise<void> {
 | 
				
			||||||
  function setupAppState({
 | 
					  function setupAppState({
 | 
				
			||||||
    mainWindowStats,
 | 
					    mainWindowStats,
 | 
				
			||||||
    menuOptions,
 | 
					    menuOptions,
 | 
				
			||||||
 | 
					    theme,
 | 
				
			||||||
  }: {
 | 
					  }: {
 | 
				
			||||||
    mainWindowStats: MainWindowStatsType;
 | 
					    mainWindowStats: MainWindowStatsType;
 | 
				
			||||||
    menuOptions: MenuOptionsType;
 | 
					    menuOptions: MenuOptionsType;
 | 
				
			||||||
 | 
					    theme: ThemeType;
 | 
				
			||||||
  }) {
 | 
					  }) {
 | 
				
			||||||
    initializeRedux({
 | 
					    initializeRedux({
 | 
				
			||||||
      callsHistory: getCallsHistoryForRedux(),
 | 
					      callsHistory: getCallsHistoryForRedux(),
 | 
				
			||||||
| 
						 | 
					@ -1198,6 +1177,7 @@ export async function startApp(): Promise<void> {
 | 
				
			||||||
      menuOptions,
 | 
					      menuOptions,
 | 
				
			||||||
      stories: getStoriesForRedux(),
 | 
					      stories: getStoriesForRedux(),
 | 
				
			||||||
      storyDistributionLists: getDistributionListsForRedux(),
 | 
					      storyDistributionLists: getDistributionListsForRedux(),
 | 
				
			||||||
 | 
					      theme,
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Here we set up a full redux store with initial state for our LeftPane Root
 | 
					    // Here we set up a full redux store with initial state for our LeftPane Root
 | 
				
			||||||
| 
						 | 
					@ -1847,18 +1827,6 @@ export async function startApp(): Promise<void> {
 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        const hasThemeSetting = Boolean(window.storage.get('theme-setting'));
 | 
					 | 
				
			||||||
        if (
 | 
					 | 
				
			||||||
          !hasThemeSetting &&
 | 
					 | 
				
			||||||
          window.textsecure.storage.get('userAgent') === 'OWI'
 | 
					 | 
				
			||||||
        ) {
 | 
					 | 
				
			||||||
          await window.storage.put(
 | 
					 | 
				
			||||||
            'theme-setting',
 | 
					 | 
				
			||||||
            await window.Events.getThemeSetting()
 | 
					 | 
				
			||||||
          );
 | 
					 | 
				
			||||||
          themeChanged();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        const waitForEvent = createTaskWithTimeout(
 | 
					        const waitForEvent = createTaskWithTimeout(
 | 
				
			||||||
          (event: string): Promise<void> => {
 | 
					          (event: string): Promise<void> => {
 | 
				
			||||||
            const { promise, resolve } = explodePromise<void>();
 | 
					            const { promise, resolve } = explodePromise<void>();
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -14,6 +14,7 @@ import type {
 | 
				
			||||||
  IPCEventsValuesType,
 | 
					  IPCEventsValuesType,
 | 
				
			||||||
  IPCEventsCallbacksType,
 | 
					  IPCEventsCallbacksType,
 | 
				
			||||||
} from '../util/createIPCEvents';
 | 
					} from '../util/createIPCEvents';
 | 
				
			||||||
 | 
					import type { EphemeralSettings, SettingsValuesType } from '../util/preload';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const EPHEMERAL_NAME_MAP = new Map([
 | 
					const EPHEMERAL_NAME_MAP = new Map([
 | 
				
			||||||
  ['spellCheck', 'spell-check'],
 | 
					  ['spellCheck', 'spell-check'],
 | 
				
			||||||
| 
						 | 
					@ -27,6 +28,9 @@ type ResponseQueueEntry = Readonly<{
 | 
				
			||||||
  reject(error: Error): void;
 | 
					  reject(error: Error): void;
 | 
				
			||||||
}>;
 | 
					}>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type SettingChangeEventType<Key extends keyof SettingsValuesType> =
 | 
				
			||||||
 | 
					  `change:${Key}`;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export class SettingsChannel extends EventEmitter {
 | 
					export class SettingsChannel extends EventEmitter {
 | 
				
			||||||
  private mainWindow?: BrowserWindow;
 | 
					  private mainWindow?: BrowserWindow;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -70,17 +74,7 @@ export class SettingsChannel extends EventEmitter {
 | 
				
			||||||
    this.installSetting('readReceiptSetting', { setter: false });
 | 
					    this.installSetting('readReceiptSetting', { setter: false });
 | 
				
			||||||
    this.installSetting('typingIndicatorSetting', { setter: false });
 | 
					    this.installSetting('typingIndicatorSetting', { setter: false });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    this.installSetting('themeSetting', {
 | 
					 | 
				
			||||||
      isEphemeral: true,
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
    this.installSetting('hideMenuBar');
 | 
					    this.installSetting('hideMenuBar');
 | 
				
			||||||
    this.installSetting('systemTraySetting', {
 | 
					 | 
				
			||||||
      isEphemeral: true,
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    this.installSetting('localeOverride', {
 | 
					 | 
				
			||||||
      isEphemeral: true,
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
    this.installSetting('notificationSetting');
 | 
					    this.installSetting('notificationSetting');
 | 
				
			||||||
    this.installSetting('notificationDrawAttention');
 | 
					    this.installSetting('notificationDrawAttention');
 | 
				
			||||||
    this.installSetting('audioMessage');
 | 
					    this.installSetting('audioMessage');
 | 
				
			||||||
| 
						 | 
					@ -88,9 +82,6 @@ export class SettingsChannel extends EventEmitter {
 | 
				
			||||||
    this.installSetting('countMutedConversations');
 | 
					    this.installSetting('countMutedConversations');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    this.installSetting('sentMediaQualitySetting');
 | 
					    this.installSetting('sentMediaQualitySetting');
 | 
				
			||||||
    this.installSetting('spellCheck', {
 | 
					 | 
				
			||||||
      isEphemeral: true,
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
    this.installSetting('textFormatting');
 | 
					    this.installSetting('textFormatting');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    this.installSetting('autoConvertEmoji');
 | 
					    this.installSetting('autoConvertEmoji');
 | 
				
			||||||
| 
						 | 
					@ -116,6 +107,11 @@ export class SettingsChannel extends EventEmitter {
 | 
				
			||||||
    this.installSetting('phoneNumberDiscoverabilitySetting');
 | 
					    this.installSetting('phoneNumberDiscoverabilitySetting');
 | 
				
			||||||
    this.installSetting('phoneNumberSharingSetting');
 | 
					    this.installSetting('phoneNumberSharingSetting');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    this.installEphemeralSetting('themeSetting');
 | 
				
			||||||
 | 
					    this.installEphemeralSetting('systemTraySetting');
 | 
				
			||||||
 | 
					    this.installEphemeralSetting('localeOverride');
 | 
				
			||||||
 | 
					    this.installEphemeralSetting('spellCheck');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    installPermissionsHandler({ session: session.defaultSession, userConfig });
 | 
					    installPermissionsHandler({ session: session.defaultSession, userConfig });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // These ones are different because its single source of truth is userConfig,
 | 
					    // These ones are different because its single source of truth is userConfig,
 | 
				
			||||||
| 
						 | 
					@ -234,8 +230,7 @@ export class SettingsChannel extends EventEmitter {
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
      getter = true,
 | 
					      getter = true,
 | 
				
			||||||
      setter = true,
 | 
					      setter = true,
 | 
				
			||||||
      isEphemeral = false,
 | 
					    }: { getter?: boolean; setter?: boolean } = {}
 | 
				
			||||||
    }: { getter?: boolean; setter?: boolean; isEphemeral?: boolean } = {}
 | 
					 | 
				
			||||||
  ): void {
 | 
					  ): void {
 | 
				
			||||||
    if (getter) {
 | 
					    if (getter) {
 | 
				
			||||||
      ipc.handle(`settings:get:${name}`, async () => {
 | 
					      ipc.handle(`settings:get:${name}`, async () => {
 | 
				
			||||||
| 
						 | 
					@ -248,18 +243,89 @@ export class SettingsChannel extends EventEmitter {
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ipc.handle(`settings:set:${name}`, async (_event, value) => {
 | 
					    ipc.handle(`settings:set:${name}`, async (_event, value) => {
 | 
				
			||||||
      if (isEphemeral) {
 | 
					 | 
				
			||||||
        const ephemeralName = EPHEMERAL_NAME_MAP.get(name);
 | 
					 | 
				
			||||||
        strictAssert(
 | 
					 | 
				
			||||||
          ephemeralName !== undefined,
 | 
					 | 
				
			||||||
          `${name} is not an ephemeral setting`
 | 
					 | 
				
			||||||
        );
 | 
					 | 
				
			||||||
        ephemeralConfig.set(ephemeralName, value);
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      await this.setSettingInMainWindow(name, value);
 | 
					      await this.setSettingInMainWindow(name, value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      this.emit(`change:${name}`, value);
 | 
					      this.emit(`change:${name}`, value);
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  private installEphemeralSetting<Name extends keyof EphemeralSettings>(
 | 
				
			||||||
 | 
					    name: Name
 | 
				
			||||||
 | 
					  ): void {
 | 
				
			||||||
 | 
					    ipc.handle(`settings:get:${name}`, async () => {
 | 
				
			||||||
 | 
					      const ephemeralName = EPHEMERAL_NAME_MAP.get(name);
 | 
				
			||||||
 | 
					      strictAssert(
 | 
				
			||||||
 | 
					        ephemeralName !== undefined,
 | 
				
			||||||
 | 
					        `${name} is not an ephemeral setting`
 | 
				
			||||||
 | 
					      );
 | 
				
			||||||
 | 
					      return ephemeralConfig.get(ephemeralName);
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ipc.handle(`settings:set:${name}`, async (_event, value) => {
 | 
				
			||||||
 | 
					      const ephemeralName = EPHEMERAL_NAME_MAP.get(name);
 | 
				
			||||||
 | 
					      strictAssert(
 | 
				
			||||||
 | 
					        ephemeralName !== undefined,
 | 
				
			||||||
 | 
					        `${name} is not an ephemeral setting`
 | 
				
			||||||
 | 
					      );
 | 
				
			||||||
 | 
					      ephemeralConfig.set(ephemeralName, value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      this.emit(`change:${name}`, value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // Notify main to notify windows of preferences change. As for DB-backed
 | 
				
			||||||
 | 
					      // settings, those are set by the renderer, and afterwards the renderer IPC sends
 | 
				
			||||||
 | 
					      // to main the event 'preferences-changed'.
 | 
				
			||||||
 | 
					      this.emit('ephemeral-setting-changed');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      const { mainWindow } = this;
 | 
				
			||||||
 | 
					      if (!mainWindow || !mainWindow.webContents) {
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      mainWindow.webContents.send(`settings:update:${name}`, value);
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // EventEmitter types
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  public override on(
 | 
				
			||||||
 | 
					    type: 'change:systemTraySetting',
 | 
				
			||||||
 | 
					    callback: (value: string) => void
 | 
				
			||||||
 | 
					  ): this;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  public override on(
 | 
				
			||||||
 | 
					    type: 'ephemeral-setting-changed',
 | 
				
			||||||
 | 
					    callback: () => void
 | 
				
			||||||
 | 
					  ): this;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  public override on(
 | 
				
			||||||
 | 
					    type: SettingChangeEventType<keyof SettingsValuesType>,
 | 
				
			||||||
 | 
					    // eslint-disable-next-line @typescript-eslint/no-explicit-any
 | 
				
			||||||
 | 
					    callback: (...args: Array<any>) => void
 | 
				
			||||||
 | 
					  ): this;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  public override on(
 | 
				
			||||||
 | 
					    type: string | symbol,
 | 
				
			||||||
 | 
					    // eslint-disable-next-line @typescript-eslint/no-explicit-any
 | 
				
			||||||
 | 
					    listener: (...args: Array<any>) => void
 | 
				
			||||||
 | 
					  ): this {
 | 
				
			||||||
 | 
					    return super.on(type, listener);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  public override emit(
 | 
				
			||||||
 | 
					    type: 'change:systemTraySetting',
 | 
				
			||||||
 | 
					    value: string
 | 
				
			||||||
 | 
					  ): boolean;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  public override emit(type: 'ephemeral-setting-changed'): boolean;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  public override emit(
 | 
				
			||||||
 | 
					    type: SettingChangeEventType<keyof SettingsValuesType>,
 | 
				
			||||||
 | 
					    // eslint-disable-next-line @typescript-eslint/no-explicit-any
 | 
				
			||||||
 | 
					    ...args: Array<any>
 | 
				
			||||||
 | 
					  ): boolean;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // eslint-disable-next-line @typescript-eslint/no-explicit-any
 | 
				
			||||||
 | 
					  public override emit(type: string | symbol, ...args: Array<any>): boolean {
 | 
				
			||||||
 | 
					    return super.emit(type, ...args);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3,9 +3,9 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import { getThemeType } from '../util/getThemeType';
 | 
					import { getThemeType } from '../util/getThemeType';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export function themeChanged(): void {
 | 
					export async function themeChanged(): Promise<void> {
 | 
				
			||||||
  if (window.reduxActions && window.reduxActions.user) {
 | 
					  if (window.reduxActions && window.reduxActions.user) {
 | 
				
			||||||
    const theme = getThemeType();
 | 
					    const theme = await getThemeType();
 | 
				
			||||||
    window.reduxActions.user.userChanged({ theme });
 | 
					    window.reduxActions.user.userChanged({ theme });
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -37,10 +37,10 @@ import type { StoryDistributionListDataType } from './ducks/storyDistributionLis
 | 
				
			||||||
import OS from '../util/os/osMain';
 | 
					import OS from '../util/os/osMain';
 | 
				
			||||||
import { getEmojiReducerState as emojis } from '../util/loadRecentEmojis';
 | 
					import { getEmojiReducerState as emojis } from '../util/loadRecentEmojis';
 | 
				
			||||||
import { getInitialState as stickers } from '../types/Stickers';
 | 
					import { getInitialState as stickers } from '../types/Stickers';
 | 
				
			||||||
import { getThemeType } from '../util/getThemeType';
 | 
					 | 
				
			||||||
import { getInteractionMode } from '../services/InteractionMode';
 | 
					import { getInteractionMode } from '../services/InteractionMode';
 | 
				
			||||||
import { makeLookup } from '../util/makeLookup';
 | 
					import { makeLookup } from '../util/makeLookup';
 | 
				
			||||||
import type { CallHistoryDetails } from '../types/CallDisposition';
 | 
					import type { CallHistoryDetails } from '../types/CallDisposition';
 | 
				
			||||||
 | 
					import type { ThemeType } from '../types/Util';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export function getInitialState({
 | 
					export function getInitialState({
 | 
				
			||||||
  badges,
 | 
					  badges,
 | 
				
			||||||
| 
						 | 
					@ -50,6 +50,7 @@ export function getInitialState({
 | 
				
			||||||
  storyDistributionLists,
 | 
					  storyDistributionLists,
 | 
				
			||||||
  mainWindowStats,
 | 
					  mainWindowStats,
 | 
				
			||||||
  menuOptions,
 | 
					  menuOptions,
 | 
				
			||||||
 | 
					  theme,
 | 
				
			||||||
}: {
 | 
					}: {
 | 
				
			||||||
  badges: BadgesStateType;
 | 
					  badges: BadgesStateType;
 | 
				
			||||||
  callsHistory: ReadonlyArray<CallHistoryDetails>;
 | 
					  callsHistory: ReadonlyArray<CallHistoryDetails>;
 | 
				
			||||||
| 
						 | 
					@ -58,6 +59,7 @@ export function getInitialState({
 | 
				
			||||||
  storyDistributionLists: Array<StoryDistributionListDataType>;
 | 
					  storyDistributionLists: Array<StoryDistributionListDataType>;
 | 
				
			||||||
  mainWindowStats: MainWindowStatsType;
 | 
					  mainWindowStats: MainWindowStatsType;
 | 
				
			||||||
  menuOptions: MenuOptionsType;
 | 
					  menuOptions: MenuOptionsType;
 | 
				
			||||||
 | 
					  theme: ThemeType;
 | 
				
			||||||
}): StateType {
 | 
					}): StateType {
 | 
				
			||||||
  const items = window.storage.getItemsState();
 | 
					  const items = window.storage.getItemsState();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -72,8 +74,6 @@ export function getInitialState({
 | 
				
			||||||
    window.ConversationController.getOurConversationId();
 | 
					    window.ConversationController.getOurConversationId();
 | 
				
			||||||
  const ourDeviceId = window.textsecure.storage.user.getDeviceId();
 | 
					  const ourDeviceId = window.textsecure.storage.user.getDeviceId();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const theme = getThemeType();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  let osName: 'windows' | 'macos' | 'linux' | undefined;
 | 
					  let osName: 'windows' | 'macos' | 'linux' | undefined;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (OS.isWindows()) {
 | 
					  if (OS.isWindows()) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -11,6 +11,7 @@ import type { StoryDistributionListDataType } from './ducks/storyDistributionLis
 | 
				
			||||||
import { actionCreators } from './actions';
 | 
					import { actionCreators } from './actions';
 | 
				
			||||||
import { createStore } from './createStore';
 | 
					import { createStore } from './createStore';
 | 
				
			||||||
import { getInitialState } from './getInitialState';
 | 
					import { getInitialState } from './getInitialState';
 | 
				
			||||||
 | 
					import type { ThemeType } from '../types/Util';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export function initializeRedux({
 | 
					export function initializeRedux({
 | 
				
			||||||
  callsHistory,
 | 
					  callsHistory,
 | 
				
			||||||
| 
						 | 
					@ -20,6 +21,7 @@ export function initializeRedux({
 | 
				
			||||||
  menuOptions,
 | 
					  menuOptions,
 | 
				
			||||||
  stories,
 | 
					  stories,
 | 
				
			||||||
  storyDistributionLists,
 | 
					  storyDistributionLists,
 | 
				
			||||||
 | 
					  theme,
 | 
				
			||||||
}: {
 | 
					}: {
 | 
				
			||||||
  callsHistory: ReadonlyArray<CallHistoryDetails>;
 | 
					  callsHistory: ReadonlyArray<CallHistoryDetails>;
 | 
				
			||||||
  callsHistoryUnreadCount: number;
 | 
					  callsHistoryUnreadCount: number;
 | 
				
			||||||
| 
						 | 
					@ -28,6 +30,7 @@ export function initializeRedux({
 | 
				
			||||||
  menuOptions: MenuOptionsType;
 | 
					  menuOptions: MenuOptionsType;
 | 
				
			||||||
  stories: Array<StoryDataType>;
 | 
					  stories: Array<StoryDataType>;
 | 
				
			||||||
  storyDistributionLists: Array<StoryDistributionListDataType>;
 | 
					  storyDistributionLists: Array<StoryDistributionListDataType>;
 | 
				
			||||||
 | 
					  theme: ThemeType;
 | 
				
			||||||
}): void {
 | 
					}): void {
 | 
				
			||||||
  const initialState = getInitialState({
 | 
					  const initialState = getInitialState({
 | 
				
			||||||
    badges: initialBadgesState,
 | 
					    badges: initialBadgesState,
 | 
				
			||||||
| 
						 | 
					@ -37,6 +40,7 @@ export function initializeRedux({
 | 
				
			||||||
    menuOptions,
 | 
					    menuOptions,
 | 
				
			||||||
    stories,
 | 
					    stories,
 | 
				
			||||||
    storyDistributionLists,
 | 
					    storyDistributionLists,
 | 
				
			||||||
 | 
					    theme,
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const store = createStore(initialState);
 | 
					  const store = createStore(initialState);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3,7 +3,6 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import { assert } from 'chai';
 | 
					import { assert } from 'chai';
 | 
				
			||||||
import * as sinon from 'sinon';
 | 
					import * as sinon from 'sinon';
 | 
				
			||||||
import type { MainSQL } from '../../sql/main';
 | 
					 | 
				
			||||||
import { SystemTraySetting } from '../../types/SystemTraySetting';
 | 
					import { SystemTraySetting } from '../../types/SystemTraySetting';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import type { ConfigType } from '../../../app/base_config';
 | 
					import type { ConfigType } from '../../../app/base_config';
 | 
				
			||||||
| 
						 | 
					@ -12,18 +11,13 @@ import { SystemTraySettingCache } from '../../../app/SystemTraySettingCache';
 | 
				
			||||||
describe('SystemTraySettingCache', () => {
 | 
					describe('SystemTraySettingCache', () => {
 | 
				
			||||||
  let sandbox: sinon.SinonSandbox;
 | 
					  let sandbox: sinon.SinonSandbox;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  let sqlCallStub: sinon.SinonStub;
 | 
					 | 
				
			||||||
  let configGetStub: sinon.SinonStub;
 | 
					  let configGetStub: sinon.SinonStub;
 | 
				
			||||||
  let configSetStub: sinon.SinonStub;
 | 
					  let configSetStub: sinon.SinonStub;
 | 
				
			||||||
  let sql: Pick<MainSQL, 'sqlCall'>;
 | 
					 | 
				
			||||||
  let config: Pick<ConfigType, 'get' | 'set'>;
 | 
					  let config: Pick<ConfigType, 'get' | 'set'>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  beforeEach(() => {
 | 
					  beforeEach(() => {
 | 
				
			||||||
    sandbox = sinon.createSandbox();
 | 
					    sandbox = sinon.createSandbox();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    sqlCallStub = sandbox.stub().resolves();
 | 
					 | 
				
			||||||
    sql = { sqlCall: sqlCallStub };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    configGetStub = sandbox.stub().returns(undefined);
 | 
					    configGetStub = sandbox.stub().returns(undefined);
 | 
				
			||||||
    configSetStub = sandbox.stub().returns(undefined);
 | 
					    configSetStub = sandbox.stub().returns(undefined);
 | 
				
			||||||
    config = { get: configGetStub, set: configSetStub };
 | 
					    config = { get: configGetStub, set: configSetStub };
 | 
				
			||||||
| 
						 | 
					@ -35,7 +29,6 @@ describe('SystemTraySettingCache', () => {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  it('returns MinimizeToAndStartInSystemTray if passed the --start-in-tray argument', async () => {
 | 
					  it('returns MinimizeToAndStartInSystemTray if passed the --start-in-tray argument', async () => {
 | 
				
			||||||
    const justOneArg = new SystemTraySettingCache(
 | 
					    const justOneArg = new SystemTraySettingCache(
 | 
				
			||||||
      sql,
 | 
					 | 
				
			||||||
      config,
 | 
					      config,
 | 
				
			||||||
      ['--start-in-tray'],
 | 
					      ['--start-in-tray'],
 | 
				
			||||||
      '1.2.3'
 | 
					      '1.2.3'
 | 
				
			||||||
| 
						 | 
					@ -46,7 +39,6 @@ describe('SystemTraySettingCache', () => {
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const bothArgs = new SystemTraySettingCache(
 | 
					    const bothArgs = new SystemTraySettingCache(
 | 
				
			||||||
      sql,
 | 
					 | 
				
			||||||
      config,
 | 
					      config,
 | 
				
			||||||
      ['--start-in-tray', '--use-tray-icon'],
 | 
					      ['--start-in-tray', '--use-tray-icon'],
 | 
				
			||||||
      '1.2.3'
 | 
					      '1.2.3'
 | 
				
			||||||
| 
						 | 
					@ -56,14 +48,12 @@ describe('SystemTraySettingCache', () => {
 | 
				
			||||||
      SystemTraySetting.MinimizeToAndStartInSystemTray
 | 
					      SystemTraySetting.MinimizeToAndStartInSystemTray
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    sinon.assert.notCalled(sqlCallStub);
 | 
					 | 
				
			||||||
    sinon.assert.notCalled(configGetStub);
 | 
					    sinon.assert.notCalled(configGetStub);
 | 
				
			||||||
    sinon.assert.notCalled(configSetStub);
 | 
					    sinon.assert.notCalled(configSetStub);
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  it('returns MinimizeToSystemTray if passed the --use-tray-icon argument', async () => {
 | 
					  it('returns MinimizeToSystemTray if passed the --use-tray-icon argument', async () => {
 | 
				
			||||||
    const cache = new SystemTraySettingCache(
 | 
					    const cache = new SystemTraySettingCache(
 | 
				
			||||||
      sql,
 | 
					 | 
				
			||||||
      config,
 | 
					      config,
 | 
				
			||||||
      ['--use-tray-icon'],
 | 
					      ['--use-tray-icon'],
 | 
				
			||||||
      '1.2.3'
 | 
					      '1.2.3'
 | 
				
			||||||
| 
						 | 
					@ -73,7 +63,6 @@ describe('SystemTraySettingCache', () => {
 | 
				
			||||||
      SystemTraySetting.MinimizeToSystemTray
 | 
					      SystemTraySetting.MinimizeToSystemTray
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    sinon.assert.notCalled(sqlCallStub);
 | 
					 | 
				
			||||||
    sinon.assert.notCalled(configGetStub);
 | 
					    sinon.assert.notCalled(configGetStub);
 | 
				
			||||||
    sinon.assert.notCalled(configSetStub);
 | 
					    sinon.assert.notCalled(configSetStub);
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
| 
						 | 
					@ -81,7 +70,7 @@ describe('SystemTraySettingCache', () => {
 | 
				
			||||||
  it('returns Uninitialized if system tray is supported but no preference is stored', async () => {
 | 
					  it('returns Uninitialized if system tray is supported but no preference is stored', async () => {
 | 
				
			||||||
    sandbox.stub(process, 'platform').value('win32');
 | 
					    sandbox.stub(process, 'platform').value('win32');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const cache = new SystemTraySettingCache(sql, config, [], '1.2.3');
 | 
					    const cache = new SystemTraySettingCache(config, [], '1.2.3');
 | 
				
			||||||
    assert.strictEqual(await cache.get(), SystemTraySetting.Uninitialized);
 | 
					    assert.strictEqual(await cache.get(), SystemTraySetting.Uninitialized);
 | 
				
			||||||
    assert(configGetStub.calledOnceWith('system-tray-setting'));
 | 
					    assert(configGetStub.calledOnceWith('system-tray-setting'));
 | 
				
			||||||
    assert(
 | 
					    assert(
 | 
				
			||||||
| 
						 | 
					@ -95,9 +84,9 @@ describe('SystemTraySettingCache', () => {
 | 
				
			||||||
  it('returns Uninitialized if system tray is supported but the stored preference is invalid', async () => {
 | 
					  it('returns Uninitialized if system tray is supported but the stored preference is invalid', async () => {
 | 
				
			||||||
    sandbox.stub(process, 'platform').value('win32');
 | 
					    sandbox.stub(process, 'platform').value('win32');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    sqlCallStub.resolves({ value: 'garbage' });
 | 
					    configGetStub.returns('garbage');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const cache = new SystemTraySettingCache(sql, config, [], '1.2.3');
 | 
					    const cache = new SystemTraySettingCache(config, [], '1.2.3');
 | 
				
			||||||
    assert.strictEqual(await cache.get(), SystemTraySetting.Uninitialized);
 | 
					    assert.strictEqual(await cache.get(), SystemTraySetting.Uninitialized);
 | 
				
			||||||
    assert(configGetStub.calledOnceWith('system-tray-setting'));
 | 
					    assert(configGetStub.calledOnceWith('system-tray-setting'));
 | 
				
			||||||
    assert(
 | 
					    assert(
 | 
				
			||||||
| 
						 | 
					@ -108,58 +97,26 @@ describe('SystemTraySettingCache', () => {
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  it('returns the stored preference if system tray is supported and something is stored', async () => {
 | 
					 | 
				
			||||||
    sandbox.stub(process, 'platform').value('win32');
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    sqlCallStub.resolves({ value: 'MinimizeToSystemTray' });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    const cache = new SystemTraySettingCache(sql, config, [], '1.2.3');
 | 
					 | 
				
			||||||
    assert.strictEqual(
 | 
					 | 
				
			||||||
      await cache.get(),
 | 
					 | 
				
			||||||
      SystemTraySetting.MinimizeToSystemTray
 | 
					 | 
				
			||||||
    );
 | 
					 | 
				
			||||||
    assert(configGetStub.calledOnceWith('system-tray-setting'));
 | 
					 | 
				
			||||||
    assert(
 | 
					 | 
				
			||||||
      configSetStub.calledOnceWith(
 | 
					 | 
				
			||||||
        'system-tray-setting',
 | 
					 | 
				
			||||||
        SystemTraySetting.MinimizeToSystemTray
 | 
					 | 
				
			||||||
      )
 | 
					 | 
				
			||||||
    );
 | 
					 | 
				
			||||||
  });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  it('returns the cached preference if system tray is supported and something is stored', async () => {
 | 
					  it('returns the cached preference if system tray is supported and something is stored', async () => {
 | 
				
			||||||
    sandbox.stub(process, 'platform').value('win32');
 | 
					    sandbox.stub(process, 'platform').value('win32');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    configGetStub.returns('MinimizeToSystemTray');
 | 
					    configGetStub.returns('MinimizeToSystemTray');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const cache = new SystemTraySettingCache(sql, config, [], '1.2.3');
 | 
					    const cache = new SystemTraySettingCache(config, [], '1.2.3');
 | 
				
			||||||
    assert.strictEqual(
 | 
					    assert.strictEqual(
 | 
				
			||||||
      await cache.get(),
 | 
					      await cache.get(),
 | 
				
			||||||
      SystemTraySetting.MinimizeToSystemTray
 | 
					      SystemTraySetting.MinimizeToSystemTray
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
    assert(configGetStub.calledOnceWith('system-tray-setting'));
 | 
					    assert(configGetStub.calledOnceWith('system-tray-setting'));
 | 
				
			||||||
    sinon.assert.notCalled(sqlCallStub);
 | 
					 | 
				
			||||||
  });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  it('only kicks off one request to the database if multiple sources ask at once', async () => {
 | 
					 | 
				
			||||||
    sandbox.stub(process, 'platform').value('win32');
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    const cache = new SystemTraySettingCache(sql, config, [], '1.2.3');
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    await Promise.all([cache.get(), cache.get(), cache.get()]);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert(configGetStub.calledOnceWith('system-tray-setting'));
 | 
					 | 
				
			||||||
    sinon.assert.calledOnce(sqlCallStub);
 | 
					 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  it('returns DoNotUseSystemTray if system tray is unsupported and there are no CLI flags', async () => {
 | 
					  it('returns DoNotUseSystemTray if system tray is unsupported and there are no CLI flags', async () => {
 | 
				
			||||||
    sandbox.stub(process, 'platform').value('darwin');
 | 
					    sandbox.stub(process, 'platform').value('darwin');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const cache = new SystemTraySettingCache(sql, config, [], '1.2.3');
 | 
					    const cache = new SystemTraySettingCache(config, [], '1.2.3');
 | 
				
			||||||
    assert.strictEqual(await cache.get(), SystemTraySetting.DoNotUseSystemTray);
 | 
					    assert.strictEqual(await cache.get(), SystemTraySetting.DoNotUseSystemTray);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    sinon.assert.notCalled(configGetStub);
 | 
					    sinon.assert.notCalled(configGetStub);
 | 
				
			||||||
    sinon.assert.notCalled(configSetStub);
 | 
					    sinon.assert.notCalled(configSetStub);
 | 
				
			||||||
    sinon.assert.notCalled(sqlCallStub);
 | 
					 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										6
									
								
								ts/types/Storage.d.ts
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										6
									
								
								ts/types/Storage.d.ts
									
										
									
									
										vendored
									
									
								
							| 
						 | 
					@ -11,7 +11,6 @@ import type { PhoneNumberDiscoverability } from '../util/phoneNumberDiscoverabil
 | 
				
			||||||
import type { PhoneNumberSharingMode } from '../util/phoneNumberSharingMode';
 | 
					import type { PhoneNumberSharingMode } from '../util/phoneNumberSharingMode';
 | 
				
			||||||
import type { RetryItemType } from '../util/retryPlaceholders';
 | 
					import type { RetryItemType } from '../util/retryPlaceholders';
 | 
				
			||||||
import type { ConfigMapType as RemoteConfigType } from '../RemoteConfig';
 | 
					import type { ConfigMapType as RemoteConfigType } from '../RemoteConfig';
 | 
				
			||||||
import type { SystemTraySetting } from './SystemTraySetting';
 | 
					 | 
				
			||||||
import type { ExtendedStorageID, UnknownRecord } from './StorageService.d';
 | 
					import type { ExtendedStorageID, UnknownRecord } from './StorageService.d';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import type { GroupCredentialType } from '../textsecure/WebAPI';
 | 
					import type { GroupCredentialType } from '../textsecure/WebAPI';
 | 
				
			||||||
| 
						 | 
					@ -19,7 +18,6 @@ import type {
 | 
				
			||||||
  SessionResetsType,
 | 
					  SessionResetsType,
 | 
				
			||||||
  StorageServiceCredentials,
 | 
					  StorageServiceCredentials,
 | 
				
			||||||
} from '../textsecure/Types.d';
 | 
					} from '../textsecure/Types.d';
 | 
				
			||||||
import type { ThemeSettingType } from './StorageUIKeys';
 | 
					 | 
				
			||||||
import type { ServiceIdString } from './ServiceId';
 | 
					import type { ServiceIdString } from './ServiceId';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import type { RegisteredChallengeType } from '../challenge';
 | 
					import type { RegisteredChallengeType } from '../challenge';
 | 
				
			||||||
| 
						 | 
					@ -57,14 +55,10 @@ export type StorageAccessType = {
 | 
				
			||||||
  'call-system-notification': boolean;
 | 
					  'call-system-notification': boolean;
 | 
				
			||||||
  'hide-menu-bar': boolean;
 | 
					  'hide-menu-bar': boolean;
 | 
				
			||||||
  'incoming-call-notification': boolean;
 | 
					  'incoming-call-notification': boolean;
 | 
				
			||||||
  localeOverride: string | null;
 | 
					 | 
				
			||||||
  'notification-draw-attention': boolean;
 | 
					  'notification-draw-attention': boolean;
 | 
				
			||||||
  'notification-setting': NotificationSettingType;
 | 
					  'notification-setting': NotificationSettingType;
 | 
				
			||||||
  'read-receipt-setting': boolean;
 | 
					  'read-receipt-setting': boolean;
 | 
				
			||||||
  'sent-media-quality': SentMediaQualitySettingType;
 | 
					  'sent-media-quality': SentMediaQualitySettingType;
 | 
				
			||||||
  'spell-check': boolean;
 | 
					 | 
				
			||||||
  'system-tray-setting': SystemTraySetting;
 | 
					 | 
				
			||||||
  'theme-setting': ThemeSettingType;
 | 
					 | 
				
			||||||
  audioMessage: boolean;
 | 
					  audioMessage: boolean;
 | 
				
			||||||
  attachmentMigration_isComplete: boolean;
 | 
					  attachmentMigration_isComplete: boolean;
 | 
				
			||||||
  attachmentMigration_lastProcessedIndex: number;
 | 
					  attachmentMigration_lastProcessedIndex: number;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -25,7 +25,6 @@ export const STORAGE_UI_KEYS: ReadonlyArray<keyof StorageAccessType> = [
 | 
				
			||||||
  'hasCompletedUsernameLinkOnboarding',
 | 
					  'hasCompletedUsernameLinkOnboarding',
 | 
				
			||||||
  'hide-menu-bar',
 | 
					  'hide-menu-bar',
 | 
				
			||||||
  'incoming-call-notification',
 | 
					  'incoming-call-notification',
 | 
				
			||||||
  'localeOverride',
 | 
					 | 
				
			||||||
  'navTabsCollapsed',
 | 
					  'navTabsCollapsed',
 | 
				
			||||||
  'notification-draw-attention',
 | 
					  'notification-draw-attention',
 | 
				
			||||||
  'notification-setting',
 | 
					  'notification-setting',
 | 
				
			||||||
| 
						 | 
					@ -40,10 +39,7 @@ export const STORAGE_UI_KEYS: ReadonlyArray<keyof StorageAccessType> = [
 | 
				
			||||||
  'showStickerPickerHint',
 | 
					  'showStickerPickerHint',
 | 
				
			||||||
  'showStickersIntroduction',
 | 
					  'showStickersIntroduction',
 | 
				
			||||||
  'skinTone',
 | 
					  'skinTone',
 | 
				
			||||||
  'spell-check',
 | 
					 | 
				
			||||||
  'system-tray-setting',
 | 
					 | 
				
			||||||
  'textFormatting',
 | 
					  'textFormatting',
 | 
				
			||||||
  'theme-setting',
 | 
					 | 
				
			||||||
  'version',
 | 
					  'version',
 | 
				
			||||||
  'zoomFactor',
 | 
					  'zoomFactor',
 | 
				
			||||||
];
 | 
					];
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -14,8 +14,6 @@ import type {
 | 
				
			||||||
import { DEFAULT_CONVERSATION_COLOR } from '../types/Colors';
 | 
					import { DEFAULT_CONVERSATION_COLOR } from '../types/Colors';
 | 
				
			||||||
import * as Errors from '../types/errors';
 | 
					import * as Errors from '../types/errors';
 | 
				
			||||||
import * as Stickers from '../types/Stickers';
 | 
					import * as Stickers from '../types/Stickers';
 | 
				
			||||||
import type { SystemTraySetting } from '../types/SystemTraySetting';
 | 
					 | 
				
			||||||
import { parseSystemTraySetting } from '../types/SystemTraySetting';
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
import type { ConversationType } from '../state/ducks/conversations';
 | 
					import type { ConversationType } from '../state/ducks/conversations';
 | 
				
			||||||
import type { AuthorizeArtCreatorDataType } from '../state/ducks/globalModals';
 | 
					import type { AuthorizeArtCreatorDataType } from '../state/ducks/globalModals';
 | 
				
			||||||
| 
						 | 
					@ -45,9 +43,15 @@ import { fromWebSafeBase64 } from './webSafeBase64';
 | 
				
			||||||
import { getConversation } from './getConversation';
 | 
					import { getConversation } from './getConversation';
 | 
				
			||||||
import { instance, PhoneNumberFormat } from './libphonenumberInstance';
 | 
					import { instance, PhoneNumberFormat } from './libphonenumberInstance';
 | 
				
			||||||
import { showConfirmationDialog } from './showConfirmationDialog';
 | 
					import { showConfirmationDialog } from './showConfirmationDialog';
 | 
				
			||||||
 | 
					import type {
 | 
				
			||||||
 | 
					  EphemeralSettings,
 | 
				
			||||||
 | 
					  SettingsValuesType,
 | 
				
			||||||
 | 
					  ThemeType,
 | 
				
			||||||
 | 
					} from './preload';
 | 
				
			||||||
 | 
					import type { SystemTraySetting } from '../types/SystemTraySetting';
 | 
				
			||||||
 | 
					import { drop } from './drop';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type SentMediaQualityType = 'standard' | 'high';
 | 
					type SentMediaQualityType = 'standard' | 'high';
 | 
				
			||||||
type ThemeType = 'light' | 'dark' | 'system';
 | 
					 | 
				
			||||||
type NotificationSettingType = 'message' | 'name' | 'count' | 'off';
 | 
					type NotificationSettingType = 'message' | 'name' | 'count' | 'off';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export type IPCEventsValuesType = {
 | 
					export type IPCEventsValuesType = {
 | 
				
			||||||
| 
						 | 
					@ -64,17 +68,13 @@ export type IPCEventsValuesType = {
 | 
				
			||||||
  hideMenuBar: boolean | undefined;
 | 
					  hideMenuBar: boolean | undefined;
 | 
				
			||||||
  incomingCallNotification: boolean;
 | 
					  incomingCallNotification: boolean;
 | 
				
			||||||
  lastSyncTime: number | undefined;
 | 
					  lastSyncTime: number | undefined;
 | 
				
			||||||
  localeOverride: string | null;
 | 
					 | 
				
			||||||
  notificationDrawAttention: boolean;
 | 
					  notificationDrawAttention: boolean;
 | 
				
			||||||
  notificationSetting: NotificationSettingType;
 | 
					  notificationSetting: NotificationSettingType;
 | 
				
			||||||
  preferredAudioInputDevice: AudioDevice | undefined;
 | 
					  preferredAudioInputDevice: AudioDevice | undefined;
 | 
				
			||||||
  preferredAudioOutputDevice: AudioDevice | undefined;
 | 
					  preferredAudioOutputDevice: AudioDevice | undefined;
 | 
				
			||||||
  preferredVideoInputDevice: string | undefined;
 | 
					  preferredVideoInputDevice: string | undefined;
 | 
				
			||||||
  sentMediaQualitySetting: SentMediaQualityType;
 | 
					  sentMediaQualitySetting: SentMediaQualityType;
 | 
				
			||||||
  spellCheck: boolean;
 | 
					 | 
				
			||||||
  systemTraySetting: SystemTraySetting;
 | 
					 | 
				
			||||||
  textFormatting: boolean;
 | 
					  textFormatting: boolean;
 | 
				
			||||||
  themeSetting: ThemeType;
 | 
					 | 
				
			||||||
  universalExpireTimer: DurationInSeconds;
 | 
					  universalExpireTimer: DurationInSeconds;
 | 
				
			||||||
  zoomFactor: ZoomFactorType;
 | 
					  zoomFactor: ZoomFactorType;
 | 
				
			||||||
  storyViewReceiptsEnabled: boolean;
 | 
					  storyViewReceiptsEnabled: boolean;
 | 
				
			||||||
| 
						 | 
					@ -144,17 +144,21 @@ export type IPCEventsCallbacksType = {
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type ValuesWithGetters = Omit<
 | 
					type ValuesWithGetters = Omit<
 | 
				
			||||||
  IPCEventsValuesType,
 | 
					  SettingsValuesType,
 | 
				
			||||||
  // Async
 | 
					  // Async
 | 
				
			||||||
  | 'zoomFactor'
 | 
					  | 'zoomFactor'
 | 
				
			||||||
 | 
					  | 'localeOverride'
 | 
				
			||||||
 | 
					  | 'spellCheck'
 | 
				
			||||||
 | 
					  | 'themeSetting'
 | 
				
			||||||
  // Optional
 | 
					  // Optional
 | 
				
			||||||
  | 'mediaPermissions'
 | 
					  | 'mediaPermissions'
 | 
				
			||||||
  | 'mediaCameraPermissions'
 | 
					  | 'mediaCameraPermissions'
 | 
				
			||||||
  | 'autoLaunch'
 | 
					  | 'autoLaunch'
 | 
				
			||||||
 | 
					  | 'systemTraySetting'
 | 
				
			||||||
>;
 | 
					>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type ValuesWithSetters = Omit<
 | 
					type ValuesWithSetters = Omit<
 | 
				
			||||||
  IPCEventsValuesType,
 | 
					  SettingsValuesType,
 | 
				
			||||||
  | 'blockedCount'
 | 
					  | 'blockedCount'
 | 
				
			||||||
  | 'defaultConversationColor'
 | 
					  | 'defaultConversationColor'
 | 
				
			||||||
  | 'linkPreviewSetting'
 | 
					  | 'linkPreviewSetting'
 | 
				
			||||||
| 
						 | 
					@ -166,19 +170,37 @@ type ValuesWithSetters = Omit<
 | 
				
			||||||
  // Optional
 | 
					  // Optional
 | 
				
			||||||
  | 'mediaPermissions'
 | 
					  | 'mediaPermissions'
 | 
				
			||||||
  | 'mediaCameraPermissions'
 | 
					  | 'mediaCameraPermissions'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Only set in the Settings window
 | 
				
			||||||
 | 
					  | 'localeOverride'
 | 
				
			||||||
 | 
					  | 'spellCheck'
 | 
				
			||||||
 | 
					  | 'systemTraySetting'
 | 
				
			||||||
>;
 | 
					>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export type IPCEventGetterType<Key extends keyof IPCEventsValuesType> =
 | 
					export type IPCEventsUpdatersType = {
 | 
				
			||||||
 | 
					  [Key in keyof EphemeralSettings as IPCEventUpdaterType<Key>]?: (
 | 
				
			||||||
 | 
					    value: EphemeralSettings[Key]
 | 
				
			||||||
 | 
					  ) => void;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export type IPCEventGetterType<Key extends keyof SettingsValuesType> =
 | 
				
			||||||
  `get${Capitalize<Key>}`;
 | 
					  `get${Capitalize<Key>}`;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export type IPCEventSetterType<Key extends keyof IPCEventsValuesType> =
 | 
					export type IPCEventSetterType<Key extends keyof SettingsValuesType> =
 | 
				
			||||||
  `set${Capitalize<Key>}`;
 | 
					  `set${Capitalize<Key>}`;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export type IPCEventUpdaterType<Key extends keyof SettingsValuesType> =
 | 
				
			||||||
 | 
					  `update${Capitalize<Key>}`;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export type IPCEventsGettersType = {
 | 
					export type IPCEventsGettersType = {
 | 
				
			||||||
  [Key in keyof ValuesWithGetters as IPCEventGetterType<Key>]: () => ValuesWithGetters[Key];
 | 
					  [Key in keyof ValuesWithGetters as IPCEventGetterType<Key>]: () => ValuesWithGetters[Key];
 | 
				
			||||||
} & {
 | 
					} & {
 | 
				
			||||||
  // Async
 | 
					  // Async
 | 
				
			||||||
  getZoomFactor: () => Promise<ZoomFactorType>;
 | 
					  getZoomFactor: () => Promise<ZoomFactorType>;
 | 
				
			||||||
 | 
					  getLocaleOverride: () => Promise<string | null>;
 | 
				
			||||||
 | 
					  getSpellCheck: () => Promise<boolean>;
 | 
				
			||||||
 | 
					  getSystemTraySetting: () => Promise<SystemTraySetting>;
 | 
				
			||||||
 | 
					  getThemeSetting: () => Promise<ThemeType>;
 | 
				
			||||||
  // Events
 | 
					  // Events
 | 
				
			||||||
  onZoomFactorChange: (callback: (zoomFactor: ZoomFactorType) => void) => void;
 | 
					  onZoomFactorChange: (callback: (zoomFactor: ZoomFactorType) => void) => void;
 | 
				
			||||||
  // Optional
 | 
					  // Optional
 | 
				
			||||||
| 
						 | 
					@ -198,6 +220,7 @@ export type IPCEventsSettersType = {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export type IPCEventsType = IPCEventsGettersType &
 | 
					export type IPCEventsType = IPCEventsGettersType &
 | 
				
			||||||
  IPCEventsSettersType &
 | 
					  IPCEventsSettersType &
 | 
				
			||||||
 | 
					  IPCEventsUpdatersType &
 | 
				
			||||||
  IPCEventsCallbacksType;
 | 
					  IPCEventsCallbacksType;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export function createIPCEvents(
 | 
					export function createIPCEvents(
 | 
				
			||||||
| 
						 | 
					@ -393,11 +416,14 @@ export function createIPCEvents(
 | 
				
			||||||
      window.storage.get('sent-media-quality', 'standard'),
 | 
					      window.storage.get('sent-media-quality', 'standard'),
 | 
				
			||||||
    setSentMediaQualitySetting: value =>
 | 
					    setSentMediaQualitySetting: value =>
 | 
				
			||||||
      window.storage.put('sent-media-quality', value),
 | 
					      window.storage.put('sent-media-quality', value),
 | 
				
			||||||
    getThemeSetting: () => window.storage.get('theme-setting', 'system'),
 | 
					    getThemeSetting: async () => {
 | 
				
			||||||
    setThemeSetting: value => {
 | 
					      return getEphemeralSetting('themeSetting') ?? null;
 | 
				
			||||||
      const promise = window.storage.put('theme-setting', value);
 | 
					    },
 | 
				
			||||||
      themeChanged();
 | 
					    setThemeSetting: async value => {
 | 
				
			||||||
      return promise;
 | 
					      drop(setEphemeralSetting('themeSetting', value));
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    updateThemeSetting: _theme => {
 | 
				
			||||||
 | 
					      drop(themeChanged());
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    getHideMenuBar: () => window.storage.get('hide-menu-bar'),
 | 
					    getHideMenuBar: () => window.storage.get('hide-menu-bar'),
 | 
				
			||||||
    setHideMenuBar: value => {
 | 
					    setHideMenuBar: value => {
 | 
				
			||||||
| 
						 | 
					@ -406,19 +432,9 @@ export function createIPCEvents(
 | 
				
			||||||
      window.IPC.setMenuBarVisibility(!value);
 | 
					      window.IPC.setMenuBarVisibility(!value);
 | 
				
			||||||
      return promise;
 | 
					      return promise;
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    getSystemTraySetting: () =>
 | 
					    getSystemTraySetting: () => getEphemeralSetting('systemTraySetting'),
 | 
				
			||||||
      parseSystemTraySetting(window.storage.get('system-tray-setting')),
 | 
					    getLocaleOverride: async () => {
 | 
				
			||||||
    setSystemTraySetting: value => {
 | 
					      return getEphemeralSetting('localeOverride') ?? null;
 | 
				
			||||||
      const promise = window.storage.put('system-tray-setting', value);
 | 
					 | 
				
			||||||
      window.IPC.updateSystemTraySetting(value);
 | 
					 | 
				
			||||||
      return promise;
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    getLocaleOverride: () => {
 | 
					 | 
				
			||||||
      return window.storage.get('localeOverride') ?? null;
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    setLocaleOverride: async (locale: string | null) => {
 | 
					 | 
				
			||||||
      await window.storage.put('localeOverride', locale);
 | 
					 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    getNotificationSetting: () =>
 | 
					    getNotificationSetting: () =>
 | 
				
			||||||
      window.storage.get('notification-setting', 'message'),
 | 
					      window.storage.get('notification-setting', 'message'),
 | 
				
			||||||
| 
						 | 
					@ -456,8 +472,9 @@ export function createIPCEvents(
 | 
				
			||||||
    setIncomingCallNotification: value =>
 | 
					    setIncomingCallNotification: value =>
 | 
				
			||||||
      window.storage.put('incoming-call-notification', value),
 | 
					      window.storage.put('incoming-call-notification', value),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    getSpellCheck: () => window.storage.get('spell-check', true),
 | 
					    getSpellCheck: () => {
 | 
				
			||||||
    setSpellCheck: value => window.storage.put('spell-check', value),
 | 
					      return getEphemeralSetting('spellCheck');
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
    getTextFormatting: () => window.storage.get('textFormatting', true),
 | 
					    getTextFormatting: () => window.storage.get('textFormatting', true),
 | 
				
			||||||
    setTextFormatting: value => window.storage.put('textFormatting', value),
 | 
					    setTextFormatting: value => window.storage.put('textFormatting', value),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -709,3 +726,16 @@ function showUnknownSgnlLinkModal(): void {
 | 
				
			||||||
    description: window.i18n('icu:unknown-sgnl-link'),
 | 
					    description: window.i18n('icu:unknown-sgnl-link'),
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function getEphemeralSetting<Name extends keyof EphemeralSettings>(
 | 
				
			||||||
 | 
					  name: Name
 | 
				
			||||||
 | 
					): Promise<EphemeralSettings[Name]> {
 | 
				
			||||||
 | 
					  return ipcRenderer.invoke(`settings:get:${name}`);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function setEphemeralSetting<Name extends keyof EphemeralSettings>(
 | 
				
			||||||
 | 
					  name: Name,
 | 
				
			||||||
 | 
					  value: EphemeralSettings[Name]
 | 
				
			||||||
 | 
					): Promise<void> {
 | 
				
			||||||
 | 
					  return ipcRenderer.invoke(`settings:set:${name}`, value);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3,8 +3,8 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import { ThemeType } from '../types/Util';
 | 
					import { ThemeType } from '../types/Util';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export function getThemeType(): ThemeType {
 | 
					export async function getThemeType(): Promise<ThemeType> {
 | 
				
			||||||
  const themeSetting = window.Events.getThemeSetting();
 | 
					  const themeSetting = await window.Events.getThemeSetting();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (themeSetting === 'light') {
 | 
					  if (themeSetting === 'light') {
 | 
				
			||||||
    return ThemeType.light;
 | 
					    return ThemeType.light;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -9,9 +9,8 @@ import type { UnwrapPromise } from '../types/Util';
 | 
				
			||||||
import type {
 | 
					import type {
 | 
				
			||||||
  IPCEventsValuesType,
 | 
					  IPCEventsValuesType,
 | 
				
			||||||
  IPCEventsCallbacksType,
 | 
					  IPCEventsCallbacksType,
 | 
				
			||||||
  IPCEventGetterType,
 | 
					 | 
				
			||||||
  IPCEventSetterType,
 | 
					 | 
				
			||||||
} from './createIPCEvents';
 | 
					} from './createIPCEvents';
 | 
				
			||||||
 | 
					import type { SystemTraySetting } from '../types/SystemTraySetting';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type SettingOptionsType = {
 | 
					type SettingOptionsType = {
 | 
				
			||||||
  getter?: boolean;
 | 
					  getter?: boolean;
 | 
				
			||||||
| 
						 | 
					@ -23,7 +22,27 @@ export type SettingType<Value> = Readonly<{
 | 
				
			||||||
  setValue: (value: Value) => Promise<Value>;
 | 
					  setValue: (value: Value) => Promise<Value>;
 | 
				
			||||||
}>;
 | 
					}>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function capitalize<Name extends keyof IPCEventsValuesType>(
 | 
					export type ThemeType = 'light' | 'dark' | 'system';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export type EphemeralSettings = {
 | 
				
			||||||
 | 
					  spellCheck: boolean;
 | 
				
			||||||
 | 
					  systemTraySetting: SystemTraySetting;
 | 
				
			||||||
 | 
					  themeSetting: ThemeType;
 | 
				
			||||||
 | 
					  localeOverride: string | null;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export type SettingsValuesType = IPCEventsValuesType & EphemeralSettings;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type SettingGetterType<Key extends keyof SettingsValuesType> =
 | 
				
			||||||
 | 
					  `get${Capitalize<Key>}`;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type SettingSetterType<Key extends keyof SettingsValuesType> =
 | 
				
			||||||
 | 
					  `set${Capitalize<Key>}`;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type SettingUpdaterType<Key extends keyof SettingsValuesType> =
 | 
				
			||||||
 | 
					  `update${Capitalize<Key>}`;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function capitalize<Name extends keyof SettingsValuesType>(
 | 
				
			||||||
  name: Name
 | 
					  name: Name
 | 
				
			||||||
): Capitalize<Name> {
 | 
					): Capitalize<Name> {
 | 
				
			||||||
  const result = name.slice(0, 1).toUpperCase() + name.slice(1);
 | 
					  const result = name.slice(0, 1).toUpperCase() + name.slice(1);
 | 
				
			||||||
| 
						 | 
					@ -31,21 +50,27 @@ function capitalize<Name extends keyof IPCEventsValuesType>(
 | 
				
			||||||
  return result as Capitalize<Name>;
 | 
					  return result as Capitalize<Name>;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function getSetterName<Key extends keyof IPCEventsValuesType>(
 | 
					function getSetterName<Key extends keyof SettingsValuesType>(
 | 
				
			||||||
  name: Key
 | 
					  name: Key
 | 
				
			||||||
): IPCEventSetterType<Key> {
 | 
					): SettingSetterType<Key> {
 | 
				
			||||||
  return `set${capitalize(name)}`;
 | 
					  return `set${capitalize(name)}`;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function getGetterName<Key extends keyof IPCEventsValuesType>(
 | 
					function getGetterName<Key extends keyof SettingsValuesType>(
 | 
				
			||||||
  name: Key
 | 
					  name: Key
 | 
				
			||||||
): IPCEventGetterType<Key> {
 | 
					): SettingGetterType<Key> {
 | 
				
			||||||
  return `get${capitalize(name)}`;
 | 
					  return `get${capitalize(name)}`;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function getUpdaterName<Key extends keyof EphemeralSettings>(
 | 
				
			||||||
 | 
					  name: Key
 | 
				
			||||||
 | 
					): SettingUpdaterType<Key> {
 | 
				
			||||||
 | 
					  return `update${capitalize(name)}`;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export function createSetting<
 | 
					export function createSetting<
 | 
				
			||||||
  Name extends keyof IPCEventsValuesType,
 | 
					  Name extends keyof SettingsValuesType,
 | 
				
			||||||
  Value extends IPCEventsValuesType[Name]
 | 
					  Value extends SettingsValuesType[Name]
 | 
				
			||||||
>(name: Name, overrideOptions: SettingOptionsType = {}): SettingType<Value> {
 | 
					>(name: Name, overrideOptions: SettingOptionsType = {}): SettingType<Value> {
 | 
				
			||||||
  const options = {
 | 
					  const options = {
 | 
				
			||||||
    getter: true,
 | 
					    getter: true,
 | 
				
			||||||
| 
						 | 
					@ -86,7 +111,7 @@ export function createCallback<
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export function installSetting(
 | 
					export function installSetting(
 | 
				
			||||||
  name: keyof IPCEventsValuesType,
 | 
					  name: keyof SettingsValuesType,
 | 
				
			||||||
  { getter = true, setter = true }: { getter?: boolean; setter?: boolean } = {}
 | 
					  { getter = true, setter = true }: { getter?: boolean; setter?: boolean } = {}
 | 
				
			||||||
): void {
 | 
					): void {
 | 
				
			||||||
  const getterName = getGetterName(name);
 | 
					  const getterName = getGetterName(name);
 | 
				
			||||||
| 
						 | 
					@ -135,6 +160,21 @@ export function installSetting(
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export function installEphemeralSetting(name: keyof EphemeralSettings): void {
 | 
				
			||||||
 | 
					  installSetting(name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const updaterName = getUpdaterName(name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  ipcRenderer.on(`settings:update:${name}`, async (_event, value) => {
 | 
				
			||||||
 | 
					    const updateFn = window.Events[updaterName] as (value: unknown) => void;
 | 
				
			||||||
 | 
					    if (!updateFn) {
 | 
				
			||||||
 | 
					      return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    await updateFn(value);
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export function installCallback<Name extends keyof IPCEventsCallbacksType>(
 | 
					export function installCallback<Name extends keyof IPCEventsCallbacksType>(
 | 
				
			||||||
  name: Name
 | 
					  name: Name
 | 
				
			||||||
): void {
 | 
					): void {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										2
									
								
								ts/window.d.ts
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								ts/window.d.ts
									
										
									
									
										vendored
									
									
								
							| 
						 | 
					@ -41,7 +41,6 @@ import type { SocketStatus } from './types/SocketStatus';
 | 
				
			||||||
import type SyncRequest from './textsecure/SyncRequest';
 | 
					import type SyncRequest from './textsecure/SyncRequest';
 | 
				
			||||||
import type { MessageCache } from './services/MessageCache';
 | 
					import type { MessageCache } from './services/MessageCache';
 | 
				
			||||||
import type { StateType } from './state/reducer';
 | 
					import type { StateType } from './state/reducer';
 | 
				
			||||||
import type { SystemTraySetting } from './types/SystemTraySetting';
 | 
					 | 
				
			||||||
import type { Address } from './types/Address';
 | 
					import type { Address } from './types/Address';
 | 
				
			||||||
import type { QualifiedAddress } from './types/QualifiedAddress';
 | 
					import type { QualifiedAddress } from './types/QualifiedAddress';
 | 
				
			||||||
import type { CIType } from './CI';
 | 
					import type { CIType } from './CI';
 | 
				
			||||||
| 
						 | 
					@ -88,7 +87,6 @@ export type IPCType = {
 | 
				
			||||||
  showWindowsNotification: (data: WindowsNotificationData) => Promise<void>;
 | 
					  showWindowsNotification: (data: WindowsNotificationData) => Promise<void>;
 | 
				
			||||||
  shutdown: () => void;
 | 
					  shutdown: () => void;
 | 
				
			||||||
  titleBarDoubleClick: () => void;
 | 
					  titleBarDoubleClick: () => void;
 | 
				
			||||||
  updateSystemTraySetting: (value: SystemTraySetting) => void;
 | 
					 | 
				
			||||||
  updateTrayIcon: (count: number) => void;
 | 
					  updateTrayIcon: (count: number) => void;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -5,11 +5,10 @@ import { ipcRenderer } from 'electron';
 | 
				
			||||||
import type { MenuItemConstructorOptions } from 'electron';
 | 
					import type { MenuItemConstructorOptions } from 'electron';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import type { MenuOptionsType } from '../types/menu';
 | 
					import type { MenuOptionsType } from '../types/menu';
 | 
				
			||||||
import type { IPCEventsValuesType } from '../util/createIPCEvents';
 | 
					 | 
				
			||||||
import type { LocalizerType } from '../types/Util';
 | 
					import type { LocalizerType } from '../types/Util';
 | 
				
			||||||
import type { LoggerType } from '../types/Logging';
 | 
					import type { LoggerType } from '../types/Logging';
 | 
				
			||||||
import type { NativeThemeType } from '../context/createNativeThemeListener';
 | 
					import type { NativeThemeType } from '../context/createNativeThemeListener';
 | 
				
			||||||
import type { SettingType } from '../util/preload';
 | 
					import type { SettingType, SettingsValuesType } from '../util/preload';
 | 
				
			||||||
import type { RendererConfigType } from '../types/RendererConfig';
 | 
					import type { RendererConfigType } from '../types/RendererConfig';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import { Bytes } from '../context/Bytes';
 | 
					import { Bytes } from '../context/Bytes';
 | 
				
			||||||
| 
						 | 
					@ -58,7 +57,7 @@ export type MinimalSignalContextType = {
 | 
				
			||||||
  nativeThemeListener: NativeThemeType;
 | 
					  nativeThemeListener: NativeThemeType;
 | 
				
			||||||
  restartApp: () => void;
 | 
					  restartApp: () => void;
 | 
				
			||||||
  Settings: {
 | 
					  Settings: {
 | 
				
			||||||
    themeSetting: SettingType<IPCEventsValuesType['themeSetting']>;
 | 
					    themeSetting: SettingType<SettingsValuesType['themeSetting']>;
 | 
				
			||||||
    waitForChange: () => Promise<void>;
 | 
					    waitForChange: () => Promise<void>;
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
  OS: {
 | 
					  OS: {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -127,11 +127,6 @@ const IPC: IPCType = {
 | 
				
			||||||
  titleBarDoubleClick: () => {
 | 
					  titleBarDoubleClick: () => {
 | 
				
			||||||
    ipc.send('title-bar-double-click');
 | 
					    ipc.send('title-bar-double-click');
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  updateSystemTraySetting: (
 | 
					 | 
				
			||||||
    systemTraySetting /* : Readonly<SystemTraySetting> */
 | 
					 | 
				
			||||||
  ) => {
 | 
					 | 
				
			||||||
    void ipc.invoke('update-system-tray-setting', systemTraySetting);
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
  updateTrayIcon: unreadCount => ipc.send('update-tray-icon', unreadCount),
 | 
					  updateTrayIcon: unreadCount => ipc.send('update-tray-icon', unreadCount),
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -14,6 +14,7 @@ import { initMessageCleanup } from '../../services/messageStateCleanup';
 | 
				
			||||||
import { initializeMessageCounter } from '../../util/incrementMessageCounter';
 | 
					import { initializeMessageCounter } from '../../util/incrementMessageCounter';
 | 
				
			||||||
import { initializeRedux } from '../../state/initializeRedux';
 | 
					import { initializeRedux } from '../../state/initializeRedux';
 | 
				
			||||||
import * as Stickers from '../../types/Stickers';
 | 
					import * as Stickers from '../../types/Stickers';
 | 
				
			||||||
 | 
					import { ThemeType } from '../../types/Util';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
window.assert = assert;
 | 
					window.assert = assert;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -51,6 +52,7 @@ window.testUtilities = {
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
      stories: [],
 | 
					      stories: [],
 | 
				
			||||||
      storyDistributionLists: [],
 | 
					      storyDistributionLists: [],
 | 
				
			||||||
 | 
					      theme: ThemeType.dark,
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,7 +1,11 @@
 | 
				
			||||||
// Copyright 2017 Signal Messenger, LLC
 | 
					// Copyright 2017 Signal Messenger, LLC
 | 
				
			||||||
// SPDX-License-Identifier: AGPL-3.0-only
 | 
					// SPDX-License-Identifier: AGPL-3.0-only
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import { installCallback, installSetting } from '../util/preload';
 | 
					import {
 | 
				
			||||||
 | 
					  installCallback,
 | 
				
			||||||
 | 
					  installSetting,
 | 
				
			||||||
 | 
					  installEphemeralSetting,
 | 
				
			||||||
 | 
					} from '../util/preload';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// ChatColorPicker redux hookups
 | 
					// ChatColorPicker redux hookups
 | 
				
			||||||
installCallback('getCustomColors');
 | 
					installCallback('getCustomColors');
 | 
				
			||||||
| 
						 | 
					@ -48,14 +52,10 @@ installSetting('hasStoriesDisabled');
 | 
				
			||||||
installSetting('hideMenuBar');
 | 
					installSetting('hideMenuBar');
 | 
				
			||||||
installSetting('incomingCallNotification');
 | 
					installSetting('incomingCallNotification');
 | 
				
			||||||
installSetting('lastSyncTime');
 | 
					installSetting('lastSyncTime');
 | 
				
			||||||
installSetting('localeOverride');
 | 
					 | 
				
			||||||
installSetting('notificationDrawAttention');
 | 
					installSetting('notificationDrawAttention');
 | 
				
			||||||
installSetting('notificationSetting');
 | 
					installSetting('notificationSetting');
 | 
				
			||||||
installSetting('spellCheck');
 | 
					 | 
				
			||||||
installSetting('systemTraySetting');
 | 
					 | 
				
			||||||
installSetting('sentMediaQualitySetting');
 | 
					installSetting('sentMediaQualitySetting');
 | 
				
			||||||
installSetting('textFormatting');
 | 
					installSetting('textFormatting');
 | 
				
			||||||
installSetting('themeSetting');
 | 
					 | 
				
			||||||
installSetting('universalExpireTimer');
 | 
					installSetting('universalExpireTimer');
 | 
				
			||||||
installSetting('zoomFactor');
 | 
					installSetting('zoomFactor');
 | 
				
			||||||
installSetting('phoneNumberDiscoverabilitySetting');
 | 
					installSetting('phoneNumberDiscoverabilitySetting');
 | 
				
			||||||
| 
						 | 
					@ -66,3 +66,8 @@ installCallback('getAvailableIODevices');
 | 
				
			||||||
installSetting('preferredAudioInputDevice');
 | 
					installSetting('preferredAudioInputDevice');
 | 
				
			||||||
installSetting('preferredAudioOutputDevice');
 | 
					installSetting('preferredAudioOutputDevice');
 | 
				
			||||||
installSetting('preferredVideoInputDevice');
 | 
					installSetting('preferredVideoInputDevice');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					installEphemeralSetting('themeSetting');
 | 
				
			||||||
 | 
					installEphemeralSetting('systemTraySetting');
 | 
				
			||||||
 | 
					installEphemeralSetting('localeOverride');
 | 
				
			||||||
 | 
					installEphemeralSetting('spellCheck');
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue