diff options
| -rw-r--r-- | packages/mobile/components/bookmarks/BookmarkCard.tsx | 49 | ||||
| -rw-r--r-- | packages/mobile/package.json | 1 | ||||
| -rw-r--r-- | pnpm-lock.yaml | 72 |
3 files changed, 107 insertions, 15 deletions
diff --git a/packages/mobile/components/bookmarks/BookmarkCard.tsx b/packages/mobile/components/bookmarks/BookmarkCard.tsx index 17e675df..57e601f7 100644 --- a/packages/mobile/components/bookmarks/BookmarkCard.tsx +++ b/packages/mobile/components/bookmarks/BookmarkCard.tsx @@ -2,6 +2,7 @@ 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 Markdown from "react-native-markdown-display"; import { api } from "@/lib/trpc"; @@ -65,7 +66,10 @@ function TagList({ tags }: { tags: ZBookmarkTags[] }) { <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"> + <View + key={t.id} + className="rounded-full border border-gray-200 px-2.5 py-0.5 text-xs font-semibold" + > <Text>{t.name}</Text> </View> ))} @@ -82,25 +86,41 @@ function LinkCard({ bookmark }: { bookmark: ZBookmark }) { const parsedUrl = new URL(bookmark.content.url); return ( - <View className="flex gap-2 rounded bg-white p-4"> + <View className="flex gap-2"> <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 className="flex gap-2"> + <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> </View> ); } function TextCard({ bookmark }: { bookmark: ZBookmark }) { - return <View />; + if (bookmark.content.type !== "text") { + throw new Error("Wrong content type rendered"); + } + return ( + <View className="flex max-h-96 gap-2"> + <View className="max-h-56 overflow-hidden pb-2"> + <Markdown>{bookmark.content.text}</Markdown> + </View> + <TagList tags={bookmark.tags} /> + <View className="flex flex-row justify-between"> + <View /> + <ActionBar bookmark={bookmark} /> + </View> + </View> + ); } export default function BookmarkCard({ @@ -115,10 +135,15 @@ export default function BookmarkCard({ { initialData }, ); + let comp; switch (bookmark.content.type) { case "link": - return <LinkCard bookmark={bookmark} />; + comp = <LinkCard bookmark={bookmark} />; + break; case "text": - return <TextCard bookmark={bookmark} />; + comp = <TextCard bookmark={bookmark} />; + break; } + + return <View className="rounded bg-white p-4">{comp}</View>; } diff --git a/packages/mobile/package.json b/packages/mobile/package.json index bbc0127c..613bb3c3 100644 --- a/packages/mobile/package.json +++ b/packages/mobile/package.json @@ -26,6 +26,7 @@ "nativewind": "^4.0.1", "react": "18.2.0", "react-native": "0.73.4", + "react-native-markdown-display": "^7.0.2", "react-native-reanimated": "^3.8.0", "react-native-safe-area-context": "4.8.2", "react-native-screens": "~3.29.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 2b2ae33a..b11597fa 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -232,9 +232,6 @@ importers: lucide-react-native: specifier: ^0.354.0 version: 0.354.0(react-native-svg@15.1.0)(react-native@0.73.4)(react@18.2.0) - metro-cache: - specifier: ^0.80.6 - version: 0.80.6 nativewind: specifier: ^4.0.1 version: 4.0.36(@babel/core@7.23.9)(react-native-reanimated@3.8.0)(react-native-safe-area-context@4.8.2)(react-native-svg@15.1.0)(react-native@0.73.4)(react@18.2.0)(tailwindcss@3.3.2) @@ -244,6 +241,9 @@ importers: react-native: specifier: 0.73.4 version: 0.73.4(@babel/core@7.23.9)(@babel/preset-env@7.24.0)(react@18.2.0) + react-native-markdown-display: + specifier: ^7.0.2 + version: 7.0.2(react-native@0.73.4)(react@18.2.0) react-native-reanimated: specifier: ^3.8.0 version: 3.8.0(@babel/core@7.23.9)(react-native@0.73.4)(react@18.2.0) @@ -7097,6 +7097,10 @@ packages: engines: {node: '>=14.16'} dev: true + /camelize@1.0.1: + resolution: {integrity: sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ==} + dev: false + /caniuse-lite@1.0.30001589: resolution: {integrity: sha512-vNQWS6kI+q6sBlHbh71IIeC+sRwK2N3EDySc/updIGhIee2x5z00J4c1242/5/d6EpEMdOnk/m+6tuk4/tcsqg==} @@ -7674,6 +7678,11 @@ packages: engines: {node: '>=8'} dev: false + /css-color-keywords@1.0.0: + resolution: {integrity: sha512-FyyrDHZKEjXDpNJYvVsV960FiqQyXc/LlYmsxl2BcdMb2WPx0OGRVgTg55rPSyLSNMqP52R9r8geSp7apN3Ofg==} + engines: {node: '>=4'} + dev: false + /css-select@5.1.0: resolution: {integrity: sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==} dependencies: @@ -7683,6 +7692,14 @@ packages: domutils: 3.1.0 nth-check: 2.1.1 + /css-to-react-native@3.2.0: + resolution: {integrity: sha512-e8RKaLXMOFii+02mOlqwjbD00KSEKqblnpO9e++1aXS1fPQOpS1YoqdVHBqPjHNoxeF2mimzVqawm2KCbEdtHQ==} + dependencies: + camelize: 1.0.1 + css-color-keywords: 1.0.0 + postcss-value-parser: 4.2.0 + dev: false + /css-tree@1.1.3: resolution: {integrity: sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==} engines: {node: '>=8.0.0'} @@ -8306,6 +8323,10 @@ packages: graceful-fs: 4.2.11 tapable: 2.2.1 + /entities@2.0.3: + resolution: {integrity: sha512-MyoZ0jgnLvB2X3Lg5HqpFmn1kybDiIfEQmKzTb5apr51Rb+T3KdmMiqa70T+bhGnyv7bQ6WMj2QMHpGMmlrUYQ==} + dev: false + /entities@4.5.0: resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} engines: {node: '>=0.12'} @@ -11433,6 +11454,12 @@ packages: /lines-and-columns@1.2.4: resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} + /linkify-it@2.2.0: + resolution: {integrity: sha512-GnAl/knGn+i1U/wjBz3akz2stz+HrHLsxMwHQGofCDfPvlf+gDKN58UtfmUquTY4/MXeE2x7k19KQmeoZi94Iw==} + dependencies: + uc.micro: 1.0.6 + dev: false + /loader-runner@4.3.0: resolution: {integrity: sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==} engines: {node: '>=6.11.5'} @@ -11694,6 +11721,17 @@ packages: tmpl: 1.0.5 dev: false + /markdown-it@10.0.0: + resolution: {integrity: sha512-YWOP1j7UbDNz+TumYP1kpwnP0aEa711cJjrAQrzd0UXlbJfc5aAq0F/PZHjiioqDC1NKgvIMX+o+9Bk7yuM2dg==} + hasBin: true + dependencies: + argparse: 1.0.10 + entities: 2.0.3 + linkify-it: 2.2.0 + mdurl: 1.0.1 + uc.micro: 1.0.6 + dev: false + /marky@1.2.5: resolution: {integrity: sha512-q9JtQJKjpsVxCRVgQ+WapguSbKC3SQ5HEzFGPAJMStgh3QjCawp00UKv3MTTAArTmGmmPUvllHZoNbZ3gs0I+Q==} dev: false @@ -11835,6 +11873,10 @@ packages: resolution: {integrity: sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==} dev: false + /mdurl@1.0.1: + resolution: {integrity: sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==} + dev: false + /meilisearch@0.37.0: resolution: {integrity: sha512-LdbK6JmRghCawrmWKJSEQF0OiE82md+YqJGE/U2JcCD8ROwlhTx0KM6NX4rQt0u0VpV0QZVG9umYiu3CSSIJAQ==} dependencies: @@ -14246,6 +14288,26 @@ packages: - supports-color dev: false + /react-native-fit-image@1.5.5: + resolution: {integrity: sha512-Wl3Vq2DQzxgsWKuW4USfck9zS7YzhvLNPpkwUUCF90bL32e1a0zOVQ3WsJILJOwzmPdHfzZmWasiiAUNBkhNkg==} + dependencies: + prop-types: 15.8.1 + dev: false + + /react-native-markdown-display@7.0.2(react-native@0.73.4)(react@18.2.0): + resolution: {integrity: sha512-Mn4wotMvMfLAwbX/huMLt202W5DsdpMO/kblk+6eUs55S57VVNni1gzZCh5qpznYLjIQELNh50VIozEfY6fvaQ==} + peerDependencies: + react: '>=16.2.0' + react-native: '>=0.50.4' + dependencies: + css-to-react-native: 3.2.0 + markdown-it: 10.0.0 + prop-types: 15.8.1 + react: 18.2.0 + react-native: 0.73.4(@babel/core@7.23.9)(@babel/preset-env@7.24.0)(react@18.2.0) + react-native-fit-image: 1.5.5 + dev: false + /react-native-reanimated@3.8.0(@babel/core@7.23.9)(react-native@0.73.4)(react@18.2.0): resolution: {integrity: sha512-xoG4+nf+lSmzv37mjTUIT0gYNEIr2Mb8WXgmqR8deCJk8CC6lXT0HRpshTPVAF00LvdzrD2W/rCpiBdHN5FW2w==} peerDependencies: @@ -16123,6 +16185,10 @@ packages: resolution: {integrity: sha512-pGtPAQmLwh+R9w81WVHzui1FfedpQWQpiaIIfPCwhtsBez4q6DYbJFfyXPVHPUTNFnedAvNEnkoFiLuhXIR94w==} dev: true + /uc.micro@1.0.6: + resolution: {integrity: sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==} + dev: false + /ufo@1.4.0: resolution: {integrity: sha512-Hhy+BhRBleFjpJ2vchUNN40qgkh0366FWJGqVLYBHev0vpHTrXSA0ryT+74UiW6KWsldNurQMKGqCm1M2zBciQ==} dev: true |
