mirror of
https://github.com/Psychotoxical/psysonic.git
synced 2026-07-22 07:15:47 +00:00
refactor(artist): co-locate artist feature into features/artist
This commit is contained in:
@@ -1,12 +1,12 @@
|
||||
import React from 'react';
|
||||
import type { SubsonicArtist } from '../../api/subsonicTypes';
|
||||
import { ArtistCoverArtImage } from '../../cover/ArtistCoverArtImage';
|
||||
import type { SubsonicArtist } from '@/api/subsonicTypes';
|
||||
import { ArtistCoverArtImage } from '@/cover/ArtistCoverArtImage';
|
||||
import {
|
||||
COVER_DENSE_ARTIST_LIST_CSS_PX,
|
||||
COVER_DENSE_GRID_MIN_CELL_CSS_PX,
|
||||
} from '../../cover/layoutSizes';
|
||||
import { ARTISTS_INPAGE_SCROLL_VIEWPORT_ID } from '../../constants/appScroll';
|
||||
import { nameColor, nameInitial } from '../../utils/componentHelpers/artistsHelpers';
|
||||
} from '@/cover/layoutSizes';
|
||||
import { ARTISTS_INPAGE_SCROLL_VIEWPORT_ID } from '@/constants/appScroll';
|
||||
import { nameColor, nameInitial } from '@/features/artist/utils/artistsHelpers';
|
||||
|
||||
interface AvatarProps {
|
||||
artist: SubsonicArtist;
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import type { SubsonicArtist } from '../api/subsonicTypes';
|
||||
import type { SubsonicArtist } from '@/api/subsonicTypes';
|
||||
import React, { useMemo } from 'react';
|
||||
import { Users } from 'lucide-react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { CoverArtImage } from '../cover/CoverArtImage';
|
||||
import { useArtistCoverRef } from '../cover/useLibraryCoverRef';
|
||||
import { COVER_DENSE_GRID_MIN_CELL_CSS_PX } from '../cover/layoutSizes';
|
||||
import { useNavigateToArtist } from '../hooks/useNavigateToArtist';
|
||||
import { coverServerScopeForServerId } from '../cover/serverScope';
|
||||
import { appendServerQuery } from '../utils/navigation/detailServerScope';
|
||||
import { CoverArtImage } from '@/cover/CoverArtImage';
|
||||
import { useArtistCoverRef } from '@/cover/useLibraryCoverRef';
|
||||
import { COVER_DENSE_GRID_MIN_CELL_CSS_PX } from '@/cover/layoutSizes';
|
||||
import { useNavigateToArtist } from '@/features/artist/hooks/useNavigateToArtist';
|
||||
import { coverServerScopeForServerId } from '@/cover/serverScope';
|
||||
import { appendServerQuery } from '@/utils/navigation/detailServerScope';
|
||||
|
||||
interface Props {
|
||||
artist: SubsonicArtist;
|
||||
|
||||
@@ -1,26 +1,26 @@
|
||||
import React, { useMemo, useRef, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useAlbumDetailBack } from '../../hooks/useAlbumDetailBack';
|
||||
import { useAlbumDetailBack } from '@/hooks/useAlbumDetailBack';
|
||||
import {
|
||||
ArrowLeft, Camera, Check, HardDriveDownload, Heart,
|
||||
Loader2, Play, Radio, Share2, Shuffle, Users,
|
||||
} from 'lucide-react';
|
||||
import type { SubsonicAlbum, SubsonicArtist, SubsonicArtistInfo } from '../../api/subsonicTypes';
|
||||
import type { SubsonicAlbum, SubsonicArtist, SubsonicArtistInfo } from '@/api/subsonicTypes';
|
||||
import { useOfflineStore } from '@/features/offline';
|
||||
import { useAuthStore } from '../../store/authStore';
|
||||
import { useThemeStore } from '../../store/themeStore';
|
||||
import { useArtistOfflineState } from '../../hooks/useArtistOfflineState';
|
||||
import { useIsMobile } from '../../hooks/useIsMobile';
|
||||
import { ArtistHeroCover } from '../../cover/artistHero';
|
||||
import { useArtistBanner, useArtistFanart } from '../../cover/useArtistFanart';
|
||||
import { backdropFromConfig } from '../../cover/artistBackdrop';
|
||||
import { usePlaybackCoverArt } from '../../cover/usePlaybackCoverArt';
|
||||
import { useAuthStore } from '@/store/authStore';
|
||||
import { useThemeStore } from '@/store/themeStore';
|
||||
import { useArtistOfflineState } from '@/features/artist/hooks/useArtistOfflineState';
|
||||
import { useIsMobile } from '@/hooks/useIsMobile';
|
||||
import { ArtistHeroCover } from '@/cover/artistHero';
|
||||
import { useArtistBanner, useArtistFanart } from '@/cover/useArtistFanart';
|
||||
import { backdropFromConfig } from '@/cover/artistBackdrop';
|
||||
import { usePlaybackCoverArt } from '@/cover/usePlaybackCoverArt';
|
||||
import { useCachedUrl } from '@/ui/CachedImage';
|
||||
import { useCoverLightboxSrc } from '../../cover/lightbox';
|
||||
import type { CoverArtRef } from '../../cover/types';
|
||||
import LastfmIcon from '../LastfmIcon';
|
||||
import WikipediaIcon from '../WikipediaIcon';
|
||||
import StarRating from '../StarRating';
|
||||
import { useCoverLightboxSrc } from '@/cover/lightbox';
|
||||
import type { CoverArtRef } from '@/cover/types';
|
||||
import LastfmIcon from '@/components/LastfmIcon';
|
||||
import WikipediaIcon from '@/components/WikipediaIcon';
|
||||
import StarRating from '@/components/StarRating';
|
||||
import { tooltipAttrs } from '@/ui/tooltipAttrs';
|
||||
import { offlineActionPolicy, type OfflineActionPolicy } from '@/features/offline';
|
||||
|
||||
|
||||
@@ -2,8 +2,8 @@ import React, { Fragment } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { ChevronDown, ChevronUp } from 'lucide-react';
|
||||
import type { SubsonicArtist } from '../../api/subsonicTypes';
|
||||
import { useIsMobile } from '../../hooks/useIsMobile';
|
||||
import type { SubsonicArtist } from '@/api/subsonicTypes';
|
||||
import { useIsMobile } from '@/hooks/useIsMobile';
|
||||
|
||||
interface Props {
|
||||
marginTop: string;
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
import React, { Fragment } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { AudioLines, ChevronRight, Play, Square } from 'lucide-react';
|
||||
import type { SubsonicAlbum, SubsonicSong } from '../../api/subsonicTypes';
|
||||
import { usePlayerStore } from '../../store/playerStore';
|
||||
import { previewInputFromSong, usePreviewStore } from '../../store/previewStore';
|
||||
import type { SubsonicAlbum, SubsonicSong } from '@/api/subsonicTypes';
|
||||
import { usePlayerStore } from '@/store/playerStore';
|
||||
import { previewInputFromSong, usePreviewStore } from '@/store/previewStore';
|
||||
import { useOrbitSongRowBehavior } from '@/features/orbit';
|
||||
import { songToTrack } from '../../utils/playback/songToTrack';
|
||||
import { formatTrackTime } from '../../utils/format/formatDuration';
|
||||
import ArtistTopTrackCover from './ArtistTopTrackCover';
|
||||
import { topSongAlbumForCover } from './topSongAlbumForCover';
|
||||
import { songToTrack } from '@/utils/playback/songToTrack';
|
||||
import { formatTrackTime } from '@/utils/format/formatDuration';
|
||||
import ArtistTopTrackCover from '@/features/artist/components/ArtistTopTrackCover';
|
||||
import { topSongAlbumForCover } from '@/features/artist/components/topSongAlbumForCover';
|
||||
|
||||
interface Props {
|
||||
topSongs: SubsonicSong[];
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import type { SubsonicArtist } from '../api/subsonicTypes';
|
||||
import type { SubsonicArtist } from '@/api/subsonicTypes';
|
||||
import React, { useRef, useState, useEffect, useLayoutEffect } from 'react';
|
||||
import ArtistCardLocal from './ArtistCardLocal';
|
||||
import ArtistCardLocal from '@/features/artist/components/ArtistCardLocal';
|
||||
import { ChevronLeft, ChevronRight, ArrowRight } from 'lucide-react';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import React from 'react';
|
||||
import { CoverArtImage } from '../../cover/CoverArtImage';
|
||||
import { useAlbumCoverRef } from '../../cover/useLibraryCoverRef';
|
||||
import { COVER_ARTIST_TOP_TRACK_CSS_PX } from '../../cover/layoutSizes';
|
||||
import type { TopSongAlbumCoverSource } from './topSongAlbumForCover';
|
||||
import { CoverArtImage } from '@/cover/CoverArtImage';
|
||||
import { useAlbumCoverRef } from '@/cover/useLibraryCoverRef';
|
||||
import { COVER_ARTIST_TOP_TRACK_CSS_PX } from '@/cover/layoutSizes';
|
||||
import type { TopSongAlbumCoverSource } from '@/features/artist/components/topSongAlbumForCover';
|
||||
|
||||
/** 32px album thumb — same cover ref path as {@link AlbumCard} on artist pages. */
|
||||
export default function ArtistTopTrackCover({ album }: { album: TopSongAlbumCoverSource }) {
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import React from 'react';
|
||||
import { Check } from 'lucide-react';
|
||||
import type { TFunction } from 'i18next';
|
||||
import type { SubsonicArtist } from '../../api/subsonicTypes';
|
||||
import type { PlayerState } from '../../store/playerStoreTypes';
|
||||
import { ARTISTS_INPAGE_SCROLL_VIEWPORT_ID } from '../../constants/appScroll';
|
||||
import { VirtualCardGrid } from '../VirtualCardGrid';
|
||||
import { ArtistCardAvatar } from './ArtistAvatars';
|
||||
import type { SubsonicArtist } from '@/api/subsonicTypes';
|
||||
import type { PlayerState } from '@/store/playerStoreTypes';
|
||||
import { ARTISTS_INPAGE_SCROLL_VIEWPORT_ID } from '@/constants/appScroll';
|
||||
import { VirtualCardGrid } from '@/components/VirtualCardGrid';
|
||||
import { ArtistCardAvatar } from '@/features/artist/components/ArtistAvatars';
|
||||
|
||||
interface TileProps {
|
||||
artist: SubsonicArtist;
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import React from 'react';
|
||||
import type { Virtualizer } from '@tanstack/react-virtual';
|
||||
import type { TFunction } from 'i18next';
|
||||
import type { SubsonicArtist } from '../../api/subsonicTypes';
|
||||
import type { PlayerState } from '../../store/playerStoreTypes';
|
||||
import { OTHER_BUCKET, type ArtistListFlatRow } from '../../utils/componentHelpers/artistsHelpers';
|
||||
import { ArtistRowAvatar } from './ArtistAvatars';
|
||||
import type { SubsonicArtist } from '@/api/subsonicTypes';
|
||||
import type { PlayerState } from '@/store/playerStoreTypes';
|
||||
import { OTHER_BUCKET, type ArtistListFlatRow } from '@/features/artist/utils/artistsHelpers';
|
||||
import { ArtistRowAvatar } from '@/features/artist/components/ArtistAvatars';
|
||||
|
||||
interface RowProps {
|
||||
artist: SubsonicArtist;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React, { Fragment } from 'react';
|
||||
import type { SubsonicOpenArtistRef } from '../api/subsonicTypes';
|
||||
import type { SubsonicOpenArtistRef } from '@/api/subsonicTypes';
|
||||
|
||||
interface Props {
|
||||
refs: SubsonicOpenArtistRef[];
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { describe, expect, it } from 'vitest';
|
||||
import { topSongAlbumForCover, topSongAlbumsForCoverWarm, artistDetailCoverWarmAlbums } from './topSongAlbumForCover';
|
||||
import { topSongAlbumForCover, topSongAlbumsForCoverWarm, artistDetailCoverWarmAlbums } from '@/features/artist/components/topSongAlbumForCover';
|
||||
|
||||
describe('topSongAlbumForCover', () => {
|
||||
it('uses the artist album row when albumId matches', () => {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { SubsonicAlbum, SubsonicSong } from '../../api/subsonicTypes';
|
||||
import type { SubsonicAlbum, SubsonicSong } from '@/api/subsonicTypes';
|
||||
|
||||
export type TopSongAlbumCoverSource = Pick<SubsonicAlbum, 'id' | 'coverArt' | 'name'>;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user