Improved windows notifications
This commit is contained in:
parent
584e39d569
commit
40c21b1666
31 changed files with 1227 additions and 151 deletions
84
app/renderWindowsToast.tsx
Normal file
84
app/renderWindowsToast.tsx
Normal file
|
@ -0,0 +1,84 @@
|
|||
// Copyright 2022 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import React from 'react';
|
||||
import { renderToStaticMarkup } from 'react-dom/server';
|
||||
|
||||
import type { WindowsNotificationData } from '../ts/services/notifications';
|
||||
|
||||
import { NotificationType } from '../ts/services/notifications';
|
||||
import { missingCaseError } from '../ts/util/missingCaseError';
|
||||
|
||||
function pathToUri(path: string) {
|
||||
return `file:///${encodeURI(path.replace(/\\/g, '/'))}`;
|
||||
}
|
||||
|
||||
const Toast = (props: {
|
||||
launch: string;
|
||||
// Note: though React doesn't like it, Windows seems to require that this be camelcase
|
||||
activationType: string;
|
||||
children: React.ReactNode;
|
||||
}) => React.createElement('toast', props);
|
||||
const Visual = (props: { children: React.ReactNode }) =>
|
||||
React.createElement('visual', props);
|
||||
const Binding = (props: { template: string; children: React.ReactNode }) =>
|
||||
React.createElement('binding', props);
|
||||
const Text = (props: { id: string; children: React.ReactNode }) =>
|
||||
React.createElement('text', props);
|
||||
const Image = (props: { id: string; src: string; 'hint-crop': string }) =>
|
||||
React.createElement('image', props);
|
||||
|
||||
export function renderWindowsToast({
|
||||
avatarPath,
|
||||
body,
|
||||
conversationId,
|
||||
heading,
|
||||
messageId,
|
||||
storyId,
|
||||
type,
|
||||
}: WindowsNotificationData): string {
|
||||
// Note: with these templates, the first <text> is one line, bolded
|
||||
// https://learn.microsoft.com/en-us/previous-versions/windows/apps/hh761494(v=win.10)?redirectedfrom=MSDN#toastimageandtext02
|
||||
// https://learn.microsoft.com/en-us/previous-versions/windows/apps/hh761494(v=win.10)?redirectedfrom=MSDN#toasttext02
|
||||
|
||||
const image = avatarPath ? (
|
||||
<Image id="1" src={pathToUri(avatarPath)} hint-crop="circle" />
|
||||
) : null;
|
||||
const template = avatarPath ? 'ToastImageAndText02' : 'ToastText02';
|
||||
let launch: URL;
|
||||
|
||||
// Note:
|
||||
// 1) this maps to the notify() function in services/notifications.ts
|
||||
// 2) this also maps to the url-handling in main.ts
|
||||
if (type === NotificationType.Message || type === NotificationType.Reaction) {
|
||||
launch = new URL('sgnl://show-conversation');
|
||||
launch.searchParams.set('conversationId', conversationId);
|
||||
if (messageId) {
|
||||
launch.searchParams.set('messageId', messageId);
|
||||
}
|
||||
if (storyId) {
|
||||
launch.searchParams.set('storyId', storyId);
|
||||
}
|
||||
} else if (type === NotificationType.IncomingGroupCall) {
|
||||
launch = new URL(`sgnl://start-call-lobby`);
|
||||
launch.searchParams.set('conversationId', conversationId);
|
||||
} else if (type === NotificationType.IncomingCall) {
|
||||
launch = new URL('sgnl://show-window');
|
||||
} else if (type === NotificationType.IsPresenting) {
|
||||
launch = new URL('sgnl://set-is-presenting');
|
||||
} else {
|
||||
throw missingCaseError(type);
|
||||
}
|
||||
|
||||
return renderToStaticMarkup(
|
||||
<Toast launch={launch.href} activationType="protocol">
|
||||
<Visual>
|
||||
<Binding template={template}>
|
||||
{image}
|
||||
<Text id="1">{heading}</Text>
|
||||
<Text id="2">{body}</Text>
|
||||
</Binding>
|
||||
</Visual>
|
||||
</Toast>
|
||||
);
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue