dispatch(openAddToPlaylist(t.id))}
+ />
))}
diff --git a/src/features/library/LibraryPage.tsx b/src/features/library/LibraryPage.tsx
index a4eeec8..5e7ca42 100644
--- a/src/features/library/LibraryPage.tsx
+++ b/src/features/library/LibraryPage.tsx
@@ -9,6 +9,7 @@ import {
Card,
TextField,
Callout,
+ SearchField,
} from '@olly/modern-sk';
import {
useGetTracksQuery,
@@ -31,6 +32,7 @@ import type { Track, Album, Artist } from '../../api/types';
import { getCoverUrl, getAlbumCoverUrl } from '../../api/endpoints/streaming';
import { formatDuration } from '../../lib/format';
import { useDebounce } from 'use-debounce';
+import { MagnifyingGlassIcon } from '@phosphor-icons/react';
/** Case-insensitive substring match used for client-side search while offline
* (the server can't run the query, so we filter the locally-cached library). */
@@ -143,7 +145,8 @@ export function LibraryPage() {
{t('library.title')}
- }
value={search}
onChange={(e) => setSearch(e.target.value)}
placeholder={t('library.searchPlaceholder')}
diff --git a/src/features/playlist-detail/PlaylistDetailPage.tsx b/src/features/playlist-detail/PlaylistDetailPage.tsx
index fe7f700..7e2b12d 100644
--- a/src/features/playlist-detail/PlaylistDetailPage.tsx
+++ b/src/features/playlist-detail/PlaylistDetailPage.tsx
@@ -1,9 +1,20 @@
+import { useState } from 'react';
import { useParams, useNavigate } from 'react-router';
import { useTranslation } from 'react-i18next';
-import { ScrollArea, IconButton, Button } from '@olly/modern-sk';
+import {
+ ScrollArea,
+ IconButton,
+ Button,
+ Dialog,
+ AlertDialog,
+ TextField,
+} from '@olly/modern-sk';
import {
useGetPlaylistQuery,
useGetPlaylistTracksQuery,
+ useUpdatePlaylistMutation,
+ useDeletePlaylistMutation,
+ useRemoveTrackFromPlaylistMutation,
} from '../../api/endpoints/playlists';
import { TrackRow } from '../../components/track/TrackRow';
import { LoadingSkeleton } from '../../components/common/LoadingSkeleton';
@@ -11,6 +22,7 @@ import { ErrorState } from '../../components/common/ErrorState';
import { EmptyState } from '../../components/common/EmptyState';
import { useAppDispatch } from '../../hooks/useAppDispatch';
import { setQueue } from '../../store/slices/queue';
+import { openAddToPlaylist } from '../../store/slices/ui';
import { formatDuration } from '../../lib/format';
export function PlaylistDetailPage() {
@@ -25,6 +37,13 @@ export function PlaylistDetailPage() {
const tracksQuery = useGetPlaylistTracksQuery(playlistId ?? '', {
skip: !playlistId,
});
+ const [updatePlaylist] = useUpdatePlaylistMutation();
+ const [deletePlaylist] = useDeletePlaylistMutation();
+ const [removeTrackFromPlaylist] = useRemoveTrackFromPlaylistMutation();
+
+ const [renameOpen, setRenameOpen] = useState(false);
+ const [renameValue, setRenameValue] = useState('');
+ const [deleteOpen, setDeleteOpen] = useState(false);
if (playlistQuery.isLoading) {
return (
@@ -124,6 +143,23 @@ export function PlaylistDetailPage() {
`${playlist.trackCount} · ${formatDuration(playlist.totalDurationMs)}`}
+ {playlist && (
+ <>
+
+
+ >
+ )}