feat: add privacy mode, thinking levels, PWA support, and i18n

- Add privacy mode to hide IP and user preferences from AI requests
- Add model thinking levels (low/medium/high) for context analysis depth
- Add PWA support with service worker, manifest, and app icons
- Add SettingsPanel for user preferences (theme, background, language)
- Add i18n translations for en/zh/ja/ko/de/fr
- Add Pinia store for centralized settings management
- Update backend to support user preferences and thinking levels
- Update config to use absolute API URLs
This commit is contained in:
2026-02-19 10:22:27 +08:00
parent d2b64ad5d6
commit aa6133e3ed
24 changed files with 1291 additions and 222 deletions

View File

@@ -16,16 +16,36 @@ async function getClientIP() {
}
}
import { useSettingsStore } from '../stores/settings'
export async function fetchSuggestion(prefix, suffix, signal, apiUrl = API_URL) {
try {
const settings = useSettingsStore()
const clientIP = await getClientIP()
const headers = { 'Content-Type': 'application/json' }
if (clientIP) headers['X-Client-IP'] = clientIP
// Only send IP if privacy mode is OFF
if (clientIP && !settings.privacyMode) {
headers['X-Client-IP'] = clientIP
}
const body = {
prefix,
suffix,
languageId: 'markdown',
model_thinking: settings.modelThinking,
privacy_mode: settings.privacyMode,
user_preferences: {
language: settings.language,
currency: settings.currency,
timezone: settings.detectedTimezone
}
}
const res = await fetch(apiUrl, {
method: 'POST',
headers,
body: JSON.stringify({ prefix, suffix, languageId: 'markdown' }),
body: JSON.stringify(body),
signal
})
@@ -45,10 +65,10 @@ export async function fetchSuggestion(prefix, suffix, signal, apiUrl = API_URL)
const { done, value } = await reader.read()
if (done) break
buffer += new TextDecoder().decode(value)
const lines = buffer.split('\n')
buffer = lines.pop() || ''
for (const line of lines) {
if (!line.startsWith('data: ')) continue
const jsonStr = line.slice(6).trim()
@@ -64,7 +84,7 @@ export async function fetchSuggestion(prefix, suffix, signal, apiUrl = API_URL)
}
}
}
return text
} catch (e) {
if (e.name === 'AbortError') {