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:
@@ -0,0 +1,50 @@
|
||||
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 };
|
||||
};
|
||||
Reference in New Issue
Block a user