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:
@@ -111,9 +111,15 @@ export function dumpPath(dump: OwnedItem, view?: "edit"): string {
|
||||
return view ? `${path}/${view}` : path;
|
||||
}
|
||||
|
||||
/** Returns the path of a playlist's page, `/@owner/playlists/<slug>`. */
|
||||
export function playlistPath(playlist: OwnedItem): string {
|
||||
return `${userPath(playlist.ownerUsername)}/playlists/${seg(playlist.slug)}`;
|
||||
/**
|
||||
* Returns the path of a playlist's page, `/@owner/playlists/<slug>`, or of
|
||||
* the page with its editor open, one segment more.
|
||||
*/
|
||||
export function playlistPath(playlist: OwnedItem, view?: "edit"): string {
|
||||
const path = `${userPath(playlist.ownerUsername)}/playlists/${
|
||||
seg(playlist.slug)
|
||||
}`;
|
||||
return view ? `${path}/${view}` : path;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -171,11 +177,11 @@ export function communityPath(view: DigestCadence = "weekly"): string {
|
||||
export type PagePath =
|
||||
| { kind: "user"; username: string; rest: string[] }
|
||||
| { kind: "dump"; username: string; slug: string; edit: boolean }
|
||||
| { kind: "playlist"; username: string; slug: string };
|
||||
| { kind: "playlist"; username: string; slug: string; edit: boolean };
|
||||
|
||||
/**
|
||||
* Returns what a page path under a user names: a profile (with its tab), a
|
||||
* dump (or its editor) or a playlist. It returns null for any other path, a
|
||||
* dump or a playlist (or its editor). It returns null for any other path, a
|
||||
* feed or an app page, and for one under a user that no page answers. The
|
||||
* names are decoded but not looked up, so the user or the item may not exist.
|
||||
*/
|
||||
@@ -195,18 +201,11 @@ export function parsePagePath(pathname: string): PagePath | null {
|
||||
const username = handle.slice(1);
|
||||
|
||||
if ((section === "dumps" || section === "playlists") && slug) {
|
||||
if (section === "dumps" && more.length <= 1) {
|
||||
if (more.length === 0) {
|
||||
return { kind: "dump", username, slug, edit: false };
|
||||
}
|
||||
if (more[0] === "edit") {
|
||||
return { kind: "dump", username, slug, edit: true };
|
||||
}
|
||||
if (more.length > 1 || (more.length === 1 && more[0] !== "edit")) {
|
||||
return null;
|
||||
}
|
||||
if (section === "playlists" && more.length === 0) {
|
||||
return { kind: "playlist", username, slug };
|
||||
}
|
||||
return null;
|
||||
const kind = section === "dumps" ? "dump" : "playlist";
|
||||
return { kind, username, slug, edit: more.length === 1 };
|
||||
}
|
||||
|
||||
const rest = segments.slice(1);
|
||||
|
||||
Reference in New Issue
Block a user