improvements

This commit is contained in:
daniel31x13 2023-12-13 06:59:36 -05:00
parent ca3eb29c48
commit a001f70b9d
11 changed files with 138 additions and 69 deletions

View File

@ -14,6 +14,10 @@ import useLinkStore from "@/store/links";
import { toast } from "react-hot-toast"; import { toast } from "react-hot-toast";
import { useRouter } from "next/router"; import { useRouter } from "next/router";
import { useSession } from "next-auth/react"; import { useSession } from "next-auth/react";
import {
pdfAvailable,
screenshotAvailable,
} from "@/lib/shared/getArchiveValidity";
export default function PreservedFormats() { export default function PreservedFormats() {
const session = useSession(); const session = useSession();
@ -29,13 +33,13 @@ export default function PreservedFormats() {
useEffect(() => { useEffect(() => {
let interval: any; let interval: any;
if (link?.screenshotPath === "pending" || link?.pdfPath === "pending") { if (screenshotAvailable(link) && pdfAvailable(link)) {
let isPublicRoute = router.pathname.startsWith("/public") let isPublicRoute = router.pathname.startsWith("/public")
? true ? true
: undefined; : undefined;
interval = setInterval( interval = setInterval(
() => getLink(link.id as number, isPublicRoute), () => getLink(link?.id as number, isPublicRoute),
5000 5000
); );
} else { } else {
@ -89,7 +93,7 @@ export default function PreservedFormats() {
return ( return (
<div className={`flex flex-col gap-3 sm:w-[35rem] w-80 pt-3`}> <div className={`flex flex-col gap-3 sm:w-[35rem] w-80 pt-3`}>
{link?.screenshotPath && link?.screenshotPath !== "pending" ? ( {screenshotAvailable(link) ? (
<div className="flex justify-between items-center pr-1 border border-neutral-content rounded-md"> <div className="flex justify-between items-center pr-1 border border-neutral-content rounded-md">
<div className="flex gap-2 items-center"> <div className="flex gap-2 items-center">
<div className="bg-primary text-primary-content p-2 rounded-l-md"> <div className="bg-primary text-primary-content p-2 rounded-l-md">
@ -112,7 +116,7 @@ export default function PreservedFormats() {
<Link <Link
href={`/api/v1/archives/${link?.id}?format=${ href={`/api/v1/archives/${link?.id}?format=${
link.screenshotPath.endsWith("png") link?.screenshotPath?.endsWith("png")
? ArchivedFormat.png ? ArchivedFormat.png
: ArchivedFormat.jpeg : ArchivedFormat.jpeg
}`} }`}
@ -128,7 +132,7 @@ export default function PreservedFormats() {
</div> </div>
) : undefined} ) : undefined}
{link?.pdfPath && link.pdfPath !== "pending" ? ( {pdfAvailable(link) ? (
<div className="flex justify-between items-center pr-1 border border-neutral-content rounded-md"> <div className="flex justify-between items-center pr-1 border border-neutral-content rounded-md">
<div className="flex gap-2 items-center"> <div className="flex gap-2 items-center">
<div className="bg-primary text-primary-content p-2 rounded-l-md"> <div className="bg-primary text-primary-content p-2 rounded-l-md">
@ -167,12 +171,7 @@ export default function PreservedFormats() {
{link?.collection.ownerId === session.data?.user.id ? ( {link?.collection.ownerId === session.data?.user.id ? (
<div <div
className={`btn btn-accent dark:border-violet-400 text-white ${ className={`btn btn-accent dark:border-violet-400 text-white ${
link?.pdfPath && screenshotAvailable(link) && pdfAvailable(link) ? "mt-3" : ""
link?.screenshotPath &&
link?.pdfPath !== "pending" &&
link?.screenshotPath !== "pending"
? "mt-3"
: ""
}`} }`}
onClick={() => updateArchive()} onClick={() => updateArchive()}
> >
@ -189,12 +188,7 @@ export default function PreservedFormats() {
)}`} )}`}
target="_blank" target="_blank"
className={`text-neutral duration-100 hover:opacity-60 flex gap-2 w-fit items-center text-sm ${ className={`text-neutral duration-100 hover:opacity-60 flex gap-2 w-fit items-center text-sm ${
link?.pdfPath && screenshotAvailable(link) && pdfAvailable(link) ? "sm:mt-3" : ""
link?.screenshotPath &&
link?.pdfPath !== "pending" &&
link?.screenshotPath !== "pending"
? "sm:mt-3"
: ""
}`} }`}
> >
<FontAwesomeIcon <FontAwesomeIcon

View File

@ -103,12 +103,9 @@ export default function DeleteCollectionModal({
/> />
</svg> </svg>
<span> <span>
<b> <b>Warning:</b> Deleting this collection will permanently erase
Warning: Deleting this collection will permanently erase all all its contents, and it will become inaccessible to everyone,
its contents including members with previous access.
</b>
, and it will become inaccessible to everyone, including members
with previous access.
</span> </span>
</div> </div>
</> </>

View File

@ -70,7 +70,9 @@ export default function DeleteLinkModal({ onClose, activeLink }: Props) {
d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"
/> />
</svg> </svg>
<span>Warning: This action is irreversible!</span> <span>
<b>Warning:</b> This action is irreversible!
</span>
</div> </div>
<p> <p>

View File

@ -1,9 +1,4 @@
import React, { useEffect, useState } from "react"; import React, { useEffect, useState } from "react";
import { Toaster } from "react-hot-toast";
import CollectionSelection from "@/components/InputSelect/CollectionSelection";
import TagSelection from "@/components/InputSelect/TagSelection";
import TextInput from "@/components/TextInput";
import unescapeString from "@/lib/client/unescapeString";
import useLinkStore from "@/store/links"; import useLinkStore from "@/store/links";
import { import {
ArchivedFormat, ArchivedFormat,
@ -23,6 +18,10 @@ import Modal from "../Modal";
import { faFileImage, faFilePdf } from "@fortawesome/free-regular-svg-icons"; import { faFileImage, faFilePdf } from "@fortawesome/free-regular-svg-icons";
import { useRouter } from "next/router"; import { useRouter } from "next/router";
import { useSession } from "next-auth/react"; import { useSession } from "next-auth/react";
import {
pdfAvailable,
screenshotAvailable,
} from "@/lib/shared/getArchiveValidity";
type Props = { type Props = {
onClose: Function; onClose: Function;
@ -114,7 +113,7 @@ export default function PreservedFormatsModal({ onClose, activeLink }: Props) {
<div className="divider mb-3 mt-1"></div> <div className="divider mb-3 mt-1"></div>
<div className={`flex flex-col gap-3`}> <div className={`flex flex-col gap-3`}>
{link?.screenshotPath && link?.screenshotPath !== "pending" ? ( {screenshotAvailable(link) ? (
<div className="flex justify-between items-center pr-1 border border-neutral-content rounded-md"> <div className="flex justify-between items-center pr-1 border border-neutral-content rounded-md">
<div className="flex gap-2 items-center"> <div className="flex gap-2 items-center">
<div className="bg-primary text-primary-content p-2 rounded-l-md"> <div className="bg-primary text-primary-content p-2 rounded-l-md">
@ -137,7 +136,7 @@ export default function PreservedFormatsModal({ onClose, activeLink }: Props) {
<Link <Link
href={`/api/v1/archives/${link?.id}?format=${ href={`/api/v1/archives/${link?.id}?format=${
link.screenshotPath.endsWith("png") link.screenshotPath?.endsWith("png")
? ArchivedFormat.png ? ArchivedFormat.png
: ArchivedFormat.jpeg : ArchivedFormat.jpeg
}`} }`}
@ -192,12 +191,7 @@ export default function PreservedFormatsModal({ onClose, activeLink }: Props) {
{link?.collection.ownerId === session.data?.user.id ? ( {link?.collection.ownerId === session.data?.user.id ? (
<div <div
className={`btn btn-accent w-1/2 dark:border-violet-400 text-white ${ className={`btn btn-accent w-1/2 dark:border-violet-400 text-white ${
link?.pdfPath && screenshotAvailable(link) && pdfAvailable(link) ? "mt-3" : ""
link?.screenshotPath &&
link?.pdfPath !== "pending" &&
link?.screenshotPath !== "pending"
? "mt-3"
: ""
}`} }`}
onClick={() => updateArchive()} onClick={() => updateArchive()}
> >
@ -214,12 +208,7 @@ export default function PreservedFormatsModal({ onClose, activeLink }: Props) {
)}`} )}`}
target="_blank" target="_blank"
className={`text-neutral duration-100 hover:opacity-60 flex gap-2 w-1/2 justify-center items-center text-sm ${ className={`text-neutral duration-100 hover:opacity-60 flex gap-2 w-1/2 justify-center items-center text-sm ${
link?.pdfPath && screenshotAvailable(link) && pdfAvailable(link) ? "sm:mt-3" : ""
link?.screenshotPath &&
link?.pdfPath !== "pending" &&
link?.screenshotPath !== "pending"
? "sm:mt-3"
: ""
}`} }`}
> >
<p className="whitespace-nowrap"> <p className="whitespace-nowrap">

View File

@ -68,7 +68,7 @@ export default function Navbar() {
<div <div
tabIndex={0} tabIndex={0}
role="button" role="button"
className="flex items-center group btn btn-accent dark:border-violet-400 text-white btn-sm px-2" className="flex min-w-[3.4rem] items-center group btn btn-accent dark:border-violet-400 text-white btn-sm px-2"
> >
<FontAwesomeIcon icon={faPlus} className="w-5 h-5" /> <FontAwesomeIcon icon={faPlus} className="w-5 h-5" />
<FontAwesomeIcon <FontAwesomeIcon

View File

@ -11,10 +11,23 @@ export default function NoLinksFound({ text }: Props) {
const [newLinkModal, setNewLinkModal] = useState(false); const [newLinkModal, setNewLinkModal] = useState(false);
return ( return (
<div className="border border-solid border-neutral-content w-full h-full flex flex-col justify-center p-10 rounded-2xl bg-base-200"> <div className="w-full h-full flex flex-col justify-center p-3">
<p className="text-center text-2xl"> <svg
xmlns="http://www.w3.org/2000/svg"
className="w-1/4 min-w-[7rem] max-w-[15rem] h-auto mx-auto mb-5"
fill="currentColor"
viewBox="0 0 16 16"
>
<path d="M9.752 6.193c.599.6 1.73.437 2.528-.362.798-.799.96-1.932.362-2.531-.599-.6-1.73-.438-2.528.361-.798.8-.96 1.933-.362 2.532" />
<path d="M15.811 3.312c-.363 1.534-1.334 3.626-3.64 6.218l-.24 2.408a2.56 2.56 0 0 1-.732 1.526L8.817 15.85a.51.51 0 0 1-.867-.434l.27-1.899c.04-.28-.013-.593-.131-.956a9.42 9.42 0 0 0-.249-.657l-.082-.202c-.815-.197-1.578-.662-2.191-1.277-.614-.615-1.079-1.379-1.275-2.195l-.203-.083a9.556 9.556 0 0 0-.655-.248c-.363-.119-.675-.172-.955-.132l-1.896.27A.51.51 0 0 1 .15 7.17l2.382-2.386c.41-.41.947-.67 1.524-.734h.006l2.4-.238C9.005 1.55 11.087.582 12.623.208c.89-.217 1.59-.232 2.08-.188.244.023.435.06.57.093.067.017.12.033.16.045.184.06.279.13.351.295l.029.073a3.475 3.475 0 0 1 .157.721c.055.485.051 1.178-.159 2.065Zm-4.828 7.475.04-.04-.107 1.081a1.536 1.536 0 0 1-.44.913l-1.298 1.3.054-.38c.072-.506-.034-.993-.172-1.418a8.548 8.548 0 0 0-.164-.45c.738-.065 1.462-.38 2.087-1.006ZM5.205 5c-.625.626-.94 1.351-1.004 2.09a8.497 8.497 0 0 0-.45-.164c-.424-.138-.91-.244-1.416-.172l-.38.054 1.3-1.3c.245-.246.566-.401.91-.44l1.08-.107-.04.039Zm9.406-3.961c-.38-.034-.967-.027-1.746.163-1.558.38-3.917 1.496-6.937 4.521-.62.62-.799 1.34-.687 2.051.107.676.483 1.362 1.048 1.928.564.565 1.25.941 1.924 1.049.71.112 1.429-.067 2.048-.688 3.079-3.083 4.192-5.444 4.556-6.987.183-.771.18-1.345.138-1.713a2.835 2.835 0 0 0-.045-.283 3.078 3.078 0 0 0-.3-.041Z" />
<path d="M7.009 12.139a7.632 7.632 0 0 1-1.804-1.352A7.568 7.568 0 0 1 3.794 8.86c-1.102.992-1.965 5.054-1.839 5.18.125.126 3.936-.896 5.054-1.902Z" />
</svg>
<p className="text-center text-xl sm:text-2xl">
{text || "You haven't created any Links Here"} {text || "You haven't created any Links Here"}
</p> </p>
<p className="text-center text-sm sm:text-base">
Start your journey by creating a new Link!
</p>
<div className="text-center w-full mt-4"> <div className="text-center w-full mt-4">
<div <div
onClick={() => { onClick={() => {

View File

@ -58,7 +58,7 @@ export default function SearchBar({ placeholder }: Props) {
} }
} }
}} }}
className="border border-neutral-content bg-base-200 focus:border-primary py-1 rounded-md pl-9 pr-2 w-44 sm:w-60 md:focus:w-80 duration-100 outline-none" className="border border-neutral-content bg-base-200 focus:border-primary py-1 rounded-md pl-9 pr-2 w-full max-w-[15rem] md:focus:w-80 md:w-[15rem] md:max-w-full duration-200 outline-none"
/> />
</div> </div>
); );

View File

@ -0,0 +1,28 @@
import { Link } from "@prisma/client";
export function screenshotAvailable(link: any) {
return (
link &&
link.screenshotPath &&
link.screenshotPath !== "pending" &&
link.screenshotPath !== "failed"
);
}
export function pdfAvailable(link: any) {
return (
link &&
link.pdfPath &&
link.pdfPath !== "pending" &&
link.pdfPath !== "failed"
);
}
export function readabilityAvailable(link: any) {
return (
link &&
link.readabilityPath &&
link.readabilityPath !== "pending" &&
link.readabilityPath !== "failed"
);
}

View File

@ -21,6 +21,7 @@ import {
import useModalStore from "@/store/modals"; import useModalStore from "@/store/modals";
import { useSession } from "next-auth/react"; import { useSession } from "next-auth/react";
import useLocalSettingsStore from "@/store/localSettings"; import useLocalSettingsStore from "@/store/localSettings";
import { readabilityAvailable } from "@/lib/shared/getArchiveValidity";
type LinkContent = { type LinkContent = {
title: string; title: string;
@ -66,11 +67,7 @@ export default function Index() {
useEffect(() => { useEffect(() => {
const fetchLinkContent = async () => { const fetchLinkContent = async () => {
if ( if (router.query.id && readabilityAvailable(link)) {
router.query.id &&
link?.readabilityPath &&
link?.readabilityPath !== "pending"
) {
const response = await fetch( const response = await fetch(
`/api/v1/archives/${link?.id}?format=${ArchivedFormat.readability}` `/api/v1/archives/${link?.id}?format=${ArchivedFormat.readability}`
); );
@ -86,11 +83,7 @@ export default function Index() {
useEffect(() => { useEffect(() => {
let interval: any; let interval: any;
if ( if (link?.readabilityPath === "pending") {
link?.screenshotPath === "pending" ||
link?.pdfPath === "pending" ||
link?.readabilityPath === "pending"
) {
interval = setInterval(() => getLink(link.id as number), 5000); interval = setInterval(() => getLink(link.id as number), 5000);
} else { } else {
if (interval) { if (interval) {

View File

@ -17,6 +17,7 @@ import { faBoxesStacked, faFolder } from "@fortawesome/free-solid-svg-icons";
import useModalStore from "@/store/modals"; import useModalStore from "@/store/modals";
import { useSession } from "next-auth/react"; import { useSession } from "next-auth/react";
import useLocalSettingsStore from "@/store/localSettings"; import useLocalSettingsStore from "@/store/localSettings";
import { readabilityAvailable } from "@/lib/shared/getArchiveValidity";
type LinkContent = { type LinkContent = {
title: string; title: string;
@ -62,11 +63,7 @@ export default function Index() {
useEffect(() => { useEffect(() => {
const fetchLinkContent = async () => { const fetchLinkContent = async () => {
if ( if (router.query.id && readabilityAvailable(link)) {
router.query.id &&
link?.readabilityPath &&
link?.readabilityPath !== "pending"
) {
const response = await fetch( const response = await fetch(
`/api/v1/archives/${link?.id}?format=${ArchivedFormat.readability}` `/api/v1/archives/${link?.id}?format=${ArchivedFormat.readability}`
); );
@ -82,11 +79,7 @@ export default function Index() {
useEffect(() => { useEffect(() => {
let interval: any; let interval: any;
if ( if (link?.readabilityPath === "pending") {
link?.screenshotPath === "pending" ||
link?.pdfPath === "pending" ||
link?.readabilityPath === "pending"
) {
interval = setInterval(() => getLink(link.id as number, true), 5000); interval = setInterval(() => getLink(link.id as number, true), 5000);
} else { } else {
if (interval) { if (interval) {

View File

@ -15,8 +15,9 @@ type LinksAndCollectionAndOwner = Link & {
}; };
async function processBatch() { async function processBatch() {
const links = await prisma.link.findMany({ const linksOldToNew = await prisma.link.findMany({
where: { where: {
url: { not: null },
OR: [ OR: [
{ {
collection: { collection: {
@ -71,6 +72,63 @@ async function processBatch() {
}, },
}); });
const linksNewToOld = await prisma.link.findMany({
where: {
url: { not: null },
OR: [
{
collection: {
owner: {
archiveAsScreenshot: true,
},
},
screenshotPath: null,
},
{
collection: {
owner: {
archiveAsScreenshot: true,
},
},
screenshotPath: "pending",
},
///////////////////////
{
collection: {
owner: {
archiveAsPDF: true,
},
},
pdfPath: null,
},
{
collection: {
owner: {
archiveAsPDF: true,
},
},
pdfPath: "pending",
},
///////////////////////
{
readabilityPath: null,
},
{
readabilityPath: "pending",
},
],
},
take: archiveTakeCount,
orderBy: { createdAt: "desc" },
include: {
collection: {
include: {
owner: true,
},
},
},
});
const archiveLink = async (link: LinksAndCollectionAndOwner) => { const archiveLink = async (link: LinksAndCollectionAndOwner) => {
try { try {
console.log( console.log(
@ -94,7 +152,9 @@ async function processBatch() {
}; };
// Process each link in the batch concurrently // Process each link in the batch concurrently
const processingPromises = links.map((e) => archiveLink(e)); const processingPromises = [...linksOldToNew, ...linksNewToOld].map((e) =>
archiveLink(e)
);
await Promise.allSettled(processingPromises); await Promise.allSettled(processingPromises);
} }