feat: refactoring
Publish Metadata Agent Image / build-and-push-image (push) Successful in 4m2s
Publish Web Player Image / build-and-push-image (push) Successful in 4m47s

This commit is contained in:
Boris Cherepanov
2026-04-04 19:17:33 +03:00
parent 3199c12af5
commit 0b6f518b72
3 changed files with 37 additions and 49 deletions
+3 -37
View File
@@ -15,8 +15,6 @@ import {
playAtIndex,
removeFromQueueAt,
moveQueueItemInOrder,
toggleShuffle,
toggleRepeat,
rebuildShuffleOrder,
selectQueueOrder,
selectPlayingOrigIdx,
@@ -71,6 +69,7 @@ export function FurumiPlayer() {
playIndex: (i: number) => void
removeFromQueue: (idx: number) => void
moveQueueItem: (fromPos: number, toPos: number) => void
clearQueue: () => void
} | null>(null)
const audioRef = useRef<HTMLAudioElement>(null)
@@ -97,16 +96,6 @@ export function FurumiPlayer() {
}
}, [nowPlayingTrack])
const shuffle = useAppSelector((s) => s.queue.shuffle)
const repeatAll = useAppSelector((s) => s.queue.repeatAll)
useEffect(() => {
const btnShuffle = document.getElementById('btnShuffle')
const btnRepeat = document.getElementById('btnRepeat')
btnShuffle?.classList.toggle('active', shuffle)
btnRepeat?.classList.toggle('active', repeatAll)
}, [shuffle, repeatAll])
useEffect(() => {
const audioEl = audioRef.current
if (!audioEl) return
@@ -359,14 +348,7 @@ export function FurumiPlayer() {
playIndex,
removeFromQueue,
moveQueueItem,
}
function onToggleShuffle() {
dispatch(toggleShuffle())
}
function onToggleRepeat() {
dispatch(toggleRepeat())
clearQueue: clearQueuePlayback,
}
function onSearch(q: string) {
@@ -452,20 +434,10 @@ export function FurumiPlayer() {
searchInput.addEventListener('keydown', onSearchKeydown)
}
const onShuffleClick = () => onToggleShuffle()
const onRepeatClick = () => onToggleRepeat()
const onClearClick = () => clearQueuePlayback()
const onPrevClick = () => prevTrack()
const onPlayClick = () => togglePlay()
const onNextClick = () => nextTrack()
const btnShuffle = document.getElementById('btnShuffle')
btnShuffle?.addEventListener('click', onShuffleClick)
const btnRepeat = document.getElementById('btnRepeat')
btnRepeat?.addEventListener('click', onRepeatClick)
const btnClear = document.getElementById('btnClearQueue')
btnClear?.addEventListener('click', onClearClick)
const btnPrev = document.getElementById('btnPrev')
btnPrev?.addEventListener('click', onPrevClick)
const btnPlay = document.getElementById('btnPlayPause')
@@ -503,9 +475,6 @@ export function FurumiPlayer() {
sidebarOverlay?.removeEventListener('click', onSidebarOverlayClick)
searchInput?.removeEventListener('input', onSearchInput)
searchInput?.removeEventListener('keydown', onSearchKeydown)
btnShuffle?.removeEventListener('click', onShuffleClick)
btnRepeat?.removeEventListener('click', onRepeatClick)
btnClear?.removeEventListener('click', onClearClick)
btnPrev?.removeEventListener('click', onPrevClick)
btnPlay?.removeEventListener('click', onPlayClick)
btnNext?.removeEventListener('click', onNextClick)
@@ -550,10 +519,6 @@ export function FurumiPlayer() {
libraryLoading={libraryLoading}
libraryError={libraryError}
libraryItems={libraryItems}
queueItemsView={queueItemsView}
queueOrderView={queueOrderView}
queuePlayingOrigIdxView={queuePlayingOrigIdxView}
queueScrollSignal={queueScrollSignal}
onQueuePlay={(origIdx) => queueActionsRef.current?.playIndex(origIdx)}
onQueueRemove={(origIdx) =>
queueActionsRef.current?.removeFromQueue(origIdx)
@@ -561,6 +526,7 @@ export function FurumiPlayer() {
onQueueMove={(fromPos, toPos) =>
queueActionsRef.current?.moveQueueItem(fromPos, toPos)
}
onClearQueue={() => queueActionsRef.current?.clearQueue()}
/>
<PlayerBar
@@ -1,7 +1,18 @@
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, type QueueItem } from './QueueList'
import { QueueList } from './QueueList'
export type Crumb = { label: string; action?: () => void }
@@ -21,13 +32,10 @@ type MainPanelProps = {
libraryLoading: boolean
libraryError: string | null
libraryItems: LibraryListItem[]
queueItemsView: QueueItem[]
queueOrderView: number[]
queuePlayingOrigIdxView: number
queueScrollSignal: number
onQueuePlay: (origIdx: number) => void
onQueueRemove: (origIdx: number) => void
onQueueMove: (fromPos: number, toPos: number) => void
onClearQueue: () => void
}
export function MainPanel({
@@ -35,14 +43,19 @@ export function MainPanel({
libraryLoading,
libraryError,
libraryItems,
queueItemsView,
queueOrderView,
queuePlayingOrigIdxView,
queueScrollSignal,
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" />
@@ -58,13 +71,21 @@ export function MainPanel({
<div className="queue-header">
<span>Queue</span>
<div className="queue-actions">
<button className="queue-btn active" id="btnShuffle">
<button
type="button"
className={`queue-btn${shuffle ? ' active' : ''}`}
onClick={() => dispatch(toggleShuffle())}
>
Shuffle
</button>
<button className="queue-btn active" id="btnRepeat">
<button
type="button"
className={`queue-btn${repeatAll ? ' active' : ''}`}
onClick={() => dispatch(toggleRepeat())}
>
Repeat
</button>
<button className="queue-btn" id="btnClearQueue">
<button type="button" className="queue-btn" onClick={onClearQueue}>
Clear
</button>
</div>
@@ -239,6 +239,7 @@ export function selectQueueItems(state: QueueSliceRoot) {
return state.queue.items
}
// TODO: toggle shuffle should rebuild the shuffle order
export function selectQueueOrder(state: QueueSliceRoot): number[] {
const q = state.queue
if (!q.shuffle) return q.items.map((_, i) => i)