// Copyright 2021 Signal Messenger, LLC // SPDX-License-Identifier: AGPL-3.0-only /* eslint-disable no-restricted-syntax */ import type { NativeThemeState } from '../types/NativeThemeNotifier.d'; export type Callback = (change: NativeThemeState) => void; export interface MinimalIPC { // eslint-disable-next-line @typescript-eslint/no-explicit-any send(channel: string, ...args: ReadonlyArray): void; // eslint-disable-next-line @typescript-eslint/no-explicit-any sendSync(channel: string): any; on( channel: string, // eslint-disable-next-line @typescript-eslint/no-explicit-any listener: (event: unknown, ...args: ReadonlyArray) => void ): this; } type SystemThemeType = 'dark' | 'light'; export type SystemThemeHolder = { systemTheme: SystemThemeType }; export type NativeThemeType = { getSystemTheme: () => SystemThemeType; subscribe: (fn: Callback) => void; unsubscribe: (fn: Callback) => void; update: () => SystemThemeType; }; export function createNativeThemeListener( ipc: MinimalIPC, holder: SystemThemeHolder ): NativeThemeType { const subscribers = new Array(); let theme = ipc.sendSync('native-theme:init'); let systemTheme: SystemThemeType; function update(): SystemThemeType { const nextSystemTheme = theme.shouldUseDarkColors ? 'dark' : 'light'; // eslint-disable-next-line no-param-reassign holder.systemTheme = nextSystemTheme; return nextSystemTheme; } function subscribe(fn: Callback): void { subscribers.push(fn); } function unsubscribe(fn: Callback): void { const index = subscribers.indexOf(fn); if (index !== -1) { subscribers.splice(index, 1); } } ipc.on( 'native-theme:changed', (_event: unknown, change: NativeThemeState) => { theme = change; systemTheme = update(); for (const fn of subscribers) { fn(change); } } ); systemTheme = update(); return { getSystemTheme: () => systemTheme, subscribe, unsubscribe, update, }; }