diff --git a/components/Modal/Link/LinkDetails.tsx b/components/Modal/Link/LinkDetails.tsx index 7060ee8..4b870d8 100644 --- a/components/Modal/Link/LinkDetails.tsx +++ b/components/Modal/Link/LinkDetails.tsx @@ -239,6 +239,16 @@ export default function LinkDetails({ link, isOwnerOrMod }: Props) {
+
handleDownload("png")} + className="cursor-pointer hover:bg-slate-200 hover:dark:bg-neutral-700 duration-100 p-2 rounded-md" + > + +
+ - -
handleDownload("png")} - className="cursor-pointer hover:bg-slate-200 hover:dark:bg-neutral-700 duration-100 p-2 rounded-md" - > - -
@@ -272,6 +272,16 @@ export default function LinkDetails({ link, isOwnerOrMod }: Props) {
+
handleDownload("pdf")} + className="cursor-pointer hover:bg-slate-200 hover:dark:bg-neutral-700 duration-100 p-2 rounded-md" + > + +
+ - -
handleDownload("pdf")} - className="cursor-pointer hover:bg-slate-200 hover:dark:bg-neutral-700 duration-100 p-2 rounded-md" - > - -
@@ -301,7 +301,9 @@ export default function LinkDetails({ link, isOwnerOrMod }: Props) { -

Archive.org Snapshot

+

+ Latest archive.org Snapshot +

{ - setModal({ - modal: "ACCOUNT", - state: true, - active: account, - }); - setProfileDropdown(!profileDropdown); - }, + href: "/settings/account", }, { name: `Switch to ${theme === "light" ? "Dark" : "Light"}`, diff --git a/lib/api/archive.ts b/lib/api/archive.ts index 685413e..fce0454 100644 --- a/lib/api/archive.ts +++ b/lib/api/archive.ts @@ -1,55 +1,72 @@ -import { Page, chromium, devices } from "playwright"; +import { chromium, devices } from "playwright"; import { prisma } from "@/lib/api/db"; import createFile from "@/lib/api/storage/createFile"; import sendToWayback from "./sendToWayback"; -export default async function archive(linkId: number, url: string) { - const browser = await chromium.launch(); - const context = await browser.newContext(devices["Desktop Chrome"]); - const page = await context.newPage(); +export default async function archive( + linkId: number, + url: string, + userId: number +) { + const user = await prisma.user.findUnique({ + where: { + id: userId, + }, + }); - sendToWayback(url); + if (user?.archiveAsWaybackMachine) sendToWayback(url); - try { - await page.goto(url, { waitUntil: "domcontentloaded" }); + if (user?.archiveAsPDF || user?.archiveAsScreenshot) { + const browser = await chromium.launch(); + const context = await browser.newContext(devices["Desktop Chrome"]); + const page = await context.newPage(); - await page.evaluate( - autoScroll, - Number(process.env.AUTOSCROLL_TIMEOUT) || 30 - ); + try { + await page.goto(url, { waitUntil: "domcontentloaded" }); - const linkExists = await prisma.link.findUnique({ - where: { - id: linkId, - }, - }); + await page.evaluate( + autoScroll, + Number(process.env.AUTOSCROLL_TIMEOUT) || 30 + ); - if (linkExists) { - const pdf = await page.pdf({ - width: "1366px", - height: "1931px", - printBackground: true, - margin: { top: "15px", bottom: "15px" }, - }); - const screenshot = await page.screenshot({ - fullPage: true, + const linkExists = await prisma.link.findUnique({ + where: { + id: linkId, + }, }); - createFile({ - data: screenshot, - filePath: `archives/${linkExists.collectionId}/${linkId}.png`, - }); + if (linkExists) { + if (user.archiveAsScreenshot) { + const screenshot = await page.screenshot({ + fullPage: true, + }); - createFile({ - data: pdf, - filePath: `archives/${linkExists.collectionId}/${linkId}.pdf`, - }); + createFile({ + data: screenshot, + filePath: `archives/${linkExists.collectionId}/${linkId}.png`, + }); + } + + if (user.archiveAsPDF) { + const pdf = await page.pdf({ + width: "1366px", + height: "1931px", + printBackground: true, + margin: { top: "15px", bottom: "15px" }, + }); + + createFile({ + data: pdf, + filePath: `archives/${linkExists.collectionId}/${linkId}.pdf`, + }); + } + } + + await browser.close(); + } catch (err) { + console.log(err); + await browser.close(); } - - await browser.close(); - } catch (err) { - console.log(err); - await browser.close(); } } diff --git a/lib/api/controllers/links/postLink.ts b/lib/api/controllers/links/postLink.ts index 8c849bb..a9afe16 100644 --- a/lib/api/controllers/links/postLink.ts +++ b/lib/api/controllers/links/postLink.ts @@ -94,7 +94,7 @@ export default async function postLink( createFolder({ filePath: `archives/${newLink.collectionId}` }); - archive(newLink.id, newLink.url); + archive(newLink.id, newLink.url, userId); return { response: newLink, status: 200 }; } diff --git a/lib/api/controllers/users/updateUser.ts b/lib/api/controllers/users/updateUser.ts index 5e1d0da..65cbb1c 100644 --- a/lib/api/controllers/users/updateUser.ts +++ b/lib/api/controllers/users/updateUser.ts @@ -108,6 +108,9 @@ export default async function updateUser( username: user.username.toLowerCase(), email: user.email?.toLowerCase(), isPrivate: user.isPrivate, + archiveAsScreenshot: user.archiveAsScreenshot, + archiveAsPDF: user.archiveAsPDF, + archiveAsWaybackMachine: user.archiveAsWaybackMachine, password: user.newPassword && user.newPassword !== "" ? newHashedPassword diff --git a/pages/settings/appearance.tsx b/pages/settings/appearance.tsx index ea5f0a3..95300f2 100644 --- a/pages/settings/appearance.tsx +++ b/pages/settings/appearance.tsx @@ -1,34 +1,37 @@ import SettingsLayout from "@/layouts/SettingsLayout"; import { useTheme } from "next-themes"; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { faSun, faMoon } from "@fortawesome/free-solid-svg-icons"; export default function appearance() { const { theme, setTheme } = useTheme(); - const handleToggle = () => { - if (theme === "dark") { - setTheme("light"); - } else { - setTheme("dark"); - } - }; - return ( +

Select Theme

setTheme("dark")} > -

Dark Theme

+ +

Dark Theme

- {/*
*/} + {/*
*/}
setTheme("light")} > -

Light Theme

- {/*
*/} + +

Light Theme

+ {/*
*/}
diff --git a/pages/settings/archive.tsx b/pages/settings/archive.tsx index c0faa5a..fc60772 100644 --- a/pages/settings/archive.tsx +++ b/pages/settings/archive.tsx @@ -1,10 +1,88 @@ +import Checkbox from "@/components/Checkbox"; +import SubmitButton from "@/components/SubmitButton"; import SettingsLayout from "@/layouts/SettingsLayout"; -import React from "react"; +import React, { useEffect, useState } from "react"; +import useAccountStore from "@/store/account"; +import { toast } from "react-hot-toast"; +import { AccountSettings } from "@/types/global"; export default function archive() { + const [submitLoader, setSubmitLoader] = useState(false); + const { account, updateAccount } = useAccountStore(); + const [user, setUser] = useState(account); + + const [archiveAsScreenshot, setArchiveAsScreenshot] = + useState(false); + const [archiveAsPDF, setArchiveAsPDF] = useState(false); + const [archiveAsWaybackMachine, setArchiveAsWaybackMachine] = + useState(false); + + useEffect(() => { + setUser({ + ...account, + archiveAsScreenshot, + archiveAsPDF, + archiveAsWaybackMachine, + }); + }, [account, archiveAsScreenshot, archiveAsPDF, archiveAsWaybackMachine]); + + function objectIsEmpty(obj: object) { + return Object.keys(obj).length === 0; + } + + useEffect(() => { + if (!objectIsEmpty(account)) { + setArchiveAsScreenshot(account.archiveAsScreenshot); + setArchiveAsPDF(account.archiveAsPDF); + setArchiveAsWaybackMachine(account.archiveAsWaybackMachine); + } + }, [account]); + + const submit = async () => { + setSubmitLoader(true); + + const load = toast.loading("Applying..."); + + const response = await updateAccount({ + ...user, + }); + + toast.dismiss(load); + + if (response.ok) { + toast.success("Settings Applied!"); + } else toast.error(response.data as string); + setSubmitLoader(false); + }; + return ( -
archive
+

Formats to Archive webpages:

+
+ setArchiveAsScreenshot(!archiveAsScreenshot)} + /> + setArchiveAsPDF(!archiveAsPDF)} + /> + + setArchiveAsWaybackMachine(!archiveAsWaybackMachine)} + /> +
+ +
); } diff --git a/prisma/migrations/20231019032936_modify_archive_formats/migration.sql b/prisma/migrations/20231019032936_modify_archive_formats/migration.sql new file mode 100644 index 0000000..89d866c --- /dev/null +++ b/prisma/migrations/20231019032936_modify_archive_formats/migration.sql @@ -0,0 +1,4 @@ +-- AlterTable +ALTER TABLE "User" ADD COLUMN "archiveAsPDF" BOOLEAN NOT NULL DEFAULT true, +ADD COLUMN "archiveAsScreenshot" BOOLEAN NOT NULL DEFAULT true, +ADD COLUMN "archiveAsWaybackMachine" BOOLEAN NOT NULL DEFAULT false; diff --git a/prisma/schema.prisma b/prisma/schema.prisma index eca457b..ab67eb6 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -54,6 +54,10 @@ model User { pinnedLinks Link[] + archiveAsScreenshot Boolean @default(true) + archiveAsPDF Boolean @default(true) + archiveAsWaybackMachine Boolean @default(false) + collectionsJoined UsersAndCollections[] isPrivate Boolean @default(false) whitelistedUsers WhitelistedUser[]