feat(app): add configurable global background wallpaper

This commit is contained in:
miracle authored and GitHub committed 2026-09-08 11:19:24 +08:00
1 parent 5fb667716f
commit 39aa663ebf
28 files changed
+1240 -1

No files matched your search

@@ -0,0 +1,33 @@
import { describe, expect, it } from "vitest";
import { DEFAULT_EDITOR_SETTINGS, normalizeEditorSettings } from "@/stores/settingsStore";
import { defaultBackgroundImageSettings } from "@/lib/app/appBackgroundImage";
describe("normalizeEditorSettings backgroundImage", () => {
it("merges default background image settings for legacy configs missing the field", () => {
const normalized = normalizeEditorSettings({ fontFamily: "'Fira Code', monospace" } as never);
expect(normalized.backgroundImage).toEqual(defaultBackgroundImageSettings());
expect(normalized.fontFamily).toBe("'Fira Code', monospace");
});
it("keeps configured background image values and clamps invalid ones", () => {
const normalized = normalizeEditorSettings({
backgroundImage: { filePath: "/data/background-image.jpg", fileName: "a.jpg", opacity: 0.4, blur: 6, displayMode: "tile" },
} as never);
expect(normalized.backgroundImage).toEqual({ filePath: "/data/background-image.jpg", fileName: "a.jpg", opacity: 0.4, blur: 6, displayMode: "tile" });
const clamped = normalizeEditorSettings({ backgroundImage: { opacity: 12, blur: -1 } } as never);
expect(clamped.backgroundImage.opacity).toBe(1);
expect(clamped.backgroundImage.blur).toBe(0);
});
it("drops unknown fields from stored settings (showOn* from the removed scoped mode)", () => {
const normalized = normalizeEditorSettings({
backgroundImage: { filePath: "/data/background-image.jpg", fileName: "a.jpg", opacity: 0.5, blur: 0, showOnWelcome: true, showOnEditor: true },
} as never);
expect(normalized.backgroundImage).toEqual({ filePath: "/data/background-image.jpg", fileName: "a.jpg", opacity: 0.5, blur: 0, displayMode: "fill" });
});
it("uses default settings for a brand-new store baseline", () => {
expect(DEFAULT_EDITOR_SETTINGS.backgroundImage).toEqual(defaultBackgroundImageSettings());
});
});
+5
View File
@@ -2,6 +2,7 @@ import { defineStore } from "pinia";
import { computed, ref } from "vue";
import { aiConfigToItem, generateId, getConfigKey } from "@/lib/ai/aiConfigList";
import { DEFAULT_DATA_GRID_FONT_FAMILY, DEFAULT_UI_FONT_FAMILY } from "@/lib/app/appFonts";
import { defaultBackgroundImageSettings, normalizeBackgroundImageSettings, type BackgroundImageSettings } from "@/lib/app/appBackgroundImage";
import * as api from "@/lib/backend/api";
import { setDebugLoggingEnabled } from "@/lib/backend/debugLog";
import { safeLocalStorageGet, safeLocalStorageRemove } from "@/lib/backend/safeStorage";
@@ -724,6 +725,7 @@ export interface EditorSettings {
uiFontFamily: string;
uiScale: number;
theme: EditorTheme;
backgroundImage: BackgroundImageSettings;
customThemeColors: CustomThemeColors;
customThemes: CustomTheme[];
activeCustomThemeId: string;
@@ -956,6 +958,7 @@ export const DEFAULT_EDITOR_SETTINGS: EditorSettings = {
uiFontFamily: DEFAULT_UI_FONT_FAMILY,
uiScale: 1,
theme: "app",
backgroundImage: defaultBackgroundImageSettings(),
customThemeColors: { ...DEFAULT_CUSTOM_THEME_COLORS },
customThemes: [...DEFAULT_CUSTOM_THEMES],
activeCustomThemeId: "default",
@@ -1586,6 +1589,7 @@ export function normalizeEditorSettings(settings: Partial<EditorSettings>, exist
clickTableNavigationTarget: normalizeClickTableNavigationTarget(settings.clickTableNavigationTarget),
completionTriggerMode: normalizeCompletionTriggerMode(settings.completionTriggerMode),
defaultTransactionMode: normalizeDefaultTransactionMode(settings.defaultTransactionMode),
backgroundImage: normalizeBackgroundImageSettings(settings.backgroundImage),
};
}
@@ -2089,6 +2093,7 @@ export const useSettingsStore = defineStore("settings", () => {
if (partial.fontSize !== undefined) editorSettings.value.fontSize = partial.fontSize;
if (partial.uiFontFamily !== undefined) editorSettings.value.uiFontFamily = normalizeFontFamily(partial.uiFontFamily, DEFAULT_EDITOR_SETTINGS.uiFontFamily);
if (partial.uiScale !== undefined) editorSettings.value.uiScale = normalizeUiScale(partial.uiScale);
if (partial.backgroundImage !== undefined) editorSettings.value.backgroundImage = normalizeBackgroundImageSettings(partial.backgroundImage);
if (partial.theme !== undefined) editorSettings.value.theme = partial.theme;
if (partial.customThemeColors !== undefined) {
editorSettings.value.customThemeColors = {