diff --git a/src/renderer/components/feature-carousel/feature-carousel.module.css b/src/renderer/components/feature-carousel/feature-carousel.module.css index 5eec0fdd1..55cf954aa 100644 --- a/src/renderer/components/feature-carousel/feature-carousel.module.css +++ b/src/renderer/components/feature-carousel/feature-carousel.module.css @@ -23,7 +23,7 @@ width: 100%; min-height: 440px; overflow: hidden; - border-radius: var(--theme-radius-md); + border-radius: var(--theme-radius-lg); isolation: isolate; } @@ -56,16 +56,17 @@ .title-section { display: flex; flex-shrink: 0; - align-items: center; + align-items: flex-start; justify-content: center; width: 100%; height: 60px; min-height: 60px; max-height: 60px; - text-align: center; + text-align: left; } .image-section { + position: relative; display: flex; flex-shrink: 0; align-items: center; @@ -76,6 +77,22 @@ max-height: 250px; } +.play-button-overlay { + position: absolute; + top: 50%; + left: 50%; + z-index: 20; + pointer-events: none; + opacity: 0; + transform: translate(-50%, -50%); + transition: opacity 0.3s ease; +} + +.image-section:hover .play-button-overlay { + pointer-events: auto; + opacity: 1; +} + .metadata-section { display: flex; flex-shrink: 0; @@ -102,17 +119,44 @@ transform: scale(0.98); } -.album-image { +.album-image-container { + position: relative; width: 100%; max-width: 180px; - height: auto; + overflow: hidden; border-radius: var(--theme-radius-lg); - box-shadow: 0 8px 24px rgb(0 0 0 / 60%); - transition: box-shadow 0.3s ease; + filter: drop-shadow(0 10px 30px rgb(0 0 0 / 50%)) drop-shadow(0 4px 12px rgb(0 0 0 / 40%)); + transition: filter 0.3s ease; } -.image-link:hover .album-image { - box-shadow: 0 12px 32px rgb(0 0 0 / 40%); +.album-image-container::before { + position: absolute; + top: 0; + left: 0; + z-index: 10; + width: 100%; + height: 100%; + pointer-events: none; + content: ''; + background-color: rgb(0 0 0 / 0%); + border-radius: var(--theme-radius-lg); + transition: background-color 0.3s ease; +} + +.image-section:hover .album-image-container::before { + background-color: rgb(0 0 0 / 40%); +} + +.album-image { + width: 100%; + height: auto; + object-fit: cover; + border-radius: var(--theme-radius-lg); +} + +.carousel-item:hover .album-image-container, +.carousel-link:hover .album-image-container { + filter: drop-shadow(0 16px 40px rgb(0 0 0 / 60%)) drop-shadow(0 6px 16px rgb(0 0 0 / 50%)); } .artist-link { @@ -195,7 +239,7 @@ max-height: 80px; } - .album-image { + .album-image-container { max-width: 160px; } } @@ -231,7 +275,7 @@ max-height: 110px; } - .album-image { + .album-image-container { max-width: 200px; } } @@ -263,7 +307,7 @@ max-height: 120px; } - .album-image { + .album-image-container { max-width: 220px; } } @@ -295,7 +339,7 @@ max-height: 130px; } - .album-image { + .album-image-container { max-width: 240px; } } diff --git a/src/renderer/components/feature-carousel/feature-carousel.tsx b/src/renderer/components/feature-carousel/feature-carousel.tsx index fbdf2f4dd..8a5f05864 100644 --- a/src/renderer/components/feature-carousel/feature-carousel.tsx +++ b/src/renderer/components/feature-carousel/feature-carousel.tsx @@ -6,18 +6,21 @@ import { generatePath, Link } from 'react-router'; import styles from './feature-carousel.module.css'; -import { ItemCard } from '/@/renderer/components/item-card/item-card'; -import { useDefaultItemListControls } from '/@/renderer/components/item-list/helpers/item-list-controls'; +import { usePlayer } from '/@/renderer/features/player/context/player-context'; import { BackgroundOverlay } from '/@/renderer/features/shared/components/library-background-overlay'; +import { PlayButtonGroup } from '/@/renderer/features/shared/components/play-button-group'; import { useContainerQuery, useFastAverageColor } from '/@/renderer/hooks'; import { AppRoute } from '/@/renderer/router/routes'; +import { useCurrentServer } from '/@/renderer/store'; import { ActionIcon } from '/@/shared/components/action-icon/action-icon'; import { Badge } from '/@/shared/components/badge/badge'; import { Group } from '/@/shared/components/group/group'; +import { Image } from '/@/shared/components/image/image'; import { Stack } from '/@/shared/components/stack/stack'; import { TextTitle } from '/@/shared/components/text-title/text-title'; import { Text } from '/@/shared/components/text/text'; import { Album, LibraryItem } from '/@/shared/types/domain-types'; +import { Play } from '/@/shared/types/types'; const containerVariants = { animate: (custom: { isNext: boolean }) => ({ @@ -98,11 +101,17 @@ const CarouselItem = ({ album }: CarouselItemProps) => { srcLoaded: true, }); - const controls = useDefaultItemListControls(); + const server = useCurrentServer(); + const { addToQueueByFetch } = usePlayer(); + + const handlePlay = (type: Play) => { + if (!server?.id) return; + addToQueueByFetch(server.id, [album.id], LibraryItem.ALBUM, type); + }; return (
- + { >
- + {album.name}
- +
+ +
@@ -136,18 +144,26 @@ const CarouselItem = ({ album }: CarouselItemProps) => { className={styles.artist} fw={600} key={`artist-${artist.id}`} - size="md" + size="xl" > {artist.name} ))} {album.genres?.slice(0, 2).map((genre) => ( - + {genre.name} ))} - {album.releaseYear && {album.releaseYear}} + {album.releaseYear && ( + + {album.releaseYear} + + )}
diff --git a/src/renderer/features/shared/components/play-button-group.module.css b/src/renderer/features/shared/components/play-button-group.module.css new file mode 100644 index 000000000..cea58415b --- /dev/null +++ b/src/renderer/features/shared/components/play-button-group.module.css @@ -0,0 +1,10 @@ +.play-button-group { + display: flex; + flex-direction: row; + flex-wrap: nowrap; + gap: var(--theme-spacing-sm); + align-items: center; + justify-content: center; + width: 100%; + height: 100%; +} diff --git a/src/renderer/features/shared/components/play-button-group.tsx b/src/renderer/features/shared/components/play-button-group.tsx index 9349e4528..29859ad3d 100644 --- a/src/renderer/features/shared/components/play-button-group.tsx +++ b/src/renderer/features/shared/components/play-button-group.tsx @@ -1,6 +1,7 @@ +import styles from './play-button-group.module.css'; + import i18n from '/@/i18n/i18n'; import { PlayButton } from '/@/renderer/features/shared/components/play-button'; -import { Group } from '/@/shared/components/group/group'; import { AppIconSelection } from '/@/shared/components/icon/icon'; import { Tooltip } from '/@/shared/components/tooltip/tooltip'; import { Play } from '/@/shared/types/types'; @@ -39,7 +40,7 @@ interface PlayButtonGroupProps { export const PlayButtonGroup = ({ loading, onPlay }: PlayButtonGroupProps) => { return ( - +
{playButtons.map((button) => ( { /> ))} - +
); };