diff --git a/components/CollectionListing.tsx b/components/CollectionListing.tsx index 01d81d0..1a309c4 100644 --- a/components/CollectionListing.tsx +++ b/components/CollectionListing.tsx @@ -223,11 +223,10 @@ const renderItem = ( return (
{Icon(item as ExtendedTreeItem, onExpand, onCollapse)} diff --git a/components/ModalContent/NewLinkModal.tsx b/components/ModalContent/NewLinkModal.tsx index 20bcef2..46c9ffe 100644 --- a/components/ModalContent/NewLinkModal.tsx +++ b/components/ModalContent/NewLinkModal.tsx @@ -109,7 +109,6 @@ export default function NewLinkModal({ onClose }: Props) { toast.success(`Created!`); onClose(); } else toast.error(response.data as string); - setSubmitLoader(false); return response; diff --git a/lib/api/controllers/links/postLink.ts b/lib/api/controllers/links/postLink.ts index eb82949..0dcc5dc 100644 --- a/lib/api/controllers/links/postLink.ts +++ b/lib/api/controllers/links/postLink.ts @@ -87,6 +87,28 @@ export default async function postLink( return { response: "Uncaught error.", status: 500 }; } + const user = await prisma.user.findUnique({ + where: { + id: userId, + }, + }); + + const existingLink = await prisma.link.findFirst({ + where: { + url: link.url, + collection: { + ownerId: userId, + }, + }, + }); + + if (existingLink && user?.mergeDuplicateLinks) { + return { + response: "Link already exists", + status: 409, + }; + } + const numberOfLinksTheUserHas = await prisma.link.count({ where: { collection: { diff --git a/lib/api/controllers/users/userId/updateUserById.ts b/lib/api/controllers/users/userId/updateUserById.ts index e4e5726..7459d1d 100644 --- a/lib/api/controllers/users/userId/updateUserById.ts +++ b/lib/api/controllers/users/userId/updateUserById.ts @@ -190,6 +190,7 @@ export default async function updateUserById( archiveAsPDF: data.archiveAsPDF, archiveAsWaybackMachine: data.archiveAsWaybackMachine, linksRouteTo: data.linksRouteTo, + mergeDuplicateLinks: data.mergeDuplicateLinks, password: data.newPassword && data.newPassword !== "" ? newHashedPassword diff --git a/pages/settings/preference.tsx b/pages/settings/preference.tsx index 2456e92..b581045 100644 --- a/pages/settings/preference.tsx +++ b/pages/settings/preference.tsx @@ -16,6 +16,8 @@ export default function Appearance() { const { account, updateAccount } = useAccountStore(); const [user, setUser] = useState(account); + const [mergeDuplicateLinks, setMergeDuplicateLinks] = + useState(false); const [archiveAsScreenshot, setArchiveAsScreenshot] = useState(false); const [archiveAsPDF, setArchiveAsPDF] = useState(false); @@ -32,6 +34,7 @@ export default function Appearance() { archiveAsPDF, archiveAsWaybackMachine, linksRouteTo, + mergeDuplicateLinks, }); }, [ account, @@ -39,6 +42,7 @@ export default function Appearance() { archiveAsPDF, archiveAsWaybackMachine, linksRouteTo, + mergeDuplicateLinks, ]); function objectIsEmpty(obj: object) { @@ -51,6 +55,7 @@ export default function Appearance() { setArchiveAsPDF(account.archiveAsPDF); setArchiveAsWaybackMachine(account.archiveAsWaybackMachine); setLinksRouteTo(account.linksRouteTo); + setMergeDuplicateLinks(account.mergeDuplicateLinks); } }, [account]); @@ -144,6 +149,13 @@ export default function Appearance() {

Link Settings

+
+ setMergeDuplicateLinks(!mergeDuplicateLinks)} + /> +

Clicking on Links should:

diff --git a/prisma/migrations/20240305045701_add_merge_duplicate_links/migration.sql b/prisma/migrations/20240305045701_add_merge_duplicate_links/migration.sql new file mode 100644 index 0000000..cb534b9 --- /dev/null +++ b/prisma/migrations/20240305045701_add_merge_duplicate_links/migration.sql @@ -0,0 +1,2 @@ +-- AlterTable +ALTER TABLE "User" ADD COLUMN "mergeDuplicateLinks" BOOLEAN NOT NULL DEFAULT false; diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 6bdc8de..64945ca 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -43,6 +43,7 @@ model User { accessTokens AccessToken[] subscriptions Subscription? linksRouteTo LinksRouteTo @default(ORIGINAL) + mergeDuplicateLinks Boolean @default(false) archiveAsScreenshot Boolean @default(true) archiveAsPDF Boolean @default(true) archiveAsWaybackMachine Boolean @default(false)