fix: clean up

fix: typecheck / lint
This commit is contained in:
Dustin Loring 2024-12-07 10:53:33 -05:00
parent 42ebd3d50e
commit a2acc77e89
8 changed files with 70 additions and 67 deletions

View File

@ -21,12 +21,12 @@ jobs:
- name: Update commit file
run: |
echo "{ \"commit\": \"$COMMIT_HASH\" }" > commit.json
echo "{ \"commit\": \"$COMMIT_HASH\" }" > app/commit.json
- name: Commit and push the update
run: |
git config --global user.name "github-actions[bot]"
git config --global user.email "github-actions[bot]@users.noreply.github.com"
git add commit.json
git add app/commit.json
git commit -m "chore: update commit hash to $COMMIT_HASH"
git push

1
app/commit.json Normal file
View File

@ -0,0 +1 @@
{ "commit": "228cf1f34fd64b6960460f84c9db47bd7ef03150" }

View File

@ -89,6 +89,7 @@ export const BaseChat = React.forwardRef<HTMLDivElement, BaseChatProps>(
const TEXTAREA_MAX_HEIGHT = chatStarted ? 400 : 200;
const [apiKeys, setApiKeys] = useState<Record<string, string>>(() => {
const savedKeys = Cookies.get('apiKeys');
if (savedKeys) {
try {
return JSON.parse(savedKeys);
@ -97,6 +98,7 @@ export const BaseChat = React.forwardRef<HTMLDivElement, BaseChatProps>(
return {};
}
}
return {};
});
const [modelList, setModelList] = useState(MODEL_LIST);
@ -108,15 +110,17 @@ export const BaseChat = React.forwardRef<HTMLDivElement, BaseChatProps>(
// Load enabled providers from cookies
const [enabledProviders, setEnabledProviders] = useState(() => {
const savedProviders = Cookies.get('providers');
if (savedProviders) {
try {
const parsedProviders = JSON.parse(savedProviders);
return PROVIDER_LIST.filter(p => parsedProviders[p.name]);
return PROVIDER_LIST.filter((p) => parsedProviders[p.name]);
} catch (error) {
console.error('Failed to parse providers from cookies:', error);
return PROVIDER_LIST;
}
}
return PROVIDER_LIST;
});
@ -124,10 +128,11 @@ export const BaseChat = React.forwardRef<HTMLDivElement, BaseChatProps>(
useEffect(() => {
const updateProvidersFromCookies = () => {
const savedProviders = Cookies.get('providers');
if (savedProviders) {
try {
const parsedProviders = JSON.parse(savedProviders);
setEnabledProviders(PROVIDER_LIST.filter(p => parsedProviders[p.name]));
setEnabledProviders(PROVIDER_LIST.filter((p) => parsedProviders[p.name]));
} catch (error) {
console.error('Failed to parse providers from cookies:', error);
}
@ -135,7 +140,9 @@ export const BaseChat = React.forwardRef<HTMLDivElement, BaseChatProps>(
};
updateProvidersFromCookies();
const interval = setInterval(updateProvidersFromCookies, 1000);
return () => clearInterval(interval);
}, [PROVIDER_LIST]);
@ -228,23 +235,6 @@ export const BaseChat = React.forwardRef<HTMLDivElement, BaseChatProps>(
}
};
const updateApiKey = (provider: string, key: string) => {
try {
const updatedApiKeys = { ...apiKeys, [provider]: key };
setApiKeys(updatedApiKeys);
// Save updated API keys to cookies with 30 day expiry and secure settings
Cookies.set('apiKeys', JSON.stringify(updatedApiKeys), {
expires: 30, // 30 days
secure: true, // Only send over HTTPS
sameSite: 'strict', // Protect against CSRF
path: '/', // Accessible across the site
});
} catch (error) {
console.error('Error saving API keys to cookies:', error);
}
};
const handleFileUpload = () => {
const input = document.createElement('input');
input.type = 'file';

View File

@ -24,15 +24,17 @@ export const ModelSelector = ({
// Load enabled providers from cookies
const [enabledProviders, setEnabledProviders] = useState(() => {
const savedProviders = Cookies.get('providers');
if (savedProviders) {
try {
const parsedProviders = JSON.parse(savedProviders);
return providerList.filter(p => parsedProviders[p.name]);
return providerList.filter((p) => parsedProviders[p.name]);
} catch (error) {
console.error('Failed to parse providers from cookies:', error);
return providerList;
}
}
return providerList;
});
@ -41,10 +43,11 @@ export const ModelSelector = ({
// Function to update providers from cookies
const updateProvidersFromCookies = () => {
const savedProviders = Cookies.get('providers');
if (savedProviders) {
try {
const parsedProviders = JSON.parse(savedProviders);
const newEnabledProviders = providerList.filter(p => parsedProviders[p.name]);
const newEnabledProviders = providerList.filter((p) => parsedProviders[p.name]);
setEnabledProviders(newEnabledProviders);
// If current provider is disabled, switch to first enabled provider
@ -53,7 +56,8 @@ export const ModelSelector = ({
setProvider?.(firstEnabledProvider);
// Also update the model to the first available one for the new provider
const firstModel = modelList.find(m => m.provider === firstEnabledProvider.name);
const firstModel = modelList.find((m) => m.provider === firstEnabledProvider.name);
if (firstModel) {
setModel?.(firstModel.name);
}
@ -77,7 +81,8 @@ export const ModelSelector = ({
return (
<div className="mb-2 p-4 rounded-lg border border-bolt-elements-borderColor bg-bolt-elements-prompt-background text-bolt-elements-textPrimary">
<p className="text-center">
No providers are currently enabled. Please enable at least one provider in the settings to start using the chat.
No providers are currently enabled. Please enable at least one provider in the settings to start using the
chat.
</p>
</div>
);

View File

@ -1,14 +1,14 @@
import * as RadixDialog from '@radix-ui/react-dialog';
import { motion } from 'framer-motion';
import { useState, useEffect }from 'react';
import { useState } from 'react';
import { classNames } from '~/utils/classNames';
import { Dialog, DialogTitle, dialogVariants, dialogBackdropVariants } from './Dialog';
import { DialogTitle, dialogVariants, dialogBackdropVariants } from './Dialog';
import { IconButton } from './IconButton';
import { providersList } from '~/lib/stores/settings';
import { db, getAll, deleteById } from '~/lib/persistence';
import { toast } from 'react-toastify';
import { useNavigate } from '@remix-run/react';
import commit from '../../../commit.json';
import commit from '~/commit.json';
import Cookies from 'js-cookie';
interface SettingsProps {
@ -31,6 +31,7 @@ export const Settings = ({ open, onClose }: SettingsProps) => {
// Load base URLs from cookies
const [baseUrls, setBaseUrls] = useState(() => {
const savedUrls = Cookies.get('providerBaseUrls');
if (savedUrls) {
try {
return JSON.parse(savedUrls);
@ -43,6 +44,7 @@ export const Settings = ({ open, onClose }: SettingsProps) => {
};
}
}
return {
Ollama: 'http://localhost:11434',
LMStudio: 'http://localhost:1234',
@ -51,9 +53,10 @@ export const Settings = ({ open, onClose }: SettingsProps) => {
});
const handleBaseUrlChange = (provider: string, url: string) => {
setBaseUrls(prev => {
setBaseUrls((prev: Record<string, string>) => {
const newUrls = { ...prev, [provider]: url };
Cookies.set('providerBaseUrls', JSON.stringify(newUrls));
return newUrls;
});
};
@ -62,38 +65,44 @@ export const Settings = ({ open, onClose }: SettingsProps) => {
{ id: 'chat-history', label: 'Chat History', icon: 'i-ph:book' },
{ id: 'providers', label: 'Providers', icon: 'i-ph:key' },
{ id: 'features', label: 'Features', icon: 'i-ph:star' },
...(isDebugEnabled ? [{ id: 'debug', label: 'Debug Tab', icon: 'i-ph:bug' }] : []),
...(isDebugEnabled ? [{ id: 'debug' as TabType, label: 'Debug Tab', icon: 'i-ph:bug' }] : []),
];
// Load providers from cookies on mount
const [providers, setProviders] = useState(() => {
const savedProviders = Cookies.get('providers');
if (savedProviders) {
try {
const parsedProviders = JSON.parse(savedProviders);
// Merge saved enabled states with the base provider list
return providersList.map(provider => ({
return providersList.map((provider) => ({
...provider,
isEnabled: parsedProviders[provider.name] || false
isEnabled: parsedProviders[provider.name] || false,
}));
} catch (error) {
console.error('Failed to parse providers from cookies:', error);
}
}
return providersList;
});
const handleToggleProvider = (providerName: string) => {
setProviders((prevProviders) => {
const newProviders = prevProviders.map((provider) =>
provider.name === providerName ? { ...provider, isEnabled: !provider.isEnabled } : provider
provider.name === providerName ? { ...provider, isEnabled: !provider.isEnabled } : provider,
);
// Save to cookies
const enabledStates = newProviders.reduce((acc, provider) => ({
const enabledStates = newProviders.reduce(
(acc, provider) => ({
...acc,
[provider.name]: provider.isEnabled
}), {});
[provider.name]: provider.isEnabled,
}),
{},
);
Cookies.set('providers', JSON.stringify(enabledStates));
return newProviders;
@ -101,7 +110,7 @@ export const Settings = ({ open, onClose }: SettingsProps) => {
};
const filteredProviders = providers
.filter(provider => provider.name.toLowerCase().includes(searchTerm.toLowerCase()))
.filter((provider) => provider.name.toLowerCase().includes(searchTerm.toLowerCase()))
.sort((a, b) => a.name.localeCompare(b.name));
const handleCopyToClipboard = () => {
@ -141,10 +150,11 @@ export const Settings = ({ open, onClose }: SettingsProps) => {
try {
setIsDeleting(true);
const allChats = await getAll(db);
// Delete all chats one by one
await Promise.all(allChats.map(chat => deleteById(db!, chat.id)));
await Promise.all(allChats.map((chat) => deleteById(db!, chat.id)));
toast.success('All chats deleted successfully');
navigate('/', { replace: true });
@ -207,9 +217,7 @@ export const Settings = ({ open, onClose }: SettingsProps) => {
onClick={() => setActiveTab(tab.id)}
className={classNames(
'w-full flex items-center gap-2 px-4 py-3 rounded-lg text-left text-sm transition-all mb-2',
activeTab === tab.id
? 'bg-blue-600 text-white'
: 'bg-gray-600 text-gray-200 hover:bg-blue-500'
activeTab === tab.id ? 'bg-blue-600 text-white' : 'bg-gray-600 text-gray-200 hover:bg-blue-500',
)}
>
<div className={tab.icon} />
@ -256,8 +264,8 @@ export const Settings = ({ open, onClose }: SettingsProps) => {
onClick={handleDeleteAllChats}
disabled={isDeleting}
className={classNames(
"bg-red-700 text-white rounded-lg px-4 py-2 transition-colors duration-200",
isDeleting ? "opacity-50 cursor-not-allowed" : "hover:bg-red-800"
'bg-red-700 text-white rounded-lg px-4 py-2 transition-colors duration-200',
isDeleting ? 'opacity-50 cursor-not-allowed' : 'hover:bg-red-800',
)}
>
{isDeleting ? 'Deleting...' : 'Delete All Chats'}
@ -334,9 +342,7 @@ export const Settings = ({ open, onClose }: SettingsProps) => {
></div>
</label>
</div>
<div className="feature-row">
{/* Your feature content here */}
</div>
<div className="feature-row">{/* Your feature content here */}</div>
</div>
)}
{activeTab === 'debug' && isDebugEnabled && (
@ -358,7 +364,9 @@ export const Settings = ({ open, onClose }: SettingsProps) => {
{providers
.filter((provider) => provider.isEnabled)
.map((provider) => (
<li key={provider.name} className="text-white">{provider.name}</li>
<li key={provider.name} className="text-white">
{provider.name}
</li>
))}
</ul>

View File

@ -26,24 +26,24 @@ export const SettingsSlider = memo(<T,>({ selected, options, setSelected }: Sett
<motion.div
className={classNames(
'absolute h-full bg-green-500 transition-all duration-300 rounded-lg',
isLeftSelected ? 'left-0 w-1/2' : 'right-0 w-1/2'
isLeftSelected ? 'left-0 w-1/2' : 'right-0 w-1/2',
)}
initial={false}
animate={{
x: isLeftSelected ? 0 : '100%',
opacity: 0.2
opacity: 0.2,
}}
transition={{
type: 'spring',
stiffness: 300,
damping: 30
damping: 30,
}}
/>
<button
onClick={() => setSelected?.(options.left.value)}
className={classNames(
'relative z-10 flex-1 p-2 rounded-lg text-sm transition-colors duration-200',
isLeftSelected ? 'text-white' : 'text-bolt-elements-textSecondary hover:text-bolt-elements-textPrimary'
isLeftSelected ? 'text-white' : 'text-bolt-elements-textSecondary hover:text-bolt-elements-textPrimary',
)}
>
{options.left.text}
@ -52,7 +52,7 @@ export const SettingsSlider = memo(<T,>({ selected, options, setSelected }: Sett
onClick={() => setSelected?.(options.right.value)}
className={classNames(
'relative z-10 flex-1 p-2 rounded-lg text-sm transition-colors duration-200',
!isLeftSelected ? 'text-white' : 'text-bolt-elements-textSecondary hover:text-bolt-elements-textPrimary'
!isLeftSelected ? 'text-white' : 'text-bolt-elements-textSecondary hover:text-bolt-elements-textPrimary',
)}
>
{options.right.text}

View File

@ -1 +0,0 @@
{ "commit": "228cf1f34fd64b6960460f84c9db47bd7ef03150" }