mirror of
https://github.com/signalapp/Signal-Desktop.git
synced 2026-05-08 08:58:38 +01:00
Interact with Windows notifications from a thread
This commit is contained in:
@@ -1,55 +1,78 @@
|
||||
// Copyright 2017 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import { ipcMain as ipc } from 'electron';
|
||||
import { ipcMain as ipc, app } from 'electron';
|
||||
import type { IpcMainInvokeEvent } from 'electron';
|
||||
import { join } from 'node:path';
|
||||
import { Worker } from 'node:worker_threads';
|
||||
|
||||
import {
|
||||
Notifier,
|
||||
sendDummyKeystroke,
|
||||
} from '@indutny/simple-windows-notifications';
|
||||
|
||||
import { createLogger } from '../ts/logging/log.std.js';
|
||||
import { AUMID } from './startup_config.main.js';
|
||||
import type { WindowsNotificationData } from '../ts/services/notifications.preload.js';
|
||||
import type {
|
||||
WindowsNotificationWorkerDataType,
|
||||
WindowsNotificationRequestType,
|
||||
WindowsNotificationData,
|
||||
} from '../ts/types/notifications.std.js';
|
||||
import { WindowsNotificationDataSchema } from '../ts/types/notifications.std.js';
|
||||
import OS from '../ts/util/os/osMain.node.js';
|
||||
import { renderWindowsToast } from './renderWindowsToast.std.js';
|
||||
|
||||
export { sendDummyKeystroke };
|
||||
import { createLogger } from '../ts/logging/log.std.js';
|
||||
|
||||
const log = createLogger('WindowsNotifications');
|
||||
|
||||
let worker: Worker | undefined;
|
||||
|
||||
if (OS.isWindows()) {
|
||||
const notifier = new Notifier(AUMID);
|
||||
|
||||
const NOTIFICATION_ID = {
|
||||
group: 'group',
|
||||
tag: 'tag',
|
||||
};
|
||||
|
||||
ipc.handle(
|
||||
'windows-notifications:show',
|
||||
(_event: IpcMainInvokeEvent, data: WindowsNotificationData) => {
|
||||
try {
|
||||
// First, clear all previous notifications - we want just one
|
||||
// notification at a time
|
||||
notifier.remove(NOTIFICATION_ID);
|
||||
notifier.show(renderWindowsToast(data), NOTIFICATION_ID);
|
||||
} catch (error) {
|
||||
log.error(
|
||||
`Windows Notifications: Failed to show notification: ${error.stack}`
|
||||
);
|
||||
}
|
||||
}
|
||||
const scriptPath = join(
|
||||
app.getAppPath(),
|
||||
'app',
|
||||
'WindowsNotificationsWorker.node.js'
|
||||
);
|
||||
|
||||
ipc.handle('windows-notifications:clear-all', () => {
|
||||
try {
|
||||
notifier.remove(NOTIFICATION_ID);
|
||||
} catch (error) {
|
||||
log.error(
|
||||
`Windows Notifications: Failed to clear notifications: ${error.stack}`
|
||||
);
|
||||
}
|
||||
worker = new Worker(scriptPath, {
|
||||
workerData: {
|
||||
AUMID,
|
||||
} satisfies WindowsNotificationWorkerDataType,
|
||||
});
|
||||
}
|
||||
|
||||
export function sendDummyKeystroke(): void {
|
||||
if (worker == null) {
|
||||
log.warn('sendDummyKeystroke without worker');
|
||||
return;
|
||||
}
|
||||
worker.postMessage({
|
||||
command: 'sendDummyKeystroke',
|
||||
} satisfies WindowsNotificationRequestType);
|
||||
}
|
||||
|
||||
export function show(notificationData: WindowsNotificationData): void {
|
||||
if (worker == null) {
|
||||
log.warn('show without worker');
|
||||
return;
|
||||
}
|
||||
worker.postMessage({
|
||||
command: 'show',
|
||||
notificationData,
|
||||
} satisfies WindowsNotificationRequestType);
|
||||
}
|
||||
|
||||
ipc.handle(
|
||||
'windows-notifications:show',
|
||||
(_event: IpcMainInvokeEvent, data: unknown) => {
|
||||
try {
|
||||
const notificationData = WindowsNotificationDataSchema.parse(data);
|
||||
show(notificationData);
|
||||
} catch (error) {
|
||||
log.error('failed to parse notification data', error.stack);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
ipc.handle('windows-notifications:clear-all', () => {
|
||||
if (worker == null) {
|
||||
log.warn('clear all without worker');
|
||||
return;
|
||||
}
|
||||
worker.postMessage({
|
||||
command: 'clearAll',
|
||||
} satisfies WindowsNotificationRequestType);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user