From ec31a971f6c2e3e058debf05fe8235c1d599b055 Mon Sep 17 00:00:00 2001 From: Simon Kenny Date: Sat, 7 Jun 2025 21:57:48 +0100 Subject: feat(mobile): add reader/screenshot/archive view to bookmark preview (#1509) * feat(mobile): add reader view by default to bookmark detail view, retaining WebView fallback * feat(mobile): add dark mode support for mobile reader view * Add selectors for different views for bookmark link --------- Co-authored-by: MohamedBassem --- .../components/bookmarks/BookmarkLinkPreview.tsx | 183 +++++++++++++++++++++ 1 file changed, 183 insertions(+) create mode 100644 apps/mobile/components/bookmarks/BookmarkLinkPreview.tsx (limited to 'apps/mobile/components') diff --git a/apps/mobile/components/bookmarks/BookmarkLinkPreview.tsx b/apps/mobile/components/bookmarks/BookmarkLinkPreview.tsx new file mode 100644 index 00000000..5e1e7aa7 --- /dev/null +++ b/apps/mobile/components/bookmarks/BookmarkLinkPreview.tsx @@ -0,0 +1,183 @@ +import { useState } from "react"; +import { Pressable, View } from "react-native"; +import ImageView from "react-native-image-viewing"; +import WebView from "react-native-webview"; +import { WebViewSourceUri } from "react-native-webview/lib/WebViewTypes"; +import { useAssetUrl } from "@/lib/hooks"; +import { api } from "@/lib/trpc"; +import { useColorScheme } from "nativewind"; + +import { BookmarkTypes, ZBookmark } from "@karakeep/shared/types/bookmarks"; + +import FullPageError from "../FullPageError"; +import FullPageSpinner from "../ui/FullPageSpinner"; +import BookmarkAssetImage from "./BookmarkAssetImage"; + +export function BookmarkLinkBrowserPreview({ + bookmark, +}: { + bookmark: ZBookmark; +}) { + if (bookmark.content.type !== BookmarkTypes.LINK) { + throw new Error("Wrong content type rendered"); + } + + return ( + + ); +} + +export function BookmarkLinkReaderPreview({ + bookmark, +}: { + bookmark: ZBookmark; +}) { + const { colorScheme } = useColorScheme(); + + const { + data: bookmarkWithContent, + error, + isLoading, + refetch, + } = api.bookmarks.getBookmark.useQuery({ + bookmarkId: bookmark.id, + includeContent: true, + }); + + if (isLoading) { + return ; + } + + if (error) { + return ; + } + + if (bookmarkWithContent?.content.type !== BookmarkTypes.LINK) { + throw new Error("Wrong content type rendered"); + } + + const isDark = colorScheme === "dark"; + + return ( + + + + + + + + + ${bookmarkWithContent.content.htmlContent} + + + `, + }} + style={{ + flex: 1, + backgroundColor: isDark ? "#000000" : "#ffffff", + }} + showsVerticalScrollIndicator={false} + showsHorizontalScrollIndicator={false} + /> + + ); +} + +export function BookmarkLinkArchivePreview({ + bookmark, +}: { + bookmark: ZBookmark; +}) { + const asset = + bookmark.assets.find((r) => r.assetType == "precrawledArchive") ?? + bookmark.assets.find((r) => r.assetType == "fullPageArchive"); + + const assetSource = useAssetUrl(asset?.id ?? ""); + + if (!asset) { + return ( + Asset has no offline archive + ); + } + + const webViewUri: WebViewSourceUri = { + uri: assetSource.uri!, + headers: assetSource.headers, + }; + return ( + + ); +} + +export function BookmarkLinkScreenshotPreview({ + bookmark, +}: { + bookmark: ZBookmark; +}) { + const asset = bookmark.assets.find((r) => r.assetType == "screenshot"); + + const assetSource = useAssetUrl(asset?.id ?? ""); + const [imageZoom, setImageZoom] = useState(false); + + if (!asset) { + return ( + Asset has no screenshot + ); + } + + return ( + + setImageZoom(false)} + doubleTapToZoomEnabled={true} + images={[assetSource]} + /> + setImageZoom(true)}> + + + + ); +} -- cgit v1.2.3-70-g09d2