108 lines
3.1 KiB
TypeScript
108 lines
3.1 KiB
TypeScript
import type { MouseEvent as ReactMouseEvent } from 'react'
|
|
import { useAppDispatch, useAppSelector } from '../store'
|
|
import {
|
|
selectPlayingOrigIdx,
|
|
selectQueueItems,
|
|
selectQueueOrder,
|
|
selectQueueScrollSignal,
|
|
selectRepeatAll,
|
|
selectShuffle,
|
|
toggleRepeat,
|
|
toggleShuffle,
|
|
} from '../store/slices/queueSlice'
|
|
import { Breadcrumbs } from './Breadcrumbs'
|
|
import { LibraryList } from './LibraryList'
|
|
import { QueueList } from './QueueList'
|
|
|
|
export type Crumb = { label: string; action?: () => void }
|
|
|
|
export type LibraryListItem = {
|
|
key: string
|
|
className: string
|
|
icon: string
|
|
name: string
|
|
detail?: string
|
|
nameClassName?: string
|
|
onClick: () => void
|
|
button?: { title: string; onClick: (ev: ReactMouseEvent<HTMLButtonElement>) => void }
|
|
}
|
|
|
|
type MainPanelProps = {
|
|
breadcrumbs: Crumb[]
|
|
libraryLoading: boolean
|
|
libraryError: string | null
|
|
libraryItems: LibraryListItem[]
|
|
onQueuePlay: (origIdx: number) => void
|
|
onQueueRemove: (origIdx: number) => void
|
|
onQueueMove: (fromPos: number, toPos: number) => void
|
|
onClearQueue: () => void
|
|
}
|
|
|
|
export function MainPanel({
|
|
breadcrumbs,
|
|
libraryLoading,
|
|
libraryError,
|
|
libraryItems,
|
|
onQueuePlay,
|
|
onQueueRemove,
|
|
onQueueMove,
|
|
onClearQueue,
|
|
}: MainPanelProps) {
|
|
const dispatch = useAppDispatch()
|
|
const queueItemsView = useAppSelector(selectQueueItems)
|
|
const queueOrderView = useAppSelector(selectQueueOrder)
|
|
const queuePlayingOrigIdxView = useAppSelector(selectPlayingOrigIdx)
|
|
const queueScrollSignal = useAppSelector(selectQueueScrollSignal)
|
|
const shuffle = useAppSelector(selectShuffle)
|
|
const repeatAll = useAppSelector(selectRepeatAll)
|
|
|
|
return (
|
|
<div className="main">
|
|
<div className="sidebar-overlay" id="sidebarOverlay" />
|
|
<aside className="sidebar" id="sidebar">
|
|
<div className="sidebar-header">Library</div>
|
|
<Breadcrumbs items={breadcrumbs} />
|
|
<div className="file-list" id="fileList">
|
|
<LibraryList loading={libraryLoading} error={libraryError} items={libraryItems} />
|
|
</div>
|
|
</aside>
|
|
|
|
<section className="queue-panel">
|
|
<div className="queue-header">
|
|
<span>Queue</span>
|
|
<div className="queue-actions">
|
|
<button
|
|
type="button"
|
|
className={`queue-btn${shuffle ? ' active' : ''}`}
|
|
onClick={() => dispatch(toggleShuffle())}
|
|
>
|
|
Shuffle
|
|
</button>
|
|
<button
|
|
type="button"
|
|
className={`queue-btn${repeatAll ? ' active' : ''}`}
|
|
onClick={() => dispatch(toggleRepeat())}
|
|
>
|
|
Repeat
|
|
</button>
|
|
<button type="button" className="queue-btn" onClick={onClearQueue}>
|
|
Clear
|
|
</button>
|
|
</div>
|
|
</div>
|
|
<div className="queue-list" id="queueList">
|
|
<QueueList
|
|
queue={queueItemsView}
|
|
order={queueOrderView}
|
|
playingOrigIdx={queuePlayingOrigIdxView}
|
|
scrollSignal={queueScrollSignal}
|
|
onPlay={onQueuePlay}
|
|
onRemove={onQueueRemove}
|
|
onMove={onQueueMove}
|
|
/>
|
|
</div>
|
|
</section>
|
|
</div>
|
|
)
|
|
}
|