Files
Desktop/app/WindowsNotificationsWorker.node.ts
2025-12-03 13:03:53 -08:00

84 lines
2.0 KiB
TypeScript

// Copyright 2025 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import { parentPort, workerData } from 'node:worker_threads';
import {
Notifier,
sendDummyKeystroke,
} from '@indutny/simple-windows-notifications';
import { createLogger } from '../ts/logging/log.std.js';
import {
WindowsNotificationWorkerDataSchema,
WindowsNotificationRequestSchema,
} from '../ts/types/notifications.std.js';
import OS from '../ts/util/os/osMain.node.js';
import { missingCaseError } from '../ts/util/missingCaseError.std.js';
import { renderWindowsToast } from './renderWindowsToast.std.js';
if (!parentPort) {
throw new Error('Must run as a worker thread');
}
if (!OS.isWindows()) {
throw new Error('Runs only on Windows');
}
const port = parentPort;
const log = createLogger('WindowsNotificationsWorker');
const { AUMID } = WindowsNotificationWorkerDataSchema.parse(workerData);
const notifier = new Notifier(AUMID);
const NOTIFICATION_ID = {
group: 'group',
tag: 'tag',
};
port.on('message', (message: unknown) => {
const request = WindowsNotificationRequestSchema.parse(message);
if (request.command === 'show') {
try {
// First, clear all previous notifications - we want just one
// notification at a time
notifier.remove(NOTIFICATION_ID);
notifier.show(
renderWindowsToast(request.notificationData),
NOTIFICATION_ID
);
} catch (error) {
log.error(
`Windows Notifications: Failed to show notification: ${error.stack}`
);
}
return;
}
if (request.command === 'clearAll') {
try {
notifier.remove(NOTIFICATION_ID);
} catch (error) {
log.error(
`Windows Notifications: Failed to clear notifications: ${error.stack}`
);
}
return;
}
if (request.command === 'sendDummyKeystroke') {
try {
sendDummyKeystroke();
} catch (error) {
log.error(
`Windows Notifications: Failed to send dummy keystroke: ${error.stack}`
);
}
return;
}
throw missingCaseError(request);
});