Redesign sidebar / header and other misc. improvements (#24)

* Remove 1920px max width

* Fix position of list controls menu

* Match size and color of search input

* Adjust library header sizing

* Move app menu to sidebar

* Increase row buffer on play queue list

* Fix query builder styles

* Fix playerbar slider track bg

* Adjust titlebar styles

* Fix invalid modal prop

* Various adjustments to detail pages

* Fix sidebar height calculation

* Fix list null indicators, add filter indicator

* Adjust playqueue styles

* Fix jellyfin releaseYear normalization

* Suppress browser context menu on ag-grid

* Add radius to drawer queue -- normalize layout

* Add modal styles to provider theme

* Fix playlist song list pagination

* Add disc number to albums with more than one disc

* Fix query builder boolean values

* Adjust input placeholder color

* Properly handle rating/favorite from context menu on table

* Conform dropdown menu styles to context menu

* Increase sort type select width

* Fix drawer queue radius

* Change primary color

* Prevent volume wheel from invalid values

* Add icons to query builder dropdowns

* Update notification styles

* Update scrollbar thumb styles

* Remove "add to playlist" on smart playlists

* Fix "add to playlist" from context menu
This commit is contained in:
Jeff 2023-02-07 22:47:23 -08:00 committed by GitHub
parent d2c0d4c11f
commit 9f2e873366
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
80 changed files with 1427 additions and 1101 deletions

View file

@ -44,7 +44,6 @@ const ContentContainer = styled.div`
display: flex;
flex-direction: column;
gap: 3rem;
max-width: 1920px;
padding: 1rem 2rem 5rem;
overflow: hidden;

View file

@ -143,7 +143,7 @@ export const AlbumArtistDiscographyHeader = ({ itemCount, tableRef }: SongListHe
);
const songs = api.normalize.songList(songsRes, server);
params.successCallback(songs?.items || [], songsRes?.totalRecordCount);
params.successCallback(songs?.items || [], songsRes?.totalRecordCount || 0);
},
rowCount: undefined,
};

View file

@ -54,8 +54,6 @@ export const AlbumArtistDetailHeader = forwardRef(
const handleClearRating = (_e: MouseEvent<HTMLDivElement>, rating?: number) => {
if (!detailQuery?.data || !detailQuery?.data.userRating) return;
console.log(rating, detailQuery.data.userRating);
const isSameRatingAsPrevious = rating === detailQuery.data.userRating;
if (!isSameRatingAsPrevious) return;

View file

@ -94,7 +94,7 @@ export const AlbumArtistDetailSongListContent = ({
);
const songs = api.normalize.songList(songsRes, server);
params.successCallback(songs?.items || [], songsRes?.totalRecordCount);
params.successCallback(songs?.items || [], songsRes?.totalRecordCount || 0);
},
rowCount: undefined,
};

View file

@ -143,7 +143,7 @@ export const AlbumArtistDetailSongListHeader = ({
);
const songs = api.normalize.songList(songsRes, server);
params.successCallback(songs?.items || [], songsRes?.totalRecordCount);
params.successCallback(songs?.items || [], songsRes?.totalRecordCount || 0);
},
rowCount: undefined,
};

View file

@ -1,16 +1,9 @@
import { Flex, Group } from '@mantine/core';
import { RiMoreFill } from 'react-icons/ri';
import { RiAddBoxFill, RiAddCircleFill, RiMoreFill, RiPlayFill } from 'react-icons/ri';
import { QueueSong } from '/@/renderer/api/types';
import {
Button,
DropdownMenu,
PageHeader,
TextTitle,
Badge,
SpinnerIcon,
} from '/@/renderer/components';
import { Button, DropdownMenu, PageHeader, SpinnerIcon, Paper } from '/@/renderer/components';
import { usePlayQueueAdd } from '/@/renderer/features/player';
import { useContainerQuery } from '/@/renderer/hooks';
import { LibraryHeaderBar } from '/@/renderer/features/shared';
import { usePlayButtonBehavior } from '/@/renderer/store/settings.store';
import { Play } from '/@/renderer/types';
interface AlbumArtistDetailTopSongsListHeaderProps {
@ -25,7 +18,7 @@ export const AlbumArtistDetailTopSongsListHeader = ({
data,
}: AlbumArtistDetailTopSongsListHeaderProps) => {
const handlePlayQueueAdd = usePlayQueueAdd();
const cq = useContainerQuery();
const playButtonBehavior = usePlayButtonBehavior();
const handlePlay = async (play: Play) => {
handlePlayQueueAdd?.({
@ -36,61 +29,49 @@ export const AlbumArtistDetailTopSongsListHeader = ({
return (
<PageHeader p="1rem">
<Flex
ref={cq.ref}
direction="row"
justify="space-between"
>
<Flex
align="center"
gap="md"
justify="center"
<LibraryHeaderBar>
<LibraryHeaderBar.PlayButton onClick={() => handlePlay(playButtonBehavior)} />
<LibraryHeaderBar.Title>Top songs from {title}</LibraryHeaderBar.Title>
<Paper
fw="600"
px="1rem"
py="0.3rem"
radius="sm"
>
<Button
compact
size="xl"
sx={{ paddingLeft: 0, paddingRight: 0 }}
variant="subtle"
>
<Group noWrap>
<TextTitle
maw="20vw"
order={2}
overflow="hidden"
weight={700}
>
{title}
</TextTitle>
<Badge
radius="xl"
size="lg"
>
{itemCount === null || itemCount === undefined ? <SpinnerIcon /> : itemCount}
</Badge>
</Group>
</Button>
<DropdownMenu position="bottom-start">
<DropdownMenu.Target>
<Button
compact
fw="600"
variant="subtle"
>
<RiMoreFill size={15} />
</Button>
</DropdownMenu.Target>
<DropdownMenu.Dropdown>
<DropdownMenu.Item onClick={() => handlePlay(Play.NOW)}>Play</DropdownMenu.Item>
<DropdownMenu.Item onClick={() => handlePlay(Play.LAST)}>
Add to queue
</DropdownMenu.Item>
<DropdownMenu.Item onClick={() => handlePlay(Play.NEXT)}>
Add to queue next
</DropdownMenu.Item>
</DropdownMenu.Dropdown>
</DropdownMenu>
</Flex>
</Flex>
{itemCount === null || itemCount === undefined ? <SpinnerIcon /> : itemCount}
</Paper>
<DropdownMenu position="bottom-start">
<DropdownMenu.Target>
<Button
compact
fw="600"
variant="subtle"
>
<RiMoreFill size={15} />
</Button>
</DropdownMenu.Target>
<DropdownMenu.Dropdown>
<DropdownMenu.Item
icon={<RiPlayFill />}
onClick={() => handlePlay(Play.NOW)}
>
Play
</DropdownMenu.Item>
<DropdownMenu.Item
icon={<RiAddBoxFill />}
onClick={() => handlePlay(Play.LAST)}
>
Add to queue
</DropdownMenu.Item>
<DropdownMenu.Item
icon={<RiAddCircleFill />}
onClick={() => handlePlay(Play.NEXT)}
>
Add to queue next
</DropdownMenu.Item>
</DropdownMenu.Dropdown>
</DropdownMenu>
</LibraryHeaderBar>
</PageHeader>
);
};

View file

@ -109,10 +109,7 @@ export const AlbumArtistListContent = ({ gridRef, tableRef }: AlbumArtistListCon
);
const albums = api.normalize.albumArtistList(albumArtistsRes, server);
params.successCallback(
albums?.items || [],
albumArtistsRes?.totalRecordCount || undefined,
);
params.successCallback(albums?.items || [], albumArtistsRes?.totalRecordCount || 0);
},
rowCount: undefined,
};

View file

@ -8,8 +8,8 @@ import {
RiSortDesc,
RiFolder2Line,
RiMoreFill,
RiSettings2Fill,
RiRefreshLine,
RiSettings3Fill,
} from 'react-icons/ri';
import { api } from '/@/renderer/api';
import { queryKeys } from '/@/renderer/api/query-keys';
@ -168,7 +168,7 @@ export const AlbumArtistListHeaderFilters = ({
const albumArtists = api.normalize.albumArtistList(albumArtistsRes, server);
params.successCallback(
albumArtists?.items || [],
albumArtistsRes?.totalRecordCount || undefined,
albumArtistsRes?.totalRecordCount || 0,
);
},
rowCount: undefined,
@ -379,14 +379,14 @@ export const AlbumArtistListHeaderFilters = ({
</DropdownMenu>
</Group>
<Group>
<DropdownMenu position="bottom-start">
<DropdownMenu position="bottom-end">
<DropdownMenu.Target>
<Button
compact
size="md"
variant="subtle"
>
<RiSettings2Fill size="1.3rem" />
<RiSettings3Fill size="1.3rem" />
</Button>
</DropdownMenu.Target>
<DropdownMenu.Dropdown>

View file

@ -108,7 +108,7 @@ export const AlbumArtistListHeader = ({
const albumArtists = api.normalize.albumArtistList(albumArtistsRes, server);
params.successCallback(
albumArtists?.items || [],
albumArtistsRes?.totalRecordCount || undefined,
albumArtistsRes?.totalRecordCount || 0,
);
},
rowCount: undefined,
@ -151,12 +151,10 @@ export const AlbumArtistListHeader = ({
<PageHeader backgroundColor="var(--titlebar-bg)">
<Flex
justify="space-between"
py="1rem"
w="100%"
>
<LibraryHeaderBar>
<Group noWrap>
<LibraryHeaderBar.Title>Album Artists</LibraryHeaderBar.Title>
</Group>
<LibraryHeaderBar.Title>Album Artists</LibraryHeaderBar.Title>
<Paper
fw="600"
px="1rem"