1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
|
import { ZBookmark } from "@hoarder/trpc/types/bookmarks";
import { ZBookmarkTags } from "@hoarder/trpc/types/tags";
import { Star, Archive, Trash } from "lucide-react-native";
import { View, Text, Image, ScrollView, Pressable } from "react-native";
import { api } from "@/lib/trpc";
function ActionBar({ bookmark }: { bookmark: ZBookmark }) {
const apiUtils = api.useUtils();
const { mutate: deleteBookmark } = api.bookmarks.deleteBookmark.useMutation({
onSuccess: () => {
apiUtils.bookmarks.getBookmarks.invalidate();
},
});
const { mutate: updateBookmark, variables } =
api.bookmarks.updateBookmark.useMutation({
onSuccess: () => {
apiUtils.bookmarks.getBookmarks.invalidate();
apiUtils.bookmarks.getBookmark.invalidate({ bookmarkId: bookmark.id });
},
});
return (
<View className="flex flex-row gap-4">
<Pressable
onPress={() =>
updateBookmark({
bookmarkId: bookmark.id,
favourited: !bookmark.favourited,
})
}
>
{(variables ? variables.favourited : bookmark.favourited) ? (
<Star fill="#ebb434" color="#ebb434" />
) : (
<Star />
)}
</Pressable>
<Pressable
onPress={() =>
updateBookmark({
bookmarkId: bookmark.id,
archived: !bookmark.archived,
})
}
>
<Archive />
</Pressable>
<Pressable
onPress={() =>
deleteBookmark({
bookmarkId: bookmark.id,
})
}
>
<Trash />
</Pressable>
</View>
);
}
function TagList({ tags }: { tags: ZBookmarkTags[] }) {
return (
<ScrollView horizontal showsHorizontalScrollIndicator={false}>
<View className="flex flex-row gap-2">
{tags.map((t) => (
<View className="rounded-full border border-gray-200 px-2.5 py-0.5 text-xs font-semibold">
<Text>{t.name}</Text>
</View>
))}
</View>
</ScrollView>
);
}
function LinkCard({ bookmark }: { bookmark: ZBookmark }) {
if (bookmark.content.type !== "link") {
throw new Error("Wrong content type rendered");
}
const parsedUrl = new URL(bookmark.content.url);
return (
<View className="flex gap-2 rounded bg-white p-4">
<Image
source={{ uri: bookmark.content.imageUrl || "" }}
className="h-56 min-h-56 w-full"
/>
<Text className="line-clamp-2 text-xl font-bold">
{bookmark.content.title || parsedUrl.host}
</Text>
<TagList tags={bookmark.tags} />
<View className="mt-2 flex flex-row justify-between">
<Text className="my-auto line-clamp-1">{parsedUrl.host}</Text>
<ActionBar bookmark={bookmark} />
</View>
</View>
);
}
function TextCard({ bookmark }: { bookmark: ZBookmark }) {
return <View />;
}
export default function BookmarkCard({
bookmark: initialData,
}: {
bookmark: ZBookmark;
}) {
const { data: bookmark } = api.bookmarks.getBookmark.useQuery(
{
bookmarkId: initialData.id,
},
{ initialData },
);
switch (bookmark.content.type) {
case "link":
return <LinkCard bookmark={bookmark} />;
case "text":
return <TextCard bookmark={bookmark} />;
}
}
|