From be622e5594ecb21c82bb6066a82c86e0917bcc35 Mon Sep 17 00:00:00 2001 From: Ahmad Mujahid <55625580+AhmadMuj@users.noreply.github.com> Date: Thu, 11 Apr 2024 15:29:51 +0400 Subject: [PATCH] feature: Add PDF support (#88) * feature: Add PDF support * fix: PDF feature enhancements * fix: Freeze expo-share-intent version to prevent breaking changes * fix: set endOfLine to auto for cross-platform development * fix: Upgrading eslint/parser and eslint-plugin to 7.6.0 to solve the linting issues * fix: enhancing PDF feature * fix: Allowing null in fiename for backward compatibility * fix: update pnpm file with pnpm 9.0.0-alpha-8 * fix:(web): PDF Preview for web --- apps/mobile/lib/upload.ts | 6 +- apps/mobile/package.json | 2 +- apps/web/app/api/assets/route.ts | 7 +- .../components/dashboard/UploadDropzone.tsx | 7 +- .../dashboard/bookmarks/AssetCard.tsx | 7 + .../dashboard/preview/AssetContentSection.tsx | 39 +- apps/workers/openaiWorker.ts | 69 +- apps/workers/package.json | 2 + apps/workers/searchWorker.ts | 7 + apps/workers/utils.ts | 32 + packages/db/drizzle/0015_first_reavers.sql | 3 + .../db/drizzle/0016_shallow_rawhide_kid.sql | 2 + packages/db/drizzle/meta/0015_snapshot.json | 959 ++++++++++++++++++ packages/db/drizzle/meta/0016_snapshot.json | 959 ++++++++++++++++++ packages/db/drizzle/meta/_journal.json | 14 + packages/db/schema.ts | 5 +- packages/shared/assetdb.ts | 1 + packages/shared/search.ts | 2 + packages/trpc/routers/bookmarks.ts | 3 + packages/trpc/types/bookmarks.ts | 3 +- packages/trpc/types/uploads.ts | 1 + pnpm-lock.yaml | 359 +++++-- tooling/eslint/package.json | 4 +- tooling/prettier/index.js | 1 + 24 files changed, 2387 insertions(+), 107 deletions(-) create mode 100644 packages/db/drizzle/0015_first_reavers.sql create mode 100644 packages/db/drizzle/0016_shallow_rawhide_kid.sql create mode 100644 packages/db/drizzle/meta/0015_snapshot.json create mode 100644 packages/db/drizzle/meta/0016_snapshot.json diff --git a/apps/mobile/lib/upload.ts b/apps/mobile/lib/upload.ts index 56b2c7a5..f9d05967 100644 --- a/apps/mobile/lib/upload.ts +++ b/apps/mobile/lib/upload.ts @@ -38,7 +38,7 @@ export function useUploadAsset( mutationFn: async (file: { type: string; name: string; uri: string }) => { const formData = new FormData(); // @ts-expect-error This is a valid api in react native - formData.append("image", { + formData.append("file", { uri: file.uri, name: file.name, type: file.type, @@ -57,7 +57,9 @@ export function useUploadAsset( }, onSuccess: (resp) => { const assetId = resp.assetId; - createBookmark({ type: "asset", assetId, assetType: "image" }); + const assetType = + resp.contentType === "application/pdf" ? "pdf" : "image"; + createBookmark({ type: "asset", assetId, assetType }); }, onError: (e) => { if (options.onError) { diff --git a/apps/mobile/package.json b/apps/mobile/package.json index 9f170040..248f1f53 100644 --- a/apps/mobile/package.json +++ b/apps/mobile/package.json @@ -31,7 +31,7 @@ "expo-navigation-bar": "~2.8.1", "expo-router": "~3.4.8", "expo-secure-store": "^12.8.1", - "expo-share-intent": "^1.1.0", + "expo-share-intent": "1.1.0", "expo-status-bar": "~1.11.1", "expo-system-ui": "^2.9.3", "expo-web-browser": "^12.8.2", diff --git a/apps/web/app/api/assets/route.ts b/apps/web/app/api/assets/route.ts index 0bb2f778..5b72033a 100644 --- a/apps/web/app/api/assets/route.ts +++ b/apps/web/app/api/assets/route.ts @@ -9,6 +9,7 @@ const SUPPORTED_ASSET_TYPES = new Set([ "image/jpeg", "image/png", "image/webp", + "application/pdf", ]); const MAX_UPLOAD_SIZE_BYTES = serverConfig.maxAssetSizeMb * 1024 * 1024; @@ -26,7 +27,7 @@ export async function POST(request: Request) { }); } const formData = await request.formData(); - const data = formData.get("image"); + const data = formData.get("file") ?? formData.get("image"); let buffer; let contentType; if (data instanceof File) { @@ -46,11 +47,12 @@ export async function POST(request: Request) { } const assetId = crypto.randomUUID(); + const fileName = data.name; await saveAsset({ userId: ctx.user.id, assetId, - metadata: { contentType }, + metadata: { contentType, fileName }, asset: buffer, }); @@ -58,5 +60,6 @@ export async function POST(request: Request) { assetId, contentType, size: buffer.byteLength, + fileName, } satisfies ZUploadResponse); } diff --git a/apps/web/components/dashboard/UploadDropzone.tsx b/apps/web/components/dashboard/UploadDropzone.tsx index bd08d2cf..f6243885 100644 --- a/apps/web/components/dashboard/UploadDropzone.tsx +++ b/apps/web/components/dashboard/UploadDropzone.tsx @@ -29,7 +29,7 @@ function useUploadAsset({ onComplete }: { onComplete: () => void }) { const { mutateAsync: runUpload } = useMutation({ mutationFn: async (file: File) => { const formData = new FormData(); - formData.append("image", file); + formData.append("file", file); const resp = await fetch("/api/assets", { method: "POST", body: formData, @@ -40,8 +40,9 @@ function useUploadAsset({ onComplete }: { onComplete: () => void }) { return zUploadResponseSchema.parse(await resp.json()); }, onSuccess: async (resp) => { - const assetId = resp.assetId; - return createBookmark({ type: "asset", assetId, assetType: "image" }); + const assetType = + resp.contentType === "application/pdf" ? "pdf" : "image"; + return createBookmark({ ...resp, type: "asset", assetType }); }, onError: (error, req) => { const err = zUploadErrorSchema.parse(JSON.parse(error.message)); diff --git a/apps/web/components/dashboard/bookmarks/AssetCard.tsx b/apps/web/components/dashboard/bookmarks/AssetCard.tsx index 460dbe98..8997a7e2 100644 --- a/apps/web/components/dashboard/bookmarks/AssetCard.tsx +++ b/apps/web/components/dashboard/bookmarks/AssetCard.tsx @@ -59,6 +59,13 @@ export default function AssetCard({ /> )} + {bookmarkedAsset.assetType == "pdf" && ( +