import React, { useState, useCallback, useMemo } from "react"; import { Button, SegmentedControl, Loader } from "@mantine/core"; import { useRainbowThemeContext } from "./RainbowThemeProvider"; import LanguageSelector from "./LanguageSelector"; import rainbowStyles from '../../styles/rainbow.module.css'; import DarkModeIcon from '@mui/icons-material/DarkMode'; import LightModeIcon from '@mui/icons-material/LightMode'; import AutoAwesomeIcon from '@mui/icons-material/AutoAwesome'; import VisibilityIcon from "@mui/icons-material/Visibility"; import EditNoteIcon from "@mui/icons-material/EditNote"; import FolderIcon from "@mui/icons-material/Folder"; import { Group } from "@mantine/core"; import { ModeType } from '../../contexts/NavigationContext'; // Stable view option objects that don't recreate on every render const VIEW_OPTIONS_BASE = [ { value: "viewer", icon: VisibilityIcon }, { value: "pageEditor", icon: EditNoteIcon }, { value: "fileEditor", icon: FolderIcon }, ] as const; interface TopControlsProps { currentView: ModeType; setCurrentView: (view: ModeType) => void; selectedToolKey?: string | null; } const TopControls = ({ currentView, setCurrentView, selectedToolKey, }: TopControlsProps) => { const { themeMode, isRainbowMode, isToggleDisabled, toggleTheme } = useRainbowThemeContext(); const [switchingTo, setSwitchingTo] = useState(null); const isToolSelected = selectedToolKey !== null; const handleViewChange = useCallback((view: string) => { // Guard against redundant changes if (view === currentView) return; // Show immediate feedback setSwitchingTo(view); // Defer the heavy view change to next frame so spinner can render requestAnimationFrame(() => { // Give the spinner one more frame to show requestAnimationFrame(() => { setCurrentView(view as ModeType); // Clear the loading state after view change completes setTimeout(() => setSwitchingTo(null), 300); }); }); }, [setCurrentView, currentView]); // Memoize the SegmentedControl data with stable references const viewOptions = useMemo(() => VIEW_OPTIONS_BASE.map(option => ({ value: option.value, label: ( {switchingTo === option.value ? ( ) : ( )} ) })), [switchingTo]); const getThemeIcon = () => { if (isRainbowMode) return ; if (themeMode === "dark") return ; return ; }; return (
{!isToolSelected && (
)}
); }; export default TopControls;