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…
Reference in a new issue