Get native theme through IPC not remote
This commit is contained in:
parent
d2cc8e5aa9
commit
71572db7a9
16 changed files with 227 additions and 60 deletions
|
@ -15,7 +15,7 @@ const {
|
||||||
|
|
||||||
const { Context: SignalContext } = require('./ts/context');
|
const { Context: SignalContext } = require('./ts/context');
|
||||||
|
|
||||||
window.SignalContext = new SignalContext();
|
window.SignalContext = new SignalContext(ipcRenderer);
|
||||||
|
|
||||||
const config = url.parse(window.location.toString(), true).query;
|
const config = url.parse(window.location.toString(), true).query;
|
||||||
const { locale } = config;
|
const { locale } = config;
|
||||||
|
|
|
@ -20,7 +20,7 @@ async function applyTheme() {
|
||||||
|
|
||||||
applyTheme();
|
applyTheme();
|
||||||
|
|
||||||
window.subscribeToSystemThemeChange(() => {
|
window.SignalContext.nativeThemeListener.subscribe(() => {
|
||||||
applyTheme();
|
applyTheme();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,7 @@ async function applyTheme() {
|
||||||
|
|
||||||
applyTheme();
|
applyTheme();
|
||||||
|
|
||||||
window.subscribeToSystemThemeChange(() => {
|
window.SignalContext.nativeThemeListener.subscribe(() => {
|
||||||
applyTheme();
|
applyTheme();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
6
main.js
6
main.js
|
@ -122,6 +122,7 @@ const {
|
||||||
} = require('./ts/types/Settings');
|
} = require('./ts/types/Settings');
|
||||||
const { Environment } = require('./ts/environment');
|
const { Environment } = require('./ts/environment');
|
||||||
const { ChallengeMainHandler } = require('./ts/main/challengeMain');
|
const { ChallengeMainHandler } = require('./ts/main/challengeMain');
|
||||||
|
const { NativeThemeNotifier } = require('./ts/main/NativeThemeNotifier');
|
||||||
const { PowerChannel } = require('./ts/main/powerChannel');
|
const { PowerChannel } = require('./ts/main/powerChannel');
|
||||||
const { maybeParseUrl, setUrlSearchParams } = require('./ts/util/url');
|
const { maybeParseUrl, setUrlSearchParams } = require('./ts/util/url');
|
||||||
|
|
||||||
|
@ -136,6 +137,9 @@ const systemTraySettingCache = new SystemTraySettingCache(
|
||||||
|
|
||||||
const challengeHandler = new ChallengeMainHandler();
|
const challengeHandler = new ChallengeMainHandler();
|
||||||
|
|
||||||
|
const nativeThemeNotifier = new NativeThemeNotifier();
|
||||||
|
nativeThemeNotifier.initialize();
|
||||||
|
|
||||||
let sqlInitTimeStart = 0;
|
let sqlInitTimeStart = 0;
|
||||||
let sqlInitTimeEnd = 0;
|
let sqlInitTimeEnd = 0;
|
||||||
|
|
||||||
|
@ -303,6 +307,8 @@ function handleCommonWindowEvents(window) {
|
||||||
window.webContents.on('preload-error', (event, preloadPath, error) => {
|
window.webContents.on('preload-error', (event, preloadPath, error) => {
|
||||||
console.error(`Preload error in ${preloadPath}: `, error.message);
|
console.error(`Preload error in ${preloadPath}: `, error.message);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
nativeThemeNotifier.addWindow(window);
|
||||||
}
|
}
|
||||||
|
|
||||||
const DEFAULT_WIDTH = 800;
|
const DEFAULT_WIDTH = 800;
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
window.React = require('react');
|
window.React = require('react');
|
||||||
window.ReactDOM = require('react-dom');
|
window.ReactDOM = require('react-dom');
|
||||||
|
|
||||||
const { ipcRenderer, remote } = require('electron');
|
const { ipcRenderer } = require('electron');
|
||||||
const url = require('url');
|
const url = require('url');
|
||||||
const i18n = require('./js/modules/i18n');
|
const i18n = require('./js/modules/i18n');
|
||||||
const { ConfirmationDialog } = require('./ts/components/ConfirmationDialog');
|
const { ConfirmationDialog } = require('./ts/components/ConfirmationDialog');
|
||||||
|
@ -17,8 +17,6 @@ const {
|
||||||
parseEnvironment,
|
parseEnvironment,
|
||||||
} = require('./ts/environment');
|
} = require('./ts/environment');
|
||||||
|
|
||||||
const { nativeTheme } = remote.require('electron');
|
|
||||||
|
|
||||||
const { Context: SignalContext } = require('./ts/context');
|
const { Context: SignalContext } = require('./ts/context');
|
||||||
|
|
||||||
const config = url.parse(window.location.toString(), true).query;
|
const config = url.parse(window.location.toString(), true).query;
|
||||||
|
@ -26,7 +24,7 @@ const { locale } = config;
|
||||||
const localeMessages = ipcRenderer.sendSync('locale-data');
|
const localeMessages = ipcRenderer.sendSync('locale-data');
|
||||||
setEnvironment(parseEnvironment(config.environment));
|
setEnvironment(parseEnvironment(config.environment));
|
||||||
|
|
||||||
window.SignalContext = new SignalContext();
|
window.SignalContext = new SignalContext(ipcRenderer);
|
||||||
|
|
||||||
window.getEnvironment = getEnvironment;
|
window.getEnvironment = getEnvironment;
|
||||||
window.getVersion = () => config.version;
|
window.getVersion = () => config.version;
|
||||||
|
@ -40,19 +38,6 @@ window.Signal = {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
function setSystemTheme() {
|
|
||||||
window.systemTheme = nativeTheme.shouldUseDarkColors ? 'dark' : 'light';
|
|
||||||
}
|
|
||||||
|
|
||||||
setSystemTheme();
|
|
||||||
|
|
||||||
window.subscribeToSystemThemeChange = fn => {
|
|
||||||
nativeTheme.on('updated', () => {
|
|
||||||
setSystemTheme();
|
|
||||||
fn();
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
require('./ts/logging/set_up_renderer_logging').initialize();
|
require('./ts/logging/set_up_renderer_logging').initialize();
|
||||||
|
|
||||||
window.closePermissionsPopup = () =>
|
window.closePermissionsPopup = () =>
|
||||||
|
|
18
preload.js
18
preload.js
|
@ -19,14 +19,14 @@ try {
|
||||||
parseEnvironment,
|
parseEnvironment,
|
||||||
Environment,
|
Environment,
|
||||||
} = require('./ts/environment');
|
} = require('./ts/environment');
|
||||||
|
const ipc = electron.ipcRenderer;
|
||||||
|
|
||||||
const { remote } = electron;
|
const { remote } = electron;
|
||||||
const { app } = remote;
|
const { app } = remote;
|
||||||
const { nativeTheme } = remote.require('electron');
|
|
||||||
|
|
||||||
const { Context: SignalContext } = require('./ts/context');
|
const { Context: SignalContext } = require('./ts/context');
|
||||||
|
|
||||||
window.SignalContext = new SignalContext();
|
window.SignalContext = new SignalContext(ipc);
|
||||||
|
|
||||||
window.sqlInitializer = require('./ts/sql/initialize');
|
window.sqlInitializer = require('./ts/sql/initialize');
|
||||||
|
|
||||||
|
@ -77,19 +77,6 @@ try {
|
||||||
app.setLoginItemSettings({ openAtLogin: Boolean(value) });
|
app.setLoginItemSettings({ openAtLogin: Boolean(value) });
|
||||||
};
|
};
|
||||||
|
|
||||||
function setSystemTheme() {
|
|
||||||
window.systemTheme = nativeTheme.shouldUseDarkColors ? 'dark' : 'light';
|
|
||||||
}
|
|
||||||
|
|
||||||
setSystemTheme();
|
|
||||||
|
|
||||||
window.subscribeToSystemThemeChange = fn => {
|
|
||||||
nativeTheme.on('updated', () => {
|
|
||||||
setSystemTheme();
|
|
||||||
fn();
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
window.isBeforeVersion = (toCheck, baseVersion) => {
|
window.isBeforeVersion = (toCheck, baseVersion) => {
|
||||||
try {
|
try {
|
||||||
return semver.lt(toCheck, baseVersion);
|
return semver.lt(toCheck, baseVersion);
|
||||||
|
@ -113,7 +100,6 @@ try {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const ipc = electron.ipcRenderer;
|
|
||||||
const localeMessages = ipc.sendSync('locale-data');
|
const localeMessages = ipc.sendSync('locale-data');
|
||||||
|
|
||||||
window.setBadgeCount = count => ipc.send('set-badge-count', count);
|
window.setBadgeCount = count => ipc.send('set-badge-count', count);
|
||||||
|
|
|
@ -20,7 +20,7 @@ const {
|
||||||
|
|
||||||
const { Context: SignalContext } = require('./ts/context');
|
const { Context: SignalContext } = require('./ts/context');
|
||||||
|
|
||||||
window.SignalContext = new SignalContext();
|
window.SignalContext = new SignalContext(ipcRenderer);
|
||||||
|
|
||||||
const config = url.parse(window.location.toString(), true).query;
|
const config = url.parse(window.location.toString(), true).query;
|
||||||
const { locale } = config;
|
const { locale } = config;
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
/* global window */
|
/* global window */
|
||||||
|
|
||||||
const { ipcRenderer, remote } = require('electron');
|
const { ipcRenderer } = require('electron');
|
||||||
|
|
||||||
const url = require('url');
|
const url = require('url');
|
||||||
const i18n = require('./js/modules/i18n');
|
const i18n = require('./js/modules/i18n');
|
||||||
|
@ -18,11 +18,9 @@ const { locale } = config;
|
||||||
const localeMessages = ipcRenderer.sendSync('locale-data');
|
const localeMessages = ipcRenderer.sendSync('locale-data');
|
||||||
setEnvironment(parseEnvironment(config.environment));
|
setEnvironment(parseEnvironment(config.environment));
|
||||||
|
|
||||||
const { nativeTheme } = remote.require('electron');
|
|
||||||
|
|
||||||
const { Context: SignalContext } = require('./ts/context');
|
const { Context: SignalContext } = require('./ts/context');
|
||||||
|
|
||||||
window.SignalContext = new SignalContext();
|
window.SignalContext = new SignalContext(ipcRenderer);
|
||||||
|
|
||||||
window.platform = process.platform;
|
window.platform = process.platform;
|
||||||
window.theme = config.theme;
|
window.theme = config.theme;
|
||||||
|
@ -30,19 +28,6 @@ window.i18n = i18n.setup(locale, localeMessages);
|
||||||
window.appStartInitialSpellcheckSetting =
|
window.appStartInitialSpellcheckSetting =
|
||||||
config.appStartInitialSpellcheckSetting === 'true';
|
config.appStartInitialSpellcheckSetting === 'true';
|
||||||
|
|
||||||
function setSystemTheme() {
|
|
||||||
window.systemTheme = nativeTheme.shouldUseDarkColors ? 'dark' : 'light';
|
|
||||||
}
|
|
||||||
|
|
||||||
setSystemTheme();
|
|
||||||
|
|
||||||
window.subscribeToSystemThemeChange = fn => {
|
|
||||||
nativeTheme.on('updated', () => {
|
|
||||||
setSystemTheme();
|
|
||||||
fn();
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
window.getEnvironment = getEnvironment;
|
window.getEnvironment = getEnvironment;
|
||||||
window.getVersion = () => config.version;
|
window.getVersion = () => config.version;
|
||||||
window.getAppInstance = () => config.appInstance;
|
window.getAppInstance = () => config.appInstance;
|
||||||
|
|
|
@ -19,7 +19,6 @@ const {
|
||||||
const { makeGetter } = require('../preload_utils');
|
const { makeGetter } = require('../preload_utils');
|
||||||
|
|
||||||
const { dialog } = remote;
|
const { dialog } = remote;
|
||||||
const { nativeTheme } = remote.require('electron');
|
|
||||||
|
|
||||||
const { Context: SignalContext } = require('../ts/context');
|
const { Context: SignalContext } = require('../ts/context');
|
||||||
|
|
||||||
|
@ -29,7 +28,7 @@ const MAX_STICKER_DIMENSION = STICKER_SIZE;
|
||||||
const MAX_WEBP_STICKER_BYTE_LENGTH = 100 * 1024;
|
const MAX_WEBP_STICKER_BYTE_LENGTH = 100 * 1024;
|
||||||
const MAX_ANIMATED_STICKER_BYTE_LENGTH = 300 * 1024;
|
const MAX_ANIMATED_STICKER_BYTE_LENGTH = 300 * 1024;
|
||||||
|
|
||||||
window.SignalContext = new SignalContext();
|
window.SignalContext = new SignalContext(ipc);
|
||||||
|
|
||||||
setEnvironment(parseEnvironment(config.environment));
|
setEnvironment(parseEnvironment(config.environment));
|
||||||
|
|
||||||
|
@ -280,6 +279,7 @@ const getThemeSetting = makeGetter('theme-setting');
|
||||||
async function resolveTheme() {
|
async function resolveTheme() {
|
||||||
const theme = (await getThemeSetting()) || 'system';
|
const theme = (await getThemeSetting()) || 'system';
|
||||||
if (process.platform === 'darwin' && theme === 'system') {
|
if (process.platform === 'darwin' && theme === 'system') {
|
||||||
|
const { theme: nativeTheme } = window.SignalContext.nativeThemeListener;
|
||||||
return nativeTheme.shouldUseDarkColors ? 'dark' : 'light';
|
return nativeTheme.shouldUseDarkColors ? 'dark' : 'light';
|
||||||
}
|
}
|
||||||
return theme;
|
return theme;
|
||||||
|
@ -293,8 +293,6 @@ async function applyTheme() {
|
||||||
|
|
||||||
window.addEventListener('DOMContentLoaded', applyTheme);
|
window.addEventListener('DOMContentLoaded', applyTheme);
|
||||||
|
|
||||||
nativeTheme.on('updated', () => {
|
window.SignalContext.nativeThemeListener.subscribe(() => applyTheme());
|
||||||
applyTheme();
|
|
||||||
});
|
|
||||||
|
|
||||||
window.log.info('sticker-creator preload complete...');
|
window.log.info('sticker-creator preload complete...');
|
||||||
|
|
|
@ -20,7 +20,7 @@ const storageMap = new Map();
|
||||||
|
|
||||||
// To replicate logic we have on the client side
|
// To replicate logic we have on the client side
|
||||||
global.window = {
|
global.window = {
|
||||||
SignalContext: new SignalContext(),
|
SignalContext: undefined,
|
||||||
log: {
|
log: {
|
||||||
info: (...args) => console.log(...args),
|
info: (...args) => console.log(...args),
|
||||||
warn: (...args) => console.warn(...args),
|
warn: (...args) => console.warn(...args),
|
||||||
|
@ -38,6 +38,21 @@ global.window = {
|
||||||
isValidGuid,
|
isValidGuid,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const fakeIPC = {
|
||||||
|
sendSync(channel) {
|
||||||
|
// See `ts/context/NativeThemeListener.ts`
|
||||||
|
if (channel === 'native-theme:init') {
|
||||||
|
return { shouldUseDarkColors: true };
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new Error(`Unsupported sendSync channel: ${channel}`);
|
||||||
|
},
|
||||||
|
|
||||||
|
on() {},
|
||||||
|
};
|
||||||
|
|
||||||
|
global.window.SignalContext = new SignalContext(fakeIPC);
|
||||||
|
|
||||||
// For ducks/network.getEmptyState()
|
// For ducks/network.getEmptyState()
|
||||||
global.navigator = {};
|
global.navigator = {};
|
||||||
global.WebSocket = {};
|
global.WebSocket = {};
|
||||||
|
|
|
@ -2295,6 +2295,10 @@ export async function startApp(): Promise<void> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
window.SignalContext.nativeThemeListener.subscribe(() => {
|
||||||
|
onChangeTheme();
|
||||||
|
});
|
||||||
|
|
||||||
const FIVE_MINUTES = 5 * 60 * 1000;
|
const FIVE_MINUTES = 5 * 60 * 1000;
|
||||||
|
|
||||||
// Note: once this function returns, there still might be messages being processed on
|
// Note: once this function returns, there still might be messages being processed on
|
||||||
|
|
48
ts/context/NativeThemeListener.ts
Normal file
48
ts/context/NativeThemeListener.ts
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
// Copyright 2021 Signal Messenger, LLC
|
||||||
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
/* eslint-disable no-restricted-syntax */
|
||||||
|
|
||||||
|
import { NativeThemeState } from '../types/NativeThemeNotifier.d';
|
||||||
|
|
||||||
|
export type Callback = (change: NativeThemeState) => void;
|
||||||
|
|
||||||
|
export interface MinimalIPC {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
|
sendSync(channel: string): any;
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
|
on(channel: string, listener: (event: unknown, ...args: any[]) => void): this;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type SystemThemeHolder = { systemTheme: 'dark' | 'light' };
|
||||||
|
|
||||||
|
export class NativeThemeListener {
|
||||||
|
private readonly subscribers = new Array<Callback>();
|
||||||
|
|
||||||
|
public theme: NativeThemeState;
|
||||||
|
|
||||||
|
constructor(ipc: MinimalIPC, private readonly holder: SystemThemeHolder) {
|
||||||
|
this.theme = ipc.sendSync('native-theme:init');
|
||||||
|
this.update();
|
||||||
|
|
||||||
|
ipc.on(
|
||||||
|
'native-theme:changed',
|
||||||
|
(_event: unknown, change: NativeThemeState) => {
|
||||||
|
this.theme = change;
|
||||||
|
this.update();
|
||||||
|
|
||||||
|
for (const fn of this.subscribers) {
|
||||||
|
fn(change);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public subscribe(fn: Callback): void {
|
||||||
|
this.subscribers.push(fn);
|
||||||
|
}
|
||||||
|
|
||||||
|
private update(): void {
|
||||||
|
this.holder.systemTheme = this.theme.shouldUseDarkColors ? 'dark' : 'light';
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,7 +2,14 @@
|
||||||
// SPDX-License-Identifier: AGPL-3.0-only
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
import { Bytes } from './Bytes';
|
import { Bytes } from './Bytes';
|
||||||
|
import { NativeThemeListener, MinimalIPC } from './NativeThemeListener';
|
||||||
|
|
||||||
export class Context {
|
export class Context {
|
||||||
public readonly bytes = new Bytes();
|
public readonly bytes = new Bytes();
|
||||||
|
|
||||||
|
public readonly nativeThemeListener;
|
||||||
|
|
||||||
|
constructor(ipc: MinimalIPC) {
|
||||||
|
this.nativeThemeListener = new NativeThemeListener(ipc, window);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
46
ts/main/NativeThemeNotifier.ts
Normal file
46
ts/main/NativeThemeNotifier.ts
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
// Copyright 2021 Signal Messenger, LLC
|
||||||
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
/* eslint-disable no-restricted-syntax */
|
||||||
|
|
||||||
|
import { ipcMain as ipc, nativeTheme, BrowserWindow } from 'electron';
|
||||||
|
|
||||||
|
import { NativeThemeState } from '../types/NativeThemeNotifier.d';
|
||||||
|
|
||||||
|
function getState(): NativeThemeState {
|
||||||
|
return {
|
||||||
|
shouldUseDarkColors: nativeTheme.shouldUseDarkColors,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export class NativeThemeNotifier {
|
||||||
|
private readonly listeners = new Set<BrowserWindow>();
|
||||||
|
|
||||||
|
public initialize(): void {
|
||||||
|
nativeTheme.on('updated', () => {
|
||||||
|
this.notifyListeners();
|
||||||
|
});
|
||||||
|
|
||||||
|
ipc.on('native-theme:init', event => {
|
||||||
|
// eslint-disable-next-line no-param-reassign
|
||||||
|
event.returnValue = getState();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public addWindow(window: BrowserWindow): void {
|
||||||
|
if (this.listeners.has(window)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.listeners.add(window);
|
||||||
|
|
||||||
|
window.once('closed', () => {
|
||||||
|
this.listeners.delete(window);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private notifyListeners(): void {
|
||||||
|
for (const window of this.listeners) {
|
||||||
|
window.webContents.send('native-theme:changed', getState());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
81
ts/test-electron/context/NativeThemeListener_test.ts
Normal file
81
ts/test-electron/context/NativeThemeListener_test.ts
Normal file
|
@ -0,0 +1,81 @@
|
||||||
|
// Copyright 2021 Signal Messenger, LLC
|
||||||
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
|
import { assert } from 'chai';
|
||||||
|
import { EventEmitter } from 'events';
|
||||||
|
|
||||||
|
import {
|
||||||
|
NativeThemeListener,
|
||||||
|
MinimalIPC,
|
||||||
|
SystemThemeHolder,
|
||||||
|
} from '../../context/NativeThemeListener';
|
||||||
|
import { NativeThemeState } from '../../types/NativeThemeNotifier.d';
|
||||||
|
|
||||||
|
class FakeIPC extends EventEmitter implements MinimalIPC {
|
||||||
|
constructor(private readonly state: NativeThemeState) {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
public sendSync(channel: string) {
|
||||||
|
assert.strictEqual(channel, 'native-theme:init');
|
||||||
|
return this.state;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
describe('NativeThemeListener', () => {
|
||||||
|
const holder: SystemThemeHolder = { systemTheme: 'dark' };
|
||||||
|
|
||||||
|
it('syncs the initial native theme', () => {
|
||||||
|
const dark = new NativeThemeListener(
|
||||||
|
new FakeIPC({
|
||||||
|
shouldUseDarkColors: true,
|
||||||
|
}),
|
||||||
|
holder
|
||||||
|
);
|
||||||
|
|
||||||
|
assert.strictEqual(holder.systemTheme, 'dark');
|
||||||
|
assert.isTrue(dark.theme.shouldUseDarkColors);
|
||||||
|
|
||||||
|
const light = new NativeThemeListener(
|
||||||
|
new FakeIPC({
|
||||||
|
shouldUseDarkColors: false,
|
||||||
|
}),
|
||||||
|
holder
|
||||||
|
);
|
||||||
|
|
||||||
|
assert.strictEqual(holder.systemTheme, 'light');
|
||||||
|
assert.isFalse(light.theme.shouldUseDarkColors);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should react to native theme changes', () => {
|
||||||
|
const ipc = new FakeIPC({
|
||||||
|
shouldUseDarkColors: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
const listener = new NativeThemeListener(ipc, holder);
|
||||||
|
|
||||||
|
ipc.emit('native-theme:changed', null, <NativeThemeState>{
|
||||||
|
shouldUseDarkColors: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
assert.strictEqual(holder.systemTheme, 'light');
|
||||||
|
assert.isFalse(listener.theme.shouldUseDarkColors);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should notify subscribers of native theme changes', done => {
|
||||||
|
const ipc = new FakeIPC({
|
||||||
|
shouldUseDarkColors: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
const listener = new NativeThemeListener(ipc, holder);
|
||||||
|
|
||||||
|
listener.subscribe(state => {
|
||||||
|
assert.isFalse(state.shouldUseDarkColors);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
|
||||||
|
ipc.emit('native-theme:changed', null, <NativeThemeState>{
|
||||||
|
shouldUseDarkColors: false,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
6
ts/types/NativeThemeNotifier.d.ts
vendored
Normal file
6
ts/types/NativeThemeNotifier.d.ts
vendored
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
// Copyright 2021 Signal Messenger, LLC
|
||||||
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
|
export type NativeThemeState = Readonly<{
|
||||||
|
shouldUseDarkColors: boolean;
|
||||||
|
}>;
|
Loading…
Reference in a new issue