a18hvcryt: Delete the signed-in person's own post from its menu

This commit is contained in:
2026-10-19 14:32:06 -06:00
parent 5a33546af2
commit 0861663bea
14 changed files with 383 additions and 8 deletions
+34 -1
View File
@@ -5,11 +5,12 @@ import { fetchFeedPage, FeedLoadError } from "@/lib/feed-client";
import { applyLikeOutcome, LikeError, sendLike } from "@/lib/like-client";
import { mergePosts, toCardPosts, type CardPost } from "@/lib/feed-model";
import { PostError, publishAndConfirm } from "@/lib/post-client";
import { DeleteError, sendDelete } from "@/lib/delete-client";
import { FeedView, type FeedStatus } from "./FeedView";
const POLL_MS = 45_000;
export function Feed({ onSignedOut }: { onSignedOut: () => void }) {
export function Feed({ onSignedOut, feedUserId }: { onSignedOut: () => void; feedUserId?: string | null }) {
const [posts, setPosts] = useState<CardPost[]>([]);
const [status, setStatus] = useState<FeedStatus>("loading");
const [nextCursor, setNextCursor] = useState<string | null>(null);
@@ -18,6 +19,8 @@ export function Feed({ onSignedOut }: { onSignedOut: () => void }) {
const [pending, setPending] = useState<CardPost[]>([]);
const [likeBusy, setLikeBusy] = useState<ReadonlySet<string>>(new Set());
const [likeErrors, setLikeErrors] = useState<ReadonlySet<string>>(new Set());
const [deleteBusy, setDeleteBusy] = useState<ReadonlySet<string>>(new Set());
const [deleteErrors, setDeleteErrors] = useState<ReadonlySet<string>>(new Set());
const [draft, setDraft] = useState("");
const [posting, setPosting] = useState(false);
const [postFailed, setPostFailed] = useState(false);
@@ -156,6 +159,32 @@ export function Feed({ onSignedOut }: { onSignedOut: () => void }) {
[fail],
);
const removePost = useCallback(
async (post: CardPost) => {
const mark = (set: ReadonlySet<string>, on: boolean) => {
const next = new Set(set);
if (on) next.add(post.key);
else next.delete(post.key);
return next;
};
setDeleteBusy((s) => mark(s, true));
setDeleteErrors((s) => mark(s, false));
try {
// Removes the card only after the feed answered 200.
if (!post.id) throw new DeleteError(false);
await sendDelete(post.id);
setPosts((cur) => cur.filter((p) => p.key !== post.key));
setPending((cur) => cur.filter((p) => p.key !== post.key));
} catch (e) {
if (e instanceof DeleteError && e.signedOut) onSignedOut();
setDeleteErrors((s) => mark(s, true));
} finally {
setDeleteBusy((s) => mark(s, false));
}
},
[onSignedOut],
);
const publish = useCallback(async () => {
const text = draft.trim();
if (!text || posting) return;
@@ -199,6 +228,10 @@ export function Feed({ onSignedOut }: { onSignedOut: () => void }) {
onToggleLike={(p) => void toggleLike(p)}
likeBusy={likeBusy}
likeErrors={likeErrors}
feedUserId={feedUserId}
onDelete={(p) => void removePost(p)}
deleteBusy={deleteBusy}
deleteErrors={deleteErrors}
onSignedOut={onSignedOut}
composer={{ value: draft, busy: posting, error: postFailed, onChange: changeDraft, onSubmit: () => void publish() }}
sentinelRef={sentinel}