diff options
| author | MohamedBassem <me@mbassem.com> | 2024-03-15 12:01:11 +0000 |
|---|---|---|
| committer | MohamedBassem <me@mbassem.com> | 2024-03-15 12:01:11 +0000 |
| commit | aa8df79ab48c2e2d9f8b10fbdf4d71197f41303e (patch) | |
| tree | 8611b119d588bb3b1b5fb165ac22c68112164e7d /apps | |
| parent | cd10200c64572ab09112ddda55fc1057bac233ab (diff) | |
| download | karakeep-aa8df79ab48c2e2d9f8b10fbdf4d71197f41303e.tar.zst | |
mobile: Revamp bookmark card's action bar
Diffstat (limited to 'apps')
| -rw-r--r-- | apps/mobile/components/bookmarks/BookmarkCard.tsx | 145 | ||||
| -rw-r--r-- | apps/mobile/package.json | 4 |
2 files changed, 92 insertions, 57 deletions
diff --git a/apps/mobile/components/bookmarks/BookmarkCard.tsx b/apps/mobile/components/bookmarks/BookmarkCard.tsx index 2189b385..07d7f4fe 100644 --- a/apps/mobile/components/bookmarks/BookmarkCard.tsx +++ b/apps/mobile/components/bookmarks/BookmarkCard.tsx @@ -1,12 +1,21 @@ -import { Image, Pressable, ScrollView, Text, View } from "react-native"; +import { + ActivityIndicator, + Image, + Platform, + Pressable, + ScrollView, + Text, + View, +} from "react-native"; import Markdown from "react-native-markdown-display"; +import * as Haptics from "expo-haptics"; import * as WebBrowser from "expo-web-browser"; import { api } from "@/lib/trpc"; -import { Archive, ArchiveRestore, Star, Trash } from "lucide-react-native"; +import { MenuView } from "@react-native-menu/menu"; +import { Ellipsis, Star } from "lucide-react-native"; import type { ZBookmark } from "@hoarder/trpc/types/bookmarks"; -import { ActionButton } from "../ui/ActionButton"; import { Divider } from "../ui/Divider"; import { Skeleton } from "../ui/Skeleton"; import { useToast } from "../ui/Toast"; @@ -36,46 +45,59 @@ function ActionBar({ bookmark }: { bookmark: ZBookmark }) { const { toast } = useToast(); const apiUtils = api.useUtils(); + const onError = () => { + toast({ + message: "Something went wrong", + variant: "destructive", + showProgress: false, + }); + }; + const { mutate: deleteBookmark, isPending: isDeletionPending } = api.bookmarks.deleteBookmark.useMutation({ onSuccess: () => { + toast({ + message: 'The bookmark has been deleted!', + showProgress: false, + }); + apiUtils.bookmarks.getBookmarks.invalidate(); + }, + onError, + }); + + const { mutate: favouriteBookmark, variables } = + api.bookmarks.updateBookmark.useMutation({ + onSuccess: () => { apiUtils.bookmarks.getBookmarks.invalidate(); + apiUtils.bookmarks.getBookmark.invalidate({ bookmarkId: bookmark.id }); }, - onError: () => { + onError, + }); + + const { mutate: archiveBookmark, isPending: isArchivePending } = + api.bookmarks.updateBookmark.useMutation({ + onSuccess: (resp) => { toast({ - message: "Something went wrong", - variant: "destructive", + message: `The bookmark has been ${resp.archived ? "archived" : "un-archived"}!`, showProgress: false, }); + apiUtils.bookmarks.getBookmarks.invalidate(); + apiUtils.bookmarks.getBookmark.invalidate({ bookmarkId: bookmark.id }); }, + onError, }); - const { - mutate: updateBookmark, - variables, - isPending: isUpdatePending, - } = api.bookmarks.updateBookmark.useMutation({ - onSuccess: () => { - apiUtils.bookmarks.getBookmarks.invalidate(); - apiUtils.bookmarks.getBookmark.invalidate({ bookmarkId: bookmark.id }); - }, - onError: () => { - toast({ - message: "Something went wrong", - variant: "destructive", - showProgress: false, - }); - }, - }); return ( <View className="flex flex-row gap-4"> + {(isArchivePending || isDeletionPending) && <ActivityIndicator />} <Pressable - onPress={() => - updateBookmark({ + onPress={() => { + Haptics.selectionAsync(); + favouriteBookmark({ bookmarkId: bookmark.id, favourited: !bookmark.favourited, - }) - } + }); + }} > {(variables ? variables.favourited : bookmark.favourited) ? ( <Star fill="#ebb434" color="#ebb434" /> @@ -83,31 +105,46 @@ function ActionBar({ bookmark }: { bookmark: ZBookmark }) { <Star color="gray" /> )} </Pressable> - <ActionButton - loading={isUpdatePending} - onPress={() => - updateBookmark({ - bookmarkId: bookmark.id, - archived: !bookmark.archived, - }) - } - > - {bookmark.archived ? ( - <ArchiveRestore color="gray" /> - ) : ( - <Archive color="gray" /> - )} - </ActionButton> - <ActionButton - loading={isDeletionPending} - onPress={() => - deleteBookmark({ - bookmarkId: bookmark.id, - }) - } + + <MenuView + onPressAction={({ nativeEvent }) => { + Haptics.selectionAsync(); + if (nativeEvent.event === "delete") { + deleteBookmark({ + bookmarkId: bookmark.id, + }); + } else if (nativeEvent.event === "archive") { + archiveBookmark({ + bookmarkId: bookmark.id, + archived: !bookmark.archived, + }); + } + }} + actions={[ + { + id: "archive", + title: bookmark.archived ? "Un-archive" : "Archive", + image: Platform.select({ + ios: "folder", + android: "ic_menu_folder", + }), + }, + { + id: "delete", + title: "Delete", + attributes: { + destructive: true, + }, + image: Platform.select({ + ios: "trash", + android: "ic_menu_delete", + }), + }, + ]} + shouldOpenOnLongPress={false} > - <Trash color="gray" /> - </ActionButton> + <Ellipsis onPress={() => Haptics.selectionAsync()} color="gray" /> + </MenuView> </View> ); } @@ -236,9 +273,5 @@ export default function BookmarkCard({ break; } - return ( - <View className="border-b border-gray-300 bg-white"> - {comp} - </View> - ); + return <View className="border-b border-gray-300 bg-white">{comp}</View>; } diff --git a/apps/mobile/package.json b/apps/mobile/package.json index ead5e796..71dff6cc 100644 --- a/apps/mobile/package.json +++ b/apps/mobile/package.json @@ -13,6 +13,7 @@ }, "dependencies": { "@hoarder/trpc": "0.1.0", + "@react-native-menu/menu": "^0.9.1", "@tanstack/react-query": "^5.24.8", "class-variance-authority": "^0.7.0", "clsx": "^2.1.0", @@ -20,6 +21,7 @@ "expo-config-plugin-ios-share-extension": "^0.0.4", "expo-constants": "~15.4.5", "expo-dev-client": "^3.3.9", + "expo-haptics": "^12.8.1", "expo-image": "^1.10.6", "expo-linking": "~6.2.2", "expo-router": "~3.4.8", @@ -42,11 +44,11 @@ "zustand": "^4.5.1" }, "devDependencies": { + "@babel/core": "^7.20.0", "@hoarder/eslint-config": "workspace:^0.2.0", "@hoarder/prettier-config": "workspace:^0.1.0", "@hoarder/tailwind-config": "workspace:^0.1.0", "@hoarder/tsconfig": "workspace:^0.1.0", - "@babel/core": "^7.20.0", "@types/react": "^18.2.55", "ajv": "latest", "eslint": "^8.57.0", |
