a18hvcryt: Delete the signed-in person's own post from its menu
This commit is contained in:
+34
-1
@@ -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}
|
||||
|
||||
Reference in New Issue
Block a user