From cba7cbfdfa75b9e8560ec8a6e7b6c11fdcef3ee2 Mon Sep 17 00:00:00 2001 From: jeffvli Date: Sat, 29 Nov 2025 20:18:55 -0800 Subject: [PATCH] add edit playlist to context menu --- .../actions/edit-playlist-action.tsx | 59 +++++++++++++++++++ .../menus/playlist-context-menu.tsx | 2 + 2 files changed, 61 insertions(+) create mode 100644 src/renderer/features/context-menu/actions/edit-playlist-action.tsx diff --git a/src/renderer/features/context-menu/actions/edit-playlist-action.tsx b/src/renderer/features/context-menu/actions/edit-playlist-action.tsx new file mode 100644 index 000000000..8a70df931 --- /dev/null +++ b/src/renderer/features/context-menu/actions/edit-playlist-action.tsx @@ -0,0 +1,59 @@ +import { useCallback } from 'react'; +import { useTranslation } from 'react-i18next'; + +import { api } from '/@/renderer/api'; +import { queryKeys } from '/@/renderer/api/query-keys'; +import { openUpdatePlaylistModal } from '/@/renderer/features/playlists/components/update-playlist-form'; +import { queryClient } from '/@/renderer/lib/react-query'; +import { useCurrentServer } from '/@/renderer/store'; +import { ContextMenu } from '/@/shared/components/context-menu/context-menu'; +import { toast } from '/@/shared/components/toast/toast'; +import { Playlist } from '/@/shared/types/domain-types'; + +interface EditPlaylistActionProps { + items: Playlist[]; +} + +export const EditPlaylistAction = ({ items }: EditPlaylistActionProps) => { + const { t } = useTranslation(); + const server = useCurrentServer(); + + const handleEditPlaylist = useCallback(async () => { + if (items.length === 0 || !server) return; + + // Only allow editing a single playlist at a time + const playlist = items[0]; + + try { + // Fetch the full playlist detail + const playlistDetail = await queryClient.fetchQuery({ + queryFn: ({ signal }) => + api.controller.getPlaylistDetail({ + apiClientProps: { serverId: server.id, signal }, + query: { id: playlist.id }, + }), + queryKey: queryKeys.playlists.detail(server.id, playlist.id, { id: playlist.id }), + }); + + if (playlistDetail) { + await openUpdatePlaylistModal({ + playlist: playlistDetail, + server, + }); + } + } catch (err: any) { + toast.error({ + message: err.message, + title: t('error.genericError', { postProcess: 'sentenceCase' }), + }); + } + }, [items, server, t]); + + if (items.length === 0 || items.length > 1) return null; + + return ( + + {t('action.editPlaylist', { postProcess: 'sentenceCase' })} + + ); +}; diff --git a/src/renderer/features/context-menu/menus/playlist-context-menu.tsx b/src/renderer/features/context-menu/menus/playlist-context-menu.tsx index 03728d977..4a2fb59fc 100644 --- a/src/renderer/features/context-menu/menus/playlist-context-menu.tsx +++ b/src/renderer/features/context-menu/menus/playlist-context-menu.tsx @@ -2,6 +2,7 @@ import { useMemo } from 'react'; import { AddToPlaylistAction } from '/@/renderer/features/context-menu/actions/add-to-playlist-action'; import { DeletePlaylistAction } from '/@/renderer/features/context-menu/actions/delete-playlist-action'; +import { EditPlaylistAction } from '/@/renderer/features/context-menu/actions/edit-playlist-action'; import { GetInfoAction } from '/@/renderer/features/context-menu/actions/get-info-action'; import { PlayAction } from '/@/renderer/features/context-menu/actions/play-action'; import { ContextMenu } from '/@/shared/components/context-menu/context-menu'; @@ -29,6 +30,7 @@ export const PlaylistContextMenu = ({ items, type }: PlaylistContextMenuProps) = + );