v4: what comes into a live list goes where its date puts it — a dump edited into a category stayed out of the index's feed of it until a reload, and a dump or a playlist made public went on top of the others' lists as if just posted. The index's feed now takes a dump edited into its scope, and orders the dumps that arrive by date, as the server pages them; a created playlist goes by date in the profile's and /playlists' lists, a new one first as before. Both use withByDate (utils/feed/pagedList.ts), which leaves an item older than every one loaded to a later page. The search runs again after a reconnection, for every page of dumps loaded, with its users and playlists; it shares refetchPages with usePagedList's resync. injectDump's doc said a private dump is never broadcast, while its poster gets it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
khannurien
2026-10-10 07:43:28 +00:00
parent 308a8299f3
commit 7c00db2b84
11 changed files with 278 additions and 61 deletions

View File

@@ -238,4 +238,50 @@ describe("Search", () => {
await user.click(screen.getByRole("button", { name: /Playlists/ }));
expect(screen.queryByText("Cats")).not.toBeInTheDocument();
});
test("a reconnect runs the search again, for every page loaded", async () => {
route(
"GET /api/search",
(req) =>
req.url.searchParams.get("page") === "2"
? results({ dumps: [makeDump({ title: "Second page" })] })
: results({
dumps: [makeDump({ title: "First page" })],
hasMore: true,
users: [makeUser({ username: "catlover" })],
}),
);
open("/search?q=cat");
const socket = FakeWebSocket.last;
socket.welcome();
await screen.findByText("First page");
const sentinel = FakeIntersectionObserver.instances.findLast((o) =>
o.elements.size > 0
)!;
act(() => sentinel.report(true));
await screen.findByText("Second page");
// Gone while the socket was down: an edit, a deletion, a new user.
route(
"GET /api/search",
(req) =>
req.url.searchParams.get("page") === "2"
? results({ dumps: [] })
: results({
dumps: [makeDump({ title: "First page, edited" })],
hasMore: true,
users: [
makeUser({ username: "catlover" }),
makeUser({ username: "cat2" }),
],
}),
);
socket.drop();
await act(() => new Promise((r) => setTimeout(r, 600)));
FakeWebSocket.last.welcome();
expect(await screen.findByText("First page, edited")).toBeInTheDocument();
expect(screen.queryByText("Second page")).not.toBeInTheDocument();
expect(screen.getByRole("button", { name: "Users (2)" }))
.toBeInTheDocument();
});
});