diff options
4 files changed, 160 insertions, 37 deletions
diff --git a/apps/mobile/app/dashboard/bookmarks/[slug].tsx b/apps/mobile/app/dashboard/bookmarks/[slug].tsx new file mode 100644 index 00000000..c7b0cead --- /dev/null +++ b/apps/mobile/app/dashboard/bookmarks/[slug].tsx @@ -0,0 +1,82 @@ +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 ( + <View className="flex gap-2"> + <BookmarkTextMarkdown text={content} /> + </View> + ); +} + +function BookmarkAssetView({ bookmark }: { bookmark: ZBookmark }) { + if (bookmark.content.type !== BookmarkTypes.ASSET) { + throw new Error("Wrong content type rendered"); + } + return ( + <View className="flex gap-2"> + <BookmarkAssetImage + assetId={bookmark.content.assetId} + className="h-56 min-h-56 w-full object-cover" + /> + </View> + ); +} + +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 = <BookmarkTextView bookmark={bookmark} />; + break; + case BookmarkTypes.ASSET: + title = bookmark.title ?? bookmark.content.fileName; + comp = <BookmarkAssetView bookmark={bookmark} />; + break; + } + } else { + comp = <FullPageSpinner />; + } + + return ( + <CustomSafeAreaView> + <Stack.Screen + options={{ + headerTitle: "", + headerBackTitle: "Back", + headerTransparent: true, + }} + /> + <PageTitle title={title ?? "Untitled"} /> + <View className="px-4 py-2">{comp}</View> + </CustomSafeAreaView> + ); +} diff --git a/apps/mobile/components/bookmarks/BookmarkAssetImage.tsx b/apps/mobile/components/bookmarks/BookmarkAssetImage.tsx new file mode 100644 index 00000000..95f963f4 --- /dev/null +++ b/apps/mobile/components/bookmarks/BookmarkAssetImage.tsx @@ -0,0 +1,23 @@ +import { Image } from "react-native"; +import useAppSettings from "@/lib/settings"; + +export default function BookmarkAssetImage({ + assetId, + className, +}: { + assetId: string; + className: string; +}) { + const { settings } = useAppSettings(); + return ( + <Image + source={{ + uri: `${settings.address}/api/assets/${assetId}`, + headers: { + Authorization: `Bearer ${settings.apiKey}`, + }, + }} + className={className} + /> + ); +} diff --git a/apps/mobile/components/bookmarks/BookmarkCard.tsx b/apps/mobile/components/bookmarks/BookmarkCard.tsx index 3be1f9a0..860e5486 100644 --- a/apps/mobile/components/bookmarks/BookmarkCard.tsx +++ b/apps/mobile/components/bookmarks/BookmarkCard.tsx @@ -8,9 +8,8 @@ import { Text, View, } from "react-native"; -import Markdown from "react-native-markdown-display"; import * as Haptics from "expo-haptics"; -import { Link } from "expo-router"; +import { Link, router } from "expo-router"; import * as WebBrowser from "expo-web-browser"; import useAppSettings from "@/lib/settings"; import { api } from "@/lib/trpc"; @@ -30,10 +29,11 @@ import { } from "@hoarder/shared-react/utils/bookmarkUtils"; import { BookmarkTypes } from "@hoarder/shared/types/bookmarks"; -import { TailwindResolver } from "../TailwindResolver"; import { Divider } from "../ui/Divider"; import { Skeleton } from "../ui/Skeleton"; import { useToast } from "../ui/Toast"; +import BookmarkAssetImage from "./BookmarkAssetImage"; +import BookmarkTextMarkdown from "./BookmarkTextMarkdown"; import ListPickerModal from "./ListPickerModal"; function ActionBar({ bookmark }: { bookmark: ZBookmark }) { @@ -250,26 +250,21 @@ function TextCard({ bookmark }: { bookmark: ZBookmark }) { const content = bookmark.content.text; return ( <View className="flex max-h-96 gap-2 p-2"> - {bookmark.title && ( - <Text className="line-clamp-2 text-xl font-bold text-foreground"> - {bookmark.title} - </Text> - )} + <Pressable + onPress={() => router.push(`/dashboard/bookmarks/${bookmark.id}`)} + > + {bookmark.title && ( + <Text className="line-clamp-2 text-xl font-bold text-foreground"> + {bookmark.title} + </Text> + )} + </Pressable> <View className="max-h-56 overflow-hidden p-2 text-foreground"> - <TailwindResolver - className="text-foreground" - comp={(styles) => ( - <Markdown - style={{ - text: { - color: styles?.color?.toString(), - }, - }} - > - {content} - </Markdown> - )} - /> + <Pressable + onPress={() => router.push(`/dashboard/bookmarks/${bookmark.id}`)} + > + <BookmarkTextMarkdown text={content} /> + </Pressable> </View> <TagList bookmark={bookmark} /> <Divider orientation="vertical" className="mt-2 h-0.5 w-full" /> @@ -282,7 +277,6 @@ function TextCard({ bookmark }: { bookmark: ZBookmark }) { } function AssetCard({ bookmark }: { bookmark: ZBookmark }) { - const { settings } = useAppSettings(); if (bookmark.content.type !== BookmarkTypes.ASSET) { throw new Error("Wrong content type rendered"); } @@ -290,21 +284,24 @@ function AssetCard({ bookmark }: { bookmark: ZBookmark }) { return ( <View className="flex gap-2"> - <Image - source={{ - uri: `${settings.address}/api/assets/${bookmark.content.assetId}`, - headers: { - Authorization: `Bearer ${settings.apiKey}`, - }, - }} - className="h-56 min-h-56 w-full object-cover" - /> + <Pressable + onPress={() => router.push(`/dashboard/bookmarks/${bookmark.id}`)} + > + <BookmarkAssetImage + assetId={bookmark.content.assetId} + className="h-56 min-h-56 w-full object-cover" + /> + </Pressable> <View className="flex gap-2 p-2"> - {title && ( - <Text className="line-clamp-2 text-xl font-bold text-foreground"> - {title} - </Text> - )} + <Pressable + onPress={() => router.push(`/dashboard/bookmarks/${bookmark.id}`)} + > + {title && ( + <Text className="line-clamp-2 text-xl font-bold text-foreground"> + {title} + </Text> + )} + </Pressable> <TagList bookmark={bookmark} /> <Divider orientation="vertical" className="mt-2 h-0.5 w-full" /> <View className="mt-2 flex flex-row justify-between px-2 pb-2"> diff --git a/apps/mobile/components/bookmarks/BookmarkTextMarkdown.tsx b/apps/mobile/components/bookmarks/BookmarkTextMarkdown.tsx new file mode 100644 index 00000000..80ea007c --- /dev/null +++ b/apps/mobile/components/bookmarks/BookmarkTextMarkdown.tsx @@ -0,0 +1,21 @@ +import Markdown from "react-native-markdown-display"; +import { TailwindResolver } from "@/components/TailwindResolver"; + +export default function BookmarkTextMarkdown({ text }: { text: string }) { + return ( + <TailwindResolver + className="text-foreground" + comp={(styles) => ( + <Markdown + style={{ + text: { + color: styles?.color?.toString(), + }, + }} + > + {text} + </Markdown> + )} + /> + ); +} |
