diff --git a/src/renderer/components/item-list/item-table-list/columns/image-column.module.css b/src/renderer/components/item-list/item-table-list/columns/image-column.module.css index c855b1f7f..b4ce7a064 100644 --- a/src/renderer/components/item-list/item-table-list/columns/image-column.module.css +++ b/src/renderer/components/item-list/item-table-list/columns/image-column.module.css @@ -6,3 +6,37 @@ .compact-image-container { width: 100%; } + +.image-container-with-aspect-ratio { + display: flex; + align-items: center; + justify-content: center; + width: 100%; + height: 100%; + aspect-ratio: unset; +} + +.image-container-with-aspect-ratio img { + width: auto; + height: 100%; + object-fit: contain; +} + +.image-container { + position: relative; + width: 100%; + height: 100%; +} + +.play-button-overlay { + position: absolute; + top: 50%; + left: 50%; + z-index: 10; + transform: translate(-50%, -50%); +} + +.play-button-overlay button { + width: 36px; + height: 36px; +} diff --git a/src/renderer/components/item-list/item-table-list/columns/image-column.tsx b/src/renderer/components/item-list/item-table-list/columns/image-column.tsx index 3bf08f35f..370057a58 100644 --- a/src/renderer/components/item-list/item-table-list/columns/image-column.tsx +++ b/src/renderer/components/item-list/item-table-list/columns/image-column.tsx @@ -1,4 +1,5 @@ import clsx from 'clsx'; +import { useState } from 'react'; import styles from './image-column.module.css'; @@ -6,23 +7,89 @@ import { ItemTableListInnerColumn, TableColumnContainer, } from '/@/renderer/components/item-list/item-table-list/item-table-list-column'; +import { PlayButton } from '/@/renderer/features/shared/components/play-button'; +import { LONG_PRESS_PLAY_BEHAVIOR } from '/@/renderer/features/shared/components/play-button-group'; +import { usePlayButtonBehavior } from '/@/renderer/store'; import { Image } from '/@/shared/components/image/image'; import { Skeleton } from '/@/shared/components/skeleton/skeleton'; +import { LibraryItem } from '/@/shared/types/domain-types'; +import { Play } from '/@/shared/types/types'; export const ImageColumn = (props: ItemTableListInnerColumn) => { const row: string | undefined = (props.data as (any | undefined)[])[props.rowIndex]?.[ props.columns[props.columnIndex].id ]; + const playButtonBehavior = usePlayButtonBehavior(); + const item = props.data[props.rowIndex] as any; + const showPlayButton = props.size === 'default' || props.size === 'large'; + const internalState = (props as any).internalState; + const [isHovered, setIsHovered] = useState(false); + + const handlePlay = (playType: Play, event: React.MouseEvent) => { + if (!item) { + return; + } + + // For SONG items, use double click behavior + if ( + (props.itemType === LibraryItem.SONG || props.itemType === LibraryItem.PLAYLIST_SONG) && + props.controls?.onDoubleClick + ) { + // Calculate the index based on rowIndex, accounting for header if enabled + const isHeaderEnabled = !!props.enableHeader; + const index = isHeaderEnabled ? props.rowIndex - 1 : props.rowIndex; + + props.controls.onDoubleClick({ + event: null, + index, + internalState, + item, + itemType: props.itemType, + }); + return; + } + + // For other item types, use regular onPlay + if (!props.controls?.onPlay) { + return; + } + + props.controls.onPlay({ + event, + item, + itemType: props.itemType, + playType, + }); + }; if (typeof row === 'string') { return ( - +
setIsHovered(true)} + onMouseLeave={() => setIsHovered(false)} + > + + {showPlayButton && isHovered && ( +
+ handlePlay(playButtonBehavior, e)} + onLongPress={(e) => + handlePlay(LONG_PRESS_PLAY_BEHAVIOR[playButtonBehavior], e) + } + /> +
+ )} +
); } diff --git a/src/renderer/features/shared/components/play-button-group.tsx b/src/renderer/features/shared/components/play-button-group.tsx index 29859ad3d..8ffd11ac6 100644 --- a/src/renderer/features/shared/components/play-button-group.tsx +++ b/src/renderer/features/shared/components/play-button-group.tsx @@ -27,7 +27,7 @@ const playButtons: { icon: AppIconSelection; label: string; secondary: boolean; }, ]; -const LONG_PRESS_PLAY_BEHAVIOR = { +export const LONG_PRESS_PLAY_BEHAVIOR = { [Play.LAST]: Play.LAST_SHUFFLE, [Play.NEXT]: Play.NEXT_SHUFFLE, [Play.NOW]: Play.SHUFFLE,