refactor(album-detail): I.7 — split AlbumDetail.tsx 511 → 369 LOC across 5 files (#679)

* refactor(album-detail): extract sanitizeFilename + useAlbumDetailData

Move sanitizeFilename into utils/albumDetailHelpers.ts. Pull the album +
related-albums fetch and the starred state seeds (isStarred,
starredSongs) into hooks/useAlbumDetailData.ts.

AlbumDetail.tsx: 511 → 483 LOC.

* refactor(album-detail): extract useAlbumOfflineState hook

Move the four primitive-selector offline status reads (cache map +
job-status filters + progress totals) into hooks/useAlbumOfflineState.ts.
Keeps the re-render minimisation comment with the code that needs it.

AlbumDetail.tsx: 483 → 461 LOC.

* refactor(album-detail): extract useAlbumDetailSort hook

Pull sortKey/Dir/clickCount state, the 3-click natural-reset cycle in
handleSort, and the displayedSongs memo (filter + sort comparator) into
hooks/useAlbumDetailSort.ts. Rating comparator keeps the same priority
chain as the row renderer.

AlbumDetail.tsx: 461 → 414 LOC.

* refactor(album-detail): extract AlbumDetailToolbar subcomponent

Pull the search input + bulk-action cluster (selection count, add-to-
playlist popover, clear-selection button) into
components/albumDetail/AlbumDetailToolbar.tsx. Parent retains showPlPicker
to coordinate the popover close with selection clears.

AlbumDetail.tsx: 414 → 369 LOC.
This commit is contained in:
Frank Stellmacher
2026-05-14 01:19:58 +02:00
committed by GitHub
parent 3dc50a2ef0
commit ff99b10faa
6 changed files with 337 additions and 170 deletions
+15
View File
@@ -0,0 +1,15 @@
/**
* Make an arbitrary album / playlist name safe to use as a file name on
* Windows, macOS, and Linux. Replaces every reserved character class with
* a dash, collapses runs of dots (which Windows treats specially) into one,
* trims leading/trailing whitespace and dots, and caps the length at 200
* characters so we don't hit MAX_PATH edges on Windows. Falls back to
* `download` when the sanitisation strips the name down to nothing.
*/
export function sanitizeFilename(name: string): string {
return name
.replace(/[/\\?%*:|"<>]/g, '-')
.replace(/\.{2,}/g, '.')
.replace(/^[\s.]+|[\s.]+$/g, '')
.substring(0, 200) || 'download';
}