v4: a playlist's editor has a URL, as a dump's has — it opened over the playlist's header as a state of the page, which a reload or a shared link lost, while a dump's editor is /@name/dumps/<slug>/edit. It is now /@name/playlists/<slug>/edit: Edit goes there, and Cancel or Save come back to the page in its place. Both paths render PlaylistDetail at the same place, so the playlist stays loaded, and a new slug keeps the view. Anyone who may not edit it gets the page, a guest the sign-in first. playlistPath takes the view, and parsePagePath reads it, so its link has no preview, as a dump editor's has none.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
khannurien
2026-10-09 22:22:24 +00:00
parent 21f4db268e
commit 9a215b0cc5
10 changed files with 130 additions and 46 deletions

View File

@@ -66,7 +66,18 @@ Deno.test("parsePagePath: what a path under a user names", () => {
kind: "playlist",
username: "bob",
slug: "mix",
edit: false,
});
assertEquals(parsePagePath("/@bob/playlists/mix/edit"), {
kind: "playlist",
username: "bob",
slug: "mix",
edit: true,
});
assertEquals(
playlistPath({ ownerUsername: "bob", slug: "mix" }, "edit"),
"/@bob/playlists/mix/edit",
);
for (
const other of [
"/",
@@ -78,7 +89,7 @@ Deno.test("parsePagePath: what a path under a user names", () => {
"/@bob/nope",
"/@bob/follow/users",
"/@bob/dumps/x/y",
"/@bob/playlists/x/edit",
"/@bob/playlists/x/y",
"/@bob/%E0%A4%A",
]
) {
@@ -96,6 +107,7 @@ Deno.test("handles: a user from another instance is /@name@host", () => {
kind: "playlist",
username: "alice@music.example",
slug: "mix",
edit: false,
});
assertEquals(parsePagePath("/@alice%40music.example"), {
kind: "user",