mirror of
https://github.com/kilyabin/psysonic.git
synced 2026-07-22 22:45:41 +00:00
refactor(album-track-list): I.2 — split AlbumTrackList.tsx 662 → 187 LOC across 7 files (#672)
* refactor(album-track-list): extract helpers + types Pull formatDuration / codecLabel, the COLUMNS / CENTERED_COLS / SORTABLE_COLS tables, ColKey / SortKey types, and the isSortable type guard into utils/albumTrackListHelpers.ts. SortKey is re-exported from AlbumTrackList.tsx so existing imports stay valid. AlbumTrackList.tsx: 662 → 633 LOC. * refactor(album-track-list): extract TrackRow subcomponent Move the memoised tracklist row (~220 LOC including renderCell switch and mouse handlers) into components/albumTrackList/TrackRow.tsx. It still subscribes to its own selection + preview state via primitive selectors, so per-row re-render scope is unchanged. AlbumTrackList.tsx: 633 → 404 LOC. * refactor(album-track-list): extract AlbumTrackListMobile subcomponent Move the narrow-viewport branch (compact tracklist with disc separators and no column grid) into components/albumTrackList/AlbumTrackListMobile.tsx. AlbumTrackList.tsx: 404 → 376 LOC. * refactor(album-track-list): extract TracklistColumnPicker subcomponent The column visibility dropdown lives outside .tracklist to avoid the overflow box clipping its menu — pull the wrapper + button + popover into components/albumTrackList/TracklistColumnPicker.tsx. AlbumTrackList.tsx: 376 → 347 LOC. * refactor(album-track-list): extract TracklistHeaderRow subcomponent The fixed header (sortable + resizable per-column with the bulk-select toggle on the num cell) moves into components/albumTrackList/TracklistHeaderRow.tsx, taking 85+ LOC of cell rendering with it. AlbumTrackList.tsx: 347 → 254 LOC. * refactor(album-track-list): extract useAlbumTrackListSelection hook Pull bulk-selection state (selectedIds-size subscription, shift-range toggle, click-outside-clear, song-list-change clear) and the drag-start dispatcher (single vs multi-song drag) into hooks/useAlbumTrackListSelection.ts. AlbumTrackList.tsx: 254 → 187 LOC.
This commit is contained in:
committed by
GitHub
parent
b591a1cb5f
commit
f14c8f21e6
@@ -0,0 +1,82 @@
|
||||
import React from 'react';
|
||||
import { AudioLines } from 'lucide-react';
|
||||
import type { SubsonicSong } from '../../api/subsonicTypes';
|
||||
import type { Track } from '../../store/playerStoreTypes';
|
||||
import { songToTrack } from '../../utils/songToTrack';
|
||||
import { formatDuration } from '../../utils/albumTrackListHelpers';
|
||||
|
||||
interface Props {
|
||||
discNums: number[];
|
||||
discs: Map<number, SubsonicSong[]>;
|
||||
isMultiDisc: boolean;
|
||||
currentTrackId: string | null;
|
||||
isPlaying: boolean;
|
||||
contextMenuSongId: string | null;
|
||||
setContextMenuSongId: (id: string | null) => void;
|
||||
onPlaySong: (song: SubsonicSong) => void;
|
||||
onContextMenu: (
|
||||
x: number,
|
||||
y: number,
|
||||
track: Track,
|
||||
type: 'song' | 'album' | 'artist' | 'queue-item' | 'album-song',
|
||||
) => void;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compact tracklist for narrow viewports. Drops the column grid + column
|
||||
* picker + drag selection entirely — just a one-line row per song with
|
||||
* disc group separators. Play on tap, context menu on long-press / right
|
||||
* click.
|
||||
*/
|
||||
export function AlbumTrackListMobile({
|
||||
discNums,
|
||||
discs,
|
||||
isMultiDisc,
|
||||
currentTrackId,
|
||||
isPlaying,
|
||||
contextMenuSongId,
|
||||
setContextMenuSongId,
|
||||
onPlaySong,
|
||||
onContextMenu,
|
||||
}: Props) {
|
||||
return (
|
||||
<div className="tracklist-mobile">
|
||||
{discNums.map(discNum => (
|
||||
<div key={discNum}>
|
||||
{isMultiDisc && (
|
||||
<div className="disc-header">
|
||||
<span className="disc-icon">💿</span> CD {discNum}
|
||||
</div>
|
||||
)}
|
||||
{discs.get(discNum)!.map(song => {
|
||||
const isActive = currentTrackId === song.id;
|
||||
return (
|
||||
<div
|
||||
key={song.id}
|
||||
className={`tracklist-mobile-row${isActive ? ' active' : ''}${contextMenuSongId === song.id ? ' context-active' : ''}`}
|
||||
onClick={() => onPlaySong(song)}
|
||||
onContextMenu={e => {
|
||||
e.preventDefault();
|
||||
setContextMenuSongId(song.id);
|
||||
onContextMenu(e.clientX, e.clientY, songToTrack(song), 'album-song');
|
||||
}}
|
||||
>
|
||||
<div className="tracklist-mobile-main">
|
||||
{isActive && isPlaying ? (
|
||||
<span className="tracklist-mobile-eq">
|
||||
<AudioLines className="eq-bars" size={14} />
|
||||
</span>
|
||||
) : (
|
||||
<span className="tracklist-mobile-num">{song.track ?? ''}</span>
|
||||
)}
|
||||
<span className="tracklist-mobile-title">{song.title}</span>
|
||||
</div>
|
||||
<span className="tracklist-mobile-duration">{formatDuration(song.duration)}</span>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user