feat: add UI customization and model management features (#60)

* feat: add UI customization and model management features

Add comprehensive UI customization options and enhanced model selection:

- **Favorite & Recent Models**: Star models for quick access, track 5 most recent
  - Add favorite/recent sections to model dropdowns
  - Persist preferences in local storage
  - Works in ModelControls and ModelSelector components

- **Tool Call Expansion Settings**: Control default expansion state for tool outputs
  - Three modes: collapsed, activity (summary), detailed
  - Applies to activity groups and individual tool calls
  - Configurable in Appearance Settings

- **Font Size & Spacing Controls**: Adjustable typography and layout density
  - Font size: 50-200% scaling of all semantic typography
  - Spacing/padding: 50-200% scaling of margins, gaps, line heights
  - Real-time preview with reset buttons
  - Settings in Appearance Settings

- **VSCode Extension Settings View**: Full settings access in VSCode extension
  - Add settings navigation and view type
  - Settings button in header
  - Navigate between sessions, chat, and settings

Technical changes:
- Enhanced useUIStore with new state management
- Dynamic CSS variable scaling for typography and spacing
- Typography helper functions for variable access
- ThemeProvider integration for auto-applying scales

* fix: hide theme mode in VSCode and fix detailed tool expansion

- Hide "Theme Mode" setting in VSCode extension settings as VSCode
  dynamically applies its own theme to the extension
- Fix bug where tools from subsequent messages in a turn weren't
  expanded when "Detailed" mode was selected
- Now correctly aggregates all tool IDs from turnGroupingContext when
  calculating effective expanded tools for progressive groups
This commit is contained in:
theblazehen
2025-12-15 18:11:38 +02:00
committed by GitHub
parent 42e25d03f3
commit 235f80643e
14 changed files with 1192 additions and 86 deletions
@@ -5,10 +5,11 @@ import { ChatView } from '@/components/views';
import { useSessionStore } from '@/stores/useSessionStore';
import { useConfigStore } from '@/stores/useConfigStore';
import { ContextUsageDisplay } from '@/components/ui/ContextUsageDisplay';
import { RiAddLine, RiArrowLeftLine } from '@remixicon/react';
import { RiAddLine, RiArrowLeftLine, RiSettings3Line } from '@remixicon/react';
import { RiLoader4Line } from '@remixicon/react';
import { SettingsPage } from '@/components/sections/settings/SettingsPage';
type VSCodeView = 'sessions' | 'chat';
type VSCodeView = 'sessions' | 'chat' | 'settings';
export const VSCodeLayout: React.FC = () => {
const [currentView, setCurrentView] = React.useState<VSCodeView>('sessions');
@@ -200,7 +201,11 @@ export const VSCodeLayout: React.FC = () => {
<div className="h-full w-full bg-background text-foreground flex flex-col">
{currentView === 'sessions' ? (
<div className="flex flex-col h-full">
<VSCodeHeader title="Sessions" onNewSession={handleNewSession} />
<VSCodeHeader
title="Sessions"
onNewSession={handleNewSession}
onSettings={() => setCurrentView('settings')}
/>
<div className="flex-1 overflow-hidden">
<SessionSidebar
mobileVariant
@@ -210,6 +215,17 @@ export const VSCodeLayout: React.FC = () => {
/>
</div>
</div>
) : currentView === 'settings' ? (
<div className="flex flex-col h-full">
<VSCodeHeader
title="Settings"
showBack
onBack={handleBackToSessions}
/>
<div className="flex-1 overflow-y-auto">
<VSCodeSettingsView />
</div>
</div>
) : (
<div className="flex flex-col h-full">
<VSCodeHeader
@@ -249,10 +265,11 @@ interface VSCodeHeaderProps {
showBack?: boolean;
onBack?: () => void;
onNewSession?: () => void;
onSettings?: () => void;
showContextUsage?: boolean;
}
const VSCodeHeader: React.FC<VSCodeHeaderProps> = ({ title, showBack, onBack, onNewSession, showContextUsage }) => {
const VSCodeHeader: React.FC<VSCodeHeaderProps> = ({ title, showBack, onBack, onNewSession, onSettings, showContextUsage }) => {
const { getCurrentModel } = useConfigStore();
const getContextUsage = useSessionStore((state) => state.getContextUsage);
@@ -285,6 +302,15 @@ const VSCodeHeader: React.FC<VSCodeHeaderProps> = ({ title, showBack, onBack, on
<RiAddLine className="h-5 w-5" />
</button>
)}
{onSettings && (
<button
onClick={onSettings}
className="p-1 rounded hover:bg-muted transition-colors"
aria-label="Settings"
>
<RiSettings3Line className="h-5 w-5" />
</button>
)}
{showContextUsage && contextUsage && contextUsage.totalTokens > 0 && (
<ContextUsageDisplay
totalTokens={contextUsage.totalTokens}
@@ -297,3 +323,14 @@ const VSCodeHeader: React.FC<VSCodeHeaderProps> = ({ title, showBack, onBack, on
</div>
);
};
const VSCodeSettingsView: React.FC = () => {
return (
<div className="flex flex-col h-full">
{/* Content */}
<div className="flex-1 overflow-y-auto p-4">
<SettingsPage />
</div>
</div>
);
};