Scrapboard.org client
at labels 108 lines 3.4 kB view raw
1import { 2 Dialog, 3 DialogClose, 4 DialogContent, 5 DialogDescription, 6 DialogFooter, 7 DialogHeader, 8 DialogTitle, 9 DialogTrigger, 10} from "@/components/ui/dialog"; 11import { useAuth } from "@/lib/hooks/useAuth"; 12import { useState } from "react"; 13import { Button } from "./ui/button"; 14import { PostView } from "@atproto/api/dist/client/types/app/bsky/feed/defs"; 15import { LoaderCircle } from "lucide-react"; 16import { useBoardsStore } from "@/lib/stores/boards"; 17import { BoardsPicker } from "./BoardPicker"; 18import { toast } from "sonner"; 19import { AtUri } from "@atproto/api"; 20import { LIST_COLLECTION, LIST_ITEM_COLLECTION } from "@/constants"; 21import { FeedItem } from "./Feed"; 22import { useCurrentBoard } from "@/lib/stores/useCurrentBoard"; 23import { useBoardItemsStore } from "@/lib/stores/boardItems"; 24 25export function UnsaveButton({ 26 post, 27 image, 28}: { 29 post: PostView; 30 image: number; 31}) { 32 const { agent } = useAuth(); 33 const [isLoading, setLoading] = useState(false); 34 const [isOpen, setOpen] = useState(false); 35 const { removeBoardItem, boardItems } = useBoardItemsStore(); 36 37 if (agent == null) return <div>not logged in :(</div>; 38 return ( 39 <Dialog open={isOpen} onOpenChange={setOpen}> 40 <DialogTrigger asChild> 41 <span 42 onClick={(e) => { 43 e.stopPropagation(); 44 }} 45 className="cursor-pointer" 46 > 47 <Button size="sm" className="cursor-pointer"> 48 Remove 49 </Button> 50 </span> 51 </DialogTrigger> 52 53 <DialogContent> 54 <DialogHeader> 55 <DialogTitle>Remove from board?</DialogTitle> 56 <DialogDescription> 57 Are you sure you want to remove this from your board? 58 </DialogDescription> 59 </DialogHeader> 60 <DialogFooter> 61 <DialogClose> 62 <Button className="cursor-pointer">Cancel</Button> 63 </DialogClose> 64 <Button 65 onClick={async (e) => { 66 e.stopPropagation(); // Optional, but safe 67 68 setLoading(true); 69 try { 70 const postRkey = AtUri.make(post.uri).rkey; 71 const record = boardItems 72 .entries() 73 .find((e) => AtUri.make(e[1].url).rkey == postRkey); 74 if (!record) 75 return toast( 76 "Couldn't find post. You might be viewing stale data." 77 ); 78 79 const rkey = record[0]; 80 console.log("using rkey", rkey, "and record", record); 81 const result = await agent.com.atproto.repo.deleteRecord({ 82 collection: LIST_ITEM_COLLECTION, 83 rkey, 84 repo: agent.assertDid, 85 }); 86 87 if (result?.success) { 88 removeBoardItem(rkey); 89 toast("Removed from board"); 90 setOpen(false); 91 } else { 92 toast("Failed to remove"); 93 } 94 } finally { 95 setLoading(false); 96 } 97 }} 98 className="cursor-pointer" 99 variant="destructive" 100 > 101 {isLoading && <LoaderCircle className="animate-spin ml-2" />} 102 Remove 103 </Button> 104 </DialogFooter> 105 </DialogContent> 106 </Dialog> 107 ); 108}