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