Add configurable play button behavior

This commit is contained in:
jeffvli
2022-11-08 03:57:56 -08:00
parent b2cc85d368
commit 7b1940e1f5
5 changed files with 69 additions and 43 deletions
@@ -14,6 +14,7 @@ import {
LibraryItem, LibraryItem,
CardRow, CardRow,
CardRoute, CardRoute,
Play,
} from '@/renderer/types'; } from '@/renderer/types';
initSimpleImg({ threshold: 0.5 }, true); initSimpleImg({ threshold: 0.5 }, true);
@@ -133,6 +134,7 @@ interface BaseGridCardProps {
cardRows: CardRow[]; cardRows: CardRow[];
handlePlayQueueAdd: (options: PlayQueueAddOptions) => void; handlePlayQueueAdd: (options: PlayQueueAddOptions) => void;
itemType: LibraryItem; itemType: LibraryItem;
playButtonBehavior: Play;
route: CardRoute; route: CardRoute;
}; };
data: any; data: any;
@@ -154,7 +156,7 @@ export const DefaultCard = ({
const navigate = useNavigate(); const navigate = useNavigate();
const { isScrolling, index } = listChildProps; const { isScrolling, index } = listChildProps;
const { itemGap, itemHeight, itemWidth } = sizes; const { itemGap, itemHeight, itemWidth } = sizes;
const { cardControls, handlePlayQueueAdd, itemType, cardRows, route } = const { handlePlayQueueAdd, itemType, cardRows, route, playButtonBehavior } =
controls; controls;
if (data) { if (data) {
@@ -204,10 +206,10 @@ export const DefaultCard = ({
<ControlsContainer> <ControlsContainer>
{!isScrolling && ( {!isScrolling && (
<GridCardControls <GridCardControls
cardControls={cardControls}
handlePlayQueueAdd={handlePlayQueueAdd} handlePlayQueueAdd={handlePlayQueueAdd}
itemData={data} itemData={data}
itemType={itemType} itemType={itemType}
playButtonBehavior={playButtonBehavior}
/> />
)} )}
</ControlsContainer> </ControlsContainer>
@@ -224,6 +226,7 @@ export const DefaultCard = ({
<React.Fragment key={`${data.id}-${item.id}`}> <React.Fragment key={`${data.id}-${item.id}`}>
{itemIndex > 0 && ( {itemIndex > 0 && (
<Text <Text
$noSelect
sx={{ sx={{
display: 'inline-block', display: 'inline-block',
padding: '0 2px 0 1px', padding: '0 2px 0 1px',
@@ -234,6 +237,7 @@ export const DefaultCard = ({
)}{' '} )}{' '}
<Text <Text
$link $link
$noSelect
$secondary={index > 0} $secondary={index > 0}
component={Link} component={Link}
overflow="hidden" overflow="hidden"
@@ -262,6 +266,7 @@ export const DefaultCard = ({
{data[row.property].map((item: any) => ( {data[row.property].map((item: any) => (
<Text <Text
key={`${data.id}-${item.id}`} key={`${data.id}-${item.id}`}
$noSelect
$secondary={index > 0} $secondary={index > 0}
overflow="hidden" overflow="hidden"
> >
@@ -277,6 +282,7 @@ export const DefaultCard = ({
{row.route ? ( {row.route ? (
<Text <Text
$link $link
$noSelect
component={Link} component={Link}
overflow="hidden" overflow="hidden"
to={generatePath( to={generatePath(
@@ -293,7 +299,7 @@ export const DefaultCard = ({
{data && data[row.property]} {data && data[row.property]}
</Text> </Text>
) : ( ) : (
<Text $secondary={index > 0} overflow="hidden"> <Text $noSelect $secondary={index > 0} overflow="hidden">
{data && data[row.property]} {data && data[row.property]}
</Text> </Text>
)} )}
@@ -10,7 +10,7 @@ import {
import styled from 'styled-components'; import styled from 'styled-components';
import { Button } from '@/renderer/components/button'; import { Button } from '@/renderer/components/button';
import { DropdownMenu } from '@/renderer/components/dropdown-menu'; import { DropdownMenu } from '@/renderer/components/dropdown-menu';
import { Play } from '@/renderer/types'; import { LibraryItem, Play, PlayQueueAddOptions } from '@/renderer/types';
type PlayButtonType = UnstyledButtonProps & type PlayButtonType = UnstyledButtonProps &
React.ComponentPropsWithoutRef<'button'>; React.ComponentPropsWithoutRef<'button'>;
@@ -74,11 +74,32 @@ const FavoriteWrapper = styled.span<{ isFavorite: boolean }>`
} }
`; `;
const PLAY_TYPES = [
{
label: 'Play',
play: Play.NOW,
},
{
label: 'Play last',
play: Play.LAST,
},
{
label: 'Play next',
play: Play.NEXT,
},
];
export const GridCardControls = ({ export const GridCardControls = ({
itemData, itemData,
itemType, itemType,
handlePlayQueueAdd, handlePlayQueueAdd,
}: any) => { playButtonBehavior,
}: {
handlePlayQueueAdd: (options: PlayQueueAddOptions) => void;
itemData: any;
itemType: LibraryItem;
playButtonBehavior: Play;
}) => {
return ( return (
<GridCardControlsContainer> <GridCardControlsContainer>
<TopControls /> <TopControls />
@@ -96,7 +117,7 @@ export const GridCardControls = ({
id: itemData.id, id: itemData.id,
type: itemType, type: itemType,
}, },
play: Play.NOW, play: playButtonBehavior,
}); });
}} }}
> >
@@ -126,36 +147,26 @@ export const GridCardControls = ({
</Button> </Button>
</DropdownMenu.Target> </DropdownMenu.Target>
<DropdownMenu.Dropdown> <DropdownMenu.Dropdown>
<DropdownMenu.Item {PLAY_TYPES.filter(
onClick={(e: MouseEvent) => { (type) => type.play !== playButtonBehavior
e.preventDefault(); ).map((type) => (
e.stopPropagation(); <DropdownMenu.Item
handlePlayQueueAdd({ key={`playtype-${type.play}`}
byItemType: { onClick={(e: MouseEvent) => {
id: itemData.id, e.preventDefault();
type: itemType, e.stopPropagation();
}, handlePlayQueueAdd({
play: Play.LAST, byItemType: {
}); id: itemData.id,
}} type: itemType,
> },
Play later play: type.play,
</DropdownMenu.Item> });
<DropdownMenu.Item }}
onClick={(e: MouseEvent) => { >
e.preventDefault(); {type.label}
e.stopPropagation(); </DropdownMenu.Item>
handlePlayQueueAdd({ ))}
byItemType: {
id: itemData.id,
type: itemType,
},
play: Play.NEXT,
});
}}
>
Play next
</DropdownMenu.Item>
<DropdownMenu.Divider /> <DropdownMenu.Divider />
<DropdownMenu.Item disabled>Add to playlist</DropdownMenu.Item> <DropdownMenu.Item disabled>Add to playlist</DropdownMenu.Item>
<DropdownMenu.Divider /> <DropdownMenu.Divider />
@@ -20,6 +20,7 @@ export const GridCard = ({
cardRows, cardRows,
itemData, itemData,
itemType, itemType,
playButtonBehavior,
route, route,
display, display,
} = data as GridCardData; } = data as GridCardData;
@@ -40,6 +41,7 @@ export const GridCard = ({
cardRows, cardRows,
handlePlayQueueAdd, handlePlayQueueAdd,
itemType, itemType,
playButtonBehavior,
route, route,
}} }}
data={itemData[i]} data={itemData[i]}
@@ -13,6 +13,7 @@ import {
LibraryItem, LibraryItem,
CardRow, CardRow,
CardRoute, CardRoute,
Play,
} from '@/renderer/types'; } from '@/renderer/types';
initSimpleImg({ threshold: 0.5 }, true); initSimpleImg({ threshold: 0.5 }, true);
@@ -125,10 +126,10 @@ const Row = styled.div<{ $secondary?: boolean }>`
interface BaseGridCardProps { interface BaseGridCardProps {
columnIndex: number; columnIndex: number;
controls: { controls: {
cardControls: any[];
cardRows: CardRow[]; cardRows: CardRow[];
handlePlayQueueAdd: (options: PlayQueueAddOptions) => void; handlePlayQueueAdd: (options: PlayQueueAddOptions) => void;
itemType: LibraryItem; itemType: LibraryItem;
playButtonBehavior: Play;
route: CardRoute; route: CardRoute;
}; };
data: any; data: any;
@@ -149,7 +150,7 @@ export const PosterCard = ({
}: BaseGridCardProps) => { }: BaseGridCardProps) => {
const { isScrolling, index } = listChildProps; const { isScrolling, index } = listChildProps;
const { itemGap, itemHeight, itemWidth } = sizes; const { itemGap, itemHeight, itemWidth } = sizes;
const { cardControls, handlePlayQueueAdd, itemType, cardRows, route } = const { handlePlayQueueAdd, itemType, cardRows, route, playButtonBehavior } =
controls; controls;
if (data) { if (data) {
@@ -196,10 +197,10 @@ export const PosterCard = ({
<ControlsContainer> <ControlsContainer>
{!isScrolling && ( {!isScrolling && (
<GridCardControls <GridCardControls
cardControls={cardControls}
handlePlayQueueAdd={handlePlayQueueAdd} handlePlayQueueAdd={handlePlayQueueAdd}
itemData={data} itemData={data}
itemType={itemType} itemType={itemType}
playButtonBehavior={playButtonBehavior}
/> />
)} )}
</ControlsContainer> </ControlsContainer>
@@ -217,6 +218,7 @@ export const PosterCard = ({
<React.Fragment key={`${data.id}-${item.id}`}> <React.Fragment key={`${data.id}-${item.id}`}>
{itemIndex > 0 && ( {itemIndex > 0 && (
<Text <Text
$noSelect
sx={{ sx={{
display: 'inline-block', display: 'inline-block',
padding: '0 2px 0 1px', padding: '0 2px 0 1px',
@@ -227,6 +229,7 @@ export const PosterCard = ({
)}{' '} )}{' '}
<Text <Text
$link $link
$noSelect
$secondary={index > 0} $secondary={index > 0}
component={Link} component={Link}
overflow="hidden" overflow="hidden"
@@ -254,6 +257,7 @@ export const PosterCard = ({
{data[row.property].map((item: any) => ( {data[row.property].map((item: any) => (
<Text <Text
key={`${data.id}-${item.id}`} key={`${data.id}-${item.id}`}
$noSelect
$secondary={index > 0} $secondary={index > 0}
overflow="hidden" overflow="hidden"
> >
@@ -269,6 +273,7 @@ export const PosterCard = ({
{row.route ? ( {row.route ? (
<Text <Text
$link $link
$noSelect
component={Link} component={Link}
overflow="hidden" overflow="hidden"
to={generatePath( to={generatePath(
@@ -284,7 +289,7 @@ export const PosterCard = ({
{data && data[row.property]} {data && data[row.property]}
</Text> </Text>
) : ( ) : (
<Text $secondary={index > 0} overflow="hidden"> <Text $noSelect $secondary={index > 0} overflow="hidden">
{data && data[row.property]} {data && data[row.property]}
</Text> </Text>
)} )}
@@ -3,6 +3,7 @@ import { FixedSizeList, FixedSizeListProps } from 'react-window';
import styled from 'styled-components'; import styled from 'styled-components';
import { GridCard } from '@/renderer/components/virtual-grid/grid-card'; import { GridCard } from '@/renderer/components/virtual-grid/grid-card';
import { usePlayQueueHandler } from '@/renderer/features/player/hooks/use-playqueue-handler'; import { usePlayQueueHandler } from '@/renderer/features/player/hooks/use-playqueue-handler';
import { useSettingsStore } from '@/renderer/store/settings.store';
import { import {
CardRow, CardRow,
LibraryItem, LibraryItem,
@@ -38,26 +39,27 @@ export const VirtualGridWrapper = ({
rowCount: number; rowCount: number;
}) => { }) => {
const handlePlayQueueAdd = usePlayQueueHandler(); const handlePlayQueueAdd = usePlayQueueHandler();
const { playButtonBehavior } = useSettingsStore((state) => state.player);
const memo = useMemo( const memo = useMemo(
() => ({ () => ({
cardRows, cardRows,
columnCount, columnCount,
display, display,
handlePlayQueueAdd,
itemCount, itemCount,
itemData, itemData,
itemGap, itemGap,
itemHeight, itemHeight,
itemType, itemType,
itemWidth, itemWidth,
playButtonBehavior,
route, route,
}), }),
[ [
cardRows, cardRows,
itemType, itemType,
columnCount, columnCount,
handlePlayQueueAdd, playButtonBehavior,
itemCount, itemCount,
itemData, itemData,
display, display,
@@ -74,7 +76,7 @@ export const VirtualGridWrapper = ({
{...rest} {...rest}
useIsScrolling useIsScrolling
itemCount={rowCount} itemCount={rowCount}
itemData={memo} itemData={{ ...memo, handlePlayQueueAdd }}
itemSize={itemHeight} itemSize={itemHeight}
overscanCount={5} overscanCount={5}
> >