diff --git a/src/renderer/app.tsx b/src/renderer/app.tsx index abdbd790..b0b71eb5 100644 --- a/src/renderer/app.tsx +++ b/src/renderer/app.tsx @@ -3,10 +3,9 @@ import { ClientSideRowModelModule } from '@ag-grid-community/client-side-row-mod import { ModuleRegistry } from '@ag-grid-community/core'; import { InfiniteRowModelModule } from '@ag-grid-community/infinite-row-model'; import { MantineProvider } from '@mantine/core'; -import { ModalsProvider } from '@mantine/modals'; import isElectron from 'is-electron'; import { initSimpleImg } from 'react-simple-img'; -import { BaseContextModal, toast } from './components'; +import { toast } from './components'; import { useTheme } from './hooks'; import { IsUpdatedDialog } from './is-updated-dialog'; import { AppRouter } from './router/app-router'; @@ -20,7 +19,6 @@ import './styles/global.scss'; import { ContextMenuProvider } from '/@/renderer/features/context-menu'; import { useHandlePlayQueueAdd } from '/@/renderer/features/player/hooks/use-handle-playqueue-add'; import { PlayQueueHandlerContext } from '/@/renderer/features/player'; -import { AddToPlaylistContextModal } from '/@/renderer/features/playlists'; import { getMpvProperties } from '/@/renderer/features/settings/components/playback/mpv-settings'; import { PlayerState, usePlayerStore, useQueueControls } from '/@/renderer/store'; import { FontType, PlaybackType, PlayerStatus } from '/@/renderer/types'; @@ -246,27 +244,11 @@ export const App = () => { }, }} > - - - - - - - + + + + + ); diff --git a/src/renderer/features/item-details/components/item-details-modal.tsx b/src/renderer/features/item-details/components/item-details-modal.tsx index 9d2cdcd3..7c0b1bde 100644 --- a/src/renderer/features/item-details/components/item-details-modal.tsx +++ b/src/renderer/features/item-details/components/item-details-modal.tsx @@ -7,10 +7,13 @@ import { Album, AlbumArtist, AnyLibraryItem, LibraryItem, Song } from '/@/render import { formatDurationString } from '/@/renderer/utils'; import { formatSizeString } from '/@/renderer/utils/format-size-string'; import { replaceURLWithHTMLLinks } from '/@/renderer/utils/linkify'; -import { Rating, Spoiler } from '/@/renderer/components'; +import { Rating, Spoiler, Text } from '/@/renderer/components'; import { sanitize } from '/@/renderer/utils/sanitize'; import { SongPath } from '/@/renderer/features/item-details/components/song-path'; -import { SEPARATOR_STRING } from '/@/renderer/api/utils'; +import { generatePath } from 'react-router'; +import { Link } from 'react-router-dom'; +import { AppRoute } from '/@/renderer/router/routes'; +import { Separator } from '/@/renderer/components/separator'; export type ItemDetailsModalProps = { item: Album | AlbumArtist | Song; @@ -43,8 +46,28 @@ const handleRow = (t: TFunction, item: T, rule: ItemDe ); }; -const formatArtists = (item: Album | Song) => - item.albumArtists?.map((artist) => artist.name).join(SEPARATOR_STRING); +const formatArtists = (isAlbumArtist: boolean) => (item: Album | Song) => + (isAlbumArtist ? item.albumArtists : item.artists)?.map((artist, index) => ( + + {index > 0 && } + + {artist.name || '—'} + + + )); const formatComment = (item: Album | Song) => item.comment ? {replaceURLWithHTMLLinks(item.comment)} : null; @@ -52,7 +75,27 @@ const formatComment = (item: Album | Song) => const formatDate = (key: string | null) => (key ? dayjs(key).fromNow() : ''); const formatGenre = (item: Album | AlbumArtist | Song) => - item.genres?.map((genre) => genre.name).join(SEPARATOR_STRING); + item.genres?.map((genre, index) => ( + + {index > 0 && } + + {genre.name || '—'} + + + )); const formatRating = (item: Album | AlbumArtist | Song) => item.userRating !== null ? ( @@ -67,7 +110,7 @@ const BoolField = (key: boolean) => const AlbumPropertyMapping: ItemDetailRow[] = [ { key: 'name', label: 'common.title' }, - { label: 'entity.albumArtist_one', render: formatArtists }, + { label: 'entity.albumArtist_one', render: formatArtists(true) }, { label: 'entity.genre_other', render: formatGenre }, { label: 'common.duration', @@ -159,13 +202,32 @@ const AlbumArtistPropertyMapping: ItemDetailRow[] = [ const SongPropertyMapping: ItemDetailRow[] = [ { key: 'name', label: 'common.title' }, { key: 'path', label: 'common.path', render: SongPath }, - { label: 'entity.albumArtist_one', render: formatArtists }, + { label: 'entity.albumArtist_one', render: formatArtists(true) }, + { key: 'artists', label: 'entity.artist_other', render: formatArtists(false) }, { - key: 'artists', - label: 'entity.artist_other', - render: (song) => song.artists.map((artist) => artist.name).join(SEPARATOR_STRING), + key: 'album', + label: 'entity.album_one', + render: (song) => + song.albumId && + song.album && ( + + {song.album} + + ), }, - { key: 'album', label: 'entity.album_one' }, { key: 'discNumber', label: 'common.disc' }, { key: 'trackNumber', label: 'common.trackNumber' }, { key: 'releaseYear', label: 'filter.releaseYear' }, diff --git a/src/renderer/router/app-router.tsx b/src/renderer/router/app-router.tsx index 41cbc628..5749c138 100644 --- a/src/renderer/router/app-router.tsx +++ b/src/renderer/router/app-router.tsx @@ -1,14 +1,12 @@ import { lazy, Suspense } from 'react'; -import { - Route, - createRoutesFromElements, - RouterProvider, - createHashRouter, -} from 'react-router-dom'; +import { Route, HashRouter, Routes } from 'react-router-dom'; import { AppRoute } from './routes'; import { DefaultLayout } from '/@/renderer/layouts'; import { AppOutlet } from '/@/renderer/router/app-outlet'; import { TitlebarOutlet } from '/@/renderer/router/titlebar-outlet'; +import { ModalsProvider } from '@mantine/modals'; +import { BaseContextModal } from '/@/renderer/components'; +import { AddToPlaylistContextModal } from '/@/renderer/features/playlists'; const NowPlayingRoute = lazy( () => import('/@/renderer/features/now-playing/routes/now-playing-route'), @@ -67,137 +65,146 @@ const RouteErrorBoundary = lazy( ); export const AppRouter = () => { - const router = createHashRouter( - createRoutesFromElements( - <> - }> - } - errorElement={} - > - }> - } - errorElement={} - /> - } - errorElement={} - path={AppRoute.HOME} - /> - } - errorElement={} - path={AppRoute.SEARCH} - /> - } - errorElement={} - path={AppRoute.SETTINGS} - /> - } - errorElement={} - path={AppRoute.NOW_PLAYING} - /> - + const router = ( + + + + }> + } + errorElement={} + > + }> } + element={} errorElement={} /> } - path={AppRoute.LIBRARY_GENRES_ALBUMS} + element={} + errorElement={} + path={AppRoute.HOME} /> } - path={AppRoute.LIBRARY_GENRES_SONGS} + element={} + errorElement={} + path={AppRoute.SEARCH} /> - - } - errorElement={} - path={AppRoute.LIBRARY_ALBUMS} - /> - } - errorElement={} - path={AppRoute.LIBRARY_ALBUMS_DETAIL} - /> - } - errorElement={} - path={AppRoute.LIBRARY_SONGS} - /> - } - errorElement={} - path={AppRoute.PLAYLISTS} - /> - } - errorElement={} - path={AppRoute.PLAYLISTS_DETAIL} - /> - } - errorElement={} - path={AppRoute.PLAYLISTS_DETAIL_SONGS} - /> - } - path={AppRoute.LIBRARY_ALBUM_ARTISTS} - > } + element={} + errorElement={} + path={AppRoute.SETTINGS} /> - + } + errorElement={} + path={AppRoute.NOW_PLAYING} + /> + } + element={} + errorElement={} /> } - path={AppRoute.LIBRARY_ALBUM_ARTISTS_DETAIL_DISCOGRAPHY} + path={AppRoute.LIBRARY_GENRES_ALBUMS} /> } - path={AppRoute.LIBRARY_ALBUM_ARTISTS_DETAIL_SONGS} - /> - } - path={AppRoute.LIBRARY_ALBUM_ARTISTS_DETAIL_TOP_SONGS} + path={AppRoute.LIBRARY_GENRES_SONGS} /> + } + errorElement={} + path={AppRoute.LIBRARY_ALBUMS} + /> + } + errorElement={} + path={AppRoute.LIBRARY_ALBUMS_DETAIL} + /> + } + errorElement={} + path={AppRoute.LIBRARY_SONGS} + /> + } + errorElement={} + path={AppRoute.PLAYLISTS} + /> + } + errorElement={} + path={AppRoute.PLAYLISTS_DETAIL} + /> + } + errorElement={} + path={AppRoute.PLAYLISTS_DETAIL_SONGS} + /> + } + path={AppRoute.LIBRARY_ALBUM_ARTISTS} + > + } + /> + + } + /> + } + path={AppRoute.LIBRARY_ALBUM_ARTISTS_DETAIL_DISCOGRAPHY} + /> + } + path={AppRoute.LIBRARY_ALBUM_ARTISTS_DETAIL_SONGS} + /> + } + path={AppRoute.LIBRARY_ALBUM_ARTISTS_DETAIL_TOP_SONGS} + /> + + + } + path="*" + /> + + + }> + }> } - path="*" + element={} + path={AppRoute.ACTION_REQUIRED} /> - - }> - }> - } - path={AppRoute.ACTION_REQUIRED} - /> - - - , - ), + + + ); - return ( - }> - - - ); + return }>{router}; };