From e79b98d3b000eda1abc6eec18fe0a4348f6df357 Mon Sep 17 00:00:00 2001 From: Isaac Wise Date: Mon, 22 Jul 2024 22:34:36 -0500 Subject: [PATCH 01/86] Replace useless ternarys with logical ANDs --- components/CollectionCard.tsx | 28 +++++------ components/CollectionListing.tsx | 9 ++-- .../LinkViews/LinkComponents/LinkActions.tsx | 34 ++++++------- components/LinkViews/LinkList.tsx | 13 +++-- components/MobileNavigation.tsx | 19 ++++--- components/ModalContent/EditLinkModal.tsx | 4 +- components/ModalContent/NewLinkModal.tsx | 4 +- components/ModalContent/NewUserModal.tsx | 4 +- .../ModalContent/PreservedFormatsModal.tsx | 31 ++++++------ components/ModalContent/UploadFileModal.tsx | 8 +-- components/Navbar.tsx | 12 ++--- components/NoLinksFound.tsx | 4 +- components/PreserverdFormatRow.tsx | 9 ++-- components/ReadableView.tsx | 21 ++++---- layouts/CenteredForm.tsx | 13 +++-- layouts/MainLayout.tsx | 4 +- pages/collections/[id].tsx | 43 ++++++++-------- pages/collections/index.tsx | 8 +-- pages/dashboard.tsx | 4 +- pages/login.tsx | 10 ++-- pages/public/collections/[id].tsx | 49 +++++++++---------- pages/register.tsx | 26 +++++----- pages/settings/access-tokens.tsx | 8 +-- pages/settings/account.tsx | 38 +++++++------- pages/settings/delete.tsx | 4 +- 25 files changed, 195 insertions(+), 212 deletions(-) diff --git a/components/CollectionCard.tsx b/components/CollectionCard.tsx index da634cc..cd7d80e 100644 --- a/components/CollectionCard.tsx +++ b/components/CollectionCard.tsx @@ -129,12 +129,12 @@ export default function CollectionCard({ collection, className }: Props) { className="flex items-center absolute bottom-3 left-3 z-10 btn px-2 btn-ghost rounded-full" onClick={() => setEditCollectionSharingModal(true)} > - {collectionOwner.id ? ( + {collectionOwner.id && ( - ) : undefined} + )} {collection.members .sort((a, b) => (a.userId as number) - (b.userId as number)) .map((e, i) => { @@ -159,11 +159,9 @@ export default function CollectionCard({ collection, className }: Props) { @@ -178,12 +176,12 @@ export default function CollectionCard({ collection, className }: Props) {
- {collection.isPublic ? ( + {collection.isPublic && ( - ) : undefined} + )}
- {editCollectionModal ? ( + {editCollectionModal && ( setEditCollectionModal(false)} activeCollection={collection} /> - ) : undefined} - {editCollectionSharingModal ? ( + )} + {editCollectionSharingModal && ( setEditCollectionSharingModal(false)} activeCollection={collection} /> - ) : undefined} - {deleteCollectionModal ? ( + )} + {deleteCollectionModal && ( setDeleteCollectionModal(false)} activeCollection={collection} /> - ) : undefined} + )}
); } diff --git a/components/CollectionListing.tsx b/components/CollectionListing.tsx index fbe2f7b..b26e8cf 100644 --- a/components/CollectionListing.tsx +++ b/components/CollectionListing.tsx @@ -231,11 +231,10 @@ const renderItem = ( return (
{Icon(item as ExtendedTreeItem, onExpand, onCollapse)} @@ -253,12 +252,12 @@ const renderItem = ( >

{collection.name}

- {collection.isPublic ? ( + {collection.isPublic && ( - ) : undefined} + )}
{collection._count?.links}
diff --git a/components/LinkViews/LinkComponents/LinkActions.tsx b/components/LinkViews/LinkComponents/LinkActions.tsx index c68dd06..41f40c5 100644 --- a/components/LinkViews/LinkComponents/LinkActions.tsx +++ b/components/LinkViews/LinkComponents/LinkActions.tsx @@ -79,9 +79,8 @@ export default function LinkActions({ return ( <>
  • - {linkInfo !== undefined && toggleShowInfo ? ( + {linkInfo !== undefined && toggleShowInfo && (
  • - ) : undefined} - {permissions === true || permissions?.canUpdate ? ( + )} + {permissions === true || permissions?.canUpdate && (
  • - ) : undefined} + )} {link.type === "url" && (
  • )} - {permissions === true || permissions?.canDelete ? ( + {permissions === true || permissions?.canDelete && (
  • - ) : undefined} + )}
- {editLinkModal ? ( + {editLinkModal && ( setEditLinkModal(false)} activeLink={link} /> - ) : undefined} - {deleteLinkModal ? ( + )} + {deleteLinkModal && ( setDeleteLinkModal(false)} activeLink={link} /> - ) : undefined} - {preservedFormatsModal ? ( + )} + {preservedFormatsModal && ( setPreservedFormatsModal(false)} activeLink={link} /> - ) : undefined} + )} {/* {expandedLink ? ( setExpandedLink(false)} link={link} /> ) : undefined} */} diff --git a/components/LinkViews/LinkList.tsx b/components/LinkViews/LinkList.tsx index 723c47e..efb10c4 100644 --- a/components/LinkViews/LinkList.tsx +++ b/components/LinkViews/LinkList.tsx @@ -91,9 +91,8 @@ export default function LinkCardCompact({ return ( <>
selectable ? handleCheckboxClick(link) @@ -139,9 +138,9 @@ export default function LinkCardCompact({
- {collection ? ( + {collection && ( - ) : undefined} + )} {link.name && }
@@ -153,8 +152,8 @@ export default function LinkCardCompact({ collection={collection} position="top-3 right-3" flipDropdown={flipDropdown} - // toggleShowInfo={() => setShowInfo(!showInfo)} - // linkInfo={showInfo} + // toggleShowInfo={() => setShowInfo(!showInfo)} + // linkInfo={showInfo} />
- {newLinkModal ? ( + {newLinkModal && ( setNewLinkModal(false)} /> - ) : undefined} - {newCollectionModal ? ( + )} + {newCollectionModal && ( setNewCollectionModal(false)} /> - ) : undefined} - {uploadFileModal ? ( + )} + {uploadFileModal && ( setUploadFileModal(false)} /> - ) : undefined} + )} ); } diff --git a/components/ModalContent/EditLinkModal.tsx b/components/ModalContent/EditLinkModal.tsx index 1d873c7..b509aa8 100644 --- a/components/ModalContent/EditLinkModal.tsx +++ b/components/ModalContent/EditLinkModal.tsx @@ -72,7 +72,7 @@ export default function EditLinkModal({ onClose, activeLink }: Props) {
- {link.url ? ( + {link.url && (

{shortenedURL}

- ) : undefined} + )}

{t("name")}

diff --git a/components/ModalContent/NewLinkModal.tsx b/components/ModalContent/NewLinkModal.tsx index 0284687..680f9ef 100644 --- a/components/ModalContent/NewLinkModal.tsx +++ b/components/ModalContent/NewLinkModal.tsx @@ -128,7 +128,7 @@ export default function NewLinkModal({ onClose }: Props) {
- {optionsExpanded ? ( + {optionsExpanded && (
@@ -163,7 +163,7 @@ export default function NewLinkModal({ onClose }: Props) {
- ) : undefined} + )}
- {emailEnabled ? ( + {emailEnabled && (

{t("email")}

- ) : undefined} + )}

diff --git a/components/ModalContent/PreservedFormatsModal.tsx b/components/ModalContent/PreservedFormatsModal.tsx index 87e84a7..4414b37 100644 --- a/components/ModalContent/PreservedFormatsModal.tsx +++ b/components/ModalContent/PreservedFormatsModal.tsx @@ -150,16 +150,16 @@ export default function PreservedFormatsModal({ onClose, activeLink }: Props) {

{t("preserved_formats")}

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

{t("available_formats")}

) : ( "" )}
- {monolithAvailable(link) ? ( + {monolithAvailable(link) && ( - ) : undefined} + )} - {screenshotAvailable(link) ? ( + {screenshotAvailable(link) && ( - ) : undefined} + )} - {pdfAvailable(link) ? ( + {pdfAvailable(link) && ( - ) : undefined} + )} - {readabilityAvailable(link) ? ( + {readabilityAvailable(link) && ( - ) : undefined} + )} {!isReady() && !atLeastOneFormatAvailable() ? (
@@ -213,7 +213,7 @@ export default function PreservedFormatsModal({ onClose, activeLink }: Props) {

{t("preservation_in_queue")}

{t("check_back_later")}

- ) : !isReady() && atLeastOneFormatAvailable() ? ( + ) : !isReady() && atLeastOneFormatAvailable() && (
{t("there_are_more_formats")}

{t("check_back_later")}

- ) : undefined} + )}

{t("collection")}

- {link.collection.name ? ( + {link.collection.name && ( - ) : null} + )}
- {optionsExpanded ? ( + {optionsExpanded && (
@@ -203,7 +203,7 @@ export default function UploadFileModal({ onClose }: Props) {
- ) : undefined} + )}
setOptionsExpanded(!optionsExpanded)} diff --git a/components/Navbar.tsx b/components/Navbar.tsx index dcc78c5..888c56b 100644 --- a/components/Navbar.tsx +++ b/components/Navbar.tsx @@ -120,15 +120,15 @@ export default function Navbar() {
) : null} - {newLinkModal ? ( + {newLinkModal && ( setNewLinkModal(false)} /> - ) : undefined} - {newCollectionModal ? ( + )} + {newCollectionModal && ( setNewCollectionModal(false)} /> - ) : undefined} - {uploadFileModal ? ( + )} + {uploadFileModal && ( setUploadFileModal(false)} /> - ) : undefined} + )}
); } diff --git a/components/NoLinksFound.tsx b/components/NoLinksFound.tsx index 516dfb6..b42516a 100644 --- a/components/NoLinksFound.tsx +++ b/components/NoLinksFound.tsx @@ -39,9 +39,9 @@ export default function NoLinksFound({ text }: Props) {
- {newLinkModal ? ( + {newLinkModal && ( setNewLinkModal(false)} /> - ) : undefined} + )}
); } diff --git a/components/PreserverdFormatRow.tsx b/components/PreserverdFormatRow.tsx index ce0f21d..e28d43d 100644 --- a/components/PreserverdFormatRow.tsx +++ b/components/PreserverdFormatRow.tsx @@ -97,19 +97,18 @@ export default function PreservedFormatRow({
- {downloadable || false ? ( + {downloadable || false && (
handleDownload()} className="btn btn-sm btn-square" >
- ) : undefined} + )} diff --git a/components/ReadableView.tsx b/components/ReadableView.tsx index b600236..b862b38 100644 --- a/components/ReadableView.tsx +++ b/components/ReadableView.tsx @@ -183,7 +183,7 @@ export default function ReadableView({ link }: Props) { link?.name || link?.description || link?.url || "" )}

- {link?.url ? ( + {link?.url && ( - {isValidUrl(link?.url || "") - ? new URL(link?.url as string).host - : undefined} + {isValidUrl(link?.url || "") && new URL(link?.url as string).host} - ) : undefined} + )}
@@ -231,10 +229,10 @@ export default function ReadableView({ link }: Props) {

{date ? new Date(date).toLocaleString("en-US", { - year: "numeric", - month: "long", - day: "numeric", - }) + year: "numeric", + month: "long", + day: "numeric", + }) : undefined}

@@ -259,9 +257,8 @@ export default function ReadableView({ link }: Props) { >
) : (
- {settings.theme ? ( + {settings.theme && ( Linkwarden - ) : undefined} - {text ? ( + )} + {text && (

{text}

- ) : undefined} + )} {children}

- {showAnnouncement ? ( + {showAnnouncement && ( - ) : undefined} + )}

diff --git a/pages/collections/[id].tsx b/pages/collections/[id].tsx index bd24a95..b50d6df 100644 --- a/pages/collections/[id].tsx +++ b/pages/collections/[id].tsx @@ -115,9 +115,8 @@ export default function Index() {
{activeCollection && ( @@ -211,12 +210,12 @@ export default function Index() { className="flex items-center btn px-2 btn-ghost rounded-full w-fit" onClick={() => setEditCollectionSharingModal(true)} > - {collectionOwner.id ? ( + {collectionOwner.id && ( - ) : undefined} + )} {activeCollection.members .sort((a, b) => (a.userId as number) - (b.userId as number)) .map((e, i) => { @@ -241,20 +240,20 @@ export default function Index() {

{activeCollection.members.length > 0 && - activeCollection.members.length === 1 + activeCollection.members.length === 1 ? t("by_author_and_other", { + author: collectionOwner.name, + count: activeCollection.members.length, + }) + : activeCollection.members.length > 0 && + activeCollection.members.length !== 1 + ? t("by_author_and_others", { author: collectionOwner.name, count: activeCollection.members.length, }) - : activeCollection.members.length > 0 && - activeCollection.members.length !== 1 - ? t("by_author_and_others", { - author: collectionOwner.name, - count: activeCollection.members.length, - }) : t("by_author", { - author: collectionOwner.name, - })} + author: collectionOwner.name, + })}

@@ -299,15 +298,15 @@ export default function Index() { setSortBy={setSortBy} editMode={ permissions === true || - permissions?.canUpdate || - permissions?.canDelete + permissions?.canUpdate || + permissions?.canDelete ? editMode : undefined } setEditMode={ permissions === true || - permissions?.canUpdate || - permissions?.canDelete + permissions?.canUpdate || + permissions?.canDelete ? setEditMode : undefined } @@ -315,11 +314,11 @@ export default function Index() {

{activeCollection?._count?.links === 1 ? t("showing_count_result", { - count: activeCollection?._count?.links, - }) + count: activeCollection?._count?.links, + }) : t("showing_count_results", { - count: activeCollection?._count?.links, - })} + count: activeCollection?._count?.links, + })}

diff --git a/pages/collections/index.tsx b/pages/collections/index.tsx index 642e3dd..717732f 100644 --- a/pages/collections/index.tsx +++ b/pages/collections/index.tsx @@ -58,7 +58,7 @@ export default function Collections() {
- {sortedCollections.filter((e) => e.ownerId !== data?.user.id)[0] ? ( + {sortedCollections.filter((e) => e.ownerId !== data?.user.id)[0] && ( <> - ) : undefined} + )} - {newCollectionModal ? ( + {newCollectionModal && ( setNewCollectionModal(false)} /> - ) : undefined} + )} ); } diff --git a/pages/dashboard.tsx b/pages/dashboard.tsx index 3d1fdb6..78239de 100644 --- a/pages/dashboard.tsx +++ b/pages/dashboard.tsx @@ -324,9 +324,9 @@ export default function Dashboard() { )} - {newLinkModal ? ( + {newLinkModal && ( setNewLinkModal(false)} /> - ) : undefined} + )} ); } diff --git a/pages/login.tsx b/pages/login.tsx index c1bc8d8..4eb59c8 100644 --- a/pages/login.tsx +++ b/pages/login.tsx @@ -203,9 +203,9 @@ export default function Login({ {t("login")} - {availableLogins.buttonAuths.length > 0 ? ( + {availableLogins.buttonAuths.length > 0 && (
{t("or_continue_with")}
- ) : undefined} + )} ); } @@ -224,9 +224,9 @@ export default function Login({ loading={submitLoader} > {value.name.toLowerCase() === "google" || - value.name.toLowerCase() === "apple" ? ( - - ) : undefined} + value.name.toLowerCase() === "apple" && ( + + )} {value.name} diff --git a/pages/public/collections/[id].tsx b/pages/public/collections/[id].tsx index 47e074f..454a957 100644 --- a/pages/public/collections/[id].tsx +++ b/pages/public/collections/[id].tsx @@ -104,16 +104,17 @@ export default function PublicCollections() { // @ts-ignore const LinkComponent = linkView[viewMode]; - return collection ? ( + if (!collection) return null; + + return (
- {collection ? ( + {collection && ( {collection.name} | Linkwarden - ) : undefined} + )}

@@ -151,12 +152,12 @@ export default function PublicCollections() { className="flex items-center btn px-2 btn-ghost rounded-full" onClick={() => setEditCollectionSharingModal(true)} > - {collectionOwner.id ? ( + {collectionOwner.id && ( - ) : undefined} + )} {collection.members .sort((a, b) => (a.userId as number) - (b.userId as number)) .map((e, i) => { @@ -181,20 +182,20 @@ export default function PublicCollections() {

{collection.members.length > 0 && - collection.members.length === 1 + collection.members.length === 1 ? t("by_author_and_other", { + author: collectionOwner.name, + count: collection.members.length, + }) + : collection.members.length > 0 && + collection.members.length !== 1 + ? t("by_author_and_others", { author: collectionOwner.name, count: collection.members.length, }) - : collection.members.length > 0 && - collection.members.length !== 1 - ? t("by_author_and_others", { - author: collectionOwner.name, - count: collection.members.length, - }) : t("by_author", { - author: collectionOwner.name, - })} + author: collectionOwner.name, + })}

@@ -218,11 +219,11 @@ export default function PublicCollections() { placeholder={ collection._count?.links === 1 ? t("search_count_link", { - count: collection._count?.links, - }) + count: collection._count?.links, + }) : t("search_count_links", { - count: collection._count?.links, - }) + count: collection._count?.links, + }) } /> @@ -248,15 +249,13 @@ export default function PublicCollections() {

*/}
- {editCollectionSharingModal ? ( + {editCollectionSharingModal && ( setEditCollectionSharingModal(false)} activeCollection={collection} /> - ) : undefined} + )} - ) : ( - <> ); } diff --git a/pages/register.tsx b/pages/register.tsx index 4eba2bc..6e7fc1e 100644 --- a/pages/register.tsx +++ b/pages/register.tsx @@ -133,9 +133,9 @@ export default function Register({ loading={submitLoader} > {value.name.toLowerCase() === "google" || - value.name.toLowerCase() === "apple" ? ( - - ) : undefined} + value.name.toLowerCase() === "apple" && ( + + )} {value.name} @@ -149,8 +149,8 @@ export default function Register({ text={ process.env.NEXT_PUBLIC_STRIPE ? t("trial_offer_desc", { - count: Number(process.env.NEXT_PUBLIC_TRIAL_PERIOD_DAYS || 14), - }) + count: Number(process.env.NEXT_PUBLIC_TRIAL_PERIOD_DAYS || 14), + }) : t("register_desc") } data-testid="registration-form" @@ -201,7 +201,7 @@ export default function Register({ )} - {emailEnabled ? ( + {emailEnabled && (

{t("email")}

@@ -214,7 +214,7 @@ export default function Register({ onChange={(e) => setForm({ ...form, email: e.target.value })} />
- ) : undefined} + )}

@@ -248,7 +248,7 @@ export default function Register({ />

- {process.env.NEXT_PUBLIC_STRIPE ? ( + {process.env.NEXT_PUBLIC_STRIPE && (

- ) : undefined} + )} - {tokens.length > 0 ? ( + {tokens.length > 0 && ( @@ -93,12 +93,12 @@ export default function AccessTokens() { ))}
- ) : undefined} + )} - {newTokenModal ? ( + {newTokenModal && ( setNewTokenModal(false)} /> - ) : undefined} + )} {revokeTokenModal && selectedToken && ( { diff --git a/pages/settings/account.tsx b/pages/settings/account.tsx index cb46442..2ba80fa 100644 --- a/pages/settings/account.tsx +++ b/pages/settings/account.tsx @@ -29,19 +29,19 @@ export default function Account() { !objectIsEmpty(account) ? account : ({ - // @ts-ignore - id: null, - name: "", - username: "", - email: "", - emailVerified: null, - password: undefined, - image: "", - isPrivate: true, - // @ts-ignore - createdAt: null, - whitelistedUsers: [], - } as unknown as AccountSettings) + // @ts-ignore + id: null, + name: "", + username: "", + email: "", + emailVerified: null, + password: undefined, + image: "", + isPrivate: true, + // @ts-ignore + createdAt: null, + whitelistedUsers: [], + } as unknown as AccountSettings) ); const { t } = useTranslation(); @@ -176,7 +176,7 @@ export default function Account() { onChange={(e) => setUser({ ...user, username: e.target.value })} /> - {emailEnabled ? ( + {emailEnabled && (

{t("email")}

setUser({ ...user, email: e.target.value })} />
- ) : undefined} + )}

{t("language")}

selectedLink.id === link.id - )} - onChange={() => handleCheckboxClick(link)} - /> - )} */}
@@ -157,8 +141,6 @@ export default function LinkCardCompact({ collection={collection} position="top-3 right-3" flipDropdown={flipDropdown} - // toggleShowInfo={() => setShowInfo(!showInfo)} - // linkInfo={showInfo} />
{ - getLink.mutateAsync(link.id as number); + getLink.mutateAsync({ id: link.id as number }); }, 5000); } @@ -107,8 +107,6 @@ export default function LinkMasonry({ link, flipDropdown, editMode }: Props) { }; }, [isVisible, link.preview]); - const [showInfo, setShowInfo] = useState(false); - const selectedStyle = selectedLinks.some( (selectedLink) => selectedLink.id === link.id ) @@ -207,57 +205,6 @@ export default function LinkMasonry({ link, flipDropdown, editMode }: Props) {
- {showInfo && ( -
-
setShowInfo(!showInfo)} - className=" float-right btn btn-sm outline-none btn-circle btn-ghost z-10" - > - -
-

- {t("description")} -

- -
-

- {link.description ? ( - unescapeString(link.description) - ) : ( - - {t("no_description")} - - )} -

- {link.tags && link.tags[0] && ( - <> -

- {t("tags")} -

- -
- -
-
- {link.tags.map((e, i) => ( - { - e.stopPropagation(); - }} - className="btn btn-xs btn-ghost truncate max-w-[19rem]" - > - #{e.name} - - ))} -
-
- - )} -
- )} - setShowInfo(!showInfo)} - linkInfo={showInfo} flipDropdown={flipDropdown} /> diff --git a/components/Modal.tsx b/components/Modal.tsx index 4691df7..2eb97e4 100644 --- a/components/Modal.tsx +++ b/components/Modal.tsx @@ -32,7 +32,7 @@ export default function Modal({ return ( dismissible && setTimeout(() => toggleModal(), 100)} + onClose={() => dismissible && setTimeout(() => toggleModal(), 350)} dismissible={dismissible} > diff --git a/components/ModalContent/EditCollectionSharingModal.tsx b/components/ModalContent/EditCollectionSharingModal.tsx index f004af4..321e672 100644 --- a/components/ModalContent/EditCollectionSharingModal.tsx +++ b/components/ModalContent/EditCollectionSharingModal.tsx @@ -11,6 +11,7 @@ import { dropdownTriggerer } from "@/lib/client/utils"; import { useTranslation } from "next-i18next"; import { useUpdateCollection } from "@/hooks/store/collections"; import { useUser } from "@/hooks/store/user"; +import CopyButton from "../CopyButton"; type Props = { onClose: Function; @@ -133,21 +134,11 @@ export default function EditCollectionSharingModal({ )} {collection.isPublic ? ( -
+

{t("sharable_link_guide")}

-
{ - try { - navigator.clipboard - .writeText(publicCollectionURL) - .then(() => toast.success(t("copied"))); - } catch (err) { - console.log(err); - } - }} - className="w-full hide-scrollbar overflow-x-auto whitespace-nowrap rounded-md p-2 bg-base-200 border-neutral-content border-solid border outline-none hover:border-primary dark:hover:border-primary duration-100 cursor-text" - > +
{publicCollectionURL} +
) : null} diff --git a/components/ModalContent/LinkDetailModal.tsx b/components/ModalContent/LinkDetailModal.tsx new file mode 100644 index 0000000..2e6308a --- /dev/null +++ b/components/ModalContent/LinkDetailModal.tsx @@ -0,0 +1,145 @@ +import React, { useEffect, useState } from "react"; +import { LinkIncludingShortenedCollectionAndTags } from "@/types/global"; +import getPublicUserData from "@/lib/client/getPublicUserData"; +import { useTranslation } from "next-i18next"; +import { useUser } from "@/hooks/store/user"; +import { useGetLink } from "@/hooks/store/links"; +import Drawer from "../Drawer"; +import LinkDetails from "../LinkDetails"; +import Link from "next/link"; +import usePermissions from "@/hooks/usePermissions"; +import { useRouter } from "next/router"; + +type Props = { + onClose: Function; + onEdit: Function; + link: LinkIncludingShortenedCollectionAndTags; +}; + +export default function LinkDetailModal({ onClose, onEdit, link }: Props) { + const { t } = useTranslation(); + const getLink = useGetLink(); + const { data: user = {} } = useUser(); + + const [collectionOwner, setCollectionOwner] = useState({ + id: null as unknown as number, + name: "", + username: "", + image: "", + archiveAsScreenshot: undefined as unknown as boolean, + archiveAsMonolith: undefined as unknown as boolean, + archiveAsPDF: undefined as unknown as boolean, + }); + + 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" + ); + }; + + useEffect(() => { + (async () => { + await getLink.mutateAsync({ + id: link.id as number, + }); + })(); + + let interval: any; + + 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 permissions = usePermissions(link.collection.id as number); + + const router = useRouter(); + + const isPublicRoute = router.pathname.startsWith("/public") ? true : false; + + return ( + +
onClose()} + >
+ + +
+ + + {permissions === true || + (permissions?.canUpdate && ( + <> +
+
+ +
+
{ + onEdit(); + onClose(); + }} + > + {t("edit_link")} +
+
+ + ))} +
+
+ ); +} diff --git a/components/ModalContent/NewLinkModal.tsx b/components/ModalContent/NewLinkModal.tsx index 660c1e4..ff628bf 100644 --- a/components/ModalContent/NewLinkModal.tsx +++ b/components/ModalContent/NewLinkModal.tsx @@ -61,7 +61,7 @@ export default function NewLinkModal({ onClose }: Props) { }; useEffect(() => { - if (router.query.id) { + if (router.pathname.startsWith("/collections/") && router.query.id) { const currentCollection = collections.find( (e) => e.id == Number(router.query.id) ); diff --git a/components/ModalContent/PreservedFormatsModal.tsx b/components/ModalContent/PreservedFormatsModal.tsx index 7cd1df0..309170a 100644 --- a/components/ModalContent/PreservedFormatsModal.tsx +++ b/components/ModalContent/PreservedFormatsModal.tsx @@ -96,14 +96,14 @@ export default function PreservedFormatsModal({ onClose, link }: Props) { useEffect(() => { (async () => { - await getLink.mutateAsync(link.id as number); + await getLink.mutateAsync({ id: link.id as number }); })(); let interval: any; if (!isReady()) { interval = setInterval(async () => { - await getLink.mutateAsync(link.id as number); + await getLink.mutateAsync({ id: link.id as number }); }, 5000); } else { if (interval) { @@ -129,7 +129,7 @@ export default function PreservedFormatsModal({ onClose, link }: Props) { toast.dismiss(load); if (response.ok) { - await getLink.mutateAsync(link?.id as number); + await getLink.mutateAsync({ id: link.id as number }); toast.success(t("link_being_archived")); } else toast.error(data.response); diff --git a/components/ModalContent/UploadFileModal.tsx b/components/ModalContent/UploadFileModal.tsx index bbb1577..85ecaff 100644 --- a/components/ModalContent/UploadFileModal.tsx +++ b/components/ModalContent/UploadFileModal.tsx @@ -70,7 +70,7 @@ export default function UploadFileModal({ onClose }: Props) { useEffect(() => { setOptionsExpanded(false); - if (router.query.id) { + if (router.pathname.startsWith("/collections/") && router.query.id) { const currentCollection = collections.find( (e) => e.id == Number(router.query.id) ); diff --git a/components/PreserverdFormatRow.tsx b/components/PreserverdFormatRow.tsx index e8ddbd1..45b156f 100644 --- a/components/PreserverdFormatRow.tsx +++ b/components/PreserverdFormatRow.tsx @@ -52,11 +52,9 @@ export default function PreservedFormatRow({ }; return ( -
+
-
- -
+

{name}

@@ -64,7 +62,7 @@ export default function PreservedFormatRow({ {downloadable || false ? (
handleDownload()} - className="btn btn-sm btn-square" + className="btn btn-sm btn-square btn-ghost" >
@@ -75,9 +73,9 @@ export default function PreservedFormatRow({ isPublic ? "/public" : "" }/preserved/${link?.id}?format=${format}`} target="_blank" - className="btn btn-sm btn-square" + className="btn btn-sm btn-square btn-ghost" > - +
diff --git a/components/ReadableView.tsx b/components/ReadableView.tsx index 801e9c1..def3185 100644 --- a/components/ReadableView.tsx +++ b/components/ReadableView.tsx @@ -46,13 +46,6 @@ export default function ReadableView({ link }: Props) { const router = useRouter(); const getLink = useGetLink(); - const { data: collections = [] } = useCollections(); - - const collection = useMemo(() => { - return collections.find( - (e) => e.id === link.collection.id - ) as CollectionIncludingMembersAndLinkCount; - }, [collections, link]); useEffect(() => { const fetchLinkContent = async () => { @@ -73,7 +66,7 @@ export default function ReadableView({ link }: Props) { }, [link]); useEffect(() => { - if (link) getLink.mutateAsync(link?.id as number); + if (link) getLink.mutateAsync({ id: link.id as number }); let interval: any; if ( @@ -88,7 +81,10 @@ export default function ReadableView({ link }: Props) { !link?.monolith) ) { interval = setInterval( - () => getLink.mutateAsync(link.id as number), + () => + getLink.mutateAsync({ + id: link.id as number, + }), 5000 ); } else { @@ -243,13 +239,6 @@ export default function ReadableView({ link }: Props) { {link?.name ?

{unescapeString(link?.description)}

: undefined}
- -
diff --git a/hooks/store/links.tsx b/hooks/store/links.tsx index abd5624..6d2177f 100644 --- a/hooks/store/links.tsx +++ b/hooks/store/links.tsx @@ -225,9 +225,21 @@ const useDeleteLink = () => { const useGetLink = () => { const queryClient = useQueryClient(); + const router = useRouter(); + return useMutation({ - mutationFn: async (id: number) => { - const response = await fetch(`/api/v1/links/${id}`); + mutationFn: async ({ + id, + isPublicRoute = router.pathname.startsWith("/public") ? true : undefined, + }: { + id: number; + isPublicRoute?: boolean; + }) => { + const path = isPublicRoute + ? `/api/v1/public/links/${id}` + : `/api/v1/links/${id}`; + + const response = await fetch(path); const data = await response.json(); if (!response.ok) throw new Error(data.response); @@ -250,7 +262,20 @@ const useGetLink = () => { }; }); - queryClient.invalidateQueries({ queryKey: ["publicLinks"] }); + queryClient.setQueriesData( + { queryKey: ["publicLinks"] }, + (oldData: any) => { + if (!oldData) return undefined; + return { + pages: oldData.pages.map((page: any) => + page.map((item: any) => (item.id === data.id ? data : item)) + ), + pageParams: oldData.pageParams, + }; + } + ); + + // queryClient.invalidateQueries({ queryKey: ["publicLinks"] }); }, }); }; diff --git a/package.json b/package.json index 7f090d9..0e72474 100644 --- a/package.json +++ b/package.json @@ -79,7 +79,7 @@ "socks-proxy-agent": "^8.0.2", "stripe": "^12.13.0", "tailwind-merge": "^2.3.0", - "vaul": "^0.8.8", + "vaul": "^0.9.1", "zustand": "^4.3.8" }, "devDependencies": { @@ -95,7 +95,7 @@ "postcss": "^8.4.26", "prettier": "3.1.1", "prisma": "^4.16.2", - "tailwindcss": "^3.3.3", + "tailwindcss": "^3.4.10", "ts-node": "^10.9.2", "typescript": "4.9.4" } diff --git a/pages/dashboard.tsx b/pages/dashboard.tsx index 5ee0f2d..7f59a3b 100644 --- a/pages/dashboard.tsx +++ b/pages/dashboard.tsx @@ -111,14 +111,14 @@ export default function Dashboard() {
-
+
-
+
-
+
diff --git a/pages/links/[id].tsx b/pages/links/[id].tsx new file mode 100644 index 0000000..cfa8785 --- /dev/null +++ b/pages/links/[id].tsx @@ -0,0 +1,41 @@ +import LinkDetails from "@/components/LinkDetails"; +import { useGetLink } from "@/hooks/store/links"; +import { useRouter } from "next/router"; +import { useEffect, useState } from "react"; +import getServerSideProps from "@/lib/client/getServerSideProps"; + +const Index = () => { + const router = useRouter(); + const { id } = router.query; + + useState; + + const getLink = useGetLink(); + + useEffect(() => { + getLink.mutate({ id: Number(id) }); + }, []); + + return ( +
+ {getLink.data ? ( + + ) : ( +
+
+
+
+
+
+
+ )} +
+ ); +}; + +export default Index; + +export { getServerSideProps }; diff --git a/pages/preserved/[id].tsx b/pages/preserved/[id].tsx index c5806ff..de21605 100644 --- a/pages/preserved/[id].tsx +++ b/pages/preserved/[id].tsx @@ -20,7 +20,7 @@ export default function Index() { useEffect(() => { const fetchLink = async () => { if (router.query.id) { - await getLink.mutateAsync(Number(router.query.id)); + await getLink.mutateAsync({ id: Number(router.query.id) }); } }; diff --git a/pages/public/links/[id].tsx b/pages/public/links/[id].tsx new file mode 100644 index 0000000..cfa8785 --- /dev/null +++ b/pages/public/links/[id].tsx @@ -0,0 +1,41 @@ +import LinkDetails from "@/components/LinkDetails"; +import { useGetLink } from "@/hooks/store/links"; +import { useRouter } from "next/router"; +import { useEffect, useState } from "react"; +import getServerSideProps from "@/lib/client/getServerSideProps"; + +const Index = () => { + const router = useRouter(); + const { id } = router.query; + + useState; + + const getLink = useGetLink(); + + useEffect(() => { + getLink.mutate({ id: Number(id) }); + }, []); + + return ( +
+ {getLink.data ? ( + + ) : ( +
+
+
+
+
+
+
+ )} +
+ ); +}; + +export default Index; + +export { getServerSideProps }; diff --git a/pages/public/preserved/[id].tsx b/pages/public/preserved/[id].tsx index 2f415ae..31544b0 100644 --- a/pages/public/preserved/[id].tsx +++ b/pages/public/preserved/[id].tsx @@ -6,10 +6,9 @@ import { } from "@/types/global"; import ReadableView from "@/components/ReadableView"; import getServerSideProps from "@/lib/client/getServerSideProps"; -import { useGetLink, useLinks } from "@/hooks/store/links"; +import { useGetLink } from "@/hooks/store/links"; export default function Index() { - const { links } = useLinks(); const getLink = useGetLink(); const [link, setLink] = useState(); @@ -19,18 +18,14 @@ export default function Index() { useEffect(() => { const fetchLink = async () => { if (router.query.id) { - await getLink.mutateAsync(Number(router.query.id)); + const get = await getLink.mutateAsync({ id: Number(router.query.id) }); + setLink(get); } }; fetchLink(); }, []); - useEffect(() => { - if (links && links[0]) - setLink(links.find((e) => e.id === Number(router.query.id))); - }, [links]); - return (
{/*
@@ -39,6 +34,12 @@ export default function Index() { {link && Number(router.query.format) === ArchivedFormat.readability && ( )} + {link && Number(router.query.format) === ArchivedFormat.monolith && ( + + )} {link && Number(router.query.format) === ArchivedFormat.pdf && ( - )} {link && Number(router.query.format) === ArchivedFormat.pdf && (