import { Popover, PopoverContent, PopoverTrigger, PopoverPortal } from '@radix-ui/react-popover'; import React, { useEffect, useState } from 'react'; import { FaMoon, FaSun } from 'react-icons/fa'; import VertDots from './ui/VertDots'; import { useNavigate } from 'react-router-dom'; import { More } from './icons'; import { Settings, Grid, MessageSquare } from 'lucide-react'; import { Button } from './ui/button'; interface VersionInfo { current_version: string; available_versions: string[]; } export default function MoreMenu() { const navigate = useNavigate(); const [open, setOpen] = useState(false); const [versions, setVersions] = useState(null); const [showVersions, setShowVersions] = useState(false); const [useSystemTheme, setUseSystemTheme] = useState( () => localStorage.getItem('use_system_theme') === 'true' ); const [isDarkMode, setDarkMode] = useState(() => { const systemPrefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches; if (useSystemTheme) { return systemPrefersDark; } const savedTheme = localStorage.getItem('theme'); return savedTheme ? savedTheme === 'dark' : systemPrefersDark; }); useEffect(() => { // Fetch available versions when the menu opens const fetchVersions = async () => { try { const port = window.appConfig.get('GOOSE_PORT'); const response = await fetch(`http://127.0.0.1:${port}/agent/versions`); if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } const data = await response.json(); setVersions(data); } catch (error) { console.error('Failed to fetch versions:', error); } }; if (open) { fetchVersions(); } }, [open]); useEffect(() => { const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)'); // Handler for system theme changes const handleThemeChange = (e: { matches: boolean }) => { if (useSystemTheme) { setDarkMode(e.matches); } }; // Add listener for system theme changes mediaQuery.addEventListener('change', handleThemeChange); // Initial setup if (useSystemTheme) { setDarkMode(mediaQuery.matches); } else { const savedTheme = localStorage.getItem('theme'); setDarkMode(savedTheme ? savedTheme === 'dark' : mediaQuery.matches); } // Cleanup return () => mediaQuery.removeEventListener('change', handleThemeChange); }, [useSystemTheme]); useEffect(() => { if (isDarkMode) { document.documentElement.classList.add('dark'); } else { document.documentElement.classList.remove('dark'); } if (!useSystemTheme) { localStorage.setItem('theme', isDarkMode ? 'dark' : 'light'); } }, [isDarkMode, useSystemTheme]); const toggleTheme = () => { if (!useSystemTheme) { setDarkMode(!isDarkMode); } }; const toggleUseSystemTheme = (event: React.ChangeEvent) => { const checked = event.target.checked; setUseSystemTheme(checked); localStorage.setItem('use_system_theme', checked.toString()); if (checked) { // If enabling system theme, immediately sync with system preference const systemPrefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches; setDarkMode(systemPrefersDark); localStorage.removeItem('theme'); // Remove manual theme setting } // If disabling system theme, keep current theme state but don't update localStorage yet }; const handleVersionSelect = (version: string) => { setOpen(false); setShowVersions(false); // Create a new chat window with the selected version window.electron.createChatWindow(undefined, undefined, version); }; return (
{/*
Use System Theme
*/} {/* {!useSystemTheme && ( */} {/* )} */} {/* Versions Menu */} {/* NOTE from alexhancock on 1/14/2025 - disabling temporarily until we figure out where this will go in settings */} {false && versions && versions.available_versions.length > 0 && ( <> {showVersions && (
{versions.available_versions.map((version) => ( ))}
)} )} {/* Settings Menu */} {/* Provider keys settings */} {process.env.NODE_ENV === 'development' && ( )}
); }