diff --git a/components/LinkDetails.tsx b/components/LinkDetails.tsx index 5c940de..7c978be 100644 --- a/components/LinkDetails.tsx +++ b/components/LinkDetails.tsx @@ -30,15 +30,9 @@ type Props = { className?: string; link: LinkIncludingShortenedCollectionAndTags; standalone?: boolean; - editMode?: boolean; }; -export default function LinkDetails({ - className, - link, - standalone, - editMode, -}: Props) { +export default function LinkDetails({ className, link, standalone }: Props) { const { t } = useTranslation(); const session = useSession(); const getLink = useGetLink(); diff --git a/components/LinkViews/LinkComponents/LinkActions.tsx b/components/LinkViews/LinkComponents/LinkActions.tsx index 3e20981..f041c11 100644 --- a/components/LinkViews/LinkComponents/LinkActions.tsx +++ b/components/LinkViews/LinkComponents/LinkActions.tsx @@ -6,11 +6,10 @@ import { import usePermissions from "@/hooks/usePermissions"; import EditLinkModal from "@/components/ModalContent/EditLinkModal"; import DeleteLinkModal from "@/components/ModalContent/DeleteLinkModal"; -import PreservedFormatsModal from "@/components/ModalContent/PreservedFormatsModal"; import { dropdownTriggerer } from "@/lib/client/utils"; import { useTranslation } from "next-i18next"; import { useUser } from "@/hooks/store/user"; -import { useDeleteLink, useUpdateLink } from "@/hooks/store/links"; +import { useDeleteLink, useGetLink, useUpdateLink } from "@/hooks/store/links"; import toast from "react-hot-toast"; import LinkDetailModal from "@/components/ModalContent/LinkDetailModal"; import { useRouter } from "next/router"; @@ -32,11 +31,11 @@ export default function LinkActions({ const { t } = useTranslation(); const permissions = usePermissions(link.collection.id as number); + const getLink = useGetLink(); const [editLinkModal, setEditLinkModal] = useState(false); const [linkDetailModal, setLinkDetailModal] = useState(false); const [deleteLinkModal, setDeleteLinkModal] = useState(false); - const [preservedFormatsModal, setPreservedFormatsModal] = useState(false); const { data: user = {} } = useUser(); @@ -69,6 +68,23 @@ export default function LinkActions({ ); }; + const updateArchive = async () => { + const load = toast.loading(t("sending_request")); + + const response = await fetch(`/api/v1/links/${link?.id}/archive`, { + method: "PUT", + }); + + const data = await response.json(); + toast.dismiss(load); + + if (response.ok) { + await getLink.mutateAsync({ id: link.id as number }); + + toast.success(t("link_being_archived")); + } else toast.error(data.response); + }; + const router = useRouter(); const isPublicRoute = router.pathname.startsWith("/public") ? true : false; @@ -157,11 +173,11 @@ export default function LinkActions({ tabIndex={0} onClick={() => { (document?.activeElement as HTMLElement)?.blur(); - setPreservedFormatsModal(true); + updateArchive(); }} className="whitespace-nowrap" > - {t("preserved_formats")} + {t("refresh_preserved_formats")} )} @@ -212,16 +228,12 @@ export default function LinkActions({ activeLink={link} /> )} - {preservedFormatsModal && ( - setPreservedFormatsModal(false)} - link={link} - /> - )} {linkDetailModal && ( setLinkDetailModal(false)} onEdit={() => setEditLinkModal(true)} + onPin={pinLink} + onUpdateArchive={updateArchive} onDelete={() => setDeleteLinkModal(true)} link={link} /> diff --git a/components/ModalContent/LinkDetailModal.tsx b/components/ModalContent/LinkDetailModal.tsx index 5dac3b6..0a803b5 100644 --- a/components/ModalContent/LinkDetailModal.tsx +++ b/components/ModalContent/LinkDetailModal.tsx @@ -12,18 +12,15 @@ import LinkDetails from "../LinkDetails"; import Link from "next/link"; import usePermissions from "@/hooks/usePermissions"; import { useRouter } from "next/router"; -import { previewAvailable } from "@/lib/shared/getArchiveValidity"; -import Image from "next/image"; import { dropdownTriggerer } from "@/lib/client/utils"; import toast from "react-hot-toast"; -import EditLinkModal from "./EditLinkModal"; -import DeleteLinkModal from "./DeleteLinkModal"; -import PreservedFormatsModal from "./PreservedFormatsModal"; type Props = { onClose: Function; onEdit: Function; onDelete: Function; + onUpdateArchive: Function; + onPin: Function; link: LinkIncludingShortenedCollectionAndTags; }; @@ -31,6 +28,8 @@ export default function LinkDetailModal({ onClose, onEdit, onDelete, + onUpdateArchive, + onPin, link, }: Props) { const { t } = useTranslation(); @@ -124,53 +123,6 @@ export default function LinkDetailModal({ const updateLink = useUpdateLink(); const deleteLink = useDeleteLink(); - const pinLink = async () => { - const isAlreadyPinned = link?.pinnedBy && link.pinnedBy[0] ? true : false; - - const load = toast.loading(t("updating")); - - await updateLink.mutateAsync( - { - ...link, - pinnedBy: isAlreadyPinned ? undefined : [{ id: user.id }], - }, - { - onSettled: (data, error) => { - toast.dismiss(load); - - if (error) { - toast.error(error.message); - } else { - toast.success( - isAlreadyPinned ? t("link_unpinned") : t("link_pinned") - ); - } - }, - } - ); - }; - - const updateArchive = async () => { - const load = toast.loading(t("sending_request")); - - const response = await fetch(`/api/v1/links/${link?.id}/archive`, { - method: "PUT", - }); - - const data = await response.json(); - toast.dismiss(load); - - if (response.ok) { - await getLink.mutateAsync({ id: link.id as number }); - - toast.success(t("link_being_archived")); - } else toast.error(data.response); - }; - - const [editLinkModal, setEditLinkModal] = useState(false); - const [deleteLinkModal, setDeleteLinkModal] = useState(false); - const [preservedFormatsModal, setPreservedFormatsModal] = useState(false); - return (
{ (document?.activeElement as HTMLElement)?.blur(); - pinLink(); + onPin(); }} className="whitespace-nowrap" > @@ -214,7 +166,8 @@ export default function LinkDetailModal({ tabIndex={0} onClick={() => { (document?.activeElement as HTMLElement)?.blur(); - setEditLinkModal(true); + onEdit(); + onClose(); }} className="whitespace-nowrap" > @@ -229,7 +182,7 @@ export default function LinkDetailModal({ tabIndex={0} onClick={() => { (document?.activeElement as HTMLElement)?.blur(); - updateArchive(); + onUpdateArchive(); }} className="whitespace-nowrap" > @@ -281,20 +234,6 @@ export default function LinkDetailModal({
- - {/* {(permissions === true || permissions?.canUpdate) && ( -
-
{ - onEdit(); - onClose(); - }} - > - {t("edit_link")} -
-
- )} */}
); diff --git a/components/ModalContent/PreservedFormatsModal.tsx b/components/ModalContent/PreservedFormatsModal.tsx deleted file mode 100644 index d883a21..0000000 --- a/components/ModalContent/PreservedFormatsModal.tsx +++ /dev/null @@ -1,246 +0,0 @@ -import React, { useEffect, useState } from "react"; -import { - LinkIncludingShortenedCollectionAndTags, - ArchivedFormat, - AccountSettings, -} from "@/types/global"; -import toast from "react-hot-toast"; -import Link from "next/link"; -import Modal from "../Modal"; -import { useRouter } from "next/router"; -import { useSession } from "next-auth/react"; -import { - pdfAvailable, - readabilityAvailable, - monolithAvailable, - screenshotAvailable, -} from "@/lib/shared/getArchiveValidity"; -import PreservedFormatRow from "@/components/PreserverdFormatRow"; -import getPublicUserData from "@/lib/client/getPublicUserData"; -import { useTranslation } from "next-i18next"; -import { BeatLoader } from "react-spinners"; -import { useUser } from "@/hooks/store/user"; -import { useGetLink } from "@/hooks/store/links"; - -type Props = { - onClose: Function; - link: LinkIncludingShortenedCollectionAndTags; -}; - -export default function PreservedFormatsModal({ onClose, link }: Props) { - const { t } = useTranslation(); - const session = useSession(); - const getLink = useGetLink(); - const { data: user = {} } = useUser(); - const router = useRouter(); - - let isPublic = router.pathname.startsWith("/public") ? true : undefined; - - const [collectionOwner, setCollectionOwner] = useState< - Partial - >({}); - - useEffect(() => { - const fetchOwner = async () => { - if (link.collection.ownerId !== user.id) { - const owner = await getPublicUserData( - link.collection.ownerId as number - ); - setCollectionOwner(owner); - } else if (link.collection.ownerId === user.id) { - setCollectionOwner({ - id: user.id as number, - name: user.name, - username: user.username as string, - image: user.image as string, - archiveAsScreenshot: user.archiveAsScreenshot as boolean, - archiveAsMonolith: user.archiveAsScreenshot as boolean, - archiveAsPDF: user.archiveAsPDF as boolean, - }); - } - }; - - fetchOwner(); - }, [link.collection.ownerId]); - - const isReady = () => { - return ( - link && - (collectionOwner.archiveAsScreenshot === true - ? link.pdf && link.pdf !== "pending" - : true) && - (collectionOwner.archiveAsMonolith === true - ? link.monolith && link.monolith !== "pending" - : true) && - (collectionOwner.archiveAsPDF === true - ? link.pdf && link.pdf !== "pending" - : true) && - link.readable && - link.readable !== "pending" - ); - }; - - const atLeastOneFormatAvailable = () => { - return ( - screenshotAvailable(link) || - pdfAvailable(link) || - readabilityAvailable(link) || - monolithAvailable(link) - ); - }; - - useEffect(() => { - (async () => { - await getLink.mutateAsync({ id: link.id as number }); - })(); - - let interval: NodeJS.Timeout | null = null; - - if (!isReady()) { - interval = setInterval(async () => { - await getLink.mutateAsync({ id: link.id as number }); - }, 5000); - } else { - if (interval) { - clearInterval(interval); - } - } - - return () => { - if (interval) { - clearInterval(interval); - } - }; - }, [link?.monolith]); - - const updateArchive = async () => { - const load = toast.loading(t("sending_request")); - - const response = await fetch(`/api/v1/links/${link?.id}/archive`, { - method: "PUT", - }); - - const data = await response.json(); - toast.dismiss(load); - - if (response.ok) { - await getLink.mutateAsync({ id: link.id as number }); - - toast.success(t("link_being_archived")); - } else toast.error(data.response); - }; - - return ( - -

{t("preserved_formats")}

-
- {screenshotAvailable(link) || - pdfAvailable(link) || - readabilityAvailable(link) || - monolithAvailable(link) ? ( -

{t("available_formats")}

- ) : ( - "" - )} - -
- {monolithAvailable(link) && ( - - )} - - {screenshotAvailable(link) && ( - - )} - - {pdfAvailable(link) && ( - - )} - - {readabilityAvailable(link) && ( - - )} - - {!isReady() && !atLeastOneFormatAvailable() ? ( -
- - -

{t("preservation_in_queue")}

-

{t("check_back_later")}

-
- ) : ( - !isReady() && - atLeastOneFormatAvailable() && ( -
- -

{t("there_are_more_formats")}

-

{t("check_back_later")}

-
- ) - )} - -
- -

{t("view_latest_snapshot")}

- - - {link?.collection.ownerId === session.data?.user.id && ( -
-
-

{t("refresh_preserved_formats")}

-

- {t("this_deletes_current_preservations")} -

-
-
- )} -
-
-
- ); -}