"use client"; import { LoadingButton } from "@/components/loading-button"; import { Badge } from "@/components/ui/badge"; import { Button } from "@/components/ui/button"; import { Checkbox } from "@/components/ui/checkbox"; import { Dialog, DialogContent, DialogFooter, DialogHeader, DialogTitle, } from "@/components/ui/dialog"; import { Label } from "@/components/ui/label"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "@/components/ui/select"; import { invoke } from "@tauri-apps/api/core"; import { useTheme } from "next-themes"; import { useEffect, useState } from "react"; interface AppSettings { set_as_default_browser: boolean; show_settings_on_startup: boolean; theme: string; auto_updates_enabled: boolean; auto_delete_unused_binaries: boolean; } interface SettingsDialogProps { isOpen: boolean; onClose: () => void; } export function SettingsDialog({ isOpen, onClose }: SettingsDialogProps) { const [settings, setSettings] = useState({ set_as_default_browser: false, show_settings_on_startup: true, theme: "system", auto_updates_enabled: true, auto_delete_unused_binaries: true, }); const [originalSettings, setOriginalSettings] = useState({ set_as_default_browser: false, show_settings_on_startup: true, theme: "system", auto_updates_enabled: true, auto_delete_unused_binaries: true, }); const [isDefaultBrowser, setIsDefaultBrowser] = useState(false); const [isLoading, setIsLoading] = useState(false); const [isSaving, setIsSaving] = useState(false); const [isSettingDefault, setIsSettingDefault] = useState(false); const [isClearingCache, setIsClearingCache] = useState(false); const [isCleaningBinaries, setIsCleaningBinaries] = useState(false); const { setTheme } = useTheme(); useEffect(() => { if (isOpen) { void loadSettings(); void checkDefaultBrowserStatus(); // Set up interval to check default browser status const intervalId = setInterval(() => { void checkDefaultBrowserStatus(); }, 500); // Check every 2 seconds // Cleanup interval on component unmount or dialog close return () => { clearInterval(intervalId); }; } }, [isOpen]); const loadSettings = async () => { setIsLoading(true); try { const appSettings = await invoke("get_app_settings"); setSettings(appSettings); setOriginalSettings(appSettings); } catch (error) { console.error("Failed to load settings:", error); } finally { setIsLoading(false); } }; const checkDefaultBrowserStatus = async () => { try { const isDefault = await invoke("is_default_browser"); setIsDefaultBrowser(isDefault); } catch (error) { console.error("Failed to check default browser status:", error); } }; const handleSetDefaultBrowser = async () => { setIsSettingDefault(true); try { await invoke("set_as_default_browser"); await checkDefaultBrowserStatus(); } catch (error) { console.error("Failed to set as default browser:", error); } finally { setIsSettingDefault(false); } }; const handleClearCache = async () => { setIsClearingCache(true); try { await invoke("clear_all_version_cache"); // Optionally show a success message console.log("Cache cleared successfully"); } catch (error) { console.error("Failed to clear cache:", error); } finally { setIsClearingCache(false); } }; const handleCleanupBinaries = async () => { setIsCleaningBinaries(true); try { const cleanedUp = await invoke("cleanup_unused_binaries"); if (cleanedUp.length > 0) { console.log( `Cleaned up ${cleanedUp.length} unused binaries:`, cleanedUp, ); // You could show a toast with the results } else { console.log("No unused binaries to clean up"); } } catch (error) { console.error("Failed to cleanup unused binaries:", error); } finally { setIsCleaningBinaries(false); } }; const handleSave = async () => { setIsSaving(true); try { await invoke("save_app_settings", { settings }); // Apply theme change immediately setTheme(settings.theme); setOriginalSettings(settings); onClose(); } catch (error) { console.error("Failed to save settings:", error); } finally { setIsSaving(false); } }; const updateSetting = (key: keyof AppSettings, value: boolean | string) => { setSettings((prev) => ({ ...prev, [key]: value })); }; // Check if settings have changed (excluding default browser setting) const hasChanges = settings.show_settings_on_startup !== originalSettings.show_settings_on_startup || settings.theme !== originalSettings.theme || settings.auto_updates_enabled !== originalSettings.auto_updates_enabled || settings.auto_delete_unused_binaries !== originalSettings.auto_delete_unused_binaries; return ( Settings
{/* Appearance Section */}

Choose your preferred theme or follow your system settings.

{/* Default Browser Section */}
{isDefaultBrowser ? "Active" : "Inactive"}
{ void handleSetDefaultBrowser(); }} disabled={isDefaultBrowser} variant={isDefaultBrowser ? "outline" : "default"} className="w-full" > {isDefaultBrowser ? "Already Default Browser" : "Set as Default Browser"}

When set as default, Donut Browser will handle web links and allow you to choose which profile to use.

{/* Auto-Update Section */}
{ updateSetting("auto_updates_enabled", checked as boolean); }} />
{ updateSetting( "auto_delete_unused_binaries", checked as boolean, ); }} />

When enabled, Donut Browser will check for browser updates and notify you when updates are available for your profiles. Unused binaries will be automatically deleted to save disk space.

{/* Startup Behavior Section */}
{ updateSetting("show_settings_on_startup", checked as boolean); }} />

When enabled, the settings dialog will be shown when the app starts.

{/* Advanced Section */}
{ void handleClearCache(); }} variant="outline" className="w-full" > Clear All Version Cache

Clear all cached browser version data. This will force a fresh download of version information on the next app restart or manual refresh.

{ void handleCleanupBinaries(); }} variant="outline" className="w-full" > Clean Up Unused Binaries

Manually remove browser binaries that are not used by any profile. This can help free up disk space. Note: This will run automatically when the setting above is enabled.

{ void handleSave(); }} disabled={isLoading || !hasChanges} > Save Settings
); }