mirror of
https://github.com/signalapp/Signal-Desktop.git
synced 2026-09-28 16:09:49 +01:00
Introduce AssetService
This commit is contained in:
@@ -0,0 +1,83 @@
|
||||
// Copyright 2024 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import { createReadStream } from 'node:fs';
|
||||
import { join } from 'node:path';
|
||||
import { protocol } from 'electron';
|
||||
|
||||
import type { OptionalResourceService } from './OptionalResourceService.main.ts';
|
||||
import { getAppRootDir } from '../ts/util/appRootDir.main.ts';
|
||||
import { toWebStream } from '../ts/util/toWebStream.node.ts';
|
||||
|
||||
const LOCAL_ASSETS = new Set([
|
||||
'fonts/signal-symbols/SignalSymbolsVariable.woff2',
|
||||
'fonts/stories/Hatsuishi-Regular.woff2',
|
||||
'fonts/stories/EBGaramond-Regular.ttf',
|
||||
'fonts/stories/Parisienne-Regular.ttf',
|
||||
'fonts/stories/BarlowCondensed-Medium.ttf',
|
||||
'fonts/inter-v3.19/Inter-Medium.woff2',
|
||||
'fonts/inter-v3.19/Inter-Regular.woff2',
|
||||
'fonts/inter-v3.19/Inter-SemiBold.woff2',
|
||||
'fonts/inter-v3.19/Inter-BoldItalic.woff2',
|
||||
'fonts/inter-v3.19/Inter-Bold.woff2',
|
||||
'fonts/inter-v3.19/Inter-Italic.woff2',
|
||||
'fonts/inter-v3.19/Inter-SemiBoldItalic.woff2',
|
||||
]);
|
||||
|
||||
// pathname to optional resource name
|
||||
const OPTIONAL_ASSETS = new Map<string, string>([]);
|
||||
|
||||
export class AssetService {
|
||||
readonly #resourceService: OptionalResourceService;
|
||||
|
||||
private constructor(resourceService: OptionalResourceService) {
|
||||
this.#resourceService = resourceService;
|
||||
|
||||
protocol.handle('asset', async req => {
|
||||
const url = new URL(req.url);
|
||||
|
||||
return this.#fetch(url.pathname);
|
||||
});
|
||||
}
|
||||
|
||||
public static create(resourceService: OptionalResourceService): AssetService {
|
||||
return new AssetService(resourceService);
|
||||
}
|
||||
|
||||
async #fetch(pathname: string): Promise<Response> {
|
||||
if (!pathname.startsWith('/')) {
|
||||
return new Response('invalid pathname', { status: 400 });
|
||||
}
|
||||
|
||||
const path = pathname.slice(1);
|
||||
|
||||
if (LOCAL_ASSETS.has(path)) {
|
||||
const stream = createReadStream(
|
||||
join(getAppRootDir(), ...path.split('/'))
|
||||
);
|
||||
return new Response(toWebStream(stream), {
|
||||
status: 200,
|
||||
headers: {
|
||||
'cache-control': 'public, max-age=2592000, immutable',
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
const optional = OPTIONAL_ASSETS.get(path);
|
||||
if (optional == null) {
|
||||
return new Response('asset not found', { status: 404 });
|
||||
}
|
||||
|
||||
const asset = await this.#resourceService.getData(optional);
|
||||
if (!asset) {
|
||||
return new Response('optional asset not found', { status: 404 });
|
||||
}
|
||||
|
||||
return new Response(asset, {
|
||||
status: 200,
|
||||
headers: {
|
||||
'cache-control': 'public, max-age=2592000, immutable',
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -84,6 +84,7 @@ import {
|
||||
import { SystemTraySettingCache } from './SystemTraySettingCache.node.ts';
|
||||
import { OptionalResourceService } from './OptionalResourceService.main.ts';
|
||||
import { EmojiService } from './EmojiService.main.ts';
|
||||
import { AssetService } from './AssetService.main.ts';
|
||||
import {
|
||||
SystemTraySetting,
|
||||
shouldMinimizeToSystemTray,
|
||||
@@ -2082,6 +2083,7 @@ app.on('ready', async () => {
|
||||
join(userDataPath, 'optionalResources')
|
||||
);
|
||||
await EmojiService.create(resourceService);
|
||||
AssetService.create(resourceService);
|
||||
|
||||
if (!resolvedTranslationsLocale) {
|
||||
preferredSystemLocales = resolveCanonicalLocales(
|
||||
|
||||
+15
-9
@@ -17,7 +17,7 @@
|
||||
content="default-src 'none';
|
||||
child-src 'self';
|
||||
connect-src 'self' https: wss: attachment:;
|
||||
font-src 'self';
|
||||
font-src 'self' asset:;
|
||||
form-action 'self';
|
||||
frame-src 'none';
|
||||
img-src 'self' blob: data: emoji: attachment:;
|
||||
@@ -29,56 +29,56 @@
|
||||
<title>Signal</title>
|
||||
<link
|
||||
rel="preload"
|
||||
href="fonts/inter-v3.19/Inter-BoldItalic.woff2"
|
||||
href="asset:///fonts/inter-v3.19/Inter-BoldItalic.woff2"
|
||||
as="font"
|
||||
crossorigin
|
||||
type="font/woff2"
|
||||
/>
|
||||
<link
|
||||
rel="preload"
|
||||
href="fonts/inter-v3.19/Inter-Bold.woff2"
|
||||
href="asset:///fonts/inter-v3.19/Inter-Bold.woff2"
|
||||
as="font"
|
||||
type="font/woff2"
|
||||
crossorigin
|
||||
/>
|
||||
<link
|
||||
rel="preload"
|
||||
href="fonts/inter-v3.19/Inter-SemiBoldItalic.woff2"
|
||||
href="asset:///fonts/inter-v3.19/Inter-SemiBoldItalic.woff2"
|
||||
as="font"
|
||||
type="font/woff2"
|
||||
crossorigin
|
||||
/>
|
||||
<link
|
||||
rel="preload"
|
||||
href="fonts/inter-v3.19/Inter-Italic.woff2"
|
||||
href="asset:///fonts/inter-v3.19/Inter-Italic.woff2"
|
||||
as="font"
|
||||
type="font/woff2"
|
||||
crossorigin
|
||||
/>
|
||||
<link
|
||||
rel="preload"
|
||||
href="fonts/inter-v3.19/Inter-SemiBold.woff2"
|
||||
href="asset:///fonts/inter-v3.19/Inter-SemiBold.woff2"
|
||||
as="font"
|
||||
type="font/woff2"
|
||||
crossorigin
|
||||
/>
|
||||
<link
|
||||
rel="preload"
|
||||
href="fonts/inter-v3.19/Inter-Regular.woff2"
|
||||
href="asset:///fonts/inter-v3.19/Inter-Regular.woff2"
|
||||
as="font"
|
||||
type="font/woff2"
|
||||
crossorigin
|
||||
/>
|
||||
<link
|
||||
rel="preload"
|
||||
href="fonts/inter-v3.19/Inter-Medium.woff2"
|
||||
href="asset:///fonts/inter-v3.19/Inter-Medium.woff2"
|
||||
as="font"
|
||||
type="font/woff2"
|
||||
crossorigin
|
||||
/>
|
||||
<link
|
||||
rel="preload"
|
||||
href="fonts/signal-symbols/SignalSymbolsVariable.woff2"
|
||||
href="asset:///fonts/signal-symbols/SignalSymbolsVariable.woff2"
|
||||
as="font"
|
||||
type="font/woff2"
|
||||
crossorigin
|
||||
@@ -90,6 +90,12 @@
|
||||
crossorigin
|
||||
/>
|
||||
<link rel="preload" href="images/signal-logo.svg" as="image" crossorigin />
|
||||
<link
|
||||
rel="preload"
|
||||
href="images/emoji-sheet-32.webp"
|
||||
as="image"
|
||||
crossorigin
|
||||
/>
|
||||
<link
|
||||
rel="preload"
|
||||
href="images/emoji-sheet-64.webp"
|
||||
|
||||
+11
-11
@@ -3,59 +3,59 @@
|
||||
|
||||
@font-face {
|
||||
font-family: 'Inter';
|
||||
src: url('../fonts/inter-v3.19/Inter-BoldItalic.woff2');
|
||||
src: url('asset:///fonts/inter-v3.19/Inter-BoldItalic.woff2');
|
||||
font-weight: bolder;
|
||||
font-style: italic;
|
||||
}
|
||||
@font-face {
|
||||
font-family: 'Inter';
|
||||
src: url('../fonts/inter-v3.19/Inter-Bold.woff2');
|
||||
src: url('asset:///fonts/inter-v3.19/Inter-Bold.woff2');
|
||||
font-weight: bolder;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Inter';
|
||||
src: url('../fonts/inter-v3.19/Inter-SemiBoldItalic.woff2');
|
||||
src: url('asset:///fonts/inter-v3.19/Inter-SemiBoldItalic.woff2');
|
||||
font-weight: bold;
|
||||
font-style: italic;
|
||||
}
|
||||
@font-face {
|
||||
font-family: 'Inter';
|
||||
src: url('../fonts/inter-v3.19/Inter-Italic.woff2');
|
||||
src: url('asset:///fonts/inter-v3.19/Inter-Italic.woff2');
|
||||
font-style: italic;
|
||||
}
|
||||
@font-face {
|
||||
font-family: 'Inter';
|
||||
src: url('../fonts/inter-v3.19/Inter-SemiBold.woff2');
|
||||
src: url('asset:///fonts/inter-v3.19/Inter-SemiBold.woff2');
|
||||
font-weight: bold;
|
||||
}
|
||||
@font-face {
|
||||
font-family: 'Inter';
|
||||
src: url('../fonts/inter-v3.19/Inter-Medium.woff2');
|
||||
src: url('asset:///fonts/inter-v3.19/Inter-Medium.woff2');
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Inter';
|
||||
src: url('../fonts/inter-v3.19/Inter-Regular.woff2');
|
||||
src: url('asset:///fonts/inter-v3.19/Inter-Regular.woff2');
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Parisienne';
|
||||
src: url('../fonts/stories/Parisienne-Regular.ttf');
|
||||
src: url('asset:///fonts/stories/Parisienne-Regular.ttf');
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Barlow Condensed';
|
||||
src: url('../fonts/stories/BarlowCondensed-Medium.ttf');
|
||||
src: url('asset:///fonts/stories/BarlowCondensed-Medium.ttf');
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'EB Garamond';
|
||||
src: url('../fonts/stories/EBGaramond-Regular.ttf');
|
||||
src: url('asset:///fonts/stories/EBGaramond-Regular.ttf');
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Hatsuishi';
|
||||
src: url('../fonts/stories/Hatsuishi-Regular.woff2');
|
||||
src: url('asset:///fonts/stories/Hatsuishi-Regular.woff2');
|
||||
}
|
||||
|
||||
@@ -247,7 +247,7 @@
|
||||
font-style: normal;
|
||||
font-weight: 300 400 700;
|
||||
font-display: block;
|
||||
src: url('../fonts/signal-symbols/SignalSymbolsVariable.woff2');
|
||||
src: url('asset:///fonts/signal-symbols/SignalSymbolsVariable.woff2');
|
||||
}
|
||||
|
||||
@layer base {
|
||||
|
||||
@@ -44,7 +44,7 @@ async function drawImage(
|
||||
async function getFont(text: string): Promise<string> {
|
||||
const font = new window.FontFace(
|
||||
'Inter',
|
||||
'url("fonts/inter-v3.19/Inter-Regular.woff2")'
|
||||
'url("asset:///fonts/inter-v3.19/Inter-Regular.woff2")'
|
||||
);
|
||||
await font.load();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user