mirror of
https://github.com/jellyfin/jellyfin-web
synced 2025-03-30 19:56:21 +00:00
Add Play, Queue, Shuffle and NewCollection Buttons
This commit is contained in:
parent
d1f2f1caa0
commit
ab0ffb857c
6 changed files with 181 additions and 2 deletions
|
@ -0,0 +1,34 @@
|
|||
import React, { FC, useCallback } from 'react';
|
||||
import { IconButton } from '@mui/material';
|
||||
import AddIcon from '@mui/icons-material/Add';
|
||||
import globalize from 'scripts/globalize';
|
||||
|
||||
const NewCollectionButton: FC = () => {
|
||||
const showCollectionEditor = useCallback(() => {
|
||||
import('components/collectionEditor/collectionEditor').then(
|
||||
({ default: CollectionEditor }) => {
|
||||
const serverId = window.ApiClient.serverId();
|
||||
const collectionEditor = new CollectionEditor();
|
||||
collectionEditor.show({
|
||||
items: [],
|
||||
serverId: serverId
|
||||
}).catch(() => {
|
||||
// closed collection editor
|
||||
});
|
||||
}).catch(err => {
|
||||
console.error('[NewCollection] failed to load collection editor', err);
|
||||
});
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<IconButton
|
||||
title={globalize.translate('Add')}
|
||||
className='paper-icon-button-light btnNewCollection autoSize'
|
||||
onClick={showCollectionEditor}
|
||||
>
|
||||
<AddIcon />
|
||||
</IconButton>
|
||||
);
|
||||
};
|
||||
|
||||
export default NewCollectionButton;
|
57
src/apps/experimental/components/library/PlayAllButton.tsx
Normal file
57
src/apps/experimental/components/library/PlayAllButton.tsx
Normal file
|
@ -0,0 +1,57 @@
|
|||
import type { BaseItemDto } from '@jellyfin/sdk/lib/generated-client';
|
||||
import React, { FC, useCallback } from 'react';
|
||||
import { IconButton } from '@mui/material';
|
||||
import PlayArrowIcon from '@mui/icons-material/PlayArrow';
|
||||
|
||||
import { playbackManager } from 'components/playback/playbackmanager';
|
||||
import globalize from 'scripts/globalize';
|
||||
import { getFiltersQuery } from 'utils/items';
|
||||
import { LibraryViewSettings } from 'types/library';
|
||||
import { LibraryTab } from 'types/libraryTab';
|
||||
|
||||
interface PlayAllButtonProps {
|
||||
item: BaseItemDto | undefined;
|
||||
items: BaseItemDto[];
|
||||
viewType: LibraryTab;
|
||||
hasFilters: boolean;
|
||||
libraryViewSettings: LibraryViewSettings
|
||||
}
|
||||
|
||||
const PlayAllButton: FC<PlayAllButtonProps> = ({ item, items, viewType, hasFilters, libraryViewSettings }) => {
|
||||
const play = useCallback(() => {
|
||||
if (item && !hasFilters) {
|
||||
playbackManager.play({
|
||||
items: [item],
|
||||
autoplay: true,
|
||||
queryOptions: {
|
||||
SortBy: [libraryViewSettings.SortBy],
|
||||
SortOrder: [libraryViewSettings.SortOrder]
|
||||
}
|
||||
});
|
||||
} else {
|
||||
playbackManager.play({
|
||||
items: items,
|
||||
autoplay: true,
|
||||
queryOptions: {
|
||||
ParentId: item?.Id ?? undefined,
|
||||
...getFiltersQuery(viewType, libraryViewSettings),
|
||||
SortBy: [libraryViewSettings.SortBy],
|
||||
SortOrder: [libraryViewSettings.SortOrder]
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
}, [hasFilters, item, items, libraryViewSettings, viewType]);
|
||||
|
||||
return (
|
||||
<IconButton
|
||||
title={globalize.translate('HeaderPlayAll')}
|
||||
className='paper-icon-button-light btnPlay autoSize'
|
||||
onClick={play}
|
||||
>
|
||||
<PlayArrowIcon />
|
||||
</IconButton>
|
||||
);
|
||||
};
|
||||
|
||||
export default PlayAllButton;
|
39
src/apps/experimental/components/library/QueueButton.tsx
Normal file
39
src/apps/experimental/components/library/QueueButton.tsx
Normal file
|
@ -0,0 +1,39 @@
|
|||
import type { BaseItemDto } from '@jellyfin/sdk/lib/generated-client';
|
||||
import React, { FC, useCallback } from 'react';
|
||||
import { IconButton } from '@mui/material';
|
||||
import QueueIcon from '@mui/icons-material/Queue';
|
||||
|
||||
import { playbackManager } from 'components/playback/playbackmanager';
|
||||
import globalize from 'scripts/globalize';
|
||||
|
||||
interface QueueButtonProps {
|
||||
item: BaseItemDto | undefined
|
||||
items: BaseItemDto[];
|
||||
hasFilters: boolean;
|
||||
}
|
||||
|
||||
const QueueButton: FC<QueueButtonProps> = ({ item, items, hasFilters }) => {
|
||||
const queue = useCallback(() => {
|
||||
if (item && !hasFilters) {
|
||||
playbackManager.queue({
|
||||
items: [item]
|
||||
});
|
||||
} else {
|
||||
playbackManager.queue({
|
||||
items: items
|
||||
});
|
||||
}
|
||||
}, [hasFilters, item, items]);
|
||||
|
||||
return (
|
||||
<IconButton
|
||||
title={globalize.translate('AddToPlayQueue')}
|
||||
className='paper-icon-button-light btnQueue autoSize'
|
||||
onClick={queue}
|
||||
>
|
||||
<QueueIcon />
|
||||
</IconButton>
|
||||
);
|
||||
};
|
||||
|
||||
export default QueueButton;
|
49
src/apps/experimental/components/library/ShuffleButton.tsx
Normal file
49
src/apps/experimental/components/library/ShuffleButton.tsx
Normal file
|
@ -0,0 +1,49 @@
|
|||
import type { BaseItemDto } from '@jellyfin/sdk/lib/generated-client';
|
||||
import { ItemSortBy } from '@jellyfin/sdk/lib/models/api/item-sort-by';
|
||||
import React, { FC, useCallback } from 'react';
|
||||
import { IconButton } from '@mui/material';
|
||||
import ShuffleIcon from '@mui/icons-material/Shuffle';
|
||||
|
||||
import { playbackManager } from 'components/playback/playbackmanager';
|
||||
import globalize from 'scripts/globalize';
|
||||
import { getFiltersQuery } from 'utils/items';
|
||||
import { LibraryViewSettings } from 'types/library';
|
||||
import { LibraryTab } from 'types/libraryTab';
|
||||
|
||||
interface ShuffleButtonProps {
|
||||
item: BaseItemDto | undefined;
|
||||
items: BaseItemDto[];
|
||||
viewType: LibraryTab
|
||||
hasFilters: boolean;
|
||||
libraryViewSettings: LibraryViewSettings
|
||||
}
|
||||
|
||||
const ShuffleButton: FC<ShuffleButtonProps> = ({ item, items, viewType, hasFilters, libraryViewSettings }) => {
|
||||
const shuffle = useCallback(() => {
|
||||
if (item && !hasFilters) {
|
||||
playbackManager.shuffle(item);
|
||||
} else {
|
||||
playbackManager.play({
|
||||
items: items,
|
||||
autoplay: true,
|
||||
queryOptions: {
|
||||
ParentId: item?.Id ?? undefined,
|
||||
...getFiltersQuery(viewType, libraryViewSettings),
|
||||
SortBy: [ItemSortBy.Random]
|
||||
}
|
||||
});
|
||||
}
|
||||
}, [hasFilters, item, items, libraryViewSettings, viewType]);
|
||||
|
||||
return (
|
||||
<IconButton
|
||||
title={globalize.translate('Shuffle')}
|
||||
className='paper-icon-button-light btnShuffle autoSize'
|
||||
onClick={shuffle}
|
||||
>
|
||||
<ShuffleIcon />
|
||||
</IconButton>
|
||||
);
|
||||
};
|
||||
|
||||
export default ShuffleButton;
|
|
@ -98,7 +98,7 @@ const SortButton: FC<SortButtonProps> = ({
|
|||
title={globalize.translate('Sort')}
|
||||
sx={{ ml: 2 }}
|
||||
aria-describedby={id}
|
||||
className='paper-icon-button-light btnShuffle autoSize'
|
||||
className='paper-icon-button-light btnSort autoSize'
|
||||
onClick={handleClick}
|
||||
>
|
||||
<SortByAlphaIcon />
|
||||
|
|
|
@ -100,7 +100,7 @@ const ViewSettingsButton: FC<ViewSettingsButtonProps> = ({
|
|||
title={globalize.translate('ButtonSelectView')}
|
||||
sx={{ ml: 2 }}
|
||||
aria-describedby={id}
|
||||
className='paper-icon-button-light btnShuffle autoSize'
|
||||
className='paper-icon-button-light btnSelectView autoSize'
|
||||
onClick={handleClick}
|
||||
>
|
||||
<ViewComfyIcon />
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue