Retro Bulletin Board Systems on atproto. Web app and TUI.
lazy mirror of alyraffauf/atbbs
atbbs.xyz
forums
python
tui
atproto
bbs
1import { queryClient } from "./queryClient";
2import { threadPageQuery, threadRefsQuery } from "./queries";
3import { REPLIES_PER_PAGE, refToUri } from "./replies";
4import type { BacklinkRef } from "./atproto";
5import type { ReplyPage } from "./thread";
6import type { Reply } from "../components/post/ReplyCard";
7
8export async function cancelRefsRefetch(threadUri: string) {
9 await queryClient.cancelQueries({
10 queryKey: threadRefsQuery(threadUri).queryKey,
11 });
12}
13
14export function getRefs(threadUri: string): BacklinkRef[] {
15 const key = threadRefsQuery(threadUri).queryKey;
16 return queryClient.getQueryData<BacklinkRef[]>(key) ?? [];
17}
18
19export function setRefs(threadUri: string, refs: BacklinkRef[]) {
20 queryClient.setQueryData(threadRefsQuery(threadUri).queryKey, refs);
21}
22
23function pageSlice(refs: BacklinkRef[], page: number): BacklinkRef[] {
24 const start = (page - 1) * REPLIES_PER_PAGE;
25 return refs.slice(start, start + REPLIES_PER_PAGE);
26}
27
28// threadPageQuery's key is fingerprinted by rkeys, so the key changes on
29// add/delete — seed the new key from the old one rather than using `prev`.
30export function appendRefAndReply(
31 threadUri: string,
32 newRef: BacklinkRef,
33 newReply: Reply,
34): BacklinkRef[] {
35 const previousRefs = getRefs(threadUri);
36 const updatedRefs = [...previousRefs, newRef];
37
38 const newLastPage = Math.max(
39 1,
40 Math.ceil(updatedRefs.length / REPLIES_PER_PAGE),
41 );
42 const oldPageRefs = pageSlice(previousRefs, newLastPage);
43 const oldKey = threadPageQuery(threadUri, newLastPage, oldPageRefs).queryKey;
44 const oldData = queryClient.getQueryData<ReplyPage>(oldKey);
45
46 setRefs(threadUri, updatedRefs);
47
48 const pageRefs = pageSlice(updatedRefs, newLastPage);
49 const newKey = threadPageQuery(threadUri, newLastPage, pageRefs).queryKey;
50 queryClient.setQueryData<ReplyPage>(newKey, {
51 replies: [...(oldData?.replies ?? []), newReply],
52 parentReplies: oldData?.parentReplies ?? {},
53 });
54
55 return updatedRefs;
56}
57
58export function removeRefAndReply(
59 threadUri: string,
60 replyUri: string,
61 currentPage: number,
62) {
63 const previousRefs = getRefs(threadUri);
64 const oldPageRefs = pageSlice(previousRefs, currentPage);
65 const oldKey = threadPageQuery(threadUri, currentPage, oldPageRefs).queryKey;
66 const oldData = queryClient.getQueryData<ReplyPage>(oldKey);
67
68 const updatedRefs = previousRefs.filter((ref) => refToUri(ref) !== replyUri);
69 setRefs(threadUri, updatedRefs);
70
71 if (!oldData) return;
72 const pageRefs = pageSlice(updatedRefs, currentPage);
73 const newKey = threadPageQuery(threadUri, currentPage, pageRefs).queryKey;
74 queryClient.setQueryData<ReplyPage>(newKey, {
75 ...oldData,
76 replies: oldData.replies.filter((r) => r.uri !== replyUri),
77 });
78}