refactor(MessageInput, ModelSelector): streamline model loading and selection handling

This commit is contained in:
Willie Zutz 2025-08-16 14:03:34 -06:00
parent 15b75328d2
commit 0d4874a3b3
2 changed files with 46 additions and 38 deletions

View file

@ -52,7 +52,6 @@ const MessageInput = ({
} | null>(null);
useEffect(() => {
// Load saved model preferences from localStorage
const chatModelProvider = localStorage.getItem('chatModelProvider');
const chatModel = localStorage.getItem('chatModel');
@ -62,7 +61,9 @@ const MessageInput = ({
model: chatModel,
});
}
}, []);
useEffect(() => {
const storedPromptIds = localStorage.getItem('selectedSystemPromptIds');
if (storedPromptIds) {
try {

View file

@ -91,42 +91,7 @@ const ModelSelector = ({
// Sort providers by name (only those that have models)
const sortedProviders = Object.keys(providersData).sort();
setProvidersList(sortedProviders);
// Initialize expanded state for all providers
const initialExpandedState: Record<string, boolean> = {};
sortedProviders.forEach((provider) => {
initialExpandedState[provider] = selectedModel?.provider === provider;
});
// Expand the first provider if none is selected
if (sortedProviders.length > 0 && !selectedModel) {
initialExpandedState[sortedProviders[0]] = true;
}
setExpandedProviders(initialExpandedState);
setProviderModels(providersData);
// Find the current model in our options to display its name
if (selectedModel) {
const provider = providersData[selectedModel.provider];
if (provider) {
const currentModel = provider.models.find(
(option) => option.model === selectedModel.model,
);
if (currentModel) {
setSelectedModelDisplay(currentModel.displayName);
setSelectedProviderDisplay(provider.displayName);
}
} else {
setSelectedModelDisplay('');
setSelectedProviderDisplay('');
}
} else {
setSelectedModelDisplay('');
setSelectedProviderDisplay('');
}
setLoading(false);
} catch (error) {
console.error('Error fetching models:', error);
@ -135,7 +100,48 @@ const ModelSelector = ({
};
fetchModels();
}, [selectedModel]);
// Fetch models once on mount; selection mapping handled in a separate effect
}, []);
// Derive display text from providerModels + selectedModel without clearing on null
useEffect(() => {
if (!selectedModel || !selectedModel.provider || !selectedModel.model || !providerModels || Object.keys(providerModels).length === 0) {
// Do not clear existing display to prevent flicker
return;
}
const provider = providerModels[selectedModel.provider];
if (!provider) {
console.warn(`Provider not found: ${selectedModel.provider} available providers: ${JSON.stringify(providerModels)}`);
return;
}
const currentModel = provider.models.find(
(option) => option.model === selectedModel.model,
);
if (currentModel) {
setExpandedProviders((prev) => ({
...prev,
[provider.displayName]: !prev[provider.displayName],
}));
setSelectedModelDisplay(currentModel.displayName);
setSelectedProviderDisplay(provider.displayName);
} else {
console.warn(
`Selected model key not found for provider ${selectedModel.provider}: ${selectedModel.model}`,
);
}
}, [providerModels, selectedModel]);
// Expand selected provider once a selection arrives, without collapsing others
useEffect(() => {
if (!selectedModel?.provider) return;
setExpandedProviders((prev) => ({
...prev,
[selectedModel.provider]: true,
}));
}, [selectedModel?.provider]);
const toggleProviderExpanded = (provider: string) => {
setExpandedProviders((prev) => ({
@ -157,7 +163,8 @@ const ModelSelector = ({
};
const getDisplayText = () => {
if (loading) return 'Loading...';
// While models are loading or selection hasn't been determined yet, show Loading to avoid flicker
if (loading || !selectedModel) return 'Loading...';
if (!selectedModelDisplay) return 'Select model';
return `${selectedModelDisplay} (${selectedProviderDisplay})`;