diff --git a/README.md b/README.md index 4e07558..dab4613 100644 --- a/README.md +++ b/README.md @@ -59,11 +59,13 @@ ## Screenshots - + - + - + + +

(back to top)

diff --git a/media/album.jpg b/media/album.jpg deleted file mode 100644 index 1f9f30d..0000000 Binary files a/media/album.jpg and /dev/null differ diff --git a/media/album.png b/media/album.png new file mode 100644 index 0000000..d923389 Binary files /dev/null and b/media/album.png differ diff --git a/media/albums.jpg b/media/albums.jpg deleted file mode 100644 index 0c3fcc3..0000000 Binary files a/media/albums.jpg and /dev/null differ diff --git a/media/albums.png b/media/albums.png new file mode 100644 index 0000000..94600fd Binary files /dev/null and b/media/albums.png differ diff --git a/media/albumsByArtist.png b/media/albumsByArtist.png new file mode 100644 index 0000000..02ba6d5 Binary files /dev/null and b/media/albumsByArtist.png differ diff --git a/media/artist.png b/media/artist.png new file mode 100644 index 0000000..4032e7f Binary files /dev/null and b/media/artist.png differ diff --git a/media/home.jpg b/media/home.jpg deleted file mode 100644 index 6d4e977..0000000 Binary files a/media/home.jpg and /dev/null differ diff --git a/media/home.png b/media/home.png new file mode 100644 index 0000000..0717ec9 Binary files /dev/null and b/media/home.png differ diff --git a/media/lyrics.jpg b/media/lyrics.jpg deleted file mode 100644 index 39cb1f5..0000000 Binary files a/media/lyrics.jpg and /dev/null differ diff --git a/media/lyrics.png b/media/lyrics.png new file mode 100644 index 0000000..fa726f7 Binary files /dev/null and b/media/lyrics.png differ diff --git a/media/player.jpeg b/media/player.jpeg deleted file mode 100644 index 26be385..0000000 Binary files a/media/player.jpeg and /dev/null differ diff --git a/media/player.png b/media/player.png new file mode 100644 index 0000000..d4b2868 Binary files /dev/null and b/media/player.png differ diff --git a/media/playlist.jpg b/media/playlist.jpg deleted file mode 100644 index abe269e..0000000 Binary files a/media/playlist.jpg and /dev/null differ diff --git a/media/playlist.png b/media/playlist.png new file mode 100644 index 0000000..c0e8492 Binary files /dev/null and b/media/playlist.png differ diff --git a/package.json b/package.json index 848de55..0980224 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "aonsoku", "private": true, - "version": "0.1.3", + "version": "0.2.0", "type": "module", "scripts": { "dev": "vite", diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index 7bd79d0..25e9557 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -64,7 +64,7 @@ checksum = "25bdb32cbbdce2b519a9cd7df3a678443100e265d5e25ca763b7572a5104f5f3" [[package]] name = "aonsoku" -version = "0.1.3" +version = "0.2.0" dependencies = [ "futures-util", "regex", diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index 42dae54..2e0cd81 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "aonsoku" -version = "0.1.3" +version = "0.2.0" description = "A modern desktop client for Navidrome/Subsonic servers." authors = ["Victor Alves"] edition = "2021" diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index a3e6a78..5a6ff67 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -7,7 +7,7 @@ }, "package": { "productName": "Aonsoku", - "version": "0.1.3" + "version": "0.2.0" }, "tauri": { "allowlist": { diff --git a/src/api/httpClient.ts b/src/api/httpClient.ts index e97f99a..0d12b1e 100644 --- a/src/api/httpClient.ts +++ b/src/api/httpClient.ts @@ -136,7 +136,7 @@ export async function httpClient( } export function getCoverArtUrl( - id: string, + id?: string, type: CoverArt = 'album', size = '300', ): string { diff --git a/src/app/components/actions.tsx b/src/app/components/actions.tsx index 7e20ef8..ff9707b 100644 --- a/src/app/components/actions.tsx +++ b/src/app/components/actions.tsx @@ -38,8 +38,8 @@ function Button({ 'rounded-full w-14 h-14 ease-linear duration-100 transition', 'border-[1px] border-transparent', buttonStyle === 'primary' - ? 'hover:scale-105' - : 'hover:bg-background hover:border-border', + ? 'hover:scale-105 mr-2' + : 'hover:bg-foreground/20', className, )} variant={buttonStyle === 'primary' ? 'default' : 'ghost'} @@ -64,7 +64,12 @@ function Dropdown({ tooltip, options }: DropdownProps) { className="outline-none focus-visible:ring-0 focus-visible:ring-offset-0 focus-visible:ring-transparent focus:ring-transparent" > diff --git a/src/app/components/album/image-header.tsx b/src/app/components/album/image-header.tsx index 26a4610..e079744 100644 --- a/src/app/components/album/image-header.tsx +++ b/src/app/components/album/image-header.tsx @@ -19,7 +19,7 @@ interface ImageHeaderProps { title: string subtitle?: string artistId?: string - coverArtId: string + coverArtId?: string coverArtType: CoverArt coverArtSize: string coverArtAlt: string @@ -127,15 +127,19 @@ export default function ImageHeader({ > {title} - {subtitle && artistId && ( + {subtitle && artistId ? (

{subtitle}

+ ) : ( +

+ {subtitle} +

)} -
{badges}
+
{badges}
@@ -148,7 +152,7 @@ export default function ImageHeader({ diff --git a/src/app/components/album/info-panel.tsx b/src/app/components/album/info-panel.tsx index 3858988..f48a993 100644 --- a/src/app/components/album/info-panel.tsx +++ b/src/app/components/album/info-panel.tsx @@ -27,6 +27,7 @@ export default function InfoPanel({ // In case the API returns a link without target blank and nofollow useEffect(() => { const links = document.querySelectorAll('#info-panel a') + if (!links) return links.forEach((link) => { link.setAttribute('target', '_blank') @@ -34,7 +35,7 @@ export default function InfoPanel({ }) }, []) - if (!bio) return <> + if (!bio) return null return (
diff --git a/src/app/components/albums/filters/main.tsx b/src/app/components/albums/filters/main.tsx index 8d1c71e..836151d 100644 --- a/src/app/components/albums/filters/main.tsx +++ b/src/app/components/albums/filters/main.tsx @@ -26,7 +26,6 @@ export function AlbumsMainFilter() { AlbumsSearchParams.MainFilter, AlbumsFilters.RecentlyAdded, ) - const artistName = getSearchParam(AlbumsSearchParams.ArtistName, '') const currentFilterLabel = albumsFilterValues.filter( (item) => item.key === currentFilter, @@ -53,15 +52,17 @@ export function AlbumsMainFilter() { - + {albumsFilterValues.map((item, index) => { + if (item.key === AlbumsFilters.ByDiscography) return null + return ( handleChangeFilter(item.key as AlbumListType) } diff --git a/src/app/components/albums/header.tsx b/src/app/components/albums/header.tsx index 8c432ba..9ee3d34 100644 --- a/src/app/components/albums/header.tsx +++ b/src/app/components/albums/header.tsx @@ -1,6 +1,9 @@ import { useTranslation } from 'react-i18next' +import { useSearchParams } from 'react-router-dom' import { ShadowHeader } from '@/app/components/album/shadow-header' import { Badge } from '@/app/components/ui/badge' +import { AlbumsSearchParams } from '@/utils/albumsFilter' +import { SearchParamsHandler } from '@/utils/searchParamsHandler' import { AlbumsFilter } from './filters' interface AlbumsHeaderProps { @@ -9,14 +12,22 @@ interface AlbumsHeaderProps { export function AlbumsHeader({ albumCount }: AlbumsHeaderProps) { const { t } = useTranslation() + const [searchParams] = useSearchParams() + const { getSearchParam } = new SearchParamsHandler(searchParams) + + const artistName = getSearchParam(AlbumsSearchParams.ArtistName, '') + + const defaultLabel = t('sidebar.albums') + const discographyLabel = t('album.list.header.albumsByArtist', { + artist: artistName, + }) + const label = artistName === '' ? defaultLabel : discographyLabel return (
-

- {t('sidebar.albums')} -

+

{label}

{albumCount > 0 && ( {albumCount} diff --git a/src/app/components/artist/artist-top-songs.tsx b/src/app/components/artist/artist-top-songs.tsx index 88f6fa5..44df57d 100644 --- a/src/app/components/artist/artist-top-songs.tsx +++ b/src/app/components/artist/artist-top-songs.tsx @@ -35,6 +35,7 @@ export default function ArtistTopSongs({ topSongs }: { topSongs: ISong[] }) { data={topTenSongs} handlePlaySong={(row) => setSongList(topTenSongs, row.index)} columnFilter={columnsToShow} + variant="modern" />
) diff --git a/src/app/components/fallbacks/album-fallbacks.tsx b/src/app/components/fallbacks/album-fallbacks.tsx index 4b74b41..11b0a94 100644 --- a/src/app/components/fallbacks/album-fallbacks.tsx +++ b/src/app/components/fallbacks/album-fallbacks.tsx @@ -26,7 +26,7 @@ export function AlbumHeaderFallback() { export function PlayButtonsFallback() { return (
- +
@@ -46,7 +46,7 @@ export function AlbumFallback() {
- +
) @@ -57,7 +57,7 @@ export function AlbumsFallback() {
- + diff --git a/src/app/components/fallbacks/home-fallbacks.tsx b/src/app/components/fallbacks/home-fallbacks.tsx index 3f4af6b..8e58852 100644 --- a/src/app/components/fallbacks/home-fallbacks.tsx +++ b/src/app/components/fallbacks/home-fallbacks.tsx @@ -58,8 +58,8 @@ export function SongsCarouselFallback() { {Array.from({ length: 8 }).map((_, index) => (
- - + +
))}
@@ -68,8 +68,8 @@ export function SongsCarouselFallback() { {Array.from({ length: 5 }).map((_, index) => (
- - + +
))}
diff --git a/src/app/components/fallbacks/playlist-fallbacks.tsx b/src/app/components/fallbacks/playlist-fallbacks.tsx index fe996af..93cb9b8 100644 --- a/src/app/components/fallbacks/playlist-fallbacks.tsx +++ b/src/app/components/fallbacks/playlist-fallbacks.tsx @@ -1,30 +1,23 @@ -import { PlayButtonsFallback } from '@/app/components/fallbacks/album-fallbacks' +import { ImageHeaderEffect } from '@/app/components/album/header-effect' +import { + AlbumHeaderFallback, + PlayButtonsFallback, +} from '@/app/components/fallbacks/album-fallbacks' import { TableFallback } from '@/app/components/fallbacks/table-fallbacks' -import { Skeleton } from '@/app/components/ui/skeleton' +import ListWrapper from '@/app/components/list-wrapper' -export function PlaylistHeaderFallback() { +export function PlaylistFallback() { return ( -
- -
- - - -
- - -
+
+
+ +
-
- ) -} -export function PlaylistFallback() { - return ( -
- - - + + + +
) } diff --git a/src/app/components/fallbacks/table-fallbacks.tsx b/src/app/components/fallbacks/table-fallbacks.tsx index 4c097b7..e46ee3d 100644 --- a/src/app/components/fallbacks/table-fallbacks.tsx +++ b/src/app/components/fallbacks/table-fallbacks.tsx @@ -1,9 +1,28 @@ +import clsx from 'clsx' import { Skeleton } from '@/app/components/ui/skeleton' -export function TableFallback() { +interface TableFallbackProps { + variant?: 'classic' | 'modern' +} + +export function TableFallback({ variant = 'classic' }: TableFallbackProps) { + const isClassic = variant === 'classic' + const isModern = variant === 'modern' + return ( -
-
+
+
@@ -16,7 +35,10 @@ export function TableFallback() { {Array.from({ length: 10 }).map((_, index) => (
@@ -44,7 +66,7 @@ export function TopSongsTableFallback() {
- +
) } diff --git a/src/app/components/header/browser-logout.tsx b/src/app/components/header/browser-logout.tsx index bf61049..2b7717a 100644 --- a/src/app/components/header/browser-logout.tsx +++ b/src/app/components/header/browser-logout.tsx @@ -1,4 +1,4 @@ -import { Globe, Keyboard, LogOut, User } from 'lucide-react' +import { Keyboard, LogOut, User } from 'lucide-react' import { useState } from 'react' import { Fragment } from 'react/jsx-runtime' import { useHotkeys } from 'react-hotkeys-hook' @@ -11,6 +11,7 @@ import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, + DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuTrigger, @@ -48,15 +49,15 @@ export function BrowserLogout() { - - - - {username} - - - - {url} - + + +
+

{username}

+

+ {url} +

+
+
setShortcutsOpen(true)}> diff --git a/src/app/components/playlist/page-header.tsx b/src/app/components/playlist/page-header.tsx deleted file mode 100644 index 86013e5..0000000 --- a/src/app/components/playlist/page-header.tsx +++ /dev/null @@ -1,51 +0,0 @@ -import { useTranslation } from 'react-i18next' -import { LazyLoadImage } from 'react-lazy-load-image-component' -import { getCoverArtUrl } from '@/api/httpClient' -import { Badge } from '@/app/components/ui/badge' -import { cn } from '@/lib/utils' -import { PlaylistWithEntries } from '@/types/responses/playlist' -import { convertSecondsToHumanRead } from '@/utils/convertSecondsToTime' -import { getTextSizeClass } from '@/utils/getTextSizeClass' - -interface PlaylistPageHeaderProps { - playlist: PlaylistWithEntries -} - -export function PlaylistPageHeader({ playlist }: PlaylistPageHeaderProps) { - const { t } = useTranslation() - - const songCount = t('playlist.songCount', { count: playlist.songCount }) - const duration = convertSecondsToHumanRead(playlist.duration) - const playlistDuration = t('playlist.duration', { duration }) - - return ( -
-
- -
-
-

{t('playlist.headline')}

-

- {playlist.name} -

-

- {playlist.comment} -

-
- {songCount} - {playlist.duration > 0 && {playlistDuration}} -
-
-
- ) -} diff --git a/src/app/components/queue/song-list.tsx b/src/app/components/queue/song-list.tsx index 1d759d0..d790f8d 100644 --- a/src/app/components/queue/song-list.tsx +++ b/src/app/components/queue/song-list.tsx @@ -52,13 +52,14 @@ export function QueueSongList() {
- + setSongList(currentList, row.index)} + variant="modern" />
diff --git a/src/app/components/table/cover-image.tsx b/src/app/components/table/cover-image.tsx index 3378d66..c85c827 100644 --- a/src/app/components/table/cover-image.tsx +++ b/src/app/components/table/cover-image.tsx @@ -29,7 +29,7 @@ export function CoverImage({ return (
diff --git a/src/app/components/table/song-title.tsx b/src/app/components/table/song-title.tsx index 8db00d9..96ee131 100644 --- a/src/app/components/table/song-title.tsx +++ b/src/app/components/table/song-title.tsx @@ -1,5 +1,4 @@ import clsx from 'clsx' -import { useEffect, useState } from 'react' import { CoverImage } from '@/app/components/table/cover-image' import { usePlayerMediaType, usePlayerSonglist } from '@/store/player.store' import { ISong } from '@/types/responses/song' @@ -7,14 +6,14 @@ import { ISong } from '@/types/responses/song' export function TableSongTitle({ song }: { song: ISong }) { const { currentSong } = usePlayerSonglist() const mediaType = usePlayerMediaType() - const [songIsPlaying, setSongIsPlaying] = useState(false) - useEffect(() => { - if (mediaType === 'radio') return + function getSongIsPlaying() { + if (mediaType === 'radio' || !currentSong) return false - const isPlaying = currentSong.id === song.id - setSongIsPlaying(isPlaying) - }, [currentSong, mediaType, song.id]) + return currentSong.id === song.id + } + + const songIsPlaying = getSongIsPlaying() return (
@@ -27,7 +26,7 @@ export function TableSongTitle({ song }: { song: ISong }) { {song.title} diff --git a/src/app/components/ui/badge.tsx b/src/app/components/ui/badge.tsx index 8629ae3..452bdf4 100644 --- a/src/app/components/ui/badge.tsx +++ b/src/app/components/ui/badge.tsx @@ -4,7 +4,7 @@ import * as React from 'react' import { cn } from '@/lib/utils' const badgeVariants = cva( - 'inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2', + 'inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 drop-shadow', { variants: { variant: { diff --git a/src/app/components/ui/data-table.tsx b/src/app/components/ui/data-table.tsx index ae73fd7..7570c5c 100644 --- a/src/app/components/ui/data-table.tsx +++ b/src/app/components/ui/data-table.tsx @@ -19,6 +19,7 @@ import { useTranslation } from 'react-i18next' import { Button } from '@/app/components/ui/button' import { DataTablePagination } from '@/app/components/ui/data-table-pagination' import { Input } from '@/app/components/ui/input' +import { usePlayerSonglist } from '@/store/player.store' import { ColumnFilter } from '@/types/columnFilter' import { ColumnDefType } from '@/types/react-table/columnDef' @@ -47,6 +48,7 @@ interface DataTableProps { allowRowSelection?: boolean showHeader?: boolean showDiscNumber?: boolean + variant?: 'classic' | 'modern' } export function DataTable({ @@ -61,11 +63,13 @@ export function DataTable({ allowRowSelection = true, showHeader = true, showDiscNumber = false, + variant = 'classic', }: DataTableProps) { const { t } = useTranslation() const newColumns = columns.filter((column) => { return columnFilter?.includes(column.id as ColumnFilter) }) + const { currentSong } = usePlayerSonglist() const [columnSearch, setColumnSearch] = useState([]) const [sorting, setSorting] = useState([]) @@ -122,6 +126,20 @@ export function DataTable({ const discNumberIndexes = getDiscIndexes() + function rowIsPlaying(row: Row) { + // @ts-expect-error row.original can't be typed + const id = row.original && row.original.id ? row.original.id : '' + + if (id === '' || !currentSong) { + return false + } + + return id === currentSong.id + } + + const isClassic = variant === 'classic' + const isModern = variant === 'modern' + return ( <> {showSearch && searchColumn && ( @@ -155,9 +173,12 @@ export function DataTable({
)} -
+
@@ -166,7 +187,10 @@ export function DataTable({ {table.getHeaderGroups().map((headerGroup) => (
{headerGroup.headers.map((header) => { @@ -203,7 +227,10 @@ export function DataTable({ {showDiscNumber && discNumberIndexes.includes(index) && (
@@ -221,7 +248,16 @@ export function DataTable({ onClick={() => { allowRowSelection && row.toggleSelected() }} - className="group/tablerow w-full flex flex-row border-b transition-colors hover:bg-muted/50 data-[state=selected]:bg-muted" + className={clsx( + 'group/tablerow w-full flex flex-row transition-colors', + isClassic && + 'border-b hover:bg-muted/50 data-[state=selected]:bg-muted', + isModern && + 'rounded-md hover:bg-muted-foreground/20 dark:hover:bg-accent', + isModern && + 'data-[state=selected]:bg-muted-foreground/20 dark:data-[state=selected]:bg-accent', + isModern && rowIsPlaying(row) && 'bg-primary/20', + )} role="row" > {row.getVisibleCells().map((cell) => { diff --git a/src/app/pages/albums/album.tsx b/src/app/pages/albums/album.tsx index 2cfb45b..930f78c 100644 --- a/src/app/pages/albums/album.tsx +++ b/src/app/pages/albums/album.tsx @@ -144,6 +144,7 @@ export default function Album() { handlePlaySong={(row) => setSongList(album.song, row.index)} columnFilter={columnsToShow} showDiscNumber={albumHasMoreThanOneDisc} + variant="modern" />
diff --git a/src/app/pages/albums/list.tsx b/src/app/pages/albums/list.tsx index 42710bd..eaeb2c8 100644 --- a/src/app/pages/albums/list.tsx +++ b/src/app/pages/albums/list.tsx @@ -137,9 +137,7 @@ export default function AlbumsList() { } } - if (isLoading) { - return - } + if (isLoading) return if (!data) return const items = data.pages.flatMap((page) => page.albums) || [] diff --git a/src/app/pages/playlists/playlist.tsx b/src/app/pages/playlists/playlist.tsx index 2df4a7f..6ad37d2 100644 --- a/src/app/pages/playlists/playlist.tsx +++ b/src/app/pages/playlists/playlist.tsx @@ -1,16 +1,20 @@ import { useQuery } from '@tanstack/react-query' +import { Fragment } from 'react/jsx-runtime' import { useTranslation } from 'react-i18next' import { useParams } from 'react-router-dom' +import ImageHeader from '@/app/components/album/image-header' import { PlaylistFallback } from '@/app/components/fallbacks/playlist-fallbacks' +import ListWrapper from '@/app/components/list-wrapper' import { PlaylistButtons } from '@/app/components/playlist/buttons' -import { PlaylistPageHeader } from '@/app/components/playlist/page-header' import { RemoveSongFromPlaylistDialog } from '@/app/components/playlist/remove-song-dialog' +import { Badge } from '@/app/components/ui/badge' import { DataTable } from '@/app/components/ui/data-table' import ErrorPage from '@/app/pages/error-page' import { songsColumns } from '@/app/tables/songs-columns' import { subsonic } from '@/service/subsonic' import { usePlayerActions } from '@/store/player.store' import { ColumnFilter } from '@/types/columnFilter' +import { convertSecondsToHumanRead } from '@/utils/convertSecondsToTime' import { queryKeys } from '@/utils/queryKeys' export default function Playlist() { @@ -19,12 +23,16 @@ export default function Playlist() { const columns = songsColumns() const { setSongList } = usePlayerActions() - const { data: playlist, isLoading } = useQuery({ + const { + data: playlist, + isLoading, + isFetching, + } = useQuery({ queryKey: [queryKeys.playlist.single, playlistId], queryFn: () => subsonic.playlists.getOne(playlistId), }) - if (isLoading) return + if (isFetching || isLoading) return if (!playlist) return const columnsToShow: ColumnFilter[] = [ @@ -38,21 +46,48 @@ export default function Playlist() { 'select', ] - return ( -
- + const songCount = t('playlist.songCount', { count: playlist.songCount }) + const duration = convertSecondsToHumanRead(playlist.duration) + const playlistDuration = t('playlist.duration', { duration }) + + const badges = ( + + {songCount} + {playlist.duration > 0 && ( + {playlistDuration} + )} + + ) - + const coverArt = playlist.songCount > 0 ? playlist.coverArt : undefined - setSongList(playlist.entry, row.index)} - columnFilter={columnsToShow} - noRowsMessage={t('playlist.noSongList')} + return ( +
+ - + + + + setSongList(playlist.entry, row.index)} + columnFilter={columnsToShow} + noRowsMessage={t('playlist.noSongList')} + variant="modern" + /> + + +
) } diff --git a/src/app/pages/songs/list.tsx b/src/app/pages/songs/list.tsx index 80eab35..30e6902 100644 --- a/src/app/pages/songs/list.tsx +++ b/src/app/pages/songs/list.tsx @@ -13,7 +13,11 @@ import { ISong } from '@/types/responses/song' import { queryKeys } from '@/utils/queryKeys' export default function SongsList() { - const { data: songlist, isLoading } = useQuery({ + const { + data: songlist, + isLoading, + isFetching, + } = useQuery({ queryKey: [queryKeys.song.all], queryFn: subsonic.songs.getAllSongs, }) @@ -39,7 +43,7 @@ export default function SongsList() { if (songlist) setSongList(songlist, index) } - if (isLoading) return + if (isFetching || isLoading) return if (!songlist) return null return ( diff --git a/src/i18n/languages/en.ts b/src/i18n/languages/en.ts index e07fa41..0d23000 100644 --- a/src/i18n/languages/en.ts +++ b/src/i18n/languages/en.ts @@ -111,6 +111,9 @@ export const english = { genreTitle: 'More from {{genre}}', }, list: { + header: { + albumsByArtist: 'Albums by {{artist}}', + }, empty: { title: 'Oops, no albums here!', info: 'Looks like there are no albums with the current filter.', @@ -131,6 +134,7 @@ export const english = { recentlyAdded: 'Recently Added', recentlyPlayed: 'Recently Played', releaseYear: 'Release Year', + discography: 'Discography', }, }, table: { diff --git a/src/i18n/languages/pt-BR.ts b/src/i18n/languages/pt-BR.ts index c78139f..5f23145 100644 --- a/src/i18n/languages/pt-BR.ts +++ b/src/i18n/languages/pt-BR.ts @@ -113,6 +113,9 @@ export const brazilianPortuguese = { genreTitle: 'Mais de {{genre}}', }, list: { + header: { + albumsByArtist: 'Álbuns por {{artist}}', + }, empty: { title: 'Nenhum resultado encontrado!', info: 'Não conseguimos encontrar álbuns que correspondam ao seu filtro.', @@ -133,6 +136,7 @@ export const brazilianPortuguese = { recentlyAdded: 'Adicionados recentemente', recentlyPlayed: 'Reproduzidos recentemente', releaseYear: 'Ano de lançamento', + discography: 'Discografia', }, }, table: { diff --git a/src/routes/routesList.ts b/src/routes/routesList.ts index 4c7513f..86b87fa 100644 --- a/src/routes/routesList.ts +++ b/src/routes/routesList.ts @@ -23,7 +23,7 @@ const ALBUMS = { GENRE: (genre: string) => `${LIBRARY.ALBUMS}?filter=${AlbumsFilters.ByGenre}&genre=${encodeURIComponent(genre)}`, ARTIST: (id: string, name: string) => - `${LIBRARY.ALBUMS}?artistId=${id}&artistName=${encodeURIComponent(name)}`, + `${LIBRARY.ALBUMS}?filter=${AlbumsFilters.ByDiscography}&artistId=${id}&artistName=${encodeURIComponent(name)}`, RECENTLY_PLAYED: `${LIBRARY.ALBUMS}?filter=${AlbumsFilters.RecentlyPlayed}`, MOST_PLAYED: `${LIBRARY.ALBUMS}?filter=${AlbumsFilters.MostPlayed}`, RECENTLY_ADDED: `${LIBRARY.ALBUMS}?filter=${AlbumsFilters.RecentlyAdded}`, diff --git a/src/utils/albumsFilter.ts b/src/utils/albumsFilter.ts index 6bd3c0c..b70df67 100644 --- a/src/utils/albumsFilter.ts +++ b/src/utils/albumsFilter.ts @@ -23,6 +23,7 @@ export enum AlbumsFilters { RecentlyAdded = 'newest', RecentlyPlayed = 'recent', ByYear = 'byYear', + ByDiscography = 'artistDiscography', } export const albumsFilterValues = [ @@ -62,4 +63,8 @@ export const albumsFilterValues = [ key: AlbumsFilters.ByYear, label: 'album.list.filter.releaseYear', }, + { + key: AlbumsFilters.ByDiscography, + label: 'album.list.filter.discography', + }, ]