Compare commits

...

1 Commits

Author SHA1 Message Date
Nikita
c970eec586 allow deleting tracks and playlists 2025-03-10 14:08:50 +01:00
3 changed files with 57 additions and 6 deletions

View File

@@ -194,3 +194,16 @@ export async function onAnonymousAccountDiscarded(
me.root.rootPlaylist.tracks.push(track);
}
}
export async function deletePlaylist(playlistId: string) {
const { root } = await MusicaAccount.getMe().ensureLoaded({
root: {
playlists: [],
},
});
const index = root.playlists.findIndex((p) => p?.id === playlistId);
if (index > -1) {
root.playlists.splice(index, 1);
}
}

View File

@@ -52,6 +52,16 @@ export function MusicTrackRow({
removeTrackFromPlaylist(playlist, track);
}
function deleteTrack() {
if (!me || !track) return;
const tracks = me.root.rootPlaylist?.tracks;
if (!tracks) return;
const index = tracks.findIndex((t) => t?.id === trackId);
if (index !== -1) {
tracks.splice(index, 1);
}
}
return (
<li
className={
@@ -90,6 +100,15 @@ export function MusicTrackRow({
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="end">
<DropdownMenuItem
key={`delete`}
onSelect={async () => {
if (!track) return;
deleteTrack();
}}
>
Delete
</DropdownMenuItem>
{playlists.map((playlist, index) => (
<Fragment key={index}>
<DropdownMenuItem

View File

@@ -1,4 +1,6 @@
import { deletePlaylist } from "@/4_actions";
import { useAccount } from "jazz-react";
import { Trash2 } from "lucide-react";
import { useNavigate, useParams } from "react-router";
import { LocalOnlyTag } from "./LocalOnlyTag";
@@ -24,6 +26,13 @@ export function SidePanel() {
navigate(`/playlist/${playlistId}`);
}
async function handleDeletePlaylist(playlistId: string) {
if (confirm("Are you sure you want to delete this playlist?")) {
await deletePlaylist(playlistId);
navigate(`/`);
}
}
return (
<aside className="w-64 p-6 bg-white overflow-y-auto">
<div className="flex items-center mb-1">
@@ -65,18 +74,28 @@ export function SidePanel() {
</a>
</li>
{me?.root.playlists.map((playlist, index) => (
<li key={index}>
<li
key={index}
className={`px-2 py-1 flex transition-all duration-300 rounded items-center justify-between ${
playlist.id === playlistId ? "bg-blue-100" : ""
}`}
>
<a
href="#"
className={`block px-2 py-1 text-sm rounded ${
playlist.id === playlistId
? "bg-blue-100 text-blue-600"
: "hover:bg-blue-100"
}`}
className={`w-full text-sm`}
onClick={(evt) => handlePlaylistClick(evt, playlist.id)}
>
{playlist.title}
</a>
{playlist.id === playlistId && (
<button
onClick={() => handleDeletePlaylist(playlist.id)}
className="ml-2 text-red-600 hover:text-red-800 animate-in fade-in scale-in duration-200"
aria-label={`Delete ${playlist.title}`}
>
<Trash2 size={16} />
</button>
)}
</li>
))}
</ul>