aboutsummaryrefslogtreecommitdiffstats
path: root/apps/mobile/lib/upload.ts
diff options
context:
space:
mode:
authorMohamed Bassem <me@mbassem.com>2024-03-19 00:33:11 +0000
committerGitHub <noreply@github.com>2024-03-19 00:33:11 +0000
commit785a5b574992296e187a66412dd42f7b4a686353 (patch)
tree64b608927cc63d7494395f639636fd4b36e5a977 /apps/mobile/lib/upload.ts
parent549520919c482e72cdf7adae5ba852d1b6cbe5aa (diff)
downloadkarakeep-785a5b574992296e187a66412dd42f7b4a686353.tar.zst
Feature: Add support for uploading images and automatically inferring their tags (#2)
* feature: Experimental support for asset uploads * feature(web): Add new bookmark type asset * feature: Add support for automatically tagging images * fix: Add support for image assets in preview page * use next Image for fetching the images * Fix auth and error codes in the route handlers * Add support for image uploads on mobile * Fix typing of upload requests * Remove the ugly dragging box * Bump mobile version to 1.3 * Change the editor card placeholder to mention uploading images * Fix a typo * Change ios icon for photo library * Silence typescript error
Diffstat (limited to 'apps/mobile/lib/upload.ts')
-rw-r--r--apps/mobile/lib/upload.ts72
1 files changed, 72 insertions, 0 deletions
diff --git a/apps/mobile/lib/upload.ts b/apps/mobile/lib/upload.ts
new file mode 100644
index 00000000..d511becc
--- /dev/null
+++ b/apps/mobile/lib/upload.ts
@@ -0,0 +1,72 @@
+import { useMutation } from "@tanstack/react-query";
+
+import type { Settings } from "./settings";
+import { api } from "./trpc";
+import type { ZBookmark } from "@hoarder/trpc/types/bookmarks";
+import { zUploadResponseSchema, zUploadErrorSchema } from "@hoarder/trpc/types/uploads";
+
+export function useUploadAsset(
+ settings: Settings,
+ options: { onSuccess?: (bookmark: ZBookmark) => void; onError?: (e: string) => void },
+) {
+ const invalidateAllBookmarks =
+ api.useUtils().bookmarks.getBookmarks.invalidate;
+
+ const {
+ mutate: createBookmark,
+ isPending: isCreatingBookmark,
+ } = api.bookmarks.createBookmark.useMutation({
+ onSuccess: (d) => {
+ invalidateAllBookmarks();
+ if (options.onSuccess) {
+ options.onSuccess(d);
+ }
+ },
+ onError: (e) => {
+ if (options.onError) {
+ options.onError(e.message);
+ }
+ },
+ });
+
+ const {
+ mutate: uploadAsset,
+ isPending: isUploading,
+ } = useMutation({
+ 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", {
+ uri: file.uri,
+ name: file.name,
+ type: file.type,
+ });
+ const resp = await fetch(`${settings.address}/api/assets`, {
+ method: "POST",
+ body: formData,
+ headers: {
+ Authorization: `Bearer ${settings.apiKey}`,
+ },
+ });
+ if (!resp.ok) {
+ throw new Error(await resp.text());
+ }
+ return zUploadResponseSchema.parse(await resp.json());
+ },
+ onSuccess: (resp) => {
+ const assetId = resp.assetId;
+ createBookmark({ type: "asset", assetId, assetType: "image" });
+ },
+ onError: (e) => {
+ if (options.onError) {
+ const err = zUploadErrorSchema.parse(JSON.parse(e.message));
+ options.onError(err.error);
+ }
+ },
+ });
+
+ return {
+ uploadAsset,
+ isPending: isUploading || isCreatingBookmark,
+ };
+}