diff --git a/src/renderer/features/shared/components/library-header-bar.tsx b/src/renderer/features/shared/components/library-header-bar.tsx
index a5949298a..588cd99a7 100644
--- a/src/renderer/features/shared/components/library-header-bar.tsx
+++ b/src/renderer/features/shared/components/library-header-bar.tsx
@@ -1,11 +1,18 @@
-import { ReactNode } from 'react';
+import { closeAllModals, openModal } from '@mantine/modals';
+import { ReactNode, useCallback } from 'react';
+import { useTranslation } from 'react-i18next';
import styles from './library-header-bar.module.css';
-import { PlayButton, PlayButtonProps } from '/@/renderer/features/shared/components/play-button';
+import { usePlayer } from '/@/renderer/features/player/context/player-context';
+import { PlayButton } from '/@/renderer/features/shared/components/play-button';
+import { PlayButtonGroup } from '/@/renderer/features/shared/components/play-button-group';
+import { useCurrentServerId } from '/@/renderer/store';
import { Badge, BadgeProps } from '/@/shared/components/badge/badge';
import { Spinner } from '/@/shared/components/spinner/spinner';
import { TextTitle } from '/@/shared/components/text-title/text-title';
+import { LibraryItem } from '/@/shared/types/domain-types';
+import { Play } from '/@/shared/types/types';
interface LibraryHeaderBarProps {
children: ReactNode;
@@ -15,14 +22,43 @@ export const LibraryHeaderBar = ({ children }: LibraryHeaderBarProps) => {
return
{children}
;
};
+interface HeaderPlayButtonProps {
+ className?: string;
+ itemType: LibraryItem;
+ query: Record;
+}
+
interface TitleProps {
children: ReactNode;
}
-const HeaderPlayButton = ({ className, ...props }: PlayButtonProps) => {
+const HeaderPlayButton = ({ className, itemType, query, ...props }: HeaderPlayButtonProps) => {
+ const serverId = useCurrentServerId();
+ const { t } = useTranslation();
+ const player = usePlayer();
+
+ const handlePlay = useCallback(
+ (playType: Play) => {
+ if (!serverId) return;
+ player.addToQueueByListQuery(serverId, query, itemType, playType);
+ closeAllModals();
+ },
+ [serverId, query, itemType, player],
+ );
+
+ const openPlayTypeModal = useCallback(() => {
+ if (!serverId) return;
+
+ openModal({
+ children: ,
+ size: 'xs',
+ title: t('player.play', { postProcess: 'titleCase' }),
+ });
+ }, [serverId, handlePlay, t]);
+
return (
);
};
diff --git a/src/renderer/features/shared/components/play-button-group.tsx b/src/renderer/features/shared/components/play-button-group.tsx
new file mode 100644
index 000000000..0d5258dab
--- /dev/null
+++ b/src/renderer/features/shared/components/play-button-group.tsx
@@ -0,0 +1,59 @@
+import i18n from '/@/i18n/i18n';
+import { ActionIcon } from '/@/shared/components/action-icon/action-icon';
+import { Group } from '/@/shared/components/group/group';
+import { AppIconSelection } from '/@/shared/components/icon/icon';
+import { Play } from '/@/shared/types/types';
+
+const playButtons: { icon: AppIconSelection; label: string; type: Play }[] = [
+ {
+ icon: 'mediaPlay',
+ label: i18n.t('player.play', { postProcess: 'sentenceCase' }),
+ type: Play.NOW,
+ },
+ {
+ icon: 'mediaPlayNext',
+ label: i18n.t('player.addNext', { postProcess: 'sentenceCase' }),
+ type: Play.NEXT,
+ },
+ {
+ icon: 'mediaPlayLast',
+ label: i18n.t('player.addLast', { postProcess: 'sentenceCase' }),
+ type: Play.LAST,
+ },
+ {
+ icon: 'mediaShuffle',
+ label: i18n.t('player.shuffle', { postProcess: 'sentenceCase' }),
+ type: Play.SHUFFLE,
+ },
+];
+
+interface PlayButtonGroupProps {
+ onPlay: (type: Play) => void;
+}
+
+export const PlayButtonGroup = ({ onPlay }: PlayButtonGroupProps) => {
+ return (
+
+ {playButtons.map((button) => (
+ onPlay(button.type)}
+ styles={{
+ root: {
+ padding: 'var(--mantine-spacing-lg)',
+ },
+ }}
+ tooltip={{
+ label: button.label,
+ openDelay: 0,
+ }}
+ variant="default"
+ />
+ ))}
+
+ );
+};