feishin/src/renderer/components/card/card-controls.tsx

180 lines
5 KiB
TypeScript
Raw Normal View History

2025-05-20 19:23:36 -07:00
import type { PlayQueueAddOptions } from '/@/shared/types/types';
2022-12-19 15:59:14 -08:00
import type { UnstyledButtonProps } from '@mantine/core';
import type { MouseEvent } from 'react';
2022-12-19 15:59:14 -08:00
import { Group } from '@mantine/core';
import React from 'react';
import { RiHeartFill, RiHeartLine, RiMore2Fill, RiPlayFill } from 'react-icons/ri';
2022-12-19 15:59:14 -08:00
import styled from 'styled-components';
import { _Button } from '/@/renderer/components/button';
import {
2023-07-01 19:10:05 -07:00
ALBUM_CONTEXT_MENU_ITEMS,
ARTIST_CONTEXT_MENU_ITEMS,
} from '/@/renderer/features/context-menu/context-menu-items';
import { useHandleGeneralContextMenu } from '/@/renderer/features/context-menu/hooks/use-handle-context-menu';
import { usePlayButtonBehavior } from '/@/renderer/store/settings.store';
2025-05-20 19:23:36 -07:00
import { LibraryItem } from '/@/shared/types/domain-types';
import { Play } from '/@/shared/types/types';
2022-12-19 15:59:14 -08:00
type PlayButtonType = React.ComponentPropsWithoutRef<'button'> & UnstyledButtonProps;
2022-12-19 15:59:14 -08:00
const PlayButton = styled.button<PlayButtonType>`
2023-07-01 19:10:05 -07:00
display: flex;
align-items: center;
justify-content: center;
width: 50px;
height: 50px;
2023-09-15 20:42:38 -07:00
background-color: rgb(255 255 255);
2023-07-01 19:10:05 -07:00
border: none;
border-radius: 50%;
opacity: 0.8;
transition: opacity 0.2s ease-in-out;
transition: scale 0.2s linear;
&:hover {
opacity: 1;
scale: 1.1;
}
&:active {
opacity: 1;
scale: 1;
}
svg {
2023-09-15 20:42:38 -07:00
fill: rgb(0 0 0);
stroke: rgb(0 0 0);
2023-07-01 19:10:05 -07:00
}
2022-12-19 15:59:14 -08:00
`;
const SecondaryButton = styled(_Button)`
2023-07-01 19:10:05 -07:00
opacity: 0.8;
transition: opacity 0.2s ease-in-out;
transition: scale 0.2s linear;
&:hover {
opacity: 1;
scale: 1.1;
}
&:active {
opacity: 1;
scale: 1;
}
2022-12-19 15:59:14 -08:00
`;
const GridCardControlsContainer = styled.div`
2023-07-01 19:10:05 -07:00
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
width: 100%;
height: 100%;
2022-12-19 15:59:14 -08:00
`;
const ControlsRow = styled.div`
2023-07-01 19:10:05 -07:00
width: 100%;
height: calc(100% / 3);
2022-12-19 15:59:14 -08:00
`;
// const TopControls = styled(ControlsRow)`
// display: flex;
// align-items: flex-start;
// justify-content: space-between;
// padding: 0.5rem;
// `;
// const CenterControls = styled(ControlsRow)`
// display: flex;
// align-items: center;
// justify-content: center;
// padding: 0.5rem;
// `;
const BottomControls = styled(ControlsRow)`
2023-07-01 19:10:05 -07:00
display: flex;
align-items: flex-end;
justify-content: space-between;
padding: 1rem 0.5rem;
2022-12-19 15:59:14 -08:00
`;
const FavoriteWrapper = styled.span<{ isFavorite: boolean }>`
2023-07-01 19:10:05 -07:00
svg {
fill: ${(props) => props.isFavorite && 'var(--primary-color)'};
}
2022-12-19 15:59:14 -08:00
`;
2022-12-20 04:11:06 -08:00
export const CardControls = ({
handlePlayQueueAdd,
2023-07-01 19:10:05 -07:00
itemData,
itemType,
2022-12-20 04:11:06 -08:00
}: {
2023-07-01 19:10:05 -07:00
handlePlayQueueAdd?: (options: PlayQueueAddOptions) => void;
itemData: any;
itemType: LibraryItem;
2022-12-20 04:11:06 -08:00
}) => {
2023-07-01 19:10:05 -07:00
const playButtonBehavior = usePlayButtonBehavior();
const handlePlay = (e: MouseEvent<HTMLButtonElement>, playType?: Play) => {
e.preventDefault();
e.stopPropagation();
handlePlayQueueAdd?.({
byItemType: {
id: [itemData.id],
type: itemType,
},
playType: playType || playButtonBehavior,
});
};
const handleContextMenu = useHandleGeneralContextMenu(
itemType,
itemType === LibraryItem.ALBUM ? ALBUM_CONTEXT_MENU_ITEMS : ARTIST_CONTEXT_MENU_ITEMS,
);
return (
<GridCardControlsContainer>
<BottomControls>
<PlayButton onClick={handlePlay}>
<RiPlayFill size={25} />
</PlayButton>
<Group spacing="xs">
<SecondaryButton
disabled
p={5}
sx={{ svg: { fill: 'white !important' } }}
variant="subtle"
>
<FavoriteWrapper isFavorite={itemData?.isFavorite}>
{itemData?.isFavorite ? (
<RiHeartFill size={20} />
) : (
<RiHeartLine
color="white"
size={20}
/>
)}
</FavoriteWrapper>
</SecondaryButton>
<SecondaryButton
onClick={(e) => {
e.preventDefault();
e.stopPropagation();
handleContextMenu(e, [itemData]);
}}
p={5}
sx={{ svg: { fill: 'white !important' } }}
variant="subtle"
2023-07-01 19:10:05 -07:00
>
<RiMore2Fill
color="white"
size={20}
/>
</SecondaryButton>
</Group>
</BottomControls>
</GridCardControlsContainer>
);
2022-12-19 15:59:14 -08:00
};