File size: 2,860 Bytes
0110dee
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
import { create } from 'zustand';
import { persist } from 'zustand/middleware';

export type AIProvider = 'webllm' | 'openrouter' | 'ollama';

export interface SettingsState {
  // AI Provider
  aiProvider: AIProvider;
  
  // API Keys (stored in localStorage - user's responsibility)
  openRouterApiKey: string;
  ollamaBaseUrl: string;
  
  // Model selection per provider
  openRouterModel: string;
  ollamaModel: string;
  
  // Theme
  theme: 'light' | 'dark' | 'system';
  
  // Editor
  fontSize: number;
  tabSize: number;
  wordWrap: boolean;
  
  // Actions
  setAIProvider: (provider: AIProvider) => void;
  setOpenRouterApiKey: (key: string) => void;
  setOllamaBaseUrl: (url: string) => void;
  setOpenRouterModel: (model: string) => void;
  setOllamaModel: (model: string) => void;
  setTheme: (theme: 'light' | 'dark' | 'system') => void;
  setFontSize: (size: number) => void;
  setTabSize: (size: number) => void;
  setWordWrap: (wrap: boolean) => void;
  clearApiKeys: () => void;
}

export const useSettingsStore = create<SettingsState>()(
  persist(
    (set) => ({
      // Initial state
      aiProvider: 'webllm',
      openRouterApiKey: '',
      ollamaBaseUrl: 'http://localhost:11434',
      openRouterModel: 'anthropic/claude-3.5-sonnet',
      ollamaModel: 'llama3.2',
      theme: 'system',
      fontSize: 14,
      tabSize: 2,
      wordWrap: true,

      // Actions
      setAIProvider: (provider) => {
        set({ aiProvider: provider });
      },

      setOpenRouterApiKey: (key) => {
        set({ openRouterApiKey: key });
      },

      setOllamaBaseUrl: (url) => {
        set({ ollamaBaseUrl: url });
      },

      setOpenRouterModel: (model) => {
        set({ openRouterModel: model });
      },

      setOllamaModel: (model) => {
        set({ ollamaModel: model });
      },

      setTheme: (theme) => {
        set({ theme });
        
        // Apply theme immediately
        if (theme === 'system') {
          const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
          document.documentElement.setAttribute('data-theme', prefersDark ? 'dark' : 'light');
        } else {
          document.documentElement.setAttribute('data-theme', theme);
        }
      },

      setFontSize: (size) => {
        set({ fontSize: Math.max(10, Math.min(24, size)) });
      },

      setTabSize: (size) => {
        set({ tabSize: Math.max(2, Math.min(8, size)) });
      },

      setWordWrap: (wrap) => {
        set({ wordWrap: wrap });
      },

      clearApiKeys: () => {
        set({
          openRouterApiKey: '',
          ollamaBaseUrl: 'http://localhost:11434',
        });
      },
    }),
    {
      name: 'bob-settings-storage',
    }
  )
);

// Made with Bob