mirror of
https://github.com/CherryHQ/cherry-studio.git
synced 2026-07-05 21:50:46 +08:00
Unify the feature under its canonical name "Quick Assistant": - Rename miniWindow.html → quickAssistant.html and windows/mini/ → windows/quickAssistant/ (via git mv to preserve history). The bounds file miniWindow-state.json is not migrated; users see default bounds once after upgrade. - Collapse half-renamed QuickWindow/MiniWindow identifiers in QuickAssistantService and its callers (ShortcutService, TrayService, ShortcutService.test) onto QuickAssistant. - Rename the Inputbar scope literal 'mini-window' → 'quick-assistant'. The Redux DEFAULT_TOOL_ORDER_BY_SCOPE keeps the legacy key behind a transitional Record<InputbarScope | 'mini-window', ToolOrder> annotation; both entries will be collapsed when Redux is removed. - Rename i18n keys miniwindow.*, mini_window, show_mini_window to quickAssistant.*, quick_assistant, show_quick_assistant across all locales; synced via i18n:sync. - Update lingering "mini window" wording in docs and comments. Legacy 'mini_window' literals intentionally retained in the v2 ShortcutMappings migrator (identifies Redux-persisted old keys) and in v1 Redux store files (to be removed with Redux).
179 lines
7.2 KiB
Markdown
179 lines
7.2 KiB
Markdown
# Preference System Overview
|
|
|
|
The Preference system provides centralized management for user configuration and application settings with cross-window synchronization.
|
|
|
|
## Purpose
|
|
|
|
PreferenceService handles data that:
|
|
|
|
- Is a **user-modifiable setting that affects app behavior**
|
|
- Has a **fixed key structure** with stable value types
|
|
- Needs to **persist permanently** until explicitly changed
|
|
- Should **sync automatically** across all application windows
|
|
|
|
## Key Characteristics
|
|
|
|
### Fixed Key Structure
|
|
|
|
- Predefined keys in the schema (users modify values, not keys)
|
|
- Supports 158 configuration items
|
|
- Nested key paths supported (e.g., `app.theme.mode`)
|
|
|
|
### Atomic Values
|
|
|
|
- Each preference item represents one logical setting
|
|
- Values are typically: boolean, string, number, or simple array/object
|
|
- Changes are independent (updating one doesn't affect others)
|
|
|
|
### Cross-Window Synchronization
|
|
|
|
- Changes automatically broadcast to all windows
|
|
- Consistent state across main window, quick assistant, etc.
|
|
- Conflict resolution handled by Main process
|
|
|
|
## Update Strategies
|
|
|
|
### Optimistic Updates (Default)
|
|
|
|
```typescript
|
|
// UI updates immediately, then syncs to database
|
|
await preferenceService.set("app.theme.mode", "dark");
|
|
```
|
|
|
|
- Best for: frequent, non-critical settings
|
|
- Behavior: Local state updates first, then persists
|
|
- Rollback: Automatic revert if persistence fails
|
|
|
|
### Pessimistic Updates
|
|
|
|
```typescript
|
|
// Waits for database confirmation before updating UI
|
|
await preferenceService.set("api.key", "secret", { optimistic: false });
|
|
```
|
|
|
|
- Best for: critical settings (API keys, security options)
|
|
- Behavior: Persists first, then updates local state
|
|
- No rollback needed: UI only updates on success
|
|
|
|
## Architecture Diagram
|
|
|
|
```
|
|
┌─────────────────────────────────────────────────────┐
|
|
│ Renderer Process │
|
|
│ ┌─────────────────────────────────────────────────┐ │
|
|
│ │ usePreference Hook │ │
|
|
│ │ - Subscribe to preference changes │ │
|
|
│ │ - Optimistic/pessimistic update support │ │
|
|
│ └──────────────────────┬──────────────────────────┘ │
|
|
│ ▼ │
|
|
│ ┌─────────────────────────────────────────────────┐ │
|
|
│ │ PreferenceService (Renderer) │ │
|
|
│ │ - Local cache for fast reads │ │
|
|
│ │ - IPC proxy to Main process │ │
|
|
│ │ - Subscription management │ │
|
|
│ └──────────────────────┬──────────────────────────┘ │
|
|
└────────────────────────┼────────────────────────────┘
|
|
│ IPC
|
|
┌────────────────────────┼────────────────────────────┐
|
|
│ Main Process ▼ │
|
|
│ ┌─────────────────────────────────────────────────┐ │
|
|
│ │ PreferenceService (Main) │ │
|
|
│ │ - Full memory cache of all preferences │ │
|
|
│ │ - SQLite persistence via Drizzle ORM │ │
|
|
│ │ - Cross-window broadcast │ │
|
|
│ └──────────────────────┬──────────────────────────┘ │
|
|
│ ▼ │
|
|
│ ┌─────────────────────────────────────────────────┐ │
|
|
│ │ SQLite Database (preference table) │ │
|
|
│ │ - scope + key structure │ │
|
|
│ │ - JSON value storage │ │
|
|
│ └─────────────────────────────────────────────────┘ │
|
|
└─────────────────────────────────────────────────────┘
|
|
```
|
|
|
|
## Main vs Renderer Responsibilities
|
|
|
|
### Main Process PreferenceService
|
|
|
|
- **Source of truth** for all preferences
|
|
- Full memory cache for fast access
|
|
- SQLite persistence via preference table
|
|
- Broadcasts changes to all renderer windows
|
|
- Handles batch operations and transactions
|
|
|
|
### Renderer Process PreferenceService
|
|
|
|
- Local cache for read performance
|
|
- Proxies write operations to Main
|
|
- Manages React hook subscriptions
|
|
- Handles optimistic update rollbacks
|
|
- Listens for cross-window updates
|
|
|
|
### Statistics (Debug)
|
|
|
|
Main process provides `getStats(details?)` for debugging subscription status:
|
|
|
|
- Returns total keys, main process subscriptions, and window subscriptions
|
|
- Pass `details=true` for per-key breakdown
|
|
- **Warning**: Resource-intensive, recommended for development only
|
|
|
|
```typescript
|
|
import { application } from '@application'
|
|
|
|
const preferenceService = application.get('PreferenceService')
|
|
const stats = preferenceService.getStats(true);
|
|
```
|
|
|
|
## Database Schema
|
|
|
|
Preferences are stored in the `preference` table:
|
|
|
|
```typescript
|
|
// Simplified schema
|
|
{
|
|
scope: string; // e.g., 'default', 'user'
|
|
key: string; // e.g., 'app.theme.mode'
|
|
value: json; // The preference value
|
|
createdAt: number;
|
|
updatedAt: number;
|
|
}
|
|
```
|
|
|
|
## Preference Categories
|
|
|
|
### Application Settings
|
|
|
|
- Theme mode, language, font sizes
|
|
- Window behavior, startup options
|
|
|
|
### Feature Toggles
|
|
|
|
- Show/hide UI elements
|
|
- Enable/disable features
|
|
|
|
### User Customization
|
|
|
|
- Keyboard shortcuts
|
|
- Default values for operations
|
|
|
|
### Provider Configuration
|
|
|
|
- AI provider settings
|
|
- API endpoints and tokens
|
|
|
|
## Usage Summary
|
|
|
|
For detailed code examples and API usage, see [Preference Usage Guide](./preference-usage.md).
|
|
|
|
| Operation | Hook | Service Method |
|
|
| -------------- | --------------------------- | ------------------------------------------ |
|
|
| Read single | `usePreference(key)` | `preferenceService.get(key)` |
|
|
| Write single | `setPreference(value)` | `preferenceService.set(key, value)` |
|
|
| Read multiple | `usePreferences([...keys])` | `preferenceService.getMultiple([...keys])` |
|
|
| Write multiple | - | `preferenceService.setMultiple({...})` |
|
|
|
|
## Related Documentation
|
|
|
|
- [Preference Schema Guide](./preference-schema-guide.md) - Adding new preference keys
|
|
- [Preference Usage Guide](./preference-usage.md) - Hooks and service API
|