diff --git a/app/components/@settings/core/ControlPanel.tsx b/app/components/@settings/core/ControlPanel.tsx index c0e19035..0d90975c 100644 --- a/app/components/@settings/core/ControlPanel.tsx +++ b/app/components/@settings/core/ControlPanel.tsx @@ -263,6 +263,27 @@ export const ControlPanel = ({ open, onClose }: ControlPanelProps) => { }, }; + // Reset to default view when modal opens/closes + useEffect(() => { + if (!open) { + // Reset when closing + setActiveTab(null); + setLoadingTab(null); + setShowTabManagement(false); + } else { + // When opening, set to null to show the main view + setActiveTab(null); + } + }, [open]); + + // Handle closing + const handleClose = () => { + setActiveTab(null); + setLoadingTab(null); + setShowTabManagement(false); + onClose(); + }; + // Handlers const handleBack = () => { if (showTabManagement) { @@ -405,8 +426,8 @@ export const ControlPanel = ({ open, onClose }: ControlPanelProps) => { { {/* Close Button */} - ))} - + Preferences
@@ -245,7 +175,7 @@ export default function SettingsTab() {
- {/* Keyboard Shortcuts */} + {/* Simplified Keyboard Shortcuts */}
- {Object.entries(useStore(shortcutsStore)).map(([name, shortcut]) => ( -
-
- - {name.replace(/([A-Z])/g, ' $1').toLowerCase()} - - {shortcut.description && ( - {shortcut.description} - )} -
-
- {shortcut.ctrlOrMetaKey && ( - - {getModifierSymbol(isMac ? 'meta' : 'ctrl')} - - )} - {shortcut.ctrlKey && ( - - {getModifierSymbol('ctrl')} - - )} - {shortcut.metaKey && ( - - {getModifierSymbol('meta')} - - )} - {shortcut.altKey && ( - - {getModifierSymbol('alt')} - - )} - {shortcut.shiftKey && ( - - {getModifierSymbol('shift')} - - )} - - {formatShortcutKey(shortcut.key)} - -
+
+
+ Toggle Theme + Switch between light and dark mode
- ))} +
+ + {getModifierSymbol('meta')} + + + {getModifierSymbol('alt')} + + + {getModifierSymbol('shift')} + + + D + +
+
diff --git a/app/components/chat/BaseChat.tsx b/app/components/chat/BaseChat.tsx index 025fa197..ff1f4184 100644 --- a/app/components/chat/BaseChat.tsx +++ b/app/components/chat/BaseChat.tsx @@ -34,6 +34,7 @@ import ChatAlert from './ChatAlert'; import type { ModelInfo } from '~/lib/modules/llm/types'; import ProgressCompilation from './ProgressCompilation'; import type { ProgressAnnotation } from '~/types/context'; +import { LOCAL_PROVIDERS } from '~/lib/stores/settings'; const TEXTAREA_MIN_HEIGHT = 76; @@ -404,7 +405,7 @@ export const BaseChat = React.forwardRef( apiKeys={apiKeys} modelLoading={isModelLoading} /> - {(providerList || []).length > 0 && provider && ( + {(providerList || []).length > 0 && provider && !LOCAL_PROVIDERS.includes(provider.name) && ( ; activeProviders: ProviderInfo[]; updateProviderSettings: (provider: string, config: IProviderSetting) => void; - isLocalModel: boolean; - enableLocalModels: (enabled: boolean) => void; // Debug and development settings debug: boolean; @@ -81,7 +76,6 @@ export function useSettings(): UseSettingsReturn { const debug = useStore(isDebugMode); const eventLogs = useStore(isEventLogsEnabled); const promptId = useStore(promptStore); - const isLocalModel = useStore(isLocalModelsEnabled); const isLatestBranch = useStore(latestBranchStore); const autoSelectTemplate = useStore(autoSelectStarterTemplate); const [activeProviders, setActiveProviders] = useState([]); @@ -100,16 +94,12 @@ export function useSettings(): UseSettingsReturn { }); useEffect(() => { - let active = Object.entries(providers) + const active = Object.entries(providers) .filter(([_key, provider]) => provider.settings.enabled) .map(([_k, p]) => p); - if (!isLocalModel) { - active = active.filter((p) => !LOCAL_PROVIDERS.includes(p.name)); - } - setActiveProviders(active); - }, [providers, isLocalModel]); + }, [providers]); const saveSettings = useCallback((newSettings: Partial) => { setSettings((prev) => { @@ -135,11 +125,6 @@ export function useSettings(): UseSettingsReturn { logStore.logSystem(`Event logs ${enabled ? 'enabled' : 'disabled'}`); }, []); - const enableLocalModels = useCallback((enabled: boolean) => { - updateLocalModels(enabled); - logStore.logSystem(`Local models ${enabled ? 'enabled' : 'disabled'}`); - }, []); - const setPromptId = useCallback((id: string) => { updatePromptId(id); logStore.logSystem(`Prompt template updated to ${id}`); @@ -205,8 +190,6 @@ export function useSettings(): UseSettingsReturn { providers, activeProviders, updateProviderSettings, - isLocalModel, - enableLocalModels, debug, enableDebugMode, eventLogs, diff --git a/app/lib/stores/settings.ts b/app/lib/stores/settings.ts index d8b1ca18..ccd3e2b1 100644 --- a/app/lib/stores/settings.ts +++ b/app/lib/stores/settings.ts @@ -1,5 +1,4 @@ import { atom, map } from 'nanostores'; -import { workbenchStore } from './workbench'; import { PROVIDER_LIST } from '~/utils/constants'; import type { IProviderConfig } from '~/types/model'; import type { @@ -11,7 +10,7 @@ import type { import { DEFAULT_TAB_CONFIG } from '~/components/@settings/core/constants'; import Cookies from 'js-cookie'; import { toggleTheme } from './theme'; -import { chatStore } from './chat'; +import { create } from 'zustand'; export interface Shortcut { key: string; @@ -26,10 +25,8 @@ export interface Shortcut { } export interface Shortcuts { - toggleTerminal: Shortcut; toggleTheme: Shortcut; - toggleChat: Shortcut; - toggleSettings: Shortcut; + toggleTerminal: Shortcut; } export const URL_CONFIGURABLE_PROVIDERS = ['Ollama', 'LMStudio', 'OpenAILike']; @@ -37,15 +34,8 @@ export const LOCAL_PROVIDERS = ['OpenAILike', 'LMStudio', 'Ollama']; export type ProviderSetting = Record; -// Define safer shortcuts that don't conflict with browser defaults +// Simplified shortcuts store with only theme toggle export const shortcutsStore = map({ - toggleTerminal: { - key: '`', - ctrlOrMetaKey: true, - action: () => workbenchStore.toggleTerminal(), - description: 'Toggle terminal', - isPreventDefault: true, - }, toggleTheme: { key: 'd', metaKey: true, @@ -55,22 +45,13 @@ export const shortcutsStore = map({ description: 'Toggle theme', isPreventDefault: true, }, - toggleChat: { - key: 'j', // Changed from 'k' to 'j' to avoid conflicts + toggleTerminal: { + key: '`', ctrlOrMetaKey: true, - altKey: true, // Added alt key to make it more unique - action: () => chatStore.setKey('showChat', !chatStore.get().showChat), - description: 'Toggle chat', - isPreventDefault: true, - }, - toggleSettings: { - key: 's', - ctrlOrMetaKey: true, - altKey: true, action: () => { - document.dispatchEvent(new CustomEvent('toggle-settings')); + // This will be handled by the terminal component }, - description: 'Toggle settings', + description: 'Toggle terminal', isPreventDefault: true, }, }); @@ -148,7 +129,6 @@ const SETTINGS_KEYS = { AUTO_SELECT_TEMPLATE: 'autoSelectTemplate', CONTEXT_OPTIMIZATION: 'contextOptimizationEnabled', EVENT_LOGS: 'isEventLogsEnabled', - LOCAL_MODELS: 'isLocalModelsEnabled', PROMPT_ID: 'promptId', DEVELOPER_MODE: 'isDeveloperMode', } as const; @@ -175,10 +155,9 @@ const getInitialSettings = () => { return { latestBranch: getStoredBoolean(SETTINGS_KEYS.LATEST_BRANCH, false), - autoSelectTemplate: getStoredBoolean(SETTINGS_KEYS.AUTO_SELECT_TEMPLATE, false), - contextOptimization: getStoredBoolean(SETTINGS_KEYS.CONTEXT_OPTIMIZATION, false), + autoSelectTemplate: getStoredBoolean(SETTINGS_KEYS.AUTO_SELECT_TEMPLATE, true), + contextOptimization: getStoredBoolean(SETTINGS_KEYS.CONTEXT_OPTIMIZATION, true), eventLogs: getStoredBoolean(SETTINGS_KEYS.EVENT_LOGS, true), - localModels: getStoredBoolean(SETTINGS_KEYS.LOCAL_MODELS, true), promptId: isBrowser ? localStorage.getItem(SETTINGS_KEYS.PROMPT_ID) || 'default' : 'default', developerMode: getStoredBoolean(SETTINGS_KEYS.DEVELOPER_MODE, false), }; @@ -191,7 +170,6 @@ export const latestBranchStore = atom(initialSettings.latestBranch); export const autoSelectStarterTemplate = atom(initialSettings.autoSelectTemplate); export const enableContextOptimizationStore = atom(initialSettings.contextOptimization); export const isEventLogsEnabled = atom(initialSettings.eventLogs); -export const isLocalModelsEnabled = atom(initialSettings.localModels); export const promptStore = atom(initialSettings.promptId); // Helper functions to update settings with persistence @@ -215,11 +193,6 @@ export const updateEventLogs = (enabled: boolean) => { localStorage.setItem(SETTINGS_KEYS.EVENT_LOGS, JSON.stringify(enabled)); }; -export const updateLocalModels = (enabled: boolean) => { - isLocalModelsEnabled.set(enabled); - localStorage.setItem(SETTINGS_KEYS.LOCAL_MODELS, JSON.stringify(enabled)); -}; - export const updatePromptId = (id: string) => { promptStore.set(id); localStorage.setItem(SETTINGS_KEYS.PROMPT_ID, id); @@ -319,3 +292,35 @@ export const setDeveloperMode = (value: boolean) => { localStorage.setItem(SETTINGS_KEYS.DEVELOPER_MODE, JSON.stringify(value)); } }; + +// First, let's define the SettingsStore interface +interface SettingsStore { + isOpen: boolean; + selectedTab: string; + openSettings: () => void; + closeSettings: () => void; + setSelectedTab: (tab: string) => void; +} + +export const useSettingsStore = create((set) => ({ + isOpen: false, + selectedTab: 'user', // Default tab + + openSettings: () => { + set({ + isOpen: true, + selectedTab: 'user', // Always open to user tab + }); + }, + + closeSettings: () => { + set({ + isOpen: false, + selectedTab: 'user', // Reset to user tab when closing + }); + }, + + setSelectedTab: (tab: string) => { + set({ selectedTab: tab }); + }, +})); diff --git a/app/utils/debounce.ts b/app/utils/debounce.ts index 3b91d7a4..56813aa9 100644 --- a/app/utils/debounce.ts +++ b/app/utils/debounce.ts @@ -1,17 +1,13 @@ -export function debounce(fn: (...args: Args) => void, delay = 100) { - if (delay === 0) { - return fn; - } +export function debounce any>(func: T, wait: number): (...args: Parameters) => void { + let timeout: NodeJS.Timeout; - let timer: number | undefined; + return function executedFunction(...args: Parameters) { + const later = () => { + clearTimeout(timeout); + func(...args); + }; - return function (this: U, ...args: Args) { - const context = this; - - clearTimeout(timer); - - timer = window.setTimeout(() => { - fn.apply(context, args); - }, delay); + clearTimeout(timeout); + timeout = setTimeout(later, wait); }; }