Files
bolt-diy/app/lib/stores/settings.ts
KevIsDev 46611a8172 refactor: remove developer mode and related components
add glowing effect component for tab tiles
improve tab tile appearance with new glow effect
add 'none' log level and simplify log level handling
simplify tab configuration store by removing developer tabs
remove useDebugStatus hook and related debug functionality
remove system info endpoints no longer needed
2025-07-01 14:26:42 +01:00

273 lines
8.1 KiB
TypeScript

import { atom, map } from 'nanostores';
import { PROVIDER_LIST } from '~/utils/constants';
import type { IProviderConfig } from '~/types/model';
import type { TabVisibilityConfig, TabWindowConfig, UserTabConfig } from '~/components/@settings/core/types';
import { DEFAULT_TAB_CONFIG } from '~/components/@settings/core/constants';
import { toggleTheme } from './theme';
import { create } from 'zustand';
export interface Shortcut {
key: string;
ctrlKey?: boolean;
shiftKey?: boolean;
altKey?: boolean;
metaKey?: boolean;
ctrlOrMetaKey?: boolean;
action: () => void;
description?: string; // Description of what the shortcut does
isPreventDefault?: boolean; // Whether to prevent default browser behavior
}
export interface Shortcuts {
toggleTheme: Shortcut;
toggleTerminal: Shortcut;
}
export const URL_CONFIGURABLE_PROVIDERS = ['Ollama', 'LMStudio', 'OpenAILike'];
export const LOCAL_PROVIDERS = ['OpenAILike', 'LMStudio', 'Ollama'];
export type ProviderSetting = Record<string, IProviderConfig>;
// Simplified shortcuts store with only theme toggle
export const shortcutsStore = map<Shortcuts>({
toggleTheme: {
key: 'd',
metaKey: true,
altKey: true,
shiftKey: true,
action: () => toggleTheme(),
description: 'Toggle theme',
isPreventDefault: true,
},
toggleTerminal: {
key: '`',
ctrlOrMetaKey: true,
action: () => {
// This will be handled by the terminal component
},
description: 'Toggle terminal',
isPreventDefault: true,
},
});
// Create a single key for provider settings
const PROVIDER_SETTINGS_KEY = 'provider_settings';
// Add this helper function at the top of the file
const isBrowser = typeof window !== 'undefined';
// Initialize provider settings from both localStorage and defaults
const getInitialProviderSettings = (): ProviderSetting => {
const initialSettings: ProviderSetting = {};
// Start with default settings
PROVIDER_LIST.forEach((provider) => {
initialSettings[provider.name] = {
...provider,
settings: {
// Local providers should be disabled by default
enabled: !LOCAL_PROVIDERS.includes(provider.name),
},
};
});
// Only try to load from localStorage in the browser
if (isBrowser) {
const savedSettings = localStorage.getItem(PROVIDER_SETTINGS_KEY);
if (savedSettings) {
try {
const parsed = JSON.parse(savedSettings);
Object.entries(parsed).forEach(([key, value]) => {
if (initialSettings[key]) {
initialSettings[key].settings = (value as IProviderConfig).settings;
}
});
} catch (error) {
console.error('Error parsing saved provider settings:', error);
}
}
}
return initialSettings;
};
export const providersStore = map<ProviderSetting>(getInitialProviderSettings());
// Create a function to update provider settings that handles both store and persistence
export const updateProviderSettings = (provider: string, settings: ProviderSetting) => {
const currentSettings = providersStore.get();
// Create new provider config with updated settings
const updatedProvider = {
...currentSettings[provider],
settings: {
...currentSettings[provider].settings,
...settings,
},
};
// Update the store with new settings
providersStore.setKey(provider, updatedProvider);
// Save to localStorage
const allSettings = providersStore.get();
localStorage.setItem(PROVIDER_SETTINGS_KEY, JSON.stringify(allSettings));
};
export const isDebugMode = atom(false);
// Define keys for localStorage
const SETTINGS_KEYS = {
LATEST_BRANCH: 'isLatestBranch',
AUTO_SELECT_TEMPLATE: 'autoSelectTemplate',
CONTEXT_OPTIMIZATION: 'contextOptimizationEnabled',
EVENT_LOGS: 'isEventLogsEnabled',
PROMPT_ID: 'promptId',
DEVELOPER_MODE: 'isDeveloperMode',
} as const;
// Initialize settings from localStorage or defaults
const getInitialSettings = () => {
const getStoredBoolean = (key: string, defaultValue: boolean): boolean => {
if (!isBrowser) {
return defaultValue;
}
const stored = localStorage.getItem(key);
if (stored === null) {
return defaultValue;
}
try {
return JSON.parse(stored);
} catch {
return defaultValue;
}
};
return {
latestBranch: getStoredBoolean(SETTINGS_KEYS.LATEST_BRANCH, false),
autoSelectTemplate: getStoredBoolean(SETTINGS_KEYS.AUTO_SELECT_TEMPLATE, true),
contextOptimization: getStoredBoolean(SETTINGS_KEYS.CONTEXT_OPTIMIZATION, true),
eventLogs: getStoredBoolean(SETTINGS_KEYS.EVENT_LOGS, true),
promptId: isBrowser ? localStorage.getItem(SETTINGS_KEYS.PROMPT_ID) || 'default' : 'default',
developerMode: getStoredBoolean(SETTINGS_KEYS.DEVELOPER_MODE, false),
};
};
// Initialize stores with persisted values
const initialSettings = getInitialSettings();
export const latestBranchStore = atom<boolean>(initialSettings.latestBranch);
export const autoSelectStarterTemplate = atom<boolean>(initialSettings.autoSelectTemplate);
export const enableContextOptimizationStore = atom<boolean>(initialSettings.contextOptimization);
export const isEventLogsEnabled = atom<boolean>(initialSettings.eventLogs);
export const promptStore = atom<string>(initialSettings.promptId);
// Helper functions to update settings with persistence
export const updateLatestBranch = (enabled: boolean) => {
latestBranchStore.set(enabled);
localStorage.setItem(SETTINGS_KEYS.LATEST_BRANCH, JSON.stringify(enabled));
};
export const updateAutoSelectTemplate = (enabled: boolean) => {
autoSelectStarterTemplate.set(enabled);
localStorage.setItem(SETTINGS_KEYS.AUTO_SELECT_TEMPLATE, JSON.stringify(enabled));
};
export const updateContextOptimization = (enabled: boolean) => {
enableContextOptimizationStore.set(enabled);
localStorage.setItem(SETTINGS_KEYS.CONTEXT_OPTIMIZATION, JSON.stringify(enabled));
};
export const updateEventLogs = (enabled: boolean) => {
isEventLogsEnabled.set(enabled);
localStorage.setItem(SETTINGS_KEYS.EVENT_LOGS, JSON.stringify(enabled));
};
export const updatePromptId = (id: string) => {
promptStore.set(id);
localStorage.setItem(SETTINGS_KEYS.PROMPT_ID, id);
};
// Initialize tab configuration from localStorage or defaults
const getInitialTabConfiguration = (): TabWindowConfig => {
const defaultConfig: TabWindowConfig = {
userTabs: DEFAULT_TAB_CONFIG.filter((tab): tab is UserTabConfig => tab.window === 'user'),
};
if (!isBrowser) {
return defaultConfig;
}
try {
const saved = localStorage.getItem('bolt_tab_configuration');
if (!saved) {
return defaultConfig;
}
const parsed = JSON.parse(saved);
if (!parsed?.userTabs) {
return defaultConfig;
}
// Ensure proper typing of loaded configuration
return {
userTabs: parsed.userTabs.filter((tab: TabVisibilityConfig): tab is UserTabConfig => tab.window === 'user'),
};
} catch (error) {
console.warn('Failed to parse tab configuration:', error);
return defaultConfig;
}
};
// console.log('Initial tab configuration:', getInitialTabConfiguration());
export const tabConfigurationStore = map<TabWindowConfig>(getInitialTabConfiguration());
// Helper function to reset tab configuration
export const resetTabConfiguration = () => {
const defaultConfig: TabWindowConfig = {
userTabs: DEFAULT_TAB_CONFIG.filter((tab): tab is UserTabConfig => tab.window === 'user'),
};
tabConfigurationStore.set(defaultConfig);
localStorage.setItem('bolt_tab_configuration', JSON.stringify(defaultConfig));
};
// 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<SettingsStore>((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 });
},
}));