refactor(genre): co-locate genre browse pages into features/genre

This commit is contained in:
Psychotoxical
2026-06-30 17:59:06 +02:00
parent 5808ef0839
commit 5fdec6cd2a
5 changed files with 32 additions and 20 deletions
+2 -2
View File
@@ -37,8 +37,8 @@ const LabelAlbums = lazy(() => import('@/features/album/pages/LabelAlbums'));
const SearchBrowsePage = lazy(() => import('@/features/search/pages/SearchBrowsePage'));
const FolderBrowser = lazy(() => import('@/features/folderBrowser/pages/FolderBrowser'));
const InternetRadio = lazy(() => import('@/features/radio/pages/InternetRadio'));
const Genres = lazy(() => import('../pages/Genres'));
const GenreDetail = lazy(() => import('../pages/GenreDetail'));
const Genres = lazy(() => import('@/features/genre/pages/Genres'));
const GenreDetail = lazy(() => import('@/features/genre/pages/GenreDetail'));
/**
* Index route ("/") = Mainstage. When the user has hidden Mainstage from the
@@ -1,6 +1,6 @@
import { useEffect, useRef, type RefObject } from 'react';
import { useLocation, useNavigationType } from 'react-router-dom';
import { GENRE_DETAIL_INPAGE_SCROLL_VIEWPORT_ID, readInpageScrollTop } from '../constants/appScroll';
import { GENRE_DETAIL_INPAGE_SCROLL_VIEWPORT_ID, readInpageScrollTop } from '@/constants/appScroll';
import {
DEFAULT_ALBUM_BROWSE_RETURN_FILTERS,
albumBrowseSortForServer,
@@ -12,7 +12,7 @@ import {
stashGenreDetailReturnFilters,
useAlbumBrowseSessionStore,
} from '@/features/album';
import { shouldRestoreAlbumBrowseSession } from '../utils/navigation/albumDetailNavigation';
import { shouldRestoreAlbumBrowseSession } from '@/utils/navigation/albumDetailNavigation';
import type { AlbumBrowseScrollSnapshot } from '@/features/album';
/** Genre detail: locked genre filter + leave/restore session (same contract as All Albums). */
+12
View File
@@ -0,0 +1,12 @@
/**
* Genre feature — the genre overview (`Genres`) and per-genre album browse
* (`GenreDetail`) pages plus the genre-detail browse hook. The pages are
* lazy-loaded by the router via their deep paths, so they are not re-exported
* here; nothing else outside the feature consumes its modules.
*
* Stays OUT (library-core / shared, consumed by this feature, not owned): the
* `lib/library/genre*` catalog/query helpers + `genreColor`, the album-side
* `useGenreAlbumBrowse` browse hook (`features/album`), and the
* `genreBrowsePlayback` queue builder (`features/playback`).
*/
export {};
@@ -3,21 +3,21 @@ import { useLocation, useNavigate, useParams } from 'react-router-dom';
import { useTranslation } from 'react-i18next';
import { ArrowLeft, Disc3, Play, ListPlus, Loader2 } from 'lucide-react';
import { AlbumCard } from '@/features/album';
import { LongPressWaveOverlay } from '../components/LongPressWaveOverlay';
import InpageScrollSentinel from '../components/InpageScrollSentinel';
import { LongPressWaveOverlay } from '@/components/LongPressWaveOverlay';
import InpageScrollSentinel from '@/components/InpageScrollSentinel';
import OverlayScrollArea from '@/ui/OverlayScrollArea';
import { VirtualCardGrid } from '../components/VirtualCardGrid';
import { GENRE_DETAIL_INPAGE_SCROLL_VIEWPORT_ID } from '../constants/appScroll';
import { albumGridWarmCovers } from '../cover/layoutSizes';
import { VirtualCardGrid } from '@/components/VirtualCardGrid';
import { GENRE_DETAIL_INPAGE_SCROLL_VIEWPORT_ID } from '@/constants/appScroll';
import { albumGridWarmCovers } from '@/cover/layoutSizes';
import { useAlbumBrowseScrollSnapshotSync, type AlbumBrowseScrollSnapshot } from '@/features/album';
import { useGenreAlbumBrowse } from '@/features/album';
import { useAlbumBrowseScrollRestore } from '@/features/album';
import { useGenreDetailBrowse } from '../hooks/useGenreDetailBrowse';
import { useInpageScrollViewport } from '../hooks/useInpageScrollViewport';
import { useGenreDetailBrowse } from '@/features/genre/hooks/useGenreDetailBrowse';
import { useInpageScrollViewport } from '@/hooks/useInpageScrollViewport';
import { useLongPressAction } from '@/lib/hooks/useLongPressAction';
import { useMainstageInpageHeaderTight } from '../hooks/useMainstageInpageHeaderTight';
import { useAuthStore } from '../store/authStore';
import { useLibraryIndexStore } from '../store/libraryIndexStore';
import { useMainstageInpageHeaderTight } from '@/hooks/useMainstageInpageHeaderTight';
import { useAuthStore } from '@/store/authStore';
import { useLibraryIndexStore } from '@/store/libraryIndexStore';
import { usePlayerStore } from '@/features/playback/store/playerStore';
import {
fetchGenreAlbumCount,
@@ -28,8 +28,8 @@ import { libraryScopeForServer } from '@/lib/api/subsonicClient';
import {
readAlbumBrowseRestore,
readAlbumDetailReturnTo,
} from '../utils/navigation/albumDetailNavigation';
import { usePerfProbeFlags } from '../utils/perf/perfFlags';
} from '@/utils/navigation/albumDetailNavigation';
import { usePerfProbeFlags } from '@/utils/perf/perfFlags';
import { runBulkEnqueue, runBulkPlayAll, runBulkShuffle } from '@/features/playback/utils/playback/runBulkPlay';
export default function GenreDetail() {
@@ -3,14 +3,14 @@ import { useEffect, useMemo, useState } from 'react';
import { useNavigate } from 'react-router-dom';
import { useTranslation } from 'react-i18next';
import { Tags } from 'lucide-react';
import { APP_MAIN_SCROLL_VIEWPORT_ID } from '../constants/appScroll';
import { APP_MAIN_SCROLL_VIEWPORT_ID } from '@/constants/appScroll';
import { subscribeLibrarySyncIdle } from '@/lib/api/library';
import { useAuthStore } from '../store/authStore';
import { useLibraryIndexStore } from '../store/libraryIndexStore';
import { useAuthStore } from '@/store/authStore';
import { useLibraryIndexStore } from '@/store/libraryIndexStore';
import { fetchGenreCatalog, filterGenresWithContent } from '@/features/playback/utils/playback/genreBrowsePlayback';
import { libraryScopeForServer } from '@/lib/api/subsonicClient';
import { peekGenreCatalogCache } from '@/lib/library/genreCatalogCountsCache';
import { resolveIndexKey } from '../utils/server/serverIndexKey';
import { resolveIndexKey } from '@/utils/server/serverIndexKey';
import { genreColor } from '@/lib/library/genreColor';
const SCROLL_KEY = 'genres-scroll';