diff --git a/components/LinkViews/LinkCard.tsx b/components/LinkViews/LinkCard.tsx
index d93904a..9299442 100644
--- a/components/LinkViews/LinkCard.tsx
+++ b/components/LinkViews/LinkCard.tsx
@@ -19,6 +19,7 @@ import { generateLinkHref } from "@/lib/client/generateLinkHref";
import useAccountStore from "@/store/account";
import usePermissions from "@/hooks/usePermissions";
import toast from "react-hot-toast";
+import LinkTypeBadge from "./LinkComponents/LinkTypeBadge";
type Props = {
link: LinkIncludingShortenedCollectionAndTags;
@@ -53,7 +54,9 @@ export default function LinkCard({ link, flipDropdown, editMode }: Props) {
let shortendURL;
try {
- shortendURL = new URL(link.url || "").host.toLowerCase();
+ if (link.url) {
+ shortendURL = new URL(link.url).host.toLowerCase();
+ }
} catch (error) {
console.log(error);
}
@@ -109,7 +112,6 @@ export default function LinkCard({ link, flipDropdown, editMode }: Props) {
editMode &&
(permissions === true || permissions?.canCreate || permissions?.canDelete);
- // window.open ('www.yourdomain.com', '_ blank');
return (
{
diff --git a/lib/api/archiveHandler.ts b/lib/api/archiveHandler.ts
index 08a35b5..a32498f 100644
--- a/lib/api/archiveHandler.ts
+++ b/lib/api/archiveHandler.ts
@@ -7,9 +7,9 @@ import { JSDOM } from "jsdom";
import DOMPurify from "dompurify";
import { Collection, Link, User } from "@prisma/client";
import validateUrlSize from "./validateUrlSize";
-import removeFile from "./storage/removeFile";
-import Jimp from "jimp";
import createFolder from "./storage/createFolder";
+import generatePreview from "./generatePreview";
+import { removeFiles } from "./manageLinkFiles";
type LinksAndCollectionAndOwner = Link & {
collection: Collection & {
@@ -51,6 +51,14 @@ export default async function archiveHandler(link: LinksAndCollectionAndOwner) {
);
});
+ createFolder({
+ filePath: `archives/preview/${link.collectionId}`,
+ });
+
+ createFolder({
+ filePath: `archives/${link.collectionId}`,
+ });
+
try {
await Promise.race([
(async () => {
@@ -162,10 +170,6 @@ export default async function archiveHandler(link: LinksAndCollectionAndOwner) {
return metaTag ? (metaTag as any).content : null;
});
- createFolder({
- filePath: `archives/preview/${link.collectionId}`,
- });
-
if (ogImageUrl) {
console.log("Found og:image URL:", ogImageUrl);
@@ -175,35 +179,7 @@ export default async function archiveHandler(link: LinksAndCollectionAndOwner) {
// Check if imageResponse is not null
if (imageResponse && !link.preview?.startsWith("archive")) {
const buffer = await imageResponse.body();
-
- // Check if buffer is not null
- if (buffer) {
- // Load the image using Jimp
- Jimp.read(buffer, async (err, image) => {
- if (image && !err) {
- image?.resize(1280, Jimp.AUTO).quality(20);
- const processedBuffer = await image?.getBufferAsync(
- Jimp.MIME_JPEG
- );
-
- createFile({
- data: processedBuffer,
- filePath: `archives/preview/${link.collectionId}/${link.id}.jpeg`,
- }).then(() => {
- return prisma.link.update({
- where: { id: link.id },
- data: {
- preview: `archives/preview/${link.collectionId}/${link.id}.jpeg`,
- },
- });
- });
- }
- }).catch((err) => {
- console.error("Error processing the image:", err);
- });
- } else {
- console.log("No image data found.");
- }
+ await generatePreview(buffer, link.collectionId, link.id);
}
await page.goBack();
@@ -323,14 +299,7 @@ export default async function archiveHandler(link: LinksAndCollectionAndOwner) {
},
});
else {
- removeFile({ filePath: `archives/${link.collectionId}/${link.id}.png` });
- removeFile({ filePath: `archives/${link.collectionId}/${link.id}.pdf` });
- removeFile({
- filePath: `archives/${link.collectionId}/${link.id}_readability.json`,
- });
- removeFile({
- filePath: `archives/preview/${link.collectionId}/${link.id}.jpeg`,
- });
+ await removeFiles(link.id, link.collectionId);
}
await browser.close();
diff --git a/lib/api/controllers/links/bulk/deleteLinksById.ts b/lib/api/controllers/links/bulk/deleteLinksById.ts
index 466db98..2db3896 100644
--- a/lib/api/controllers/links/bulk/deleteLinksById.ts
+++ b/lib/api/controllers/links/bulk/deleteLinksById.ts
@@ -2,6 +2,7 @@ import { prisma } from "@/lib/api/db";
import { UsersAndCollections } from "@prisma/client";
import getPermission from "@/lib/api/getPermission";
import removeFile from "@/lib/api/storage/removeFile";
+import { removeFiles } from "@/lib/api/manageLinkFiles";
export default async function deleteLinksById(
userId: number,
@@ -43,15 +44,7 @@ export default async function deleteLinksById(
const linkId = linkIds[i];
const collectionIsAccessible = collectionIsAccessibleArray[i];
- removeFile({
- filePath: `archives/${collectionIsAccessible?.id}/${linkId}.pdf`,
- });
- removeFile({
- filePath: `archives/${collectionIsAccessible?.id}/${linkId}.png`,
- });
- removeFile({
- filePath: `archives/${collectionIsAccessible?.id}/${linkId}_readability.json`,
- });
+ if (collectionIsAccessible) removeFiles(linkId, collectionIsAccessible.id);
}
return { response: deletedLinks, status: 200 };
diff --git a/lib/api/controllers/links/linkId/deleteLinkById.ts b/lib/api/controllers/links/linkId/deleteLinkById.ts
index db68ee7..dba90cb 100644
--- a/lib/api/controllers/links/linkId/deleteLinkById.ts
+++ b/lib/api/controllers/links/linkId/deleteLinkById.ts
@@ -2,6 +2,7 @@ import { prisma } from "@/lib/api/db";
import { Link, UsersAndCollections } from "@prisma/client";
import getPermission from "@/lib/api/getPermission";
import removeFile from "@/lib/api/storage/removeFile";
+import { removeFiles } from "@/lib/api/manageLinkFiles";
export default async function deleteLink(userId: number, linkId: number) {
if (!linkId) return { response: "Please choose a valid link.", status: 401 };
@@ -12,7 +13,10 @@ export default async function deleteLink(userId: number, linkId: number) {
(e: UsersAndCollections) => e.userId === userId && e.canDelete
);
- if (!(collectionIsAccessible?.ownerId === userId || memberHasAccess))
+ if (
+ !collectionIsAccessible ||
+ !(collectionIsAccessible?.ownerId === userId || memberHasAccess)
+ )
return { response: "Collection is not accessible.", status: 401 };
const deleteLink: Link = await prisma.link.delete({
@@ -21,15 +25,7 @@ export default async function deleteLink(userId: number, linkId: number) {
},
});
- removeFile({
- filePath: `archives/${collectionIsAccessible?.id}/${linkId}.pdf`,
- });
- removeFile({
- filePath: `archives/${collectionIsAccessible?.id}/${linkId}.png`,
- });
- removeFile({
- filePath: `archives/${collectionIsAccessible?.id}/${linkId}_readability.json`,
- });
+ removeFiles(linkId, collectionIsAccessible.id);
return { response: deleteLink, status: 200 };
}
diff --git a/lib/api/controllers/links/linkId/updateLinkById.ts b/lib/api/controllers/links/linkId/updateLinkById.ts
index e6f7f0d..4a24f4a 100644
--- a/lib/api/controllers/links/linkId/updateLinkById.ts
+++ b/lib/api/controllers/links/linkId/updateLinkById.ts
@@ -2,7 +2,7 @@ import { prisma } from "@/lib/api/db";
import { LinkIncludingShortenedCollectionAndTags } from "@/types/global";
import { UsersAndCollections } from "@prisma/client";
import getPermission from "@/lib/api/getPermission";
-import moveFile from "@/lib/api/storage/moveFile";
+import { moveFiles } from "@/lib/api/manageLinkFiles";
export default async function updateLinkById(
userId: number,
@@ -146,20 +146,7 @@ export default async function updateLinkById(
});
if (collectionIsAccessible?.id !== data.collection.id) {
- await moveFile(
- `archives/${collectionIsAccessible?.id}/${linkId}.pdf`,
- `archives/${data.collection.id}/${linkId}.pdf`
- );
-
- await moveFile(
- `archives/${collectionIsAccessible?.id}/${linkId}.png`,
- `archives/${data.collection.id}/${linkId}.png`
- );
-
- await moveFile(
- `archives/${collectionIsAccessible?.id}/${linkId}_readability.json`,
- `archives/${data.collection.id}/${linkId}_readability.json`
- );
+ await moveFiles(linkId, collectionIsAccessible?.id, data.collection.id);
}
return { response: updatedLink, status: 200 };
diff --git a/lib/api/controllers/links/postLink.ts b/lib/api/controllers/links/postLink.ts
index ba4e513..85fd537 100644
--- a/lib/api/controllers/links/postLink.ts
+++ b/lib/api/controllers/links/postLink.ts
@@ -12,14 +12,16 @@ export default async function postLink(
link: LinkIncludingShortenedCollectionAndTags,
userId: number
) {
- try {
- new URL(link.url || "");
- } catch (error) {
- return {
- response:
- "Please enter a valid Address for the Link. (It should start with http/https)",
- status: 400,
- };
+ if (link.url || link.type === "url") {
+ try {
+ new URL(link.url || "");
+ } catch (error) {
+ return {
+ response:
+ "Please enter a valid Address for the Link. (It should start with http/https)",
+ status: 400,
+ };
+ }
}
if (!link.collection.id && link.collection.name) {
@@ -172,7 +174,7 @@ export default async function postLink(
const newLink = await prisma.link.create({
data: {
- url: link.url?.trim(),
+ url: link.url?.trim() || null,
name: link.name,
description,
type: linkType,
diff --git a/lib/api/controllers/users/userId/deleteUserById.ts b/lib/api/controllers/users/userId/deleteUserById.ts
index 2a5a083..976bd71 100644
--- a/lib/api/controllers/users/userId/deleteUserById.ts
+++ b/lib/api/controllers/users/userId/deleteUserById.ts
@@ -71,6 +71,10 @@ export default async function deleteUserById(
// Delete archive folders
removeFolder({ filePath: `archives/${collection.id}` });
+
+ await removeFolder({
+ filePath: `archives/preview/${collection.id}`,
+ });
}
// Delete collections after cleaning up related data
diff --git a/lib/api/generatePreview.ts b/lib/api/generatePreview.ts
new file mode 100644
index 0000000..6e81630
--- /dev/null
+++ b/lib/api/generatePreview.ts
@@ -0,0 +1,36 @@
+import Jimp from "jimp";
+import { prisma } from "./db";
+import createFile from "./storage/createFile";
+import createFolder from "./storage/createFolder";
+
+const generatePreview = async (
+ buffer: Buffer,
+ collectionId: number,
+ linkId: number
+) => {
+ if (buffer && collectionId && linkId) {
+ // Load the image using Jimp
+ await Jimp.read(buffer, async (err, image) => {
+ if (image && !err) {
+ image?.resize(1280, Jimp.AUTO).quality(20);
+ const processedBuffer = await image?.getBufferAsync(Jimp.MIME_JPEG);
+
+ createFile({
+ data: processedBuffer,
+ filePath: `archives/preview/${collectionId}/${linkId}.jpeg`,
+ }).then(() => {
+ return prisma.link.update({
+ where: { id: linkId },
+ data: {
+ preview: `archives/preview/${collectionId}/${linkId}.jpeg`,
+ },
+ });
+ });
+ }
+ }).catch((err) => {
+ console.error("Error processing the image:", err);
+ });
+ }
+};
+
+export default generatePreview;
diff --git a/lib/api/manageLinkFiles.ts b/lib/api/manageLinkFiles.ts
new file mode 100644
index 0000000..7bacdab
--- /dev/null
+++ b/lib/api/manageLinkFiles.ts
@@ -0,0 +1,61 @@
+import moveFile from "./storage/moveFile";
+import removeFile from "./storage/removeFile";
+
+const removeFiles = async (linkId: number, collectionId: number) => {
+ // PDF
+ await removeFile({
+ filePath: `archives/${collectionId}/${linkId}.pdf`,
+ });
+ // Images
+ await removeFile({
+ filePath: `archives/${collectionId}/${linkId}.png`,
+ });
+ await removeFile({
+ filePath: `archives/${collectionId}/${linkId}.jpeg`,
+ });
+ await removeFile({
+ filePath: `archives/${collectionId}/${linkId}.jpg`,
+ });
+ // Preview
+ await removeFile({
+ filePath: `archives/preview/${collectionId}/${linkId}.jpeg`,
+ });
+ // Readability
+ await removeFile({
+ filePath: `archives/${collectionId}/${linkId}_readability.json`,
+ });
+};
+
+const moveFiles = async (linkId: number, from: number, to: number) => {
+ await moveFile(
+ `archives/${from}/${linkId}.pdf`,
+ `archives/${to}/${linkId}.pdf`
+ );
+
+ await moveFile(
+ `archives/${from}/${linkId}.png`,
+ `archives/${to}/${linkId}.png`
+ );
+
+ await moveFile(
+ `archives/${from}/${linkId}.jpeg`,
+ `archives/${to}/${linkId}.jpeg`
+ );
+
+ await moveFile(
+ `archives/${from}/${linkId}.jpg`,
+ `archives/${to}/${linkId}.jpg`
+ );
+
+ await moveFile(
+ `archives/preview/${from}/${linkId}.jpeg`,
+ `archives/preview/${to}/${linkId}.jpeg`
+ );
+
+ await moveFile(
+ `archives/${from}/${linkId}_readability.json`,
+ `archives/${to}/${linkId}_readability.json`
+ );
+};
+
+export { removeFiles, moveFiles };
diff --git a/lib/client/generateLinkHref.ts b/lib/client/generateLinkHref.ts
index 47c1888..f012ab9 100644
--- a/lib/client/generateLinkHref.ts
+++ b/lib/client/generateLinkHref.ts
@@ -16,24 +16,30 @@ export const generateLinkHref = (
): string => {
// Return the links href based on the account's preference
// If the user's preference is not available, return the original link
- switch (account.linksRouteTo) {
- case LinksRouteTo.ORIGINAL:
- return link.url || "";
- case LinksRouteTo.PDF:
- if (!pdfAvailable(link)) return link.url || "";
+ if (account.linksRouteTo === LinksRouteTo.ORIGINAL && link.type === "url") {
+ return link.url || "";
+ } else if (account.linksRouteTo === LinksRouteTo.PDF || link.type === "pdf") {
+ if (!pdfAvailable(link)) return link.url || "";
- return `/preserved/${link?.id}?format=${ArchivedFormat.pdf}`;
- case LinksRouteTo.READABLE:
- if (!readabilityAvailable(link)) return link.url || "";
+ return `/preserved/${link?.id}?format=${ArchivedFormat.pdf}`;
+ } else if (
+ account.linksRouteTo === LinksRouteTo.READABLE &&
+ link.type === "url"
+ ) {
+ if (!readabilityAvailable(link)) return link.url || "";
- return `/preserved/${link?.id}?format=${ArchivedFormat.readability}`;
- case LinksRouteTo.SCREENSHOT:
- if (!screenshotAvailable(link)) return link.url || "";
+ return `/preserved/${link?.id}?format=${ArchivedFormat.readability}`;
+ } else if (
+ account.linksRouteTo === LinksRouteTo.SCREENSHOT ||
+ link.type === "image"
+ ) {
+ console.log(link);
+ if (!screenshotAvailable(link)) return link.url || "";
- return `/preserved/${link?.id}?format=${
- link?.image?.endsWith("png") ? ArchivedFormat.png : ArchivedFormat.jpeg
- }`;
- default:
- return link.url || "";
+ return `/preserved/${link?.id}?format=${
+ link?.image?.endsWith("png") ? ArchivedFormat.png : ArchivedFormat.jpeg
+ }`;
+ } else {
+ return link.url || "";
}
};
diff --git a/package.json b/package.json
index 4568588..6b03cf3 100644
--- a/package.json
+++ b/package.json
@@ -79,7 +79,7 @@
"nodemon": "^3.0.2",
"postcss": "^8.4.26",
"prettier": "3.1.1",
- "prisma": "^5.1.0",
+ "prisma": "^4.16.2",
"tailwindcss": "^3.3.3",
"ts-node": "^10.9.2",
"typescript": "4.9.4"
diff --git a/pages/api/v1/archives/[linkId].ts b/pages/api/v1/archives/[linkId].ts
index b13e690..9a439ec 100644
--- a/pages/api/v1/archives/[linkId].ts
+++ b/pages/api/v1/archives/[linkId].ts
@@ -9,6 +9,9 @@ import formidable from "formidable";
import createFile from "@/lib/api/storage/createFile";
import fs from "fs";
import verifyToken from "@/lib/api/verifyToken";
+import Jimp from "jimp";
+import generatePreview from "@/lib/api/generatePreview";
+import createFolder from "@/lib/api/storage/createFolder";
export const config = {
api: {
@@ -73,83 +76,97 @@ export default async function Index(req: NextApiRequest, res: NextApiResponse) {
return res.send(file);
}
+ } else if (req.method === "POST") {
+ const user = await verifyUser({ req, res });
+ if (!user) return;
+
+ const collectionPermissions = await getPermission({
+ userId: user.id,
+ linkId,
+ });
+
+ const memberHasAccess = collectionPermissions?.members.some(
+ (e: UsersAndCollections) => e.userId === user.id && e.canCreate
+ );
+
+ if (!(collectionPermissions?.ownerId === user.id || memberHasAccess))
+ return { response: "Collection is not accessible.", status: 401 };
+
+ // await uploadHandler(linkId, )
+
+ const MAX_UPLOAD_SIZE = Number(process.env.NEXT_PUBLIC_MAX_FILE_SIZE);
+
+ const form = formidable({
+ maxFields: 1,
+ maxFiles: 1,
+ maxFileSize: MAX_UPLOAD_SIZE || 30 * 1048576,
+ });
+
+ form.parse(req, async (err, fields, files) => {
+ const allowedMIMETypes = [
+ "application/pdf",
+ "image/png",
+ "image/jpg",
+ "image/jpeg",
+ ];
+
+ if (
+ err ||
+ !files.file ||
+ !files.file[0] ||
+ !allowedMIMETypes.includes(files.file[0].mimetype || "")
+ ) {
+ // Handle parsing error
+ return res.status(500).json({
+ response: `Sorry, we couldn't process your file. Please ensure it's a PDF, PNG, or JPG format and doesn't exceed ${MAX_UPLOAD_SIZE}MB.`,
+ });
+ } else {
+ const fileBuffer = fs.readFileSync(files.file[0].filepath);
+
+ const linkStillExists = await prisma.link.findUnique({
+ where: { id: linkId },
+ });
+
+ if (linkStillExists && files.file[0].mimetype?.includes("image")) {
+ const collectionId = collectionPermissions?.id as number;
+ createFolder({
+ filePath: `archives/preview/${collectionId}`,
+ });
+
+ generatePreview(fileBuffer, collectionId, linkId);
+ }
+
+ if (linkStillExists) {
+ await createFile({
+ filePath: `archives/${collectionPermissions?.id}/${
+ linkId + suffix
+ }`,
+ data: fileBuffer,
+ });
+
+ await prisma.link.update({
+ where: { id: linkId },
+ data: {
+ preview: files.file[0].mimetype?.includes("pdf")
+ ? "unavailable"
+ : undefined,
+ image: files.file[0].mimetype?.includes("image")
+ ? `archives/${collectionPermissions?.id}/${linkId + suffix}`
+ : null,
+ pdf: files.file[0].mimetype?.includes("pdf")
+ ? `archives/${collectionPermissions?.id}/${linkId + suffix}`
+ : null,
+ lastPreserved: new Date().toISOString(),
+ },
+ });
+ }
+
+ fs.unlinkSync(files.file[0].filepath);
+ }
+
+ return res.status(200).json({
+ response: files,
+ });
+ });
}
- // else if (req.method === "POST") {
- // const user = await verifyUser({ req, res });
- // if (!user) return;
-
- // const collectionPermissions = await getPermission({
- // userId: user.id,
- // linkId,
- // });
-
- // const memberHasAccess = collectionPermissions?.members.some(
- // (e: UsersAndCollections) => e.userId === user.id && e.canCreate
- // );
-
- // if (!(collectionPermissions?.ownerId === user.id || memberHasAccess))
- // return { response: "Collection is not accessible.", status: 401 };
-
- // // await uploadHandler(linkId, )
-
- // const MAX_UPLOAD_SIZE = Number(process.env.NEXT_PUBLIC_MAX_FILE_SIZE);
-
- // const form = formidable({
- // maxFields: 1,
- // maxFiles: 1,
- // maxFileSize: MAX_UPLOAD_SIZE || 30 * 1048576,
- // });
-
- // form.parse(req, async (err, fields, files) => {
- // const allowedMIMETypes = [
- // "application/pdf",
- // "image/png",
- // "image/jpg",
- // "image/jpeg",
- // ];
-
- // if (
- // err ||
- // !files.file ||
- // !files.file[0] ||
- // !allowedMIMETypes.includes(files.file[0].mimetype || "")
- // ) {
- // // Handle parsing error
- // return res.status(500).json({
- // response: `Sorry, we couldn't process your file. Please ensure it's a PDF, PNG, or JPG format and doesn't exceed ${MAX_UPLOAD_SIZE}MB.`,
- // });
- // } else {
- // const fileBuffer = fs.readFileSync(files.file[0].filepath);
-
- // const linkStillExists = await prisma.link.findUnique({
- // where: { id: linkId },
- // });
-
- // if (linkStillExists) {
- // await createFile({
- // filePath: `archives/${collectionPermissions?.id}/${
- // linkId + suffix
- // }`,
- // data: fileBuffer,
- // });
-
- // await prisma.link.update({
- // where: { id: linkId },
- // data: {
- // image: `archives/${collectionPermissions?.id}/${
- // linkId + suffix
- // }`,
- // lastPreserved: new Date().toISOString(),
- // },
- // });
- // }
-
- // fs.unlinkSync(files.file[0].filepath);
- // }
-
- // return res.status(200).json({
- // response: files,
- // });
- // });
- // }
}
diff --git a/pages/api/v1/links/[id]/archive/index.ts b/pages/api/v1/links/[id]/archive/index.ts
index 4693fac..78353bb 100644
--- a/pages/api/v1/links/[id]/archive/index.ts
+++ b/pages/api/v1/links/[id]/archive/index.ts
@@ -2,8 +2,8 @@ import type { NextApiRequest, NextApiResponse } from "next";
import { prisma } from "@/lib/api/db";
import verifyUser from "@/lib/api/verifyUser";
import isValidUrl from "@/lib/shared/isValidUrl";
-import removeFile from "@/lib/api/storage/removeFile";
import { Collection, Link } from "@prisma/client";
+import { removeFiles } from "@/lib/api/manageLinkFiles";
const RE_ARCHIVE_LIMIT = Number(process.env.RE_ARCHIVE_LIMIT) || 5;
@@ -80,16 +80,5 @@ const deleteArchivedFiles = async (link: Link & { collection: Collection }) => {
},
});
- await removeFile({
- filePath: `archives/${link.collection.id}/${link.id}.pdf`,
- });
- await removeFile({
- filePath: `archives/${link.collection.id}/${link.id}.png`,
- });
- await removeFile({
- filePath: `archives/${link.collection.id}/${link.id}_readability.json`,
- });
- await removeFile({
- filePath: `archives/preview/${link.collection.id}/${link.id}.png`,
- });
+ await removeFiles(link.id, link.collection.id);
};
diff --git a/store/links.ts b/store/links.ts
index 408a3ee..c2c3a8a 100644
--- a/store/links.ts
+++ b/store/links.ts
@@ -1,5 +1,8 @@
import { create } from "zustand";
-import { LinkIncludingShortenedCollectionAndTags } from "@/types/global";
+import {
+ ArchivedFormat,
+ LinkIncludingShortenedCollectionAndTags,
+} from "@/types/global";
import useTagStore from "./tags";
import useCollectionStore from "./collections";
@@ -19,6 +22,10 @@ type LinkStore = {
addLink: (
body: LinkIncludingShortenedCollectionAndTags
) => Promise;
+ uploadFile: (
+ link: LinkIncludingShortenedCollectionAndTags,
+ file: File
+ ) => Promise;
getLink: (linkId: number, publicRoute?: boolean) => Promise;
updateLink: (
link: LinkIncludingShortenedCollectionAndTags
@@ -79,6 +86,82 @@ const useLinkStore = create()((set) => ({
return { ok: response.ok, data: data.response };
},
+ uploadFile: async (link, file) => {
+ let fileType: ArchivedFormat | null = null;
+ let linkType: "url" | "image" | "pdf" | null = null;
+
+ if (file?.type === "image/jpg" || file.type === "image/jpeg") {
+ fileType = ArchivedFormat.jpeg;
+ linkType = "image";
+ } else if (file.type === "image/png") {
+ fileType = ArchivedFormat.png;
+ linkType = "image";
+ } else if (file.type === "application/pdf") {
+ fileType = ArchivedFormat.pdf;
+ linkType = "pdf";
+ } else {
+ return { ok: false, data: "Invalid file type." };
+ }
+
+ const response = await fetch("/api/v1/links", {
+ body: JSON.stringify({
+ ...link,
+ type: linkType,
+ name: link.name ? link.name : file.name,
+ }),
+ headers: {
+ "Content-Type": "application/json",
+ },
+ method: "POST",
+ });
+
+ const data = await response.json();
+
+ const createdLink: LinkIncludingShortenedCollectionAndTags = data.response;
+
+ console.log(data);
+
+ if (response.ok) {
+ const formBody = new FormData();
+ file && formBody.append("file", file);
+
+ await fetch(
+ `/api/v1/archives/${(data as any).response.id}?format=${fileType}`,
+ {
+ body: formBody,
+ method: "POST",
+ }
+ );
+
+ // get file extension
+ const extension = file.name.split(".").pop() || "";
+
+ set((state) => ({
+ links: [
+ {
+ ...createdLink,
+ image:
+ linkType === "image"
+ ? `archives/${createdLink.collectionId}/${
+ createdLink.id + extension
+ }`
+ : null,
+ pdf:
+ linkType === "pdf"
+ ? `archives/${createdLink.collectionId}/${
+ createdLink.id + ".pdf"
+ }`
+ : null,
+ },
+ ...state.links,
+ ],
+ }));
+ useTagStore.getState().setTags();
+ useCollectionStore.getState().setCollections();
+ }
+
+ return { ok: response.ok, data: data.response };
+ },
getLink: async (linkId, publicRoute) => {
const path = publicRoute
? `/api/v1/public/links/${linkId}`
diff --git a/yarn.lock b/yarn.lock
index 37c6839..d016ae9 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1301,10 +1301,10 @@
resolved "https://registry.yarnpkg.com/@prisma/engines-version/-/engines-version-4.16.1-1.4bc8b6e1b66cb932731fb1bdbbc550d1e010de81.tgz#d3b5dcf95b6d220e258cbf6ae19b06d30a7e9f14"
integrity sha512-q617EUWfRIDTriWADZ4YiWRZXCa/WuhNgLTVd+HqWLffjMSPzyM5uOWoauX91wvQClSKZU4pzI4JJLQ9Kl62Qg==
-"@prisma/engines@5.1.0":
- version "5.1.0"
- resolved "https://registry.yarnpkg.com/@prisma/engines/-/engines-5.1.0.tgz#4ccf7f344eaeee08ca1e4a1bb2dc14e36ff1d5ec"
- integrity sha512-HqaFsnPmZOdMWkPq6tT2eTVTQyaAXEDdKszcZ4yc7DGMBIYRP6j/zAJTtZUG9SsMV8FaucdL5vRyxY/p5Ni28g==
+"@prisma/engines@4.16.2":
+ version "4.16.2"
+ resolved "https://registry.yarnpkg.com/@prisma/engines/-/engines-4.16.2.tgz#5ec8dd672c2173d597e469194916ad4826ce2e5f"
+ integrity sha512-vx1nxVvN4QeT/cepQce68deh/Turxy5Mr+4L4zClFuK1GlxN3+ivxfuv+ej/gvidWn1cE1uAhW7ALLNlYbRUAw==
"@radix-ui/primitive@1.0.1":
version "1.0.1"
@@ -5038,12 +5038,12 @@ pretty-format@^3.8.0:
resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-3.8.0.tgz#bfbed56d5e9a776645f4b1ff7aa1a3ac4fa3c385"
integrity sha512-WuxUnVtlWL1OfZFQFuqvnvs6MiAGk9UNsBostyBOB0Is9wb5uRESevA6rnl/rkksXaGX3GzZhPup5d6Vp1nFew==
-prisma@^5.1.0:
- version "5.1.0"
- resolved "https://registry.yarnpkg.com/prisma/-/prisma-5.1.0.tgz#29e316b54844f5694a83017a9781a6d6f7cb99ea"
- integrity sha512-wkXvh+6wxk03G8qwpZMOed4Y3j+EQ+bMTlvbDZHeal6k1E8QuGKzRO7DRXlE1NV0WNgOAas8kwZqcLETQ2+BiQ==
+prisma@^4.16.2:
+ version "4.16.2"
+ resolved "https://registry.yarnpkg.com/prisma/-/prisma-4.16.2.tgz#469e0a0991c6ae5bcde289401726bb012253339e"
+ integrity sha512-SYCsBvDf0/7XSJyf2cHTLjLeTLVXYfqp7pG5eEVafFLeT0u/hLFz/9W196nDRGUOo1JfPatAEb+uEnTQImQC1g==
dependencies:
- "@prisma/engines" "5.1.0"
+ "@prisma/engines" "4.16.2"
process@^0.11.10:
version "0.11.10"