Improved windows notifications

This commit is contained in:
Scott Nonnenberg 2023-08-01 09:06:29 -07:00 committed by GitHub
parent 584e39d569
commit 40c21b1666
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
31 changed files with 1227 additions and 151 deletions

View file

@ -6,25 +6,55 @@ import loadImage from 'blueimp-load-image';
import { renderToString } from 'react-dom/server';
import type { AvatarColorType } from '../types/Colors';
import { AvatarColorMap } from '../types/Colors';
import { IdenticonSVG } from '../components/IdenticonSVG';
import {
IdenticonSVGForContact,
IdenticonSVGForGroup,
} from '../components/IdenticonSVG';
import { missingCaseError } from './missingCaseError';
const TARGET_MIME = 'image/png';
type IdenticonDetailsType =
| {
type: 'contact';
text: string;
}
| {
type: 'group';
};
export function createIdenticon(
color: AvatarColorType,
content: string
): Promise<string> {
details: IdenticonDetailsType,
{ saveToDisk }: { saveToDisk?: boolean } = {}
): Promise<{ url: string; path?: string }> {
const [defaultColorValue] = Array.from(AvatarColorMap.values());
const avatarColor = AvatarColorMap.get(color);
const html = renderToString(
<IdenticonSVG
backgroundColor={avatarColor?.bg || defaultColorValue.bg}
content={content}
foregroundColor={avatarColor?.fg || defaultColorValue.fg}
/>
);
let html: string;
if (details.type === 'contact') {
html = renderToString(
<IdenticonSVGForContact
backgroundColor={avatarColor?.bg || defaultColorValue.bg}
text={details.text}
foregroundColor={avatarColor?.fg || defaultColorValue.fg}
/>
);
} else if (details.type === 'group') {
html = renderToString(
<IdenticonSVGForGroup
backgroundColor={avatarColor?.bg || defaultColorValue.bg}
foregroundColor={avatarColor?.fg || defaultColorValue.fg}
/>
);
} else {
throw missingCaseError(details);
}
const svg = new Blob([html], { type: 'image/svg+xml;charset=utf-8' });
const svgUrl = URL.createObjectURL(svg);
return new Promise(resolve => {
return new Promise((resolve, reject) => {
const img = document.createElement('img');
img.onload = () => {
const canvas = loadImage.scale(img, {
@ -33,7 +63,11 @@ export function createIdenticon(
maxHeight: 100,
});
if (!(canvas instanceof HTMLCanvasElement)) {
resolve('');
reject(
new Error(
'createIdenticon: canvas was not an instance of HTMLCanvasElement'
)
);
return;
}
@ -42,11 +76,46 @@ export function createIdenticon(
ctx.drawImage(img, 0, 0);
}
URL.revokeObjectURL(svgUrl);
resolve(canvas.toDataURL('image/png'));
const url = canvas.toDataURL(TARGET_MIME);
if (!saveToDisk) {
resolve({ url });
}
canvas.toBlob(blob => {
if (!blob) {
reject(
new Error(
'createIdenticon: no blob data provided in toBlob callback'
)
);
return;
}
const reader = new FileReader();
reader.addEventListener('loadend', async () => {
const arrayBuffer = reader.result;
if (!arrayBuffer || typeof arrayBuffer === 'string') {
reject(
new Error(
'createIdenticon: no data in reader.result in FileReader loadend event'
)
);
return;
}
const data = new Uint8Array(arrayBuffer);
const path = await window.Signal.Migrations.writeNewTempData(data);
resolve({ url, path });
});
reader.readAsArrayBuffer(blob);
}, TARGET_MIME);
};
img.onerror = () => {
URL.revokeObjectURL(svgUrl);
resolve('');
reject(new Error('createIdenticon: Unable to create img element'));
};
img.src = svgUrl;