From 797d82ca0d725f14537cb0076149f23cac3d11af Mon Sep 17 00:00:00 2001 From: TRIP <1933142963@qq.com> Date: Fri, 8 May 2026 18:58:13 +0800 Subject: [PATCH] =?UTF-8?q?Revert=20"feat(ui):=20bundle=20Noto=20Sans=20JP?= =?UTF-8?q?=20locally=20+=20UI=20font=20picker=20with=20system=20fo?= =?UTF-8?q?=E2=80=A6"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 57f7e137046967507834b067950253571d660c50. --- openless-all/app/package-lock.json | 27 ---- openless-all/app/package.json | 2 - .../app/src/components/SettingsModal.tsx | 149 ------------------ openless-all/app/src/i18n/en.ts | 52 ------ openless-all/app/src/i18n/ja.ts | 56 +------ openless-all/app/src/i18n/ko.ts | 52 ------ openless-all/app/src/i18n/zh-CN.ts | 52 ------ openless-all/app/src/i18n/zh-TW.ts | 52 ------ openless-all/app/src/lib/fontFamily.ts | 140 ---------------- openless-all/app/src/lib/quietMode.ts | 20 --- openless-all/app/src/main.tsx | 10 -- openless-all/app/src/styles/tokens.css | 15 +- 12 files changed, 7 insertions(+), 620 deletions(-) delete mode 100644 openless-all/app/src/lib/fontFamily.ts delete mode 100644 openless-all/app/src/lib/quietMode.ts diff --git a/openless-all/app/package-lock.json b/openless-all/app/package-lock.json index fd8f7241..4f9b7c9f 100644 --- a/openless-all/app/package-lock.json +++ b/openless-all/app/package-lock.json @@ -8,8 +8,6 @@ "name": "openless-app", "version": "1.2.24-4", "dependencies": { - "@fontsource/inter": "^5.2.8", - "@fontsource/noto-sans-jp": "^5.2.9", "@tauri-apps/api": "^2.1.1", "@tauri-apps/plugin-autostart": "^2.5.1", "@tauri-apps/plugin-dialog": "^2.7.1", @@ -61,7 +59,6 @@ "integrity": "sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/code-frame": "^7.29.0", "@babel/generator": "^7.29.0", @@ -713,24 +710,6 @@ "node": ">=12" } }, - "node_modules/@fontsource/inter": { - "version": "5.2.8", - "resolved": "https://registry.npmjs.org/@fontsource/inter/-/inter-5.2.8.tgz", - "integrity": "sha512-P6r5WnJoKiNVV+zvW2xM13gNdFhAEpQ9dQJHt3naLvfg+LkF2ldgSLiF4T41lf1SQCM9QmkqPTn4TH568IRagg==", - "license": "OFL-1.1", - "funding": { - "url": "https://github.com/sponsors/ayuhito" - } - }, - "node_modules/@fontsource/noto-sans-jp": { - "version": "5.2.9", - "resolved": "https://registry.npmjs.org/@fontsource/noto-sans-jp/-/noto-sans-jp-5.2.9.tgz", - "integrity": "sha512-6yVGiofnrnbiJjU8ch4JGSs2HqyozxMvsVyVmFwOnDH3u//qQKLqmKM4n0lqN0637uaJNzUW9nIJqbbMgHVQzw==", - "license": "OFL-1.1", - "funding": { - "url": "https://github.com/sponsors/ayuhito" - } - }, "node_modules/@jridgewell/gen-mapping": { "version": "0.3.13", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", @@ -1466,7 +1445,6 @@ "integrity": "sha512-z9VXpC7MWrhfWipitjNdgCauoMLRdIILQsAEV+ZesIzBq/oUlxk0m3ApZuMFCXdnS4U7KrI+l3WRUEGQ8K1QKw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@types/prop-types": "*", "csstype": "^3.2.2" @@ -1536,7 +1514,6 @@ } ], "license": "MIT", - "peer": true, "dependencies": { "baseline-browser-mapping": "^2.10.12", "caniuse-lite": "^1.0.30001782", @@ -1713,7 +1690,6 @@ } ], "license": "MIT", - "peer": true, "peerDependencies": { "typescript": "^5 || ^6" }, @@ -1863,7 +1839,6 @@ "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", "license": "MIT", - "peer": true, "dependencies": { "loose-envify": "^1.1.0" }, @@ -2001,7 +1976,6 @@ "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", "devOptional": true, "license": "Apache-2.0", - "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -2056,7 +2030,6 @@ "integrity": "sha512-o5a9xKjbtuhY6Bi5S3+HvbRERmouabWbyUcpXXUA1u+GNUKoROi9byOJ8M0nHbHYHkYICiMlqxkg1KkYmm25Sw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "esbuild": "^0.21.3", "postcss": "^8.4.43", diff --git a/openless-all/app/package.json b/openless-all/app/package.json index 5339c1ba..4f2e75f4 100644 --- a/openless-all/app/package.json +++ b/openless-all/app/package.json @@ -11,8 +11,6 @@ "check:hotkey-injection": "node scripts/check-hotkey-injection.mjs" }, "dependencies": { - "@fontsource/inter": "^5.2.8", - "@fontsource/noto-sans-jp": "^5.2.9", "@tauri-apps/api": "^2.1.1", "@tauri-apps/plugin-autostart": "^2.5.1", "@tauri-apps/plugin-dialog": "^2.7.1", diff --git a/openless-all/app/src/components/SettingsModal.tsx b/openless-all/app/src/components/SettingsModal.tsx index ecab61d2..62e98e85 100644 --- a/openless-all/app/src/components/SettingsModal.tsx +++ b/openless-all/app/src/components/SettingsModal.tsx @@ -10,14 +10,6 @@ import { Icon } from './Icon'; import { AboutUpdateControl, Settings as SettingsContent, Toggle, type SettingsSectionId } from '../pages/Settings'; import { Row } from './ui/Row'; import { readFontScale, setFontScale, type FontScaleId } from '../lib/fontScale'; -import { - type FontFamilyId, - readFontFamily, - readFontFamilyCustom, - setFontFamily, - querySystemFonts, -} from '../lib/fontFamily'; -import { readQuietCompletion, setQuietCompletion } from '../lib/quietMode'; import { exportErrorLog, fetchLatestBetaRelease, @@ -230,17 +222,6 @@ function PersonalizeSection() { ['large', t('modal.personalize.fontLarge')], ]; - // UI フォント(PolishMode の出力スタイルではなく、アプリ内 UI のフォントファミリ)。 - // localStorage キーは fontFamily.ts 側で管理(`ol-font-family` / `ol-font-family-custom`)。 - const [fontFamilyId, setFontFamilyIdState] = useState(() => readFontFamily()); - const [fontFamilyCustom, setFontFamilyCustomState] = useState(() => readFontFamilyCustom()); - const [systemFonts, setSystemFonts] = useState([]); - const [systemFontsLoading, setSystemFontsLoading] = useState(false); - const [systemFontsError, setSystemFontsError] = useState(null); - - // サイレントモード — Capsule のテキストオーバーレイ抑制。`ol-quiet-completion` をそのまま使う。 - const [quietMode, setQuietModeState] = useState(() => readQuietCompletion()); - return (
@@ -276,136 +257,6 @@ function PersonalizeSection() { })}
- -
-
- - -
- {fontFamilyId === 'custom' && ( - { - const name = e.target.value; - setFontFamilyCustomState(name); - setFontFamily('custom', name); - }} - placeholder={t('modal.personalize.fontFamilyCustomPlaceholder')} - style={{ - padding: '6px 10px', - borderRadius: 8, - border: '0.5px solid var(--ol-line-strong)', - background: 'var(--ol-surface)', - color: 'var(--ol-ink)', - fontFamily: 'inherit', - fontSize: 12.5, - width: '100%', - maxWidth: 360, - }} - /> - )} - {systemFontsError && ( -
- {systemFontsError} -
- )} -
-
- - -
, string> = { - notoSansJp: "'Noto Sans JP', sans-serif", - yuGothic: "'Yu Gothic UI', 'Yu Gothic', 'Meiryo', sans-serif", - meiryo: "'Meiryo', sans-serif", - hiragino: "'Hiragino Sans', 'Hiragino Kaku Gothic ProN', sans-serif", -}; - -const FALLBACK_TAIL = "'Microsoft YaHei', system-ui, sans-serif"; - -const FONT_FAMILY_KEY = 'ol-font-family'; -const FONT_FAMILY_CUSTOM_KEY = 'ol-font-family-custom'; - -function escapeFontName(name: string): string { - // Quote the family name; CSS allows unquoted single-word names but anything - // with spaces or punctuation must be quoted. Always quote to keep things - // predictable. Replace any embedded single quotes defensively. - return `'${name.replace(/'/g, '\\\'')}'`; -} - -export function readFontFamily(): FontFamilyId { - try { - const v = window.localStorage.getItem(FONT_FAMILY_KEY); - if ( - v === 'auto' || - v === 'notoSansJp' || - v === 'yuGothic' || - v === 'meiryo' || - v === 'hiragino' || - v === 'custom' - ) { - return v; - } - } catch { - /* localStorage unavailable: ignore */ - } - return 'auto'; -} - -export function readFontFamilyCustom(): string { - try { - return window.localStorage.getItem(FONT_FAMILY_CUSTOM_KEY) ?? ''; - } catch { - return ''; - } -} - -export function applyFontFamily(id: FontFamilyId, customName?: string): void { - const root = document.documentElement; - if (id === 'auto') { - root.style.removeProperty('--ol-font-sans-active'); - return; - } - if (id === 'custom') { - const name = (customName ?? '').trim(); - if (!name) { - root.style.removeProperty('--ol-font-sans-active'); - return; - } - root.style.setProperty( - '--ol-font-sans-active', - `'Inter', ${escapeFontName(name)}, ${FALLBACK_TAIL}`, - ); - return; - } - const stack = PRESET_STACKS[id]; - root.style.setProperty( - '--ol-font-sans-active', - `'Inter', ${stack}, ${FALLBACK_TAIL}`, - ); -} - -export function setFontFamily(id: FontFamilyId, customName?: string): void { - applyFontFamily(id, customName); - try { - window.localStorage.setItem(FONT_FAMILY_KEY, id); - if (id === 'custom' && customName !== undefined) { - window.localStorage.setItem(FONT_FAMILY_CUSTOM_KEY, customName); - } - } catch { - /* ignore */ - } -} - -/** - * Enumerate fonts installed on the host via the Web Local Font Access API. - * Returns unique family names sorted alphabetically. Returns an empty array - * (without throwing) when the API is unavailable or the user denied access; - * the caller should treat that as "feature not available" and keep the - * default presets. - * - * Must be called from a user gesture (button click) — Chromium gates this - * API behind a one-time permission prompt. - */ -export async function querySystemFonts(): Promise { - type LocalFont = { family: string }; - const w = window as unknown as { - queryLocalFonts?: () => Promise; - }; - if (typeof w.queryLocalFonts !== 'function') return []; - try { - const fonts = await w.queryLocalFonts(); - const families = new Set(); - for (const f of fonts) { - if (f.family) families.add(f.family); - } - return Array.from(families).sort((a, b) => - a.localeCompare(b, 'ja', { sensitivity: 'base' }), - ); - } catch (err) { - // Permission denied or API blocked — caller falls back to manual entry. - // eslint-disable-next-line no-console - console.warn('[fontFamily] queryLocalFonts failed:', err); - return []; - } -} - -// Apply the saved choice on module load so the override takes effect before -// the first paint. main.tsx imports this for its side effect. -applyFontFamily(readFontFamily(), readFontFamilyCustom()); diff --git a/openless-all/app/src/lib/quietMode.ts b/openless-all/app/src/lib/quietMode.ts deleted file mode 100644 index 8e4bb143..00000000 --- a/openless-all/app/src/lib/quietMode.ts +++ /dev/null @@ -1,20 +0,0 @@ -// Quiet mode 状態(capsule のテキストオーバーレイ抑制)の localStorage アクセスを集約。 -// Capsule.tsx と SettingsModal.tsx 双方から同じキー(ol-quiet-completion)を参照する。 - -const QUIET_COMPLETION_KEY = 'ol-quiet-completion'; - -export function readQuietCompletion(): boolean { - try { - return window.localStorage.getItem(QUIET_COMPLETION_KEY) === 'true'; - } catch { - return false; - } -} - -export function setQuietCompletion(value: boolean): void { - try { - window.localStorage.setItem(QUIET_COMPLETION_KEY, value ? 'true' : 'false'); - } catch { - /* localStorage unavailable: ignore */ - } -} diff --git a/openless-all/app/src/main.tsx b/openless-all/app/src/main.tsx index 0506df64..0c592ec5 100644 --- a/openless-all/app/src/main.tsx +++ b/openless-all/app/src/main.tsx @@ -2,16 +2,6 @@ import React from "react"; import ReactDOM from "react-dom/client"; import { App } from "./App"; import i18n from "./i18n"; // 副作用:触发 i18next init -import "./lib/fontFamily"; // 副作用:把保存された UIフォントの選択を初期適用 -// Bundle web fonts locally so they load without network access (CSP-safe) -import "@fontsource/inter/400.css"; -import "@fontsource/inter/500.css"; -import "@fontsource/inter/600.css"; -import "@fontsource/inter/700.css"; -import "@fontsource/noto-sans-jp/400.css"; -import "@fontsource/noto-sans-jp/500.css"; -import "@fontsource/noto-sans-jp/600.css"; -import "@fontsource/noto-sans-jp/700.css"; import "./styles/tokens.css"; import "./styles/global.css"; diff --git a/openless-all/app/src/styles/tokens.css b/openless-all/app/src/styles/tokens.css index 2138f7b8..da26024f 100755 --- a/openless-all/app/src/styles/tokens.css +++ b/openless-all/app/src/styles/tokens.css @@ -1,5 +1,7 @@ /* OpenLess design tokens — black + white + electric blue accent, glassy */ +@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap'); + :root { /* Palette — neutrals */ --ol-white: #ffffff; @@ -49,12 +51,8 @@ --ol-r-2xl: 22px; --ol-r-pill: 999px; - /* Typography - ja: prefer Genshin Gothic (bundled) and Windows/Mac native Japanese fonts - before falling back to Chinese fonts; this prevents Japanese text from - being rendered with Chinese glyphs (e.g. "直" "骨" "户" shape variants) - on Windows when Microsoft YaHei would otherwise be selected. */ - --ol-font-sans: 'Inter', 'Noto Sans JP', 'Genshin Gothic', 'Yu Gothic UI', 'Hiragino Sans', 'Meiryo', 'PingFang SC', 'Microsoft YaHei', -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif; + /* Typography */ + --ol-font-sans: 'Inter', 'PingFang SC', 'Microsoft YaHei', -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif; --ol-font-mono: 'JetBrains Mono', 'SF Mono', 'Cascadia Code', 'Consolas', monospace; /* Status colors (sparse use only) */ @@ -69,10 +67,7 @@ body { margin: 0; - /* `--ol-font-sans-active` is set by src/lib/fontFamily.ts when the user - picks a non-default font in Style settings. Falls back to the default - cascade when unset. */ - font-family: var(--ol-font-sans-active, var(--ol-font-sans)); + font-family: var(--ol-font-sans); color: var(--ol-ink); -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale;