Files
openchamber/packages/ui/src/hooks/useModelLists.ts
T
theblazehen 235f80643e 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
2025-12-15 18:11:38 +02:00

51 lines
1.9 KiB
TypeScript

import React from 'react';
import { useConfigStore } from '@/stores/useConfigStore';
import { useUIStore } from '@/stores/useUIStore';
import type { Provider } from '@opencode-ai/sdk';
type ProviderModel = Provider["models"][string];
type ProviderWithModelList = Omit<Provider, "models"> & { models: ProviderModel[] };
export interface ModelListItem {
provider: ProviderWithModelList;
model: ProviderModel;
providerID: string;
modelID: string;
}
export const useModelLists = () => {
const { providers } = useConfigStore();
const { favoriteModels, recentModels } = useUIStore();
const favoriteModelsList = React.useMemo(() => {
return favoriteModels
.map(({ providerID, modelID }) => {
const provider = providers.find((p) => p.id === providerID);
if (!provider) return null;
const providerModels = Array.isArray(provider.models) ? provider.models : [];
const model = providerModels.find((m: ProviderModel) => m.id === modelID);
if (!model) return null;
return { provider, model, providerID, modelID };
})
.filter((item): item is ModelListItem => item !== null);
}, [favoriteModels, providers]);
const recentModelsList = React.useMemo(() => {
return recentModels
.map(({ providerID, modelID }) => {
const provider = providers.find((p) => p.id === providerID);
if (!provider) return null;
const providerModels = Array.isArray(provider.models) ? provider.models : [];
const model = providerModels.find((m: ProviderModel) => m.id === modelID);
if (!model) return null;
return { provider, model, providerID, modelID };
})
.filter((item): item is ModelListItem => item !== null)
.filter(({ providerID, modelID }) =>
!favoriteModels.some(fav => fav.providerID === providerID && fav.modelID === modelID)
);
}, [recentModels, providers, favoriteModels]);
return { favoriteModelsList, recentModelsList };
};