Add Single file archive method.

This commit is contained in:
András Rutkai
2024-03-15 19:41:41 +01:00
parent 5990d4ce2d
commit 5fe6a5b19a
32 changed files with 211 additions and 31 deletions
+2
View File
@@ -37,6 +37,7 @@ export default function CollectionCard({ collection, className }: Props) {
username: "",
image: "",
archiveAsScreenshot: undefined as unknown as boolean,
archiveAsSinglefile: undefined as unknown as boolean,
archiveAsPDF: undefined as unknown as boolean,
});
@@ -52,6 +53,7 @@ export default function CollectionCard({ collection, className }: Props) {
username: account.username as string,
image: account.image as string,
archiveAsScreenshot: account.archiveAsScreenshot as boolean,
archiveAsSinglefile: account.archiveAsSinglefile as boolean,
archiveAsPDF: account.archiveAsPDF as boolean,
});
}
@@ -43,6 +43,8 @@ export default function LinkGroupedIconURL({
<i className={`bi-file-earmark-pdf`}></i>
) : link.type === "image" ? (
<i className={`bi-file-earmark-image`}></i>
) : link.type === "singlefile" ? (
<i className={`bi-filetype-html`}></i>
) : undefined}
<p className="truncate bg-white text-black mr-1">
<p className="text-sm">{shortendURL}</p>
@@ -42,6 +42,8 @@ export default function LinkIcon({
<i className={`bi-file-earmark-pdf ${iconClasses}`}></i>
) : link.type === "image" ? (
<i className={`bi-file-earmark-image ${iconClasses}`}></i>
) : link.type === "singlefile" ? (
<i className={`bi-filetype-html ${iconClasses}`}></i>
) : undefined}
</>
);
@@ -65,6 +65,7 @@ export default function EditCollectionSharingModal({
username: "",
image: "",
archiveAsScreenshot: undefined as unknown as boolean,
archiveAsSinglefile: undefined as unknown as boolean,
archiveAsPDF: undefined as unknown as boolean,
});
+1
View File
@@ -29,6 +29,7 @@ export default function NewLinkModal({ onClose }: Props) {
image: "",
pdf: "",
readable: "",
singlefile: "",
textContent: "",
collection: {
name: "",
@@ -12,6 +12,7 @@ import { useSession } from "next-auth/react";
import {
pdfAvailable,
readabilityAvailable,
singlefileAvailable,
screenshotAvailable,
} from "@/lib/shared/getArchiveValidity";
import PreservedFormatRow from "@/components/PreserverdFormatRow";
@@ -42,6 +43,7 @@ export default function PreservedFormatsModal({ onClose, activeLink }: Props) {
username: "",
image: "",
archiveAsScreenshot: undefined as unknown as boolean,
archiveAsSinglefile: undefined as unknown as boolean,
archiveAsPDF: undefined as unknown as boolean,
});
@@ -59,6 +61,7 @@ export default function PreservedFormatsModal({ onClose, activeLink }: Props) {
username: account.username as string,
image: account.image as string,
archiveAsScreenshot: account.archiveAsScreenshot as boolean,
archiveAsSinglefile: account.archiveAsScreenshot as boolean,
archiveAsPDF: account.archiveAsPDF as boolean,
});
}
@@ -73,6 +76,9 @@ export default function PreservedFormatsModal({ onClose, activeLink }: Props) {
(collectionOwner.archiveAsScreenshot === true
? link.pdf && link.pdf !== "pending"
: true) &&
(collectionOwner.archiveAsSinglefile === true
? link.singlefile && link.singlefile !== "pending"
: true) &&
(collectionOwner.archiveAsPDF === true
? link.pdf && link.pdf !== "pending"
: true) &&
@@ -109,7 +115,7 @@ export default function PreservedFormatsModal({ onClose, activeLink }: Props) {
clearInterval(interval);
}
};
}, [link?.image, link?.pdf, link?.readable]);
}, [link?.image, link?.pdf, link?.readable, link?.singlefile]);
const updateArchive = async () => {
const load = toast.loading("Sending request...");
@@ -140,7 +146,8 @@ export default function PreservedFormatsModal({ onClose, activeLink }: Props) {
{isReady() &&
(screenshotAvailable(link) ||
pdfAvailable(link) ||
readabilityAvailable(link)) ? (
readabilityAvailable(link) ||
singlefileAvailable(link)) ? (
<p className="mb-3">
The following formats are available for this link:
</p>
@@ -183,6 +190,16 @@ export default function PreservedFormatsModal({ onClose, activeLink }: Props) {
activeLink={link}
/>
) : undefined}
{singlefileAvailable(link) ? (
<PreservedFormatRow
name={"Singlefile"}
icon={"bi-filetype-html"}
format={ArchivedFormat.singlefile}
activeLink={link}
downloadable={true}
/>
) : undefined}
</>
) : (
<div
+7 -3
View File
@@ -31,6 +31,7 @@ export default function UploadFileModal({ onClose }: Props) {
image: "",
pdf: "",
readable: "",
singlefile: "",
textContent: "",
collection: {
name: "",
@@ -101,7 +102,7 @@ export default function UploadFileModal({ onClose }: Props) {
const submit = async () => {
if (!submitLoader && file) {
let fileType: ArchivedFormat | null = null;
let linkType: "url" | "image" | "pdf" | null = null;
let linkType: "url" | "image" | "singlefile" | "pdf" | null = null;
if (file?.type === "image/jpg" || file.type === "image/jpeg") {
fileType = ArchivedFormat.jpeg;
@@ -109,6 +110,9 @@ export default function UploadFileModal({ onClose }: Props) {
} else if (file.type === "image/png") {
fileType = ArchivedFormat.png;
linkType = "image";
} else if (file.type === "text/html") {
fileType = ArchivedFormat.singlefile;
linkType = "singlefile";
} else if (file.type === "application/pdf") {
fileType = ArchivedFormat.pdf;
linkType = "pdf";
@@ -165,13 +169,13 @@ export default function UploadFileModal({ onClose }: Props) {
<label className="btn h-10 btn-sm w-full border border-neutral-content hover:border-neutral-content flex justify-between">
<input
type="file"
accept=".pdf,.png,.jpg,.jpeg"
accept=".pdf,.png,.jpg,.jpeg,.html"
className="cursor-pointer custom-file-input"
onChange={(e) => e.target.files && setFile(e.target.files[0])}
/>
</label>
<p className="text-xs font-semibold mt-2">
PDF, PNG, JPG (Up to {process.env.NEXT_PUBLIC_MAX_FILE_SIZE || 30}
PDF, PNG, JPG, HTML (Up to {process.env.NEXT_PUBLIC_MAX_FILE_SIZE || 30}
MB)
</p>
</div>
+6 -10
View File
@@ -1,10 +1,6 @@
import React, { useEffect, useState } from "react";
import useLinkStore from "@/store/links";
import {
ArchivedFormat,
LinkIncludingShortenedCollectionAndTags,
} from "@/types/global";
import toast from "react-hot-toast";
import { ArchivedFormat, LinkIncludingShortenedCollectionAndTags } from "@/types/global";
import Link from "next/link";
import { useRouter } from "next/router";
import { useSession } from "next-auth/react";
@@ -61,7 +57,7 @@ export default function PreservedFormatRow({
clearInterval(interval);
}
};
}, [link?.image, link?.pdf, link?.readable]);
}, [link?.image, link?.pdf, link?.readable, link?.singlefile]);
const handleDownload = () => {
const path = `/api/v1/archives/${link?.id}?format=${format}`;
@@ -69,10 +65,10 @@ export default function PreservedFormatRow({
.then((response) => {
if (response.ok) {
// Create a temporary link and click it to trigger the download
const link = document.createElement("a");
link.href = path;
link.download = format === ArchivedFormat.pdf ? "PDF" : "Screenshot";
link.click();
const anchorElement = document.createElement("a");
anchorElement.href = path;
anchorElement.download = format === ArchivedFormat.singlefile ? (link.name ?? 'index') : format === ArchivedFormat.pdf ? "PDF" : "Screenshot";
anchorElement.click();
} else {
console.error("Failed to download file");
}
+4 -2
View File
@@ -65,9 +65,11 @@ export default function ReadableView({ link }: Props) {
(link?.image === "pending" ||
link?.pdf === "pending" ||
link?.readable === "pending" ||
link?.singlefile === "pending" ||
!link?.image ||
!link?.pdf ||
!link?.readable)
!link?.readable ||
!link?.singlefile)
) {
interval = setInterval(() => getLink(link.id as number), 5000);
} else {
@@ -81,7 +83,7 @@ export default function ReadableView({ link }: Props) {
clearInterval(interval);
}
};
}, [link?.image, link?.pdf, link?.readable]);
}, [link?.image, link?.pdf, link?.readable, link?.singlefile]);
const rgbToHex = (r: number, g: number, b: number): string =>
"#" +