v4: the followed feed's two views are pages — "From people" and "From playlists" on a feed's "follow" tab were a state of the page, which a reload, Back or a shared link lost, while a profile's same split is /@name/follow/playlists. They are now /follow and /follow/playlists, and /music/follow/playlists in a category, feedPath taking the view as userPath does (FOLLOW_VIEWS); picking a category keeps it. Their dumps come from GET /api/dumps?follow=users|playlists, signed in, which the feed's word for it names, instead of GET /api/me/feed?from=; an unknown category is a 404 there, as on the rest of the feed, rather than an empty list.
A feed's tab, as a profile's, a search's or the community page's, now takes the place of the current history entry, since it is a view of the same page; picking a category, another page, still adds one. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -12,6 +12,12 @@
|
||||
* dumps the caller may see, newest first.
|
||||
* - `GET /api/dumps?category=&page=&limit=` — optional sign-in. The same, in
|
||||
* the category with that slug; 404 when there is none.
|
||||
* - `GET /api/dumps?follow=users&category=&page=&limit=` — signed in. The
|
||||
* index's "follow" tab: a page of the public dumps of the users the caller
|
||||
* follows, newest first, optionally in one category.
|
||||
* - `GET /api/dumps?follow=playlists&category=&page=&limit=` — signed in. Its
|
||||
* `/follow/playlists` view: a page of the public dumps in the public
|
||||
* playlists the caller follows, most recently added first.
|
||||
* - `GET /api/dumps?url=` — optional sign-in. Answers the dumps already
|
||||
* pointing at the same thing as `url`, for the create form's duplicate hint.
|
||||
* - `GET /api/dumps/:dumpId` — optional sign-in. Answers a dump.
|
||||
@@ -50,7 +56,7 @@ import { toPublicUser } from "../model/user.ts";
|
||||
import { authMiddleware } from "../middleware/auth.ts";
|
||||
import { can } from "../lib/permissions.ts";
|
||||
import { parseOptionalAuth } from "../lib/auth.ts";
|
||||
import { parsePagination } from "../lib/pagination.ts";
|
||||
import { type Page, parsePagination } from "../lib/pagination.ts";
|
||||
import {
|
||||
createFileDump,
|
||||
createUrlDump,
|
||||
@@ -61,7 +67,15 @@ import {
|
||||
refreshDumpMetadata,
|
||||
updateDump,
|
||||
} from "../services/dump-service.ts";
|
||||
import { listDumpsByCategory } from "../services/category-service.ts";
|
||||
import {
|
||||
getCategoryBySlug,
|
||||
listDumpsByCategory,
|
||||
} from "../services/category-service.ts";
|
||||
import {
|
||||
getFollowedPlaylistsDumpFeed,
|
||||
getFollowedUsersDumpFeed,
|
||||
} from "../services/follow-service.ts";
|
||||
import { FOLLOW_VIEWS, type FollowView } from "../../shared/paths.ts";
|
||||
import { getDumpVoters } from "../services/vote-service.ts";
|
||||
import { getRelatedDumps } from "../services/backlink-service.ts";
|
||||
import { getPlaylistsForDump } from "../services/playlist-service.ts";
|
||||
@@ -174,9 +188,25 @@ router.get("/", async (ctx) => {
|
||||
}
|
||||
const { page, limit } = parsePagination(params);
|
||||
const category = params.get("category");
|
||||
const { items, hasMore } = category
|
||||
? listDumpsByCategory(category, page, limit, requestingUserId)
|
||||
: listDumps(page, limit, requestingUserId);
|
||||
const follow = params.get("follow");
|
||||
let feed: Page<Dump>;
|
||||
if (follow !== null) {
|
||||
if (!requestingUserId) throw new APIException(401, "Missing token");
|
||||
if (!(FOLLOW_VIEWS as readonly string[]).includes(follow)) {
|
||||
throw new APIException(400, "follow must be users or playlists");
|
||||
}
|
||||
const categoryId = category
|
||||
? getCategoryBySlug("dump", category).id
|
||||
: undefined;
|
||||
feed = (follow as FollowView) === "users"
|
||||
? getFollowedUsersDumpFeed(requestingUserId, page, limit, categoryId)
|
||||
: getFollowedPlaylistsDumpFeed(requestingUserId, page, limit, categoryId);
|
||||
} else {
|
||||
feed = category
|
||||
? listDumpsByCategory(category, page, limit, requestingUserId)
|
||||
: listDumps(page, limit, requestingUserId);
|
||||
}
|
||||
const { items, hasMore } = feed;
|
||||
const responseBody: APIResponse<PaginatedData<Dump>> = {
|
||||
success: true,
|
||||
data: { items, hasMore },
|
||||
|
||||
Reference in New Issue
Block a user