Add option to play similar tracks from the context menu (#650)

* Add option to play similar songs from context menu

* remove console.log
This commit is contained in:
isaiahfuller 2024-07-03 04:17:56 -04:00 committed by GitHub
parent b30fadd149
commit 0768ce80a7
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 32 additions and 4 deletions

View file

@ -322,6 +322,7 @@
"moveToTop": "$t(action.moveToTop)", "moveToTop": "$t(action.moveToTop)",
"numberSelected": "{{count}} selected", "numberSelected": "{{count}} selected",
"play": "$t(player.play)", "play": "$t(player.play)",
"playSimilarSongs": "$t(player.playSimilarSongs)",
"removeFromFavorites": "$t(action.removeFromFavorites)", "removeFromFavorites": "$t(action.removeFromFavorites)",
"removeFromPlaylist": "$t(action.removeFromPlaylist)", "removeFromPlaylist": "$t(action.removeFromPlaylist)",
"removeFromQueue": "$t(action.removeFromQueue)", "removeFromQueue": "$t(action.removeFromQueue)",
@ -416,6 +417,7 @@
"playbackFetchNoResults": "no songs found", "playbackFetchNoResults": "no songs found",
"playbackSpeed": "playback speed", "playbackSpeed": "playback speed",
"playRandom": "play random", "playRandom": "play random",
"playSimilarSongs": "play similar songs",
"previous": "previous", "previous": "previous",
"queue_clear": "clear queue", "queue_clear": "clear queue",
"queue_moveToBottom": "move selected to top", "queue_moveToBottom": "move selected to top",

View file

@ -15,7 +15,8 @@ export const QUEUE_CONTEXT_MENU_ITEMS: SetContextMenuItems = [
export const SONG_CONTEXT_MENU_ITEMS: SetContextMenuItems = [ export const SONG_CONTEXT_MENU_ITEMS: SetContextMenuItems = [
{ id: 'play' }, { id: 'play' },
{ id: 'playLast' }, { id: 'playLast' },
{ divider: true, id: 'playNext' }, { id: 'playNext' },
{ divider: true, id: 'playSimilarSongs' },
{ divider: true, id: 'addToPlaylist' }, { divider: true, id: 'addToPlaylist' },
{ id: 'addToFavorites' }, { id: 'addToFavorites' },
{ divider: true, id: 'removeFromFavorites' }, { divider: true, id: 'removeFromFavorites' },
@ -34,7 +35,8 @@ export const SONG_ALBUM_PAGE: SetContextMenuItems = [
export const PLAYLIST_SONG_CONTEXT_MENU_ITEMS: SetContextMenuItems = [ export const PLAYLIST_SONG_CONTEXT_MENU_ITEMS: SetContextMenuItems = [
{ id: 'play' }, { id: 'play' },
{ id: 'playLast' }, { id: 'playLast' },
{ divider: true, id: 'playNext' }, { id: 'playNext' },
{ divider: true, id: 'playSimilarSongs' },
{ id: 'addToPlaylist' }, { id: 'addToPlaylist' },
{ divider: true, id: 'removeFromPlaylist' }, { divider: true, id: 'removeFromPlaylist' },
{ id: 'addToFavorites' }, { id: 'addToFavorites' },
@ -46,7 +48,8 @@ export const PLAYLIST_SONG_CONTEXT_MENU_ITEMS: SetContextMenuItems = [
export const SMART_PLAYLIST_SONG_CONTEXT_MENU_ITEMS: SetContextMenuItems = [ export const SMART_PLAYLIST_SONG_CONTEXT_MENU_ITEMS: SetContextMenuItems = [
{ id: 'play' }, { id: 'play' },
{ id: 'playLast' }, { id: 'playLast' },
{ divider: true, id: 'playNext' }, { id: 'playNext' },
{ divider: true, id: 'playSimilarSongs' },
{ divider: true, id: 'addToPlaylist' }, { divider: true, id: 'addToPlaylist' },
{ id: 'addToFavorites' }, { id: 'addToFavorites' },
{ divider: true, id: 'removeFromFavorites' }, { divider: true, id: 'removeFromFavorites' },

View file

@ -29,6 +29,7 @@ import {
RiCloseCircleLine, RiCloseCircleLine,
RiShareForwardFill, RiShareForwardFill,
RiInformationFill, RiInformationFill,
RiRadio2Fill,
} from 'react-icons/ri'; } from 'react-icons/ri';
import { AnyLibraryItems, LibraryItem, ServerType, AnyLibraryItem } from '/@/renderer/api/types'; import { AnyLibraryItems, LibraryItem, ServerType, AnyLibraryItem } from '/@/renderer/api/types';
import { import {
@ -50,6 +51,7 @@ import { useDeletePlaylist } from '/@/renderer/features/playlists';
import { useRemoveFromPlaylist } from '/@/renderer/features/playlists/mutations/remove-from-playlist-mutation'; import { useRemoveFromPlaylist } from '/@/renderer/features/playlists/mutations/remove-from-playlist-mutation';
import { useCreateFavorite, useDeleteFavorite, useSetRating } from '/@/renderer/features/shared'; import { useCreateFavorite, useDeleteFavorite, useSetRating } from '/@/renderer/features/shared';
import { import {
getServerById,
useAuthStore, useAuthStore,
useCurrentServer, useCurrentServer,
usePlayerStore, usePlayerStore,
@ -58,6 +60,7 @@ import {
import { usePlaybackType } from '/@/renderer/store/settings.store'; import { usePlaybackType } from '/@/renderer/store/settings.store';
import { Play, PlaybackType } from '/@/renderer/types'; import { Play, PlaybackType } from '/@/renderer/types';
import { ItemDetailsModal } from '/@/renderer/features/item-details/components/item-details-modal'; import { ItemDetailsModal } from '/@/renderer/features/item-details/components/item-details-modal';
import { controller } from '/@/renderer/api/controller';
type ContextMenuContextProps = { type ContextMenuContextProps = {
closeContextMenu: () => void; closeContextMenu: () => void;
@ -658,6 +661,18 @@ export const ContextMenuProvider = ({ children }: ContextMenuProviderProps) => {
}); });
}, [ctx.data, t]); }, [ctx.data, t]);
const handleSimilar = useCallback(async () => {
const item = ctx.data[0];
const songs = await controller.getSimilarSongs({
apiClientProps: {
server: getServerById(item.serverId),
signal: undefined,
},
query: { albumArtistIds: item.albumArtistIds, songId: item.id },
});
handlePlayQueueAdd?.({ byData: [ctx.data[0], ...songs], playType: Play.NOW });
}, [ctx, handlePlayQueueAdd]);
const contextMenuItems: Record<ContextMenuItemType, ContextMenuItem> = useMemo(() => { const contextMenuItems: Record<ContextMenuItemType, ContextMenuItem> = useMemo(() => {
return { return {
addToFavorites: { addToFavorites: {
@ -719,6 +734,12 @@ export const ContextMenuProvider = ({ children }: ContextMenuProviderProps) => {
leftIcon: <RiAddCircleFill size="1.1rem" />, leftIcon: <RiAddCircleFill size="1.1rem" />,
onClick: () => handlePlay(Play.NEXT), onClick: () => handlePlay(Play.NEXT),
}, },
playSimilarSongs: {
id: 'playSimilarSongs',
label: t('page.contextMenu.playSimilarSongs', { postProcess: 'sentenceCase' }),
leftIcon: <RiRadio2Fill size="1.1rem" />,
onClick: handleSimilar,
},
removeFromFavorites: { removeFromFavorites: {
id: 'removeFromFavorites', id: 'removeFromFavorites',
label: t('page.contextMenu.removeFromFavorites', { postProcess: 'sentenceCase' }), label: t('page.contextMenu.removeFromFavorites', { postProcess: 'sentenceCase' }),
@ -838,6 +859,7 @@ export const ContextMenuProvider = ({ children }: ContextMenuProviderProps) => {
handleUpdateRating, handleUpdateRating,
handleShareItem, handleShareItem,
server, server,
handleSimilar,
]); ]);
const mergedRef = useMergedRef(ref, clickOutsideRef); const mergedRef = useMergedRef(ref, clickOutsideRef);

View file

@ -35,7 +35,8 @@ export type ContextMenuItemType =
| 'moveToTopOfQueue' | 'moveToTopOfQueue'
| 'removeFromQueue' | 'removeFromQueue'
| 'deselectAll' | 'deselectAll'
| 'showDetails'; | 'showDetails'
| 'playSimilarSongs';
export type SetContextMenuItems = { export type SetContextMenuItems = {
children?: boolean; children?: boolean;