redesign queue controls bar

This commit is contained in:
jeffvli
2026-04-04 14:24:56 -07:00
parent 3a0dfe59ce
commit 99530c670e
2 changed files with 84 additions and 50 deletions
@@ -16,6 +16,8 @@ import { SearchInput } from '/@/renderer/features/shared/components/search-input
import { useCurrentServer, usePlayerStoreBase } from '/@/renderer/store'; import { useCurrentServer, usePlayerStoreBase } from '/@/renderer/store';
import { hasFeature } from '/@/shared/api/utils'; import { hasFeature } from '/@/shared/api/utils';
import { ActionIcon } from '/@/shared/components/action-icon/action-icon'; import { ActionIcon } from '/@/shared/components/action-icon/action-icon';
import { Box } from '/@/shared/components/box/box';
import { Divider } from '/@/shared/components/divider/divider';
import { Group } from '/@/shared/components/group/group'; import { Group } from '/@/shared/components/group/group';
import { ServerFeature } from '/@/shared/types/features-types'; import { ServerFeature } from '/@/shared/types/features-types';
import { ItemListKey, ListDisplayType } from '/@/shared/types/types'; import { ItemListKey, ListDisplayType } from '/@/shared/types/types';
@@ -33,6 +35,52 @@ export const PlayQueueListControls = ({
tableRef, tableRef,
type, type,
}: PlayQueueListOptionsProps) => { }: PlayQueueListOptionsProps) => {
return (
<Group
align="center"
gap="sm"
justify="flex-start"
px="md"
py="xs"
style={{ borderBottom: '1px solid var(--theme-colors-border)' }}
w="100%"
wrap="nowrap"
>
<Group gap="xs" style={{ flexShrink: 0 }} wrap="nowrap">
<QueueRestoreActions />
<QueuePlaybackIcons tableRef={tableRef} />
</Group>
<Divider h="60%" orientation="vertical" style={{ alignSelf: 'center' }} />
<Box style={{ display: 'flex', flex: 1, minWidth: 0 }}>
<SearchInput
enableHotkey={false}
fillContainer
onChange={(e) => handleSearch(e.target.value)}
value={searchTerm}
/>
</Box>
<Divider h="60%" orientation="vertical" style={{ alignSelf: 'center' }} />
<Box style={{ flexShrink: 0 }}>
<ListConfigMenu
displayTypes={[
{ hidden: true, value: ListDisplayType.GRID },
...SONG_DISPLAY_TYPES,
]}
listKey={type}
optionsConfig={{
table: {
itemsPerPage: { hidden: true },
pagination: { hidden: true },
},
}}
tableColumnsData={SONG_TABLE_COLUMNS}
/>
</Box>
</Group>
);
};
const QueuePlaybackIcons = ({ tableRef }: { tableRef: RefObject<ItemListHandle | null> }) => {
const { t } = useTranslation(); const { t } = useTranslation();
const player = usePlayer(); const player = usePlayer();
@@ -52,53 +100,29 @@ export const PlayQueueListControls = ({
}; };
return ( return (
<Group h="65px" justify="space-between" px="1rem" py="1rem" w="100%"> <>
<Group gap="xs"> <ActionIcon
<QueueRestoreActions /> icon="mediaShuffle"
<ActionIcon iconProps={{ size: 'lg' }}
icon="mediaShuffle" onClick={handleShuffleQueue}
iconProps={{ size: 'lg' }} tooltip={{ label: t('player.shuffle', { postProcess: 'sentenceCase' }) }}
onClick={handleShuffleQueue} variant="subtle"
tooltip={{ label: t('player.shuffle', { postProcess: 'sentenceCase' }) }} />
variant="subtle" <ActionIcon
/> icon="x"
<ActionIcon iconProps={{ size: 'lg' }}
icon="x" onClick={handleClearQueue}
iconProps={{ size: 'lg' }} tooltip={{ label: t('action.clearQueue', { postProcess: 'sentenceCase' }) }}
onClick={handleClearQueue} variant="subtle"
tooltip={{ label: t('action.clearQueue', { postProcess: 'sentenceCase' }) }} />
variant="subtle" <ActionIcon
/> icon="goToItem"
<ActionIcon iconProps={{ size: 'lg' }}
icon="goToItem" onClick={handleJumpToCurrent}
iconProps={{ size: 'lg' }} tooltip={{ label: t('action.goToCurrent', { postProcess: 'sentenceCase' }) }}
onClick={handleJumpToCurrent} variant="subtle"
tooltip={{ label: t('action.goToCurrent', { postProcess: 'sentenceCase' }) }} />
variant="subtle" </>
/>
</Group>
<Group gap="xs">
<SearchInput
enableHotkey={false}
onChange={(e) => handleSearch(e.target.value)}
value={searchTerm}
/>
<ListConfigMenu
displayTypes={[
{ hidden: true, value: ListDisplayType.GRID },
...SONG_DISPLAY_TYPES,
]}
listKey={type}
optionsConfig={{
table: {
itemsPerPage: { hidden: true },
pagination: { hidden: true },
},
}}
tableColumnsData={SONG_TABLE_COLUMNS}
/>
</Group>
</Group>
); );
}; };
@@ -19,6 +19,7 @@ import { useHotkeys } from '/@/shared/hooks/use-hotkeys';
interface SearchInputProps extends TextInputProps { interface SearchInputProps extends TextInputProps {
buttonProps?: Partial<ActionIconProps>; buttonProps?: Partial<ActionIconProps>;
enableHotkey?: boolean; enableHotkey?: boolean;
fillContainer?: boolean;
inputProps?: Partial<TextInputProps>; inputProps?: Partial<TextInputProps>;
value?: string; value?: string;
} }
@@ -26,6 +27,7 @@ interface SearchInputProps extends TextInputProps {
export const SearchInput = ({ export const SearchInput = ({
buttonProps, buttonProps,
enableHotkey = true, enableHotkey = true,
fillContainer = false,
inputProps, inputProps,
onChange, onChange,
...props ...props
@@ -104,9 +106,17 @@ export const SearchInput = ({
overflow: 'hidden', overflow: 'hidden',
position: 'relative', position: 'relative',
transition: 'width 0.3s ease-in-out', transition: 'width 0.3s ease-in-out',
width: shouldExpand ? '200px' : '36px', ...(fillContainer
? {
flex: '1 1 0',
minWidth: 0,
width: shouldExpand ? '100%' : '36px',
}
: {
width: shouldExpand ? '200px' : '36px',
}),
}), }),
[shouldExpand], [fillContainer, shouldExpand],
); );
const buttonStyle: CSSProperties = useMemo( const buttonStyle: CSSProperties = useMemo(
@@ -135,7 +145,7 @@ export const SearchInput = ({
<Box style={containerStyle}> <Box style={containerStyle}>
<TextInput <TextInput
leftSection={<Icon icon="search" />} leftSection={<Icon icon="search" />}
maw="20dvw" maw={fillContainer ? '100%' : '20dvw'}
{...inputProps} {...inputProps}
onBlur={handleBlur} onBlur={handleBlur}
onChange={onChange} onChange={onChange}