mirror of
https://github.com/Psychotoxical/psysonic.git
synced 2026-07-22 07:15:47 +00:00
refactor(home): co-locate Mainstage/home feature into features/home
This commit is contained in:
@@ -9,7 +9,7 @@ import { resolveStartRoute } from '@/features/sidebar';
|
||||
|
||||
// Route-level lazy loading: keeps the non-page graph (shell, player, stores) in
|
||||
// the entry chunk; each page is fetched when its route is first visited.
|
||||
const Home = lazy(() => import('../pages/Home'));
|
||||
const Home = lazy(() => import('@/features/home/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'));
|
||||
|
||||
@@ -7,7 +7,7 @@ import { Play, ListPlus, RefreshCw, Sparkles } from 'lucide-react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useAuthStore } from '../../store/authStore';
|
||||
import { usePlayerStore } from '@/features/playback/store/playerStore';
|
||||
import SongRail from '../SongRail';
|
||||
import { SongRail } from '@/features/home';
|
||||
import { playSongNow } from '@/features/playback/utils/playback/playSong';
|
||||
import { ndListSongs, ndInvalidateSongsCache } from '@/lib/api/navidromeBrowse';
|
||||
import { usePerfProbeFlags } from '../../utils/perf/perfFlags';
|
||||
|
||||
+8
-8
@@ -8,21 +8,21 @@ import React, { memo, useEffect, useLayoutEffect, useMemo, useRef, useState } fr
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { Play, ListPlus, Music } from 'lucide-react';
|
||||
import { useAlbumCoverRef } from '../cover/useLibraryCoverRef';
|
||||
import { useLibraryCoverPrefetch } from '../cover/useLibraryCoverPrefetch';
|
||||
import { coverImgSrc } from '../cover/imgSrc';
|
||||
import { useCoverArt } from '../cover/useCoverArt';
|
||||
import { primeAlbumCoversForDisplay } from '../cover/warmDiskPeek';
|
||||
import { useAlbumCoverRef } from '@/cover/useLibraryCoverRef';
|
||||
import { useLibraryCoverPrefetch } from '@/cover/useLibraryCoverPrefetch';
|
||||
import { coverImgSrc } from '@/cover/imgSrc';
|
||||
import { useCoverArt } from '@/cover/useCoverArt';
|
||||
import { primeAlbumCoversForDisplay } from '@/cover/warmDiskPeek';
|
||||
import {
|
||||
readBecauseYouLikeCache,
|
||||
writeBecauseYouLikeCache,
|
||||
type BecauseYouLikeAnchor,
|
||||
} from '../store/becauseYouLikeCache';
|
||||
} from '@/features/home/store/becauseYouLikeCache';
|
||||
import { usePlayerStore } from '@/features/playback/store/playerStore';
|
||||
import { useAuthStore } from '../store/authStore';
|
||||
import { useAuthStore } from '@/store/authStore';
|
||||
import { playAlbum, playAlbumShuffled } from '@/features/playback/utils/playback/playAlbum';
|
||||
import { useLongPressAction } from '@/lib/hooks/useLongPressAction';
|
||||
import { LongPressWaveOverlay } from './LongPressWaveOverlay';
|
||||
import { LongPressWaveOverlay } from '@/components/LongPressWaveOverlay';
|
||||
import { formatHumanHoursMinutes } from '@/lib/format/formatHumanDuration';
|
||||
import { AlbumRow } from '@/features/album';
|
||||
import { albumArtistDisplayName } from '@/features/album';
|
||||
@@ -5,23 +5,23 @@ import { songToTrack } from '@/lib/media/songToTrack';
|
||||
import React, { useEffect, useState, useRef, useCallback, useMemo } from 'react';
|
||||
import { useNavigateToAlbum } from '@/features/album';
|
||||
import { Play, ListPlus, ChevronLeft, ChevronRight } from 'lucide-react';
|
||||
import { CoverArtImage } from '../cover/CoverArtImage';
|
||||
import { useAlbumCoverRef } from '../cover/useLibraryCoverRef';
|
||||
import { useArtistBanner, useArtistFanart } from '../cover/useArtistFanart';
|
||||
import { useCoverArt } from '../cover/useCoverArt';
|
||||
import { useHeroBackdrop } from '../cover/useHeroBackdrop';
|
||||
import { CoverArtImage } from '@/cover/CoverArtImage';
|
||||
import { useAlbumCoverRef } from '@/cover/useLibraryCoverRef';
|
||||
import { useArtistBanner, useArtistFanart } from '@/cover/useArtistFanart';
|
||||
import { useCoverArt } from '@/cover/useCoverArt';
|
||||
import { useHeroBackdrop } from '@/cover/useHeroBackdrop';
|
||||
import { useCachedUrl } from '@/ui/CachedImage';
|
||||
import { usePlayerStore } from '@/features/playback/store/playerStore';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useIsMobile } from '@/lib/hooks/useIsMobile';
|
||||
import { useWindowVisibility } from '@/lib/hooks/useWindowVisibility';
|
||||
import { useAuthStore } from '../store/authStore';
|
||||
import { useThemeStore } from '../store/themeStore';
|
||||
import { filterAlbumsByMixRatings, getMixMinRatingsConfigFromAuth } from '../utils/mix/mixRatingFilter';
|
||||
import { usePerfProbeFlags } from '../utils/perf/perfFlags';
|
||||
import { useAuthStore } from '@/store/authStore';
|
||||
import { useThemeStore } from '@/store/themeStore';
|
||||
import { filterAlbumsByMixRatings, getMixMinRatingsConfigFromAuth } from '@/utils/mix/mixRatingFilter';
|
||||
import { usePerfProbeFlags } from '@/utils/perf/perfFlags';
|
||||
import { playAlbum, playAlbumShuffled } from '@/features/playback/utils/playback/playAlbum';
|
||||
import { useLongPressAction } from '@/lib/hooks/useLongPressAction';
|
||||
import { LongPressWaveOverlay } from './LongPressWaveOverlay';
|
||||
import { LongPressWaveOverlay } from '@/components/LongPressWaveOverlay';
|
||||
import { albumArtistDisplayName, deriveAlbumArtistRefs } from '@/features/album';
|
||||
|
||||
const INTERVAL_MS = 10000;
|
||||
@@ -1,8 +1,8 @@
|
||||
import type { SubsonicSong } from '@/lib/api/subsonicTypes';
|
||||
import React, { useRef, useState, useEffect, useMemo } from 'react';
|
||||
import { ChevronLeft, ChevronRight, RefreshCw } from 'lucide-react';
|
||||
import SongCard from './SongCard';
|
||||
import { usePerfProbeFlags } from '../utils/perf/perfFlags';
|
||||
import SongCard from '@/components/SongCard';
|
||||
import { usePerfProbeFlags } from '@/utils/perf/perfFlags';
|
||||
import { dedupeById } from '@/lib/util/dedupeById';
|
||||
|
||||
interface Props {
|
||||
@@ -0,0 +1,11 @@
|
||||
/**
|
||||
* Home (Mainstage) feature — the Home landing page, its Hero banner, the song
|
||||
* rail + "because you like" recommendation rail, the mainstage section config
|
||||
* store, and the home-feed / because-you-like client caches. The page is
|
||||
* lazy-loaded by the router via its deep path, so it is not re-exported here.
|
||||
*
|
||||
* Cross-feature consumers pull only the section config store (settings'
|
||||
* mainstage customiser, the tracks-page chrome).
|
||||
*/
|
||||
export { useHomeStore, type HomeSectionId, type HomeSectionConfig, DEFAULT_HOME_SECTIONS } from './store/homeStore';
|
||||
export { default as SongRail } from './components/SongRail';
|
||||
@@ -3,32 +3,32 @@ import { getAlbumList, getRandomSongs } from '@/lib/api/subsonicLibrary';
|
||||
import type { SubsonicAlbum, SubsonicArtist, SubsonicSong } from '@/lib/api/subsonicTypes';
|
||||
import { runLocalRandomSongs } from '@/lib/library/browseTextSearch';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import Hero from '../components/Hero';
|
||||
import Hero from '@/features/home/components/Hero';
|
||||
import { AlbumRow } from '@/features/album';
|
||||
import SongRail from '../components/SongRail';
|
||||
import BecauseYouLikeRail from '../components/BecauseYouLikeRail';
|
||||
import SongRail from '@/features/home/components/SongRail';
|
||||
import BecauseYouLikeRail from '@/features/home/components/BecauseYouLikeRail';
|
||||
import { LosslessAlbumsRail } from '@/features/album';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { NavLink, useNavigate } from 'react-router-dom';
|
||||
import { ChevronRight } from 'lucide-react';
|
||||
import { useHomeStore } from '../store/homeStore';
|
||||
import { useAuthStore } from '../store/authStore';
|
||||
import { filterAlbumsByMixRatings, getMixMinRatingsConfigFromAuth } from '../utils/mix/mixRatingFilter';
|
||||
import { usePerfProbeFlags } from '../utils/perf/perfFlags';
|
||||
import { bumpPerfCounter } from '../utils/perf/perfTelemetry';
|
||||
import { useHomeStore } from '@/features/home/store/homeStore';
|
||||
import { useAuthStore } from '@/store/authStore';
|
||||
import { filterAlbumsByMixRatings, getMixMinRatingsConfigFromAuth } from '@/utils/mix/mixRatingFilter';
|
||||
import { usePerfProbeFlags } from '@/utils/perf/perfFlags';
|
||||
import { bumpPerfCounter } from '@/utils/perf/perfTelemetry';
|
||||
import { dedupeById } from '@/lib/util/dedupeById';
|
||||
import { shuffleArray } from '@/lib/util/shuffleArray';
|
||||
import { useLibraryCoverPrefetch } from '../cover/useLibraryCoverPrefetch';
|
||||
import { primeAlbumCoversForDisplay, warmHomeMainstageCovers } from '../cover/warmDiskPeek';
|
||||
import { readBecauseYouLikeCache } from '../store/becauseYouLikeCache';
|
||||
import { useLibraryCoverPrefetch } from '@/cover/useLibraryCoverPrefetch';
|
||||
import { primeAlbumCoversForDisplay, warmHomeMainstageCovers } from '@/cover/warmDiskPeek';
|
||||
import { readBecauseYouLikeCache } from '@/features/home/store/becauseYouLikeCache';
|
||||
import {
|
||||
isHomeFeedSnapshotEmpty,
|
||||
readHomeFeedCache,
|
||||
readHomeFeedCacheStale,
|
||||
writeHomeFeedCache,
|
||||
type HomeFeedSnapshot,
|
||||
} from '../store/homeFeedCache';
|
||||
import { useConnectionStatus } from '../hooks/useConnectionStatus';
|
||||
} from '@/features/home/store/homeFeedCache';
|
||||
import { useConnectionStatus } from '@/hooks/useConnectionStatus';
|
||||
import { useOfflineBrowseContext } from '@/features/offline';
|
||||
import { useOfflineBrowseReloadToken } from '@/features/offline';
|
||||
import { useDevOfflineBrowseStore } from '@/features/offline';
|
||||
+1
-1
@@ -3,7 +3,7 @@ import {
|
||||
clearBecauseYouLikeCache,
|
||||
readBecauseYouLikeCache,
|
||||
writeBecauseYouLikeCache,
|
||||
} from './becauseYouLikeCache';
|
||||
} from '@/features/home/store/becauseYouLikeCache';
|
||||
|
||||
describe('becauseYouLikeCache', () => {
|
||||
it('invalidates when music library filter version changes', () => {
|
||||
@@ -1,5 +1,5 @@
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useHomeStore, HomeSectionId } from '@/store/homeStore';
|
||||
import { useHomeStore, HomeSectionId } from '@/features/home';
|
||||
|
||||
export function HomeCustomizer() {
|
||||
const { t } = useTranslation();
|
||||
|
||||
@@ -3,7 +3,7 @@ import { Disc3, LayoutGrid, ListOrdered, ListTodo, PanelLeft, RotateCcw, Users }
|
||||
import { useArtistLayoutStore } from '@/features/artist';
|
||||
import { useAuthStore } from '@/store/authStore';
|
||||
import type { QueueDisplayMode } from '@/store/authStoreTypes';
|
||||
import { useHomeStore } from '@/store/homeStore';
|
||||
import { useHomeStore } from '@/features/home';
|
||||
import { usePlayerBarLayoutStore } from '@/store/playerBarLayoutStore';
|
||||
import { usePlaylistLayoutStore } from '@/features/playlist';
|
||||
import { useQueueToolbarStore } from '@/store/queueToolbarStore';
|
||||
|
||||
Reference in New Issue
Block a user