mirror of
https://github.com/t8y2/dbx.git
synced 2026-11-02 08:30:35 +00:00
feat: custom theme system with PostgreSQL PL/pgSQL highlighting fix
- Fix PostgreSQL function highlighting by disabling doubleDollarQuotedStrings in extended PostgreSQL dialect, enabling PL/pgSQL syntax highlighting inside $ blocks - Add complete custom editor theme system with multi-theme management (create, rename, duplicate, delete), visual color editor (12 colors), JSON import/export, real-time preview, and 12 preset color schemes - Add background/foreground color customization with system theme defaults - Optimize EditorSettingsDialog layout: 2-column grid with font selector taking available space and theme dropdown grouped with custom theme button - Add i18n support for custom theme UI (en, zh-CN, zh-TW, es) - Fix Tauri production build by adding custom-protocol feature - Update .gitignore for temporary build artifacts Closes t8y2#788 Co-authored-by: Sam <14344444@@qq.com>
This commit is contained in:
@@ -179,7 +179,8 @@ export type EditorTheme =
|
||||
| "material"
|
||||
| "duotone-light"
|
||||
| "duotone-dark"
|
||||
| "xcode";
|
||||
| "xcode"
|
||||
| "custom";
|
||||
|
||||
const STRUCTURE_EDITOR_DENSITIES = ["compact", "standard", "comfortable"] as const;
|
||||
export type StructureEditorDensity = (typeof STRUCTURE_EDITOR_DENSITIES)[number];
|
||||
@@ -190,11 +191,53 @@ export type DataGridRenderMode = (typeof DATA_GRID_RENDER_MODES)[number];
|
||||
const DISCONNECT_TAB_HANDLING_MODES = ["close-tabs", "keep-tabs-clear-results", "keep-tabs-keep-results"] as const;
|
||||
export type DisconnectTabHandlingMode = (typeof DISCONNECT_TAB_HANDLING_MODES)[number];
|
||||
|
||||
// 自定义主题颜色配置
|
||||
export interface CustomThemeColors {
|
||||
keyword: string;
|
||||
field: string;
|
||||
function: string;
|
||||
string: string;
|
||||
number: string;
|
||||
comment: string;
|
||||
table: string;
|
||||
operator: string;
|
||||
type: string;
|
||||
builtin: string;
|
||||
background?: string;
|
||||
foreground?: string;
|
||||
}
|
||||
|
||||
export const DEFAULT_CUSTOM_THEME_COLORS: CustomThemeColors = {
|
||||
keyword: "#cba6f7",
|
||||
field: "#f9e2af",
|
||||
function: "#89dceb",
|
||||
string: "#a6e3a1",
|
||||
number: "#fab387",
|
||||
comment: "#6c7086",
|
||||
table: "#a6e3a1",
|
||||
operator: "#89b4fa",
|
||||
type: "#89b4fa",
|
||||
builtin: "#f38ba8",
|
||||
};
|
||||
|
||||
export interface CustomTheme {
|
||||
id: string;
|
||||
name: string;
|
||||
colors: CustomThemeColors;
|
||||
}
|
||||
|
||||
export const DEFAULT_CUSTOM_THEMES: CustomTheme[] = [
|
||||
{ id: "default", name: "自定义", colors: { ...DEFAULT_CUSTOM_THEME_COLORS } },
|
||||
];
|
||||
|
||||
export interface EditorSettings {
|
||||
fontFamily: string;
|
||||
fontSize: number;
|
||||
uiScale: number;
|
||||
theme: EditorTheme;
|
||||
customThemeColors: CustomThemeColors;
|
||||
customThemes: CustomTheme[];
|
||||
activeCustomThemeId: string;
|
||||
executeMode: "all" | "current";
|
||||
wordWrap: boolean;
|
||||
confirmDangerousSqlExecution: boolean;
|
||||
@@ -236,6 +279,7 @@ export const EDITOR_THEMES: { value: EditorTheme; label: string; dark: boolean }
|
||||
{ value: "duotone-light", label: "Duotone Light", dark: false },
|
||||
{ value: "duotone-dark", label: "Duotone Dark", dark: true },
|
||||
{ value: "xcode", label: "Xcode", dark: false },
|
||||
{ value: "custom", label: "Custom (可自定义)", dark: true },
|
||||
];
|
||||
|
||||
const EDITOR_THEME_VALUES = new Set<EditorTheme>(EDITOR_THEMES.map((theme) => theme.value));
|
||||
@@ -255,6 +299,9 @@ export const DEFAULT_EDITOR_SETTINGS: EditorSettings = {
|
||||
fontSize: 13,
|
||||
uiScale: 1,
|
||||
theme: "app",
|
||||
customThemeColors: { ...DEFAULT_CUSTOM_THEME_COLORS },
|
||||
customThemes: [...DEFAULT_CUSTOM_THEMES],
|
||||
activeCustomThemeId: "default",
|
||||
executeMode: "all",
|
||||
wordWrap: false,
|
||||
confirmDangerousSqlExecution: true,
|
||||
@@ -385,6 +432,29 @@ export function normalizeEditorSettings(settings: Partial<EditorSettings>, exist
|
||||
fontSize: settings.fontSize ?? DEFAULT_EDITOR_SETTINGS.fontSize,
|
||||
uiScale: normalizeUiScale(settings.uiScale),
|
||||
theme: settings.theme && EDITOR_THEME_VALUES.has(settings.theme) ? settings.theme : DEFAULT_EDITOR_SETTINGS.theme,
|
||||
customThemeColors: {
|
||||
...DEFAULT_CUSTOM_THEME_COLORS,
|
||||
...settings.customThemeColors,
|
||||
},
|
||||
customThemes: (() => {
|
||||
if (Array.isArray(settings.customThemes) && settings.customThemes.length > 0) {
|
||||
// 自动重命名"默认"为"自定义"
|
||||
return settings.customThemes.map((theme) => (theme.name === "默认" ? { ...theme, name: "自定义" } : theme));
|
||||
}
|
||||
return [
|
||||
...(settings.customThemeColors
|
||||
? [
|
||||
{
|
||||
id: "migrated",
|
||||
name: "已迁移",
|
||||
colors: { ...DEFAULT_CUSTOM_THEME_COLORS, ...settings.customThemeColors },
|
||||
},
|
||||
]
|
||||
: []),
|
||||
...DEFAULT_CUSTOM_THEMES,
|
||||
];
|
||||
})(),
|
||||
activeCustomThemeId: settings.activeCustomThemeId ?? "default",
|
||||
executeMode: settings.executeMode ?? DEFAULT_EDITOR_SETTINGS.executeMode,
|
||||
wordWrap: settings.wordWrap ?? DEFAULT_EDITOR_SETTINGS.wordWrap,
|
||||
confirmDangerousSqlExecution:
|
||||
@@ -543,6 +613,29 @@ export const useSettingsStore = defineStore("settings", () => {
|
||||
if (partial.fontSize !== undefined) editorSettings.value.fontSize = partial.fontSize;
|
||||
if (partial.uiScale !== undefined) editorSettings.value.uiScale = normalizeUiScale(partial.uiScale);
|
||||
if (partial.theme !== undefined) editorSettings.value.theme = partial.theme;
|
||||
if (partial.customThemeColors !== undefined) {
|
||||
editorSettings.value.customThemeColors = {
|
||||
...editorSettings.value.customThemeColors,
|
||||
...partial.customThemeColors,
|
||||
};
|
||||
}
|
||||
if (partial.customThemes !== undefined) {
|
||||
editorSettings.value.customThemes = Array.isArray(partial.customThemes)
|
||||
? partial.customThemes
|
||||
: editorSettings.value.customThemes;
|
||||
}
|
||||
if (partial.activeCustomThemeId !== undefined) {
|
||||
editorSettings.value.activeCustomThemeId = partial.activeCustomThemeId;
|
||||
}
|
||||
// 同步 customThemeColors 为当前激活主题的颜色(兼容回退逻辑)
|
||||
if (partial.customThemes !== undefined || partial.activeCustomThemeId !== undefined) {
|
||||
const themes = editorSettings.value.customThemes;
|
||||
const activeId = editorSettings.value.activeCustomThemeId;
|
||||
const activeTheme = themes.find((t) => t.id === activeId) || themes[0];
|
||||
if (activeTheme) {
|
||||
editorSettings.value.customThemeColors = { ...activeTheme.colors };
|
||||
}
|
||||
}
|
||||
if (partial.executeMode !== undefined) editorSettings.value.executeMode = partial.executeMode;
|
||||
if (partial.wordWrap !== undefined) editorSettings.value.wordWrap = partial.wordWrap;
|
||||
if (partial.confirmDangerousSqlExecution !== undefined)
|
||||
|
||||
Reference in New Issue
Block a user