"use client"; import { useCallback, useState } from "react"; import { useSession } from "next-auth/react"; import { ListMusic, X } from "lucide-react"; import TopNav from "@/components/layout/TopNav"; import LeftSidebar from "@/components/layout/LeftSidebar"; import MainContent from "@/components/player/MainContent"; import QueueSidebar from "@/components/player/QueueSidebar"; import PlayerBar from "@/components/player/PlayerBar"; import type { DiscordServer, Track } from "@/types/music"; // 화면 모드 타입 정의 export type ViewMode = "SERVER_LIST" | "SERVER_DETAIL" | "SEARCH_RESULT"; export default function MusicPlayerLayout() { const { status } = useSession(); const [viewMode, setViewMode] = useState("SERVER_LIST"); const [selectedServer, setSelectedServer] = useState(null); const [searchQuery, setSearchQuery] = useState(""); // 대기열 표시 상태는 화면 크기별로 기본값이 달라서 두 개로 나눠 둔다. // (창 크기를 읽어 한 상태로 합치면 SSR·하이드레이션이 어긋난다) // · 좁은 화면: 기본 접힘 → 버튼으로 슬라이드 패널을 연다 // · 넓은 화면: 기본 펼침 → 재생바의 대기열 버튼으로 접을 수 있다 const [isQueueOpen, setIsQueueOpen] = useState(false); const [isQueueDocked, setIsQueueDocked] = useState(true); // 재생바가 이미 폴링하는 현재 곡을 대기열 패널과 공유한다(같은 API 를 두 번 부르지 않기 위함). const [nowPlaying, setNowPlaying] = useState(null); const handleNowPlayingChange = useCallback((t: Track | null) => setNowPlaying(t), []); const isAuthed = status === "authenticated"; // 서버를 고르기 전에는 재생/대기열이 의미가 없어, 화면을 차지하지 않게 숨긴다. const showPlayback = isAuthed && !!selectedServer; const handleHome = () => { if (selectedServer) { setViewMode("SERVER_DETAIL"); } else { setViewMode("SERVER_LIST"); setSelectedServer(null); setSearchQuery(""); } }; const handleSearch = (query: string) => { setSearchQuery(query); setViewMode("SEARCH_RESULT"); }; const handleSelectServer = (server: DiscordServer) => { setSelectedServer(server); setViewMode("SERVER_DETAIL"); }; const handleBackToServers = () => { setViewMode("SERVER_LIST"); setSelectedServer(null); setSearchQuery(""); setIsQueueOpen(false); }; return (
{/* 좌측 사이드바: 보조 정보라 넓은 화면에서만 노출한다(모바일 공간 절약). */} {showPlayback && ( )} {showPlayback && ( <> {/* 모바일에서 대기열이 열렸을 때 뒤쪽을 덮는 배경(탭하면 닫힘) */} {isQueueOpen && (
{showPlayback && ( setIsQueueOpen((v) => !v)} isQueueOpen={isQueueOpen} onToggleDock={() => setIsQueueDocked((v) => !v)} isQueueDocked={isQueueDocked} onNowPlayingChange={handleNowPlayingChange} /> )} {/* 모바일 전용 대기열 열기 버튼: 플레이어바에도 있지만, 재생 전에도 접근할 수 있게 둔다. */} {showPlayback && !isQueueOpen && ( )} {/* 모바일 패널 닫기 버튼(패널 위에 떠 있음) */} {showPlayback && isQueueOpen && ( )}
); }