From a7e6a75c689fff4a64bd480c32e7b48ff1d6f1d7 Mon Sep 17 00:00:00 2001 From: jeffvli Date: Wed, 3 Dec 2025 16:00:41 -0800 Subject: [PATCH] normalize tooltips --- src/i18n/locales/en.json | 3 +- .../item-card/item-card-controls.tsx | 46 +++++---- .../item-table-list/columns/image-column.tsx | 21 ++-- src/renderer/components/item-list/types.ts | 1 + .../player/components/left-controls.tsx | 4 +- .../player/components/mobile-playerbar.tsx | 2 +- .../player/components/player-button.tsx | 1 + .../components/library-command-item.tsx | 5 - .../shared/components/play-button-group.tsx | 96 +++++++++++++++---- .../components/sidebar-playlist-list.tsx | 6 -- .../features/sidebar/components/sidebar.tsx | 1 - src/shared/components/tooltip/tooltip.tsx | 2 + 12 files changed, 129 insertions(+), 59 deletions(-) diff --git a/src/i18n/locales/en.json b/src/i18n/locales/en.json index cf597dc7b..fbd286d34 100644 --- a/src/i18n/locales/en.json +++ b/src/i18n/locales/en.json @@ -9,7 +9,7 @@ "downloadStarted": "started download of {{count}} items", "editPlaylist": "edit $t(entity.playlist_one)", "goToPage": "go to page", - "largeFetch": "this action will make {{count}} network requests to your server", + "largeFetch": "this action will attempt to fetch {{count}} items from your server", "moveToNext": "move to next", "moveToBottom": "move to bottom", "moveToTop": "move to top", @@ -530,6 +530,7 @@ "addNext": "add next", "addLastShuffled": "add last (shuffled)", "addNextShuffled": "add next (shuffled)", + "holdToShuffle": "hold to shuffle", "favorite": "favorite", "mute": "mute", "muted": "muted", diff --git a/src/renderer/components/item-card/item-card-controls.tsx b/src/renderer/components/item-card/item-card-controls.tsx index e672fb75d..722a44b0f 100644 --- a/src/renderer/components/item-card/item-card-controls.tsx +++ b/src/renderer/components/item-card/item-card-controls.tsx @@ -7,12 +7,14 @@ import styles from './item-card-controls.module.css'; import { ItemListStateActions } from '/@/renderer/components/item-list/helpers/item-list-state'; import { ItemControls } from '/@/renderer/components/item-list/types'; import { PlayButton } from '/@/renderer/features/shared/components/play-button'; +import { PlayTooltip } from '/@/renderer/features/shared/components/play-button-group'; import { useIsMutatingCreateFavorite } from '/@/renderer/features/shared/mutations/create-favorite-mutation'; import { useIsMutatingDeleteFavorite } from '/@/renderer/features/shared/mutations/delete-favorite-mutation'; import { useIsMutatingRating } from '/@/renderer/features/shared/mutations/set-rating-mutation'; import { animationVariants } from '/@/shared/components/animations/animation-variants'; import { AppIcon, Icon, IconProps } from '/@/shared/components/icon/icon'; import { Rating } from '/@/shared/components/rating/rating'; +import { Tooltip } from '/@/shared/components/tooltip/tooltip'; import { Album, AlbumArtist, @@ -234,25 +236,31 @@ export const ItemCardControls = ({ return ( {controls?.onPlay && ( - <> - - - - + + + + + + + + + + + )} {controls?.onFavorite && ( 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 ef39b65e3..eed3bc1ae 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 @@ -8,7 +8,10 @@ import { 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 { + LONG_PRESS_PLAY_BEHAVIOR, + PlayTooltip, +} from '/@/renderer/features/shared/components/play-button-group'; import { usePlayButtonBehavior } from '/@/renderer/store'; import { Icon } from '/@/shared/components/icon/icon'; import { Image } from '/@/shared/components/image/image'; @@ -85,13 +88,15 @@ export const ImageColumn = (props: ItemTableListInnerColumn) => { [styles.compactPlayButtonOverlay]: props.size === 'compact', })} > - handlePlay(playButtonBehavior, e)} - onLongPress={(e) => - handlePlay(LONG_PRESS_PLAY_BEHAVIOR[playButtonBehavior], e) - } - /> + + handlePlay(playButtonBehavior, e)} + onLongPress={(e) => + handlePlay(LONG_PRESS_PLAY_BEHAVIOR[playButtonBehavior], e) + } + /> + )} diff --git a/src/renderer/components/item-list/types.ts b/src/renderer/components/item-list/types.ts index 711d2ecf8..38d4fbba7 100644 --- a/src/renderer/components/item-list/types.ts +++ b/src/renderer/components/item-list/types.ts @@ -16,6 +16,7 @@ export interface DefaultItemControlProps { internalState?: ItemListStateActions; item: ItemListItem | undefined; itemType: LibraryItem; + meta?: Record; } export interface ItemControls { diff --git a/src/renderer/features/player/components/left-controls.tsx b/src/renderer/features/player/components/left-controls.tsx index 3129bd1b7..311a7efb4 100644 --- a/src/renderer/features/player/components/left-controls.tsx +++ b/src/renderer/features/player/components/left-controls.tsx @@ -110,7 +110,7 @@ export const LeftControls = () => { label={t('player.toggleFullscreenPlayer', { postProcess: 'sentenceCase', })} - openDelay={500} + openDelay={0} > { label: t('common.expand', { postProcess: 'titleCase', }), - openDelay: 500, + openDelay: 0, }} /> )} diff --git a/src/renderer/features/player/components/mobile-playerbar.tsx b/src/renderer/features/player/components/mobile-playerbar.tsx index f24680aa1..bd68f61a1 100644 --- a/src/renderer/features/player/components/mobile-playerbar.tsx +++ b/src/renderer/features/player/components/mobile-playerbar.tsx @@ -85,7 +85,7 @@ export const MobilePlayerbar = () => { label={t('player.toggleFullscreenPlayer', { postProcess: 'sentenceCase', })} - openDelay={500} + openDelay={0} > ( label: isPaused ? (t('player.play', { postProcess: 'sentenceCase' }) as string) : (t('player.pause', { postProcess: 'sentenceCase' }) as string), + openDelay: 0, }} {...props} /> diff --git a/src/renderer/features/search/components/library-command-item.tsx b/src/renderer/features/search/components/library-command-item.tsx index fe1cd627e..0df0a4937 100644 --- a/src/renderer/features/search/components/library-command-item.tsx +++ b/src/renderer/features/search/components/library-command-item.tsx @@ -90,7 +90,6 @@ export const LibraryCommandItem = ({ tabIndex={disabled ? -1 : 0} tooltip={{ label: t('player.play', { postProcess: 'sentenceCase' }), - openDelay: 500, }} variant="subtle" /> @@ -108,7 +107,6 @@ export const LibraryCommandItem = ({ tabIndex={disabled ? -1 : 0} tooltip={{ label: t('player.shuffle', { postProcess: 'sentenceCase' }), - openDelay: 500, }} variant="subtle" /> @@ -126,8 +124,6 @@ export const LibraryCommandItem = ({ tabIndex={disabled ? -1 : 0} tooltip={{ label: t('player.addLast', { postProcess: 'sentenceCase' }), - - openDelay: 500, }} variant="subtle" /> @@ -144,7 +140,6 @@ export const LibraryCommandItem = ({ tabIndex={disabled ? -1 : 0} tooltip={{ label: t('player.addNext', { postProcess: 'sentenceCase' }), - openDelay: 500, }} variant="subtle" /> diff --git a/src/renderer/features/shared/components/play-button-group.tsx b/src/renderer/features/shared/components/play-button-group.tsx index 8ffd11ac6..2a78f3b70 100644 --- a/src/renderer/features/shared/components/play-button-group.tsx +++ b/src/renderer/features/shared/components/play-button-group.tsx @@ -3,25 +3,60 @@ import styles from './play-button-group.module.css'; import i18n from '/@/i18n/i18n'; import { PlayButton } from '/@/renderer/features/shared/components/play-button'; import { AppIconSelection } from '/@/shared/components/icon/icon'; +import { Stack } from '/@/shared/components/stack/stack'; +import { Text } from '/@/shared/components/text/text'; import { Tooltip } from '/@/shared/components/tooltip/tooltip'; import { Play } from '/@/shared/types/types'; -const playButtons: { icon: AppIconSelection; label: string; secondary: boolean; type: Play }[] = [ +const playButtons: { + icon: AppIconSelection; + label: React.ReactNode | string; + secondary: boolean; + type: Play; +}[] = [ { icon: 'mediaPlayNext', - label: i18n.t('player.addNext', { postProcess: 'sentenceCase' }), + label: ( + + + {i18n.t('player.addNext', { postProcess: 'sentenceCase' })} + + + {i18n.t('player.holdToShuffle', { postProcess: 'sentenceCase' })} + + + ), + secondary: true, type: Play.NEXT, }, { icon: 'mediaPlay', - label: i18n.t('player.play', { postProcess: 'sentenceCase' }), + label: ( + + + {i18n.t('player.play', { postProcess: 'sentenceCase' })} + + + {i18n.t('player.holdToShuffle', { postProcess: 'sentenceCase' })} + + + ), secondary: false, type: Play.NOW, }, { icon: 'mediaPlayLast', - label: i18n.t('player.addLast', { postProcess: 'sentenceCase' }), + label: ( + + + {i18n.t('player.addLast', { postProcess: 'sentenceCase' })} + + + {i18n.t('player.holdToShuffle', { postProcess: 'sentenceCase' })} + + + ), secondary: true, type: Play.LAST, }, @@ -33,6 +68,33 @@ export const LONG_PRESS_PLAY_BEHAVIOR = { [Play.NOW]: Play.SHUFFLE, }; +const PLAY_BEHAVIOR_TO_LABEL = { + [Play.LAST]: i18n.t('player.addLast', { postProcess: 'sentenceCase' }), + [Play.NEXT]: i18n.t('player.addNext', { postProcess: 'sentenceCase' }), + [Play.NOW]: i18n.t('player.play', { postProcess: 'sentenceCase' }), +}; + +const TooltipLabel = ({ label }: { label: React.ReactNode | string; type: Play }) => { + return ( + + + {label} + + + {i18n.t('player.holdToShuffle', { postProcess: 'sentenceCase' })} + + + ); +}; + +export const PlayTooltip = ({ children, type }: { children: React.ReactNode; type: Play }) => { + return ( + }> + {children} + + ); +}; + interface PlayButtonGroupProps { loading?: boolean | Play; onPlay: (type: Play) => void; @@ -41,18 +103,20 @@ interface PlayButtonGroupProps { export const PlayButtonGroup = ({ loading, onPlay }: PlayButtonGroupProps) => { return (
- {playButtons.map((button) => ( - - onPlay(button.type)} - onLongPress={() => onPlay(LONG_PRESS_PLAY_BEHAVIOR[button.type])} - /> - - ))} + + {playButtons.map((button) => ( + + onPlay(button.type)} + onLongPress={() => onPlay(LONG_PRESS_PLAY_BEHAVIOR[button.type])} + /> + + ))} +
); }; diff --git a/src/renderer/features/sidebar/components/sidebar-playlist-list.tsx b/src/renderer/features/sidebar/components/sidebar-playlist-list.tsx index 5ab24d740..45c412aac 100644 --- a/src/renderer/features/sidebar/components/sidebar-playlist-list.tsx +++ b/src/renderer/features/sidebar/components/sidebar-playlist-list.tsx @@ -192,7 +192,6 @@ const RowControls = ({ size="xs" tooltip={{ label: t('player.play', { postProcess: 'sentenceCase' }), - openDelay: 500, }} variant="subtle" /> @@ -207,7 +206,6 @@ const RowControls = ({ size="xs" tooltip={{ label: t('player.shuffle', { postProcess: 'sentenceCase' }), - openDelay: 500, }} variant="subtle" /> @@ -222,7 +220,6 @@ const RowControls = ({ size="xs" tooltip={{ label: t('player.addLast', { postProcess: 'sentenceCase' }), - openDelay: 500, }} variant="subtle" /> @@ -237,7 +234,6 @@ const RowControls = ({ size="xs" tooltip={{ label: t('player.addNext', { postProcess: 'sentenceCase' }), - openDelay: 500, }} variant="subtle" /> @@ -328,7 +324,6 @@ export const SidebarPlaylistList = () => { label: t('action.createPlaylist', { postProcess: 'sentenceCase', }), - openDelay: 500, }} variant="subtle" /> @@ -345,7 +340,6 @@ export const SidebarPlaylistList = () => { label: t('action.viewPlaylists', { postProcess: 'sentenceCase', }), - openDelay: 500, }} variant="subtle" /> diff --git a/src/renderer/features/sidebar/components/sidebar.tsx b/src/renderer/features/sidebar/components/sidebar.tsx index c4a3b05ba..45bb19899 100644 --- a/src/renderer/features/sidebar/components/sidebar.tsx +++ b/src/renderer/features/sidebar/components/sidebar.tsx @@ -197,7 +197,6 @@ const SidebarImage = () => { label={t('player.toggleFullscreenPlayer', { postProcess: 'sentenceCase', })} - openDelay={500} > {upsizedImageUrl ? ( diff --git a/src/shared/components/tooltip/tooltip.tsx b/src/shared/components/tooltip/tooltip.tsx index 77bc4703f..d40b19f47 100644 --- a/src/shared/components/tooltip/tooltip.tsx +++ b/src/shared/components/tooltip/tooltip.tsx @@ -34,3 +34,5 @@ export const Tooltip = ({ ); }; + +Tooltip.Group = MantineTooltip.Group;