mirror of
https://github.com/jeffvli/feishin.git
synced 2026-06-10 22:32:17 +02:00
Better cross platform font handling (#2104)
* fix: better handling of custom font Practically speaking, custom font seems to have only worked on Linux, because `net.fetch` would include the mime type in the response headers which could validate the payload. This doesn't appear to be the case on windows/macOS. Instead: 1. On Linux (or if some other system supports it), check the content type. If good, serve as normal 2. Otherwise, fetch the payload. Read the first four to five bytes and check for a valid magic number. Additionally, to prevent arbitrary requests fetching other paths via injected content, sync the custom font path to the main process, and then make _every_ request to `feishin:/` point to the same renderer path. When setting the font, first send the path to the main process. This will register `feishin:/` to point to the path provided. This is done via a promise-based set. Finally, provide a default value for the file input (a best effort approximation for the last part of the file path) on the file input component. * make the linter happy
This commit is contained in:
@@ -36,6 +36,7 @@ import { FontType } from '/@/shared/types/types';
|
||||
|
||||
const localSettings = isElectron() ? window.api.localSettings : null;
|
||||
const ipc = isElectron() ? window.api.ipc : null;
|
||||
const utils = isElectron() ? window.api.utils : null;
|
||||
// Electron 32+ removed file.path, use this which is exposed in preload to get real path
|
||||
const getPathForFile = isElectron() ? window.api.getPathForFile : null;
|
||||
|
||||
@@ -289,21 +290,29 @@ export const ApplicationSettings = memo(() => {
|
||||
control: (
|
||||
<FileInput
|
||||
accept=".ttc,.ttf,.otf,.woff,.woff2"
|
||||
onChange={(e) =>
|
||||
clearable
|
||||
defaultValue={
|
||||
fontSettings.custom
|
||||
? new File([], fontSettings.custom.split(utils?.separator || '').pop()!)
|
||||
: null
|
||||
}
|
||||
onChange={async (e) => {
|
||||
const custom = e ? getPathForFile?.(e) || null : null;
|
||||
await localSettings?.setSync('local_font_path', custom);
|
||||
setSettings({
|
||||
font: {
|
||||
...fontSettings,
|
||||
custom: e ? getPathForFile?.(e) || null : null,
|
||||
custom,
|
||||
},
|
||||
})
|
||||
}
|
||||
});
|
||||
}}
|
||||
w={300}
|
||||
/>
|
||||
),
|
||||
description: t('setting.customFontPath', {
|
||||
context: 'description',
|
||||
}),
|
||||
isHidden: fontSettings.type !== FontType.CUSTOM,
|
||||
isHidden: !isElectron() || fontSettings.type !== FontType.CUSTOM,
|
||||
title: t('setting.customFontPath'),
|
||||
},
|
||||
{
|
||||
|
||||
@@ -32,6 +32,7 @@ export const useSyncSettingsToMain = () => {
|
||||
const settingsFromStore = useSettingsStore.getState();
|
||||
|
||||
const settings = {
|
||||
font: settingsFromStore.font,
|
||||
general: settingsFromStore.general,
|
||||
hotkeys: settingsFromStore.hotkeys,
|
||||
lyrics: settingsFromStore.lyrics,
|
||||
@@ -101,6 +102,10 @@ export const useSyncSettingsToMain = () => {
|
||||
mainStoreKey: 'enableNeteaseTranslation',
|
||||
rendererValue: settings.lyrics.enableNeteaseTranslation,
|
||||
},
|
||||
{
|
||||
mainStoreKey: 'local_font_path',
|
||||
rendererValue: settings.font.custom,
|
||||
},
|
||||
];
|
||||
|
||||
// Compare and sync each setting
|
||||
|
||||
@@ -134,6 +134,11 @@ export const useAppTheme = (overrideTheme?: AppTheme) => {
|
||||
document.body.appendChild(textStyleRef.current);
|
||||
}
|
||||
|
||||
// Note: we change the url to bust caches when changing the path
|
||||
// The url provided here does NOT matter, validation is done
|
||||
// on the main process. Any feishin:/ url will fetch the same
|
||||
// item, which the renderer will check via magic number to be
|
||||
// some font item
|
||||
textStyleRef.current.textContent = `
|
||||
@font-face {
|
||||
font-family: "dynamic-font";
|
||||
|
||||
Reference in New Issue
Block a user