Hey is a decentralized and permissionless social media app built with Lens Protocol 馃尶
1import type { ApolloCache, NormalizedCacheObject } from "@apollo/client";
2import { MenuItem } from "@headlessui/react";
3import { EyeIcon, EyeSlashIcon } from "@heroicons/react/24/outline";
4import {
5 type PostFragment,
6 type PostNotInterestedRequest,
7 useAddPostNotInterestedMutation,
8 useUndoPostNotInterestedMutation
9} from "@hey/indexer";
10import type { ApolloClientError } from "@hey/types/errors";
11import { useCallback } from "react";
12import { toast } from "sonner";
13import cn from "@/helpers/cn";
14import errorToast from "@/helpers/errorToast";
15import stopEventPropagation from "@/helpers/stopEventPropagation";
16
17interface NotInterestedProps {
18 post: PostFragment;
19}
20
21const NotInterested = ({ post }: NotInterestedProps) => {
22 const notInterested = post.operations?.isNotInterested;
23
24 const request: PostNotInterestedRequest = {
25 post: post.id
26 };
27
28 const updateCache = (
29 cache: ApolloCache<NormalizedCacheObject>,
30 notInterested: boolean
31 ) => {
32 if (!post.operations) {
33 return;
34 }
35
36 cache.modify({
37 fields: { isNotInterested: () => notInterested },
38 id: cache.identify(post.operations)
39 });
40 };
41
42 const onError = useCallback((error: ApolloClientError) => {
43 errorToast(error);
44 }, []);
45
46 const [addPostNotInterested] = useAddPostNotInterestedMutation({
47 onCompleted: () => {
48 toast.success("Marked as not Interested");
49 },
50 onError,
51 update: (cache) => updateCache(cache, true),
52 variables: { request }
53 });
54
55 const [undoPostNotInterested] = useUndoPostNotInterestedMutation({
56 onCompleted: () => {
57 toast.success("Undo Not interested");
58 },
59 onError,
60 update: (cache) => updateCache(cache, false),
61 variables: { request }
62 });
63
64 const handleToggleNotInterested = async () => {
65 if (notInterested) {
66 return await undoPostNotInterested();
67 }
68
69 return await addPostNotInterested();
70 };
71
72 return (
73 <MenuItem
74 as="div"
75 className={({ focus }) =>
76 cn(
77 { "dropdown-active": focus },
78 "m-2 block cursor-pointer rounded-lg px-2 py-1.5 text-sm"
79 )
80 }
81 onClick={(event) => {
82 stopEventPropagation(event);
83 handleToggleNotInterested();
84 }}
85 >
86 <div className="flex items-center space-x-2">
87 {notInterested ? (
88 <>
89 <EyeIcon className="size-4" />
90 <div>Undo Not interested</div>
91 </>
92 ) : (
93 <>
94 <EyeSlashIcon className="size-4" />
95 <div>Not interested</div>
96 </>
97 )}
98 </div>
99 </MenuItem>
100 );
101};
102
103export default NotInterested;