mirror of
https://github.com/Psychotoxical/psysonic.git
synced 2026-07-22 07:15:47 +00:00
refactor(composers): co-locate composers feature into features/composers
This commit is contained in:
@@ -13,8 +13,8 @@ const Home = lazy(() => import('../pages/Home'));
|
||||
const Albums = lazy(() => import('@/features/album/pages/Albums'));
|
||||
const Artists = lazy(() => import('@/features/artist/pages/Artists'));
|
||||
const ArtistDetail = lazy(() => import('@/features/artist/pages/ArtistDetail'));
|
||||
const Composers = lazy(() => import('../pages/Composers'));
|
||||
const ComposerDetail = lazy(() => import('../pages/ComposerDetail'));
|
||||
const Composers = lazy(() => import('@/features/composers/pages/Composers'));
|
||||
const ComposerDetail = lazy(() => import('@/features/composers/pages/ComposerDetail'));
|
||||
const NewReleases = lazy(() => import('@/features/album/pages/NewReleases'));
|
||||
const Favorites = lazy(() => import('@/features/favorites/pages/Favorites'));
|
||||
const RandomMix = lazy(() => import('../pages/RandomMix'));
|
||||
|
||||
+3
-3
@@ -7,9 +7,9 @@ import {
|
||||
type ComposerBrowseViewMode,
|
||||
isComposersBrowsePath,
|
||||
useComposerBrowseSessionStore,
|
||||
} from '../store/composerBrowseSessionStore';
|
||||
import { shouldRestoreComposerBrowseSession } from '../utils/navigation/albumDetailNavigation';
|
||||
import { useLiveSearchScopeStore } from '../store/liveSearchScopeStore';
|
||||
} from '@/features/composers/store/composerBrowseSessionStore';
|
||||
import { shouldRestoreComposerBrowseSession } from '@/utils/navigation/albumDetailNavigation';
|
||||
import { useLiveSearchScopeStore } from '@/store/liveSearchScopeStore';
|
||||
|
||||
export type ComposerBrowseScrollSnapshot = {
|
||||
scrollTop: number;
|
||||
+2
-2
@@ -3,8 +3,8 @@ import { useLocation, useNavigationType, type NavigationType } from 'react-route
|
||||
import {
|
||||
peekComposerBrowseScrollRestore,
|
||||
useComposerBrowseSessionStore,
|
||||
} from '../store/composerBrowseSessionStore';
|
||||
import { shouldRestoreComposerBrowseSession } from '../utils/navigation/albumDetailNavigation';
|
||||
} from '@/features/composers/store/composerBrowseSessionStore';
|
||||
import { shouldRestoreComposerBrowseSession } from '@/utils/navigation/albumDetailNavigation';
|
||||
|
||||
type PendingScroll = {
|
||||
scrollTop: number;
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
import { useCallback } from 'react';
|
||||
import { useLocation, useNavigate } from 'react-router-dom';
|
||||
import { navigateToComposerDetail } from '../utils/navigation/albumDetailNavigation';
|
||||
import { navigateToComposerDetail } from '@/utils/navigation/albumDetailNavigation';
|
||||
|
||||
/** Navigate to composer detail, remembering the current page for the back button. */
|
||||
export function useNavigateToComposer() {
|
||||
@@ -0,0 +1,8 @@
|
||||
/**
|
||||
* Composers feature — the composer overview (`Composers`) and per-composer
|
||||
* works (`ComposerDetail`) browse pages, their browse-filter / scroll-restore /
|
||||
* navigation hooks, and the composer browse-session store. The pages are
|
||||
* lazy-loaded by the router via their deep paths, so they are not re-exported
|
||||
* here. Only the live-search scope predicate is consumed cross-feature.
|
||||
*/
|
||||
export { isComposersBrowsePath } from './store/composerBrowseSessionStore';
|
||||
@@ -5,21 +5,21 @@ import { useEffect, useState, useMemo } from 'react';
|
||||
import { useParams, useNavigate } from 'react-router-dom';
|
||||
import { ndListAlbumsByArtistRole } from '@/lib/api/navidromeBrowse';
|
||||
import { AlbumCard } from '@/features/album';
|
||||
import { ArtistHeroCover } from '../cover/artistHero';
|
||||
import { coverArtRef } from '../cover/ref';
|
||||
import { useCoverLightboxSrc } from '../cover/lightbox';
|
||||
import { ArtistHeroCover } from '@/cover/artistHero';
|
||||
import { coverArtRef } from '@/cover/ref';
|
||||
import { useCoverLightboxSrc } from '@/cover/lightbox';
|
||||
import { ArrowLeft, Users, Heart, Feather, Share2 } from 'lucide-react';
|
||||
import WikipediaIcon from '../components/WikipediaIcon';
|
||||
import WikipediaIcon from '@/components/WikipediaIcon';
|
||||
import { open } from '@tauri-apps/plugin-shell';
|
||||
import { usePlayerStore } from '@/features/playback/store/playerStore';
|
||||
import { useAuthStore } from '../store/authStore';
|
||||
import { useAuthStore } from '@/store/authStore';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { copyEntityShareLink } from '../utils/share/copyEntityShareLink';
|
||||
import { showToast } from '../utils/ui/toast';
|
||||
import { copyEntityShareLink } from '@/utils/share/copyEntityShareLink';
|
||||
import { showToast } from '@/utils/ui/toast';
|
||||
import { sanitizeHtml } from '@/lib/util/sanitizeHtml';
|
||||
import { usePerfProbeFlags } from '../utils/perf/perfFlags';
|
||||
import { albumGridWarmCovers } from '../cover/layoutSizes';
|
||||
import { VirtualCardGrid } from '../components/VirtualCardGrid';
|
||||
import { usePerfProbeFlags } from '@/utils/perf/perfFlags';
|
||||
import { albumGridWarmCovers } from '@/cover/layoutSizes';
|
||||
import { VirtualCardGrid } from '@/components/VirtualCardGrid';
|
||||
|
||||
export default function ComposerDetail() {
|
||||
const { t } = useTranslation();
|
||||
@@ -3,32 +3,32 @@ import { useEffect, useState, useCallback, useRef, useMemo } from 'react';
|
||||
import { useLocation, useNavigate } from 'react-router-dom';
|
||||
import { ndListArtistsByRole } from '@/lib/api/navidromeBrowse';
|
||||
import { LayoutGrid, List } from 'lucide-react';
|
||||
import StarFilterButton from '../components/StarFilterButton';
|
||||
import StarFilterButton from '@/components/StarFilterButton';
|
||||
import { usePlayerStore } from '@/features/playback/store/playerStore';
|
||||
import { useAuthStore } from '../store/authStore';
|
||||
import { useAuthStore } from '@/store/authStore';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useVirtualizer } from '@tanstack/react-virtual';
|
||||
import { APP_MAIN_SCROLL_VIEWPORT_ID, COMPOSERS_INPAGE_SCROLL_VIEWPORT_ID } from '../constants/appScroll';
|
||||
import { APP_MAIN_SCROLL_VIEWPORT_ID, COMPOSERS_INPAGE_SCROLL_VIEWPORT_ID } from '@/constants/appScroll';
|
||||
import { useElementClientHeightById, useElementClientHeightForElement } from '@/lib/hooks/useResizeClientHeight';
|
||||
import { useMainstageInpageHeaderTight } from '../hooks/useMainstageInpageHeaderTight';
|
||||
import { useMainstageInpageHeaderTight } from '@/hooks/useMainstageInpageHeaderTight';
|
||||
import { useBrowseArtistTextSearch } from '@/features/artist';
|
||||
import { useComposersBrowseFilters, type ComposerBrowseScrollSnapshot } from '../hooks/useComposersBrowseFilters';
|
||||
import { useComposersBrowseScrollRestore } from '../hooks/useComposersBrowseScrollRestore';
|
||||
import { useComposersBrowseFilters, type ComposerBrowseScrollSnapshot } from '@/features/composers/hooks/useComposersBrowseFilters';
|
||||
import { useComposersBrowseScrollRestore } from '@/features/composers/hooks/useComposersBrowseScrollRestore';
|
||||
import { useArtistsBrowseScrollReset } from '@/features/artist';
|
||||
import { useNavigateToComposer } from '../hooks/useNavigateToComposer';
|
||||
import { peekComposerBrowseScrollRestore } from '../store/composerBrowseSessionStore';
|
||||
import { useScopedBrowseSearchQuery } from '../store/liveSearchScopeStore';
|
||||
import { readComposerBrowseRestore } from '../utils/navigation/albumDetailNavigation';
|
||||
import { useNavigateToComposer } from '@/features/composers/hooks/useNavigateToComposer';
|
||||
import { peekComposerBrowseScrollRestore } from '@/features/composers/store/composerBrowseSessionStore';
|
||||
import { useScopedBrowseSearchQuery } from '@/store/liveSearchScopeStore';
|
||||
import { readComposerBrowseRestore } from '@/utils/navigation/albumDetailNavigation';
|
||||
import { filterArtistsWithRoleAlbumCredits } from '@/lib/library/composerBrowse';
|
||||
import { ALL_SENTINEL, artistLetterBucket } from '@/features/artist';
|
||||
import { useLibraryIgnoredArticles } from '../hooks/useLibraryIgnoredArticles';
|
||||
import { usePerfProbeFlags } from '../utils/perf/perfFlags';
|
||||
import { VirtualCardGrid } from '../components/VirtualCardGrid';
|
||||
import { useLibraryIgnoredArticles } from '@/hooks/useLibraryIgnoredArticles';
|
||||
import { usePerfProbeFlags } from '@/utils/perf/perfFlags';
|
||||
import { VirtualCardGrid } from '@/components/VirtualCardGrid';
|
||||
import OverlayScrollArea from '@/ui/OverlayScrollArea';
|
||||
import { useVirtualizerScrollMargin } from '@/lib/hooks/useVirtualizerScrollMargin';
|
||||
import { useClientSliceInfiniteScroll } from '../hooks/useClientSliceInfiniteScroll';
|
||||
import { useInpageScrollViewport } from '../hooks/useInpageScrollViewport';
|
||||
import InpageScrollSentinel from '../components/InpageScrollSentinel';
|
||||
import { useClientSliceInfiniteScroll } from '@/hooks/useClientSliceInfiniteScroll';
|
||||
import { useInpageScrollViewport } from '@/hooks/useInpageScrollViewport';
|
||||
import InpageScrollSentinel from '@/components/InpageScrollSentinel';
|
||||
|
||||
const ALPHABET = [ALL_SENTINEL, '#', ...'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.split('')];
|
||||
|
||||
@@ -4,7 +4,7 @@ import type { LiveSearchScope } from '@/store/liveSearchScopeStore';
|
||||
import { isAlbumsBrowsePath, isNewReleasesBrowsePath } from '@/features/album';
|
||||
import { isTracksBrowsePath } from '@/store/advancedSearchSessionStore';
|
||||
import { isArtistsBrowsePath } from '@/features/artist';
|
||||
import { isComposersBrowsePath } from '@/store/composerBrowseSessionStore';
|
||||
import { isComposersBrowsePath } from '@/features/composers';
|
||||
|
||||
export const SCOPE_NAV_ITEM: Record<LiveSearchScope, keyof typeof ALL_NAV_ITEMS> = {
|
||||
artists: 'artists',
|
||||
|
||||
@@ -3,7 +3,7 @@ import { useLocation } from 'react-router-dom';
|
||||
import { isAlbumsBrowsePath, isNewReleasesBrowsePath } from '@/features/album';
|
||||
import { isArtistsBrowsePath } from '@/features/artist';
|
||||
import { isTracksBrowsePath } from '@/store/advancedSearchSessionStore';
|
||||
import { isComposersBrowsePath } from '@/store/composerBrowseSessionStore';
|
||||
import { isComposersBrowsePath } from '@/features/composers';
|
||||
import { useLiveSearchScopeStore } from '@/store/liveSearchScopeStore';
|
||||
|
||||
/** Keep scope badge in sync with browse routes; clear field text when leaving browse. */
|
||||
|
||||
Reference in New Issue
Block a user