import { NavLink, Outlet, useLocation } from "react-router-dom"; import { LuSettings, LuMouse, LuKeyboard, LuVideo, LuCpu, LuShieldCheck, LuWrench, LuArrowLeft, LuPalette, LuCommand, LuNetwork, } from "react-icons/lu"; import React, { useEffect, useRef, useState } from "react"; import { useResizeObserver } from "usehooks-ts"; import Card from "@/components/Card"; import { LinkButton } from "@/components/Button"; import LoadingSpinner from "@/components/LoadingSpinner"; import { useUiStore } from "@/hooks/stores"; import useKeyboard from "@/hooks/useKeyboard"; import { cx } from "../cva.config"; /* TODO: Migrate to using URLs instead of the global state. To simplify the refactoring, we'll keep the global state for now. */ export default function SettingsRoute() { const location = useLocation(); const setDisableVideoFocusTrap = useUiStore(state => state.setDisableVideoFocusTrap); const { sendKeyboardEvent } = useKeyboard(); const scrollContainerRef = useRef(null); const [showLeftGradient, setShowLeftGradient] = useState(false); const [showRightGradient, setShowRightGradient] = useState(false); const { width = 0 } = useResizeObserver({ ref: scrollContainerRef as React.RefObject }); // Handle scroll position to show/hide gradients const handleScroll = () => { if (scrollContainerRef.current) { const { scrollLeft, scrollWidth, clientWidth } = scrollContainerRef.current; // Show left gradient only if scrolled to the right setShowLeftGradient(scrollLeft > 0); // Show right gradient only if there's more content to scroll to the right setShowRightGradient(scrollLeft < scrollWidth - clientWidth - 1); // -1 for rounding errors } }; useEffect(() => { // Check initial scroll position handleScroll(); // Add scroll event listener to the container const scrollContainer = scrollContainerRef.current; if (scrollContainer) { scrollContainer.addEventListener("scroll", handleScroll); } return () => { // Clean up event listener if (scrollContainer) { scrollContainer.removeEventListener("scroll", handleScroll); } }; }, [width]); useEffect(() => { // disable focus trap setTimeout(() => { // Reset keyboard state. Incase the user is pressing a key while enabling the sidebar sendKeyboardEvent([], []); setDisableVideoFocusTrap(true); // For some reason, the focus trap is not disabled immediately // so we need to blur the active element (document.activeElement as HTMLElement)?.blur(); console.log("Just disabled focus trap"); }, 300); return () => { setDisableVideoFocusTrap(false); }; }, [setDisableVideoFocusTrap, sendKeyboardEvent]); return (
{/* Gradient overlay for left side - only visible on mobile when scrolled */}
{/* Gradient overlay for right side - only visible on mobile when there's more content */}
(isActive ? "active" : "")} >

General

(isActive ? "active" : "")} >

Mouse

(isActive ? "active" : "")} >

Keyboard

(isActive ? "active" : "")} >

Video

(isActive ? "active" : "")} >

Hardware

(isActive ? "active" : "")} >

Access

(isActive ? "active" : "")} >

Appearance

(isActive ? "active" : "")} >

Keyboard Macros

(isActive ? "active" : "")} >

Network

(isActive ? "active" : "")} >

Advanced

{/* */}
{/*
*/}
); } export function SettingsItem({ title, description, children, className, loading, badge, }: { title: string; description: string | React.ReactNode; children?: React.ReactNode; className?: string; name?: string; loading?: boolean; badge?: string; }) { return ( ); }