import { useCallback } from "react"; import { useRouter } from 'next/navigation'; import Image from "next/image"; import { Github, Mail } from "lucide-react" import { Menubar, MenubarCheckboxItem, MenubarContent, MenubarLabel, MenubarItem, MenubarMenu, MenubarSeparator, MenubarShortcut, MenubarSub, MenubarSubContent, MenubarSubTrigger, MenubarTrigger, } from "@/components/ui/menubar" import { useState, useEffect } from "react" import { Button } from "@/components/ui/button" import { Separator } from '@/components/ui/separator'; import { useNavidrome } from "./NavidromeContext"; import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger, } from "@/components/ui/dialog" import { Input } from "@/components/ui/input" import { Label } from "@/components/ui/label" interface MenuProps { toggleSidebar: () => void; isSidebarVisible: boolean; toggleStatusBar: () => void; isStatusBarVisible: boolean; } export function Menu({ toggleSidebar, isSidebarVisible, toggleStatusBar, isStatusBarVisible }: MenuProps) { const [isFullScreen, setIsFullScreen] = useState(false) const router = useRouter(); const [open, setOpen] = useState(false); const { isConnected } = useNavidrome(); // For this demo, we'll show connection status instead of user auth const connectionStatus = isConnected ? "Connected to Navidrome" : "Not connected"; const handleFullScreen = useCallback(() => { if (!isFullScreen) { document.documentElement.requestFullscreen() } else { document.exitFullscreen() } setIsFullScreen(!isFullScreen) }, [isFullScreen]) useEffect(() => { const handleKeyDown = (event: KeyboardEvent) => { if ((event.metaKey || event.ctrlKey) && event.key === ',') { event.preventDefault(); router.push('/settings'); } if ((event.metaKey || event.ctrlKey) && event.key === 's') { event.preventDefault(); toggleSidebar(); } if ((event.metaKey || event.ctrlKey) && event.key === 'f') { event.preventDefault(); handleFullScreen(); } }; window.addEventListener('keydown', handleKeyDown); return () => { window.removeEventListener('keydown', handleKeyDown); }; }, [router, toggleSidebar, handleFullScreen]); return ( <>

j

mice setOpen(true)}>About Music router.push('/settings')}> Preferences ⌘, Hide Music ⌘H Hide Others ⇧⌘H Quit Music ⌘Q

j

File New Playlist ⌘N Playlist from Selection ⇧⌘N Smart Playlist ⌥⌘N Playlist Folder Genius Playlist Open Stream URL ⌘U Close Window ⌘W Library Update Cloud Library Update Genius Organize Library Export Library Import Playlist Export Playlist Show Duplicate Items Get Album Artwork Get Track Names Import ⌘O Burn Playlist to Disc Show in Finder ⇧⌘R{" "} Convert Page Setup Print ⌘P Edit Undo ⌘Z Redo ⇧⌘Z Cut ⌘X Copy ⌘C Paste ⌘V Select All ⌘A Deselect All ⇧⌘A Smart Dictation{" "} Emoji & Symbols{" "} View Show Playing Next Show Lyrics {isStatusBarVisible ? "Hide Status Bar" : "Show Status Bar"} {isSidebarVisible ? "Hide Sidebar" : "Show Sidebar"} ⌘S {isFullScreen ? "Exit Full Screen" : "Enter Full Screen"} Account Server Status {connectionStatus} router.push('/settings')}> Settings
music

mice

{/* Version 1.0.0 */}

A Navidrome client built with Next.js and Shadcn/UI.

Server Status

{isConnected ? "Connected" : "Not connected"}

Navidrome URL {typeof window !== "undefined" ? (() => { const config = localStorage.getItem("navidrome-config"); if (config) { try { const { serverUrl } = JSON.parse(config); if (serverUrl) { // Remove protocol (http:// or https://) and trailing slash const prettyUrl = serverUrl.replace(/^https?:\/\//, "").replace(/\/$/, ""); return prettyUrl; } return Not set; } catch { return Invalid config; } } return Not set; })() : Not available}
Copyright © {new Date().getFullYear()} sillyangel
) }