diff --git a/debian/changelog b/debian/changelog index 8fb4c320..b78193f9 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,4 +1,4 @@ -spark-store (5.3.0.1) UNRELEASED; urgency=medium +spark-store (5.3.0.2-test) UNRELEASED; urgency=medium * Initial release. diff --git a/src/App.vue b/src/App.vue index abd3b205..e9ed680b 100644 --- a/src/App.vue +++ b/src/App.vue @@ -344,6 +344,7 @@ import ReviewUserProfileModal from "./components/ReviewUserProfileModal.vue"; import WindowTitleBar from "./components/WindowTitleBar.vue"; import SubmitterWindow from "./components/SubmitterWindow.vue"; import { initTagPriorityStrategy } from "./global/tagPriority"; +import { initFontSize } from "./global/displaySettings"; import { FLARUM_BASE_URL, FLARUM_REGISTER_URL, @@ -1052,6 +1053,8 @@ onMounted(async () => { // 应用启动即锁定标签优先显示策略的真实持久化值,避免依赖详情页挂载顺序 // 导致先读到内存默认值 "auto" 再懒加载的竞态窗口。 initTagPriorityStrategy(); + // 恢复并应用持久化的字体大小档位(仅字号),避免渲染瞬间默认字号闪烁。 + initFontSize(); initTheme(); updateCenterStore.bind(); diff --git a/src/components/SettingsModal.vue b/src/components/SettingsModal.vue index 7cc55d35..f14110c8 100644 --- a/src/components/SettingsModal.vue +++ b/src/components/SettingsModal.vue @@ -163,6 +163,56 @@ + + +
+
+
+ +
+
+

+ 字体大小 +

+

+ 调整全局界面字体大小(仅字号) +

+
+ +
+

+ 预览:星火应用商店 Spark Store 123 +

+
+
+
@@ -185,6 +235,12 @@ import { setTagPriorityStrategy, type TagPriorityStrategy, } from "../global/tagPriority"; +import { + getFontSize, + setFontSize, + FONT_SIZE_OPTIONS, + type FontSizeOption, +} from "../global/displaySettings"; const props = defineProps<{ show: boolean; @@ -206,6 +262,9 @@ const strategyOptions: Array<{ value: TagPriorityStrategy; label: string }> = [ { value: "apm", label: "APM 优先" }, ]; +// 字体大小档位选项(小 / 标准 / 大 / 特大) +const fontSizeOptions = FONT_SIZE_OPTIONS; + const tagPriorityStrategy = ref("auto"); // 加载标签优先显示策略(从持久化读取) @@ -219,6 +278,19 @@ const selectStrategy = (value: TagPriorityStrategy) => { setTagPriorityStrategy(value); }; +// 字体大小档位(仅字号,不含整体缩放/字体族) +const fontSize = ref("medium"); + +const loadFontSize = () => { + fontSize.value = getFontSize(); +}; + +// 选择并保存字号档位(立即应用到 html,全局 rem 字号类联动) +const selectFontSize = (value: FontSizeOption) => { + fontSize.value = value; + setFontSize(value); +}; + const settings = ref({ enableUpdateCheck: true, enableCreateDesktop: true, @@ -279,6 +351,7 @@ watch( if (newVal) { loadSettings(); loadTagPriority(); + loadFontSize(); } }, ); diff --git a/src/global/displaySettings.ts b/src/global/displaySettings.ts new file mode 100644 index 00000000..e34bcc71 --- /dev/null +++ b/src/global/displaySettings.ts @@ -0,0 +1,75 @@ +/** + * 显示设置:全局字体大小档位(仅字号,不含整体缩放/字体族)。 + * + * 实现原理:Tailwind 4 的 `text-*` 字号类均为 rem 单位(如 text-sm = 0.875rem), + * 因此修改根元素 `html` 的 font-size 即可让全部 rem 字号类联动缩放。 + * 取值范围:14px(小) ~ 18px(特大),默认 16px(标准)。 + * + * 持久化:localStorage key = "spark-store-font-size",存档位枚举字符串。 + */ +export type FontSizeOption = "small" | "medium" | "large" | "xlarge"; + +interface FontSizeMeta { + /** 应用到 html 的 font-size(px) */ + px: number; + label: string; +} + +export const FONT_SIZE_OPTIONS: Array<{ + value: FontSizeOption; + label: string; +}> = [ + { value: "small", label: "小" }, + { value: "medium", label: "标准" }, + { value: "large", label: "大" }, + { value: "xlarge", label: "特大" }, +]; + +// 各档位对应的根字号。medium 保持现状 16px,向上放大、向下略缩。 +const FONT_SIZE_MAP: Record = { + small: { px: 15, label: "小" }, + medium: { px: 16, label: "标准" }, + large: { px: 17, label: "大" }, + xlarge: { px: 18, label: "特大" }, +}; + +const FONT_SIZE_STORAGE_KEY = "spark-store-font-size"; +const DEFAULT_FONT_SIZE: FontSizeOption = "medium"; + +const isValidFontSize = (v: unknown): v is FontSizeOption => + typeof v === "string" && v in FONT_SIZE_MAP; + +/** 读取持久化的字号档位(无/非法时回退默认「标准」) */ +export const getFontSize = (): FontSizeOption => { + try { + const raw = localStorage.getItem(FONT_SIZE_STORAGE_KEY); + if (isValidFontSize(raw)) return raw; + } catch { + // localStorage 不可用时忽略,使用默认 + } + return DEFAULT_FONT_SIZE; +}; + +/** 将字号档位应用到根元素 html(写入 inline font-size) */ +export const applyFontSize = (option: FontSizeOption): void => { + const meta = FONT_SIZE_MAP[option] ?? FONT_SIZE_MAP[DEFAULT_FONT_SIZE]; + document.documentElement.style.fontSize = `${meta.px}px`; +}; + +/** 选择并持久化字号档位,同时立即应用 */ +export const setFontSize = (option: FontSizeOption): void => { + applyFontSize(option); + try { + localStorage.setItem(FONT_SIZE_STORAGE_KEY, option); + } catch { + // 持久化失败时仍已应用当前会话,忽略写入错误 + } +}; + +/** + * 应用启动时初始化:从持久化恢复并使用,避免渲染瞬间闪烁。 + * 应在 App.vue 的 onMounted 最前调用(与 initTagPriorityStrategy 同级)。 + */ +export const initFontSize = (): void => { + applyFontSize(getFontSize()); +};