diff --git a/src/components/UI/CardDecoration.vue b/src/components/UI/CardDecoration.vue index a05eb053..bb33607c 100644 --- a/src/components/UI/CardDecoration.vue +++ b/src/components/UI/CardDecoration.vue @@ -1,10 +1,41 @@ + + + + diff --git a/src/components/common/Settings/BasicSettingsTab.vue b/src/components/common/Settings/BasicSettingsTab.vue index 5878f7fe..ebcc7101 100644 --- a/src/components/common/Settings/BasicSettingsTab.vue +++ b/src/components/common/Settings/BasicSettingsTab.vue @@ -10,6 +10,7 @@ import NetworkSettingsSection from './NetworkSettingsSection.vue' import UITabs from '@/components/UI/Tabs.vue' import { usePlatformService } from '@/services' import { IS_ELECTRON } from '@/utils/platform' +import { INSIGHT_CARD_THEMES, type InsightCardThemeId } from '@/utils/insight-card-theme' const { t } = useI18n() @@ -17,7 +18,7 @@ const { t } = useI18n() const layoutStore = useLayoutStore() const settingsStore = useSettingsStore() const { toolsPanelPosition } = storeToRefs(layoutStore) -const { locale, defaultSessionTab } = storeToRefs(settingsStore) +const { locale, defaultSessionTab, insightCardTheme } = storeToRefs(settingsStore) // Auto Launch const openAtLogin = ref(false) @@ -58,6 +59,16 @@ const colorModeOptions = computed(() => [ { label: t('settings.basic.appearance.dark'), value: 'dark' }, ]) +function getInsightCardThemePreview(startColor: string, endColor: string) { + return { + background: `linear-gradient(135deg, color-mix(in srgb, ${startColor} 35%, white), color-mix(in srgb, ${endColor} 42%, white))`, + } +} + +function selectInsightCardTheme(theme: InsightCardThemeId) { + insightCardTheme.value = theme +} + // Language options const languageOptions = computed(() => availableLocales.map((l) => ({ @@ -131,8 +142,8 @@ const toolsPanelPositionOptions = computed(() => [ {{ t('settings.basic.appearance.title') }} -
-
+
+

{{ t('settings.basic.appearance.themeMode') }} @@ -142,6 +153,42 @@ const toolsPanelPositionOptions = computed(() => [

+
+
+
+

+ {{ t('settings.basic.appearance.insightCardTheme') }} +

+
+
+ +
+
diff --git a/src/i18n/locales/en-US/settings.json b/src/i18n/locales/en-US/settings.json index 61e2190a..0f6ca8b8 100644 --- a/src/i18n/locales/en-US/settings.json +++ b/src/i18n/locales/en-US/settings.json @@ -34,6 +34,8 @@ "appearance": { "title": "Appearance", "themeMode": "Theme Mode", + "insightCardTheme": "Insight card colors", + "insightCardThemeOption": "Color scheme {index}", "auto": "System", "light": "Light", "dark": "Dark" diff --git a/src/i18n/locales/ja-JP/settings.json b/src/i18n/locales/ja-JP/settings.json index 6bae8b2d..d92537db 100644 --- a/src/i18n/locales/ja-JP/settings.json +++ b/src/i18n/locales/ja-JP/settings.json @@ -34,6 +34,8 @@ "appearance": { "title": "外観設定", "themeMode": "テーマモード", + "insightCardTheme": "インサイトカードの配色", + "insightCardThemeOption": "配色 {index}", "auto": "システムに従う", "light": "ライトモード", "dark": "ダークモード" diff --git a/src/i18n/locales/zh-CN/settings.json b/src/i18n/locales/zh-CN/settings.json index a70970e4..67018ff4 100644 --- a/src/i18n/locales/zh-CN/settings.json +++ b/src/i18n/locales/zh-CN/settings.json @@ -34,6 +34,8 @@ "appearance": { "title": "外观设置", "themeMode": "主题模式", + "insightCardTheme": "洞察卡片配色", + "insightCardThemeOption": "配色 {index}", "auto": "跟随系统", "light": "浅色模式", "dark": "深色模式" diff --git a/src/i18n/locales/zh-TW/settings.json b/src/i18n/locales/zh-TW/settings.json index 48ba65f4..54d42c6b 100644 --- a/src/i18n/locales/zh-TW/settings.json +++ b/src/i18n/locales/zh-TW/settings.json @@ -34,6 +34,8 @@ "appearance": { "title": "外觀設定", "themeMode": "主題模式", + "insightCardTheme": "洞察卡片配色", + "insightCardThemeOption": "配色 {index}", "auto": "依系統設定", "light": "淺色模式", "dark": "深色模式" diff --git a/src/stores/settings.ts b/src/stores/settings.ts index a60c2440..d08453f8 100644 --- a/src/stores/settings.ts +++ b/src/stores/settings.ts @@ -10,6 +10,7 @@ import type { PreprocessConfig } from '@electron/preload/index' import type { AIPreprocessConfig } from '@openchatlab/shared-types' import { useAIService, usePlatformService } from '@/services' import { PLATFORM_CAPABILITIES } from '@/utils/platform-capabilities' +import { DEFAULT_INSIGHT_CARD_THEME, type InsightCardThemeId } from '@/utils/insight-card-theme' const DESENSITIZE_RULES_SCHEMA_VERSION = 2 @@ -35,6 +36,8 @@ export const useSettingsStore = defineStore( const defaultSessionTab = ref<'insights' | 'ai-chat'>('insights') + const insightCardTheme = ref(DEFAULT_INSIGHT_CARD_THEME) + const debugMode = ref(false) function setDebugMode(enabled: boolean) { @@ -112,6 +115,7 @@ export const useSettingsStore = defineStore( setLocale, initLocale, defaultSessionTab, + insightCardTheme, debugMode, setDebugMode, aiPreprocessConfig, @@ -120,7 +124,7 @@ export const useSettingsStore = defineStore( }, { persist: { - pick: ['debugMode'], + pick: ['debugMode', 'insightCardTheme'], storage: localStorage, }, backendPersist: { diff --git a/src/utils/insight-card-theme.ts b/src/utils/insight-card-theme.ts new file mode 100644 index 00000000..e929d781 --- /dev/null +++ b/src/utils/insight-card-theme.ts @@ -0,0 +1,35 @@ +export const INSIGHT_CARD_THEME_IDS = [ + 'default', + 'sunset', + 'galaxy', + 'mist', + 'moonlight', + 'berry', + 'sunshine', + 'aurora', +] as const + +export type InsightCardThemeId = (typeof INSIGHT_CARD_THEME_IDS)[number] + +export interface InsightCardTheme { + id: InsightCardThemeId + startColor: string + endColor: string +} + +export const DEFAULT_INSIGHT_CARD_THEME: InsightCardThemeId = 'default' + +export const INSIGHT_CARD_THEMES: readonly InsightCardTheme[] = [ + { id: 'default', startColor: '#60a5fa', endColor: '#f472b6' }, + { id: 'sunset', startColor: '#fb923c', endColor: '#fb7185' }, + { id: 'galaxy', startColor: '#818cf8', endColor: '#c084fc' }, + { id: 'mist', startColor: '#22d3ee', endColor: '#60a5fa' }, + { id: 'moonlight', startColor: '#22c55e', endColor: '#14b8a6' }, + { id: 'berry', startColor: '#fb7185', endColor: '#a78bfa' }, + { id: 'sunshine', startColor: '#f59e0b', endColor: '#facc15' }, + { id: 'aurora', startColor: '#34d399', endColor: '#818cf8' }, +] + +export function getInsightCardTheme(id: InsightCardThemeId): InsightCardTheme { + return INSIGHT_CARD_THEMES.find((theme) => theme.id === id) ?? INSIGHT_CARD_THEMES[0] +}