From b094b2cecb0da1bcdf4c63dd081638d87793c53c Mon Sep 17 00:00:00 2001 From: MohamedBassem Date: Mon, 26 Aug 2024 13:41:13 +0300 Subject: feature(mobile): Change the view bookmark page to be a modal and add tags and notes --- apps/mobile/app/dashboard/bookmarks/[slug].tsx | 82 --------- apps/mobile/components/bookmarks/BookmarkCard.tsx | 100 +++++------ .../components/bookmarks/NewBookmarkModal.tsx | 71 ++------ apps/mobile/components/bookmarks/TagPill.tsx | 17 ++ .../components/bookmarks/ViewBookmarkModal.tsx | 192 +++++++++++++++++++++ apps/mobile/components/ui/Input.tsx | 15 +- 6 files changed, 285 insertions(+), 192 deletions(-) delete mode 100644 apps/mobile/app/dashboard/bookmarks/[slug].tsx create mode 100644 apps/mobile/components/bookmarks/TagPill.tsx create mode 100644 apps/mobile/components/bookmarks/ViewBookmarkModal.tsx (limited to 'apps') diff --git a/apps/mobile/app/dashboard/bookmarks/[slug].tsx b/apps/mobile/app/dashboard/bookmarks/[slug].tsx deleted file mode 100644 index c7b0cead..00000000 --- a/apps/mobile/app/dashboard/bookmarks/[slug].tsx +++ /dev/null @@ -1,82 +0,0 @@ -import { View } from "react-native"; -import { Stack, useLocalSearchParams } from "expo-router"; -import BookmarkAssetImage from "@/components/bookmarks/BookmarkAssetImage"; -import BookmarkTextMarkdown from "@/components/bookmarks/BookmarkTextMarkdown"; -import CustomSafeAreaView from "@/components/ui/CustomSafeAreaView"; -import FullPageSpinner from "@/components/ui/FullPageSpinner"; -import PageTitle from "@/components/ui/PageTitle"; -import { api } from "@/lib/trpc"; - -import { BookmarkTypes, ZBookmark } from "@hoarder/shared/types/bookmarks"; - -function BookmarkTextView({ bookmark }: { bookmark: ZBookmark }) { - if (bookmark.content.type !== BookmarkTypes.TEXT) { - throw new Error("Wrong content type rendered"); - } - const content = bookmark.content.text; - - return ( - - - - ); -} - -function BookmarkAssetView({ bookmark }: { bookmark: ZBookmark }) { - if (bookmark.content.type !== BookmarkTypes.ASSET) { - throw new Error("Wrong content type rendered"); - } - return ( - - - - ); -} - -export default function BookmarkView() { - const { slug } = useLocalSearchParams(); - if (typeof slug !== "string") { - throw new Error("Unexpected param type"); - } - - const { data: bookmark } = api.bookmarks.getBookmark.useQuery({ - bookmarkId: slug, - }); - - let comp; - let title = null; - if (bookmark) { - switch (bookmark.content.type) { - case BookmarkTypes.LINK: - comp = null; - break; - case BookmarkTypes.TEXT: - title = bookmark.title; - comp = ; - break; - case BookmarkTypes.ASSET: - title = bookmark.title ?? bookmark.content.fileName; - comp = ; - break; - } - } else { - comp = ; - } - - return ( - - - - {comp} - - ); -} diff --git a/apps/mobile/components/bookmarks/BookmarkCard.tsx b/apps/mobile/components/bookmarks/BookmarkCard.tsx index 8c582d59..0b787372 100644 --- a/apps/mobile/components/bookmarks/BookmarkCard.tsx +++ b/apps/mobile/components/bookmarks/BookmarkCard.tsx @@ -9,7 +9,6 @@ import { View, } from "react-native"; import * as Haptics from "expo-haptics"; -import { Link, router } from "expo-router"; import * as WebBrowser from "expo-web-browser"; import useAppSettings from "@/lib/settings"; import { api } from "@/lib/trpc"; @@ -35,7 +34,8 @@ import { useToast } from "../ui/Toast"; import BookmarkAssetImage from "./BookmarkAssetImage"; import BookmarkTextMarkdown from "./BookmarkTextMarkdown"; import ListPickerModal from "./ListPickerModal"; -import NoteEditorModal from "./NewBookmarkModal"; +import TagPill from "./TagPill"; +import ViewBookmarkModal from "./ViewBookmarkModal"; function ActionBar({ bookmark }: { bookmark: ZBookmark }) { const { toast } = useToast(); @@ -75,7 +75,6 @@ function ActionBar({ bookmark }: { bookmark: ZBookmark }) { }); const manageListsSheetRef = useRef(null); - const editBookmarkModal = useRef(null); return ( @@ -101,13 +100,6 @@ function ActionBar({ bookmark }: { bookmark: ZBookmark }) { snapPoints={["50%", "90%"]} bookmarkId={bookmark.id} /> - {bookmark.content.type === BookmarkTypes.TEXT && ( - - )} { @@ -123,21 +115,9 @@ function ActionBar({ bookmark }: { bookmark: ZBookmark }) { }); } else if (nativeEvent.event === "manage_list") { manageListsSheetRef?.current?.present(); - } else if (nativeEvent.event === "edit") { - editBookmarkModal.current?.present(); } }} actions={[ - { - id: "edit", - title: "Edit", - image: Platform.select({ - ios: "edit", - }), - attributes: { - hidden: bookmark.content.type !== BookmarkTypes.TEXT, - }, - }, { id: "archive", title: bookmark.archived ? "Un-archive" : "Archive", @@ -187,21 +167,19 @@ function TagList({ bookmark }: { bookmark: ZBookmark }) { {tags.map((t) => ( - - - {t.name} - - + ))} ); } -function LinkCard({ bookmark }: { bookmark: ZBookmark }) { +function LinkCard({ + bookmark, +}: { + bookmark: ZBookmark; + onOpenBookmark: () => void; +}) { const { settings } = useAppSettings(); if (bookmark.content.type !== BookmarkTypes.LINK) { throw new Error("Wrong content type rendered"); @@ -264,16 +242,20 @@ function LinkCard({ bookmark }: { bookmark: ZBookmark }) { ); } -function TextCard({ bookmark }: { bookmark: ZBookmark }) { +function TextCard({ + bookmark, + onOpenBookmark, +}: { + bookmark: ZBookmark; + onOpenBookmark: () => void; +}) { if (bookmark.content.type !== BookmarkTypes.TEXT) { throw new Error("Wrong content type rendered"); } const content = bookmark.content.text; return ( - router.push(`/dashboard/bookmarks/${bookmark.id}`)} - > + {bookmark.title && ( {bookmark.title} @@ -281,9 +263,7 @@ function TextCard({ bookmark }: { bookmark: ZBookmark }) { )} - router.push(`/dashboard/bookmarks/${bookmark.id}`)} - > + @@ -297,7 +277,13 @@ function TextCard({ bookmark }: { bookmark: ZBookmark }) { ); } -function AssetCard({ bookmark }: { bookmark: ZBookmark }) { +function AssetCard({ + bookmark, + onOpenBookmark, +}: { + bookmark: ZBookmark; + onOpenBookmark: () => void; +}) { if (bookmark.content.type !== BookmarkTypes.ASSET) { throw new Error("Wrong content type rendered"); } @@ -305,18 +291,14 @@ function AssetCard({ bookmark }: { bookmark: ZBookmark }) { return ( - router.push(`/dashboard/bookmarks/${bookmark.id}`)} - > + - router.push(`/dashboard/bookmarks/${bookmark.id}`)} - > + {title && ( {title} @@ -359,21 +341,43 @@ export default function BookmarkCard({ }, ); + const viewBookmarkModal = useRef(null); + let comp; switch (bookmark.content.type) { case BookmarkTypes.LINK: - comp = ; + comp = ( + viewBookmarkModal.current?.present()} + /> + ); break; case BookmarkTypes.TEXT: - comp = ; + comp = ( + viewBookmarkModal.current?.present()} + /> + ); break; case BookmarkTypes.ASSET: - comp = ; + comp = ( + viewBookmarkModal.current?.present()} + /> + ); break; } return ( + {comp} ); diff --git a/apps/mobile/components/bookmarks/NewBookmarkModal.tsx b/apps/mobile/components/bookmarks/NewBookmarkModal.tsx index 8ac8bb39..6915c663 100644 --- a/apps/mobile/components/bookmarks/NewBookmarkModal.tsx +++ b/apps/mobile/components/bookmarks/NewBookmarkModal.tsx @@ -1,51 +1,31 @@ -import React, { useEffect, useState } from "react"; +import React, { useState } from "react"; import { Text, View } from "react-native"; import { BottomSheetBackdrop, BottomSheetModal, BottomSheetModalProps, - BottomSheetTextInput, BottomSheetView, useBottomSheetModal, } from "@gorhom/bottom-sheet"; -import { - useCreateBookmark, - useUpdateBookmarkText, -} from "@hoarder/shared-react/hooks/bookmarks"; -import { BookmarkTypes, ZBookmark } from "@hoarder/shared/types/bookmarks"; +import { useCreateBookmark } from "@hoarder/shared-react/hooks/bookmarks"; +import { BookmarkTypes } from "@hoarder/shared/types/bookmarks"; import { Button } from "../ui/Button"; +import { Input } from "../ui/Input"; import PageTitle from "../ui/PageTitle"; const NoteEditorModal = React.forwardRef< BottomSheetModal, - Omit< - BottomSheetModalProps, - "children" | "backdropComponent" | "onDismiss" - > & { - bookmark?: ZBookmark; - } ->(({ bookmark, ...props }, ref) => { + Omit +>(({ ...props }, ref) => { const { dismiss } = useBottomSheetModal(); - const isEditing = !!bookmark; const [text, setText] = useState(""); const [error, setError] = useState(); - const resetText = () => { - if (bookmark) { - if (bookmark.content.type !== BookmarkTypes.TEXT) { - throw new Error("Wrong content type rendered"); - } - setText(bookmark.content.text); - } - }; - - useEffect(resetText, []); - const onSuccess = () => { - resetText(); + setText(""); dismiss(); }; @@ -63,31 +43,6 @@ const NoteEditorModal = React.forwardRef< }, }); - const { mutate: updateBookmark } = useUpdateBookmarkText({ - onSuccess, - onError: (e) => { - let message; - if (e.data?.zodError) { - const zodError = e.data.zodError; - message = JSON.stringify(zodError); - } else { - message = `Something went wrong: ${e.message}`; - } - setError(message); - }, - }); - - const mutate = (text: string) => { - if (isEditing) { - updateBookmark({ - bookmarkId: bookmark.id, - text, - }); - } else { - createBookmark({ type: BookmarkTypes.TEXT, text }); - } - }; - return ( - - + + {error && ( {error} )} -