diff --git a/components/LinkViews/Layouts/CardView.tsx b/components/LinkViews/Layouts/CardView.tsx
deleted file mode 100644
index 8e85431..0000000
--- a/components/LinkViews/Layouts/CardView.tsx
+++ /dev/null
@@ -1,60 +0,0 @@
-import LinkCard from "@/components/LinkViews/LinkCard";
-import { useLinks } from "@/hooks/store/links";
-import { LinkIncludingShortenedCollectionAndTags } from "@/types/global";
-import { useEffect } from "react";
-import { useInView } from "react-intersection-observer";
-import { GridLoader } from "react-spinners";
-
-export default function CardView({
- links,
- editMode,
- isLoading,
-}: {
- links: LinkIncludingShortenedCollectionAndTags[];
- editMode?: boolean;
- isLoading?: boolean;
-}) {
- const { ref, inView } = useInView();
-
- const { data } = useLinks();
-
- useEffect(() => {
- if (inView) {
- data.fetchNextPage();
- }
- }, [data.fetchNextPage, inView]);
-
- return (
-
- {links.map((e, i) => {
- return (
-
- );
- })}
-
- {data.hasNextPage && (
-
- )}
-
- {isLoading && links.length > 0 && (
-
- )}
-
- );
-}
diff --git a/components/LinkViews/Layouts/ListView.tsx b/components/LinkViews/Layouts/ListView.tsx
deleted file mode 100644
index a83609c..0000000
--- a/components/LinkViews/Layouts/ListView.tsx
+++ /dev/null
@@ -1,38 +0,0 @@
-import LinkList from "@/components/LinkViews/LinkList";
-import { LinkIncludingShortenedCollectionAndTags } from "@/types/global";
-import { GridLoader } from "react-spinners";
-
-export default function ListView({
- links,
- editMode,
- isLoading,
-}: {
- links: LinkIncludingShortenedCollectionAndTags[];
- editMode?: boolean;
- isLoading?: boolean;
-}) {
- return (
-
- {links.map((e, i) => {
- return (
-
- );
- })}
-
- {isLoading && links.length > 0 && (
-
- )}
-
- );
-}
diff --git a/components/LinkViews/Layouts/MasonryView.tsx b/components/LinkViews/Layouts/MasonryView.tsx
deleted file mode 100644
index bceaf33..0000000
--- a/components/LinkViews/Layouts/MasonryView.tsx
+++ /dev/null
@@ -1,58 +0,0 @@
-import LinkMasonry from "@/components/LinkViews/LinkMasonry";
-import { LinkIncludingShortenedCollectionAndTags } from "@/types/global";
-import { GridLoader } from "react-spinners";
-import Masonry from "react-masonry-css";
-import resolveConfig from "tailwindcss/resolveConfig";
-import tailwindConfig from "../../../tailwind.config.js";
-import { useMemo } from "react";
-
-export default function MasonryView({
- links,
- editMode,
- isLoading,
-}: {
- links: LinkIncludingShortenedCollectionAndTags[];
- editMode?: boolean;
- isLoading?: boolean;
-}) {
- const fullConfig = resolveConfig(tailwindConfig as any);
-
- const breakpointColumnsObj = useMemo(() => {
- return {
- default: 5,
- 1900: 4,
- 1500: 3,
- 880: 2,
- 550: 1,
- };
- }, []);
-
- return (
-
- {links.map((e, i) => {
- return (
-
- );
- })}
-
- {isLoading && links.length > 0 && (
-
- )}
-
- );
-}
diff --git a/components/LinkViews/LinkComponents/LinkActions.tsx b/components/LinkViews/LinkComponents/LinkActions.tsx
index ffa0051..6d55d85 100644
--- a/components/LinkViews/LinkComponents/LinkActions.tsx
+++ b/components/LinkViews/LinkComponents/LinkActions.tsx
@@ -162,7 +162,7 @@ export default function LinkActions({
{preservedFormatsModal ? (
setPreservedFormatsModal(false)}
- activeLink={link}
+ link={link}
/>
) : undefined}
{/* {expandedLink ? (
diff --git a/components/LinkViews/LinkCard.tsx b/components/LinkViews/LinkComponents/LinkCard.tsx
similarity index 98%
rename from components/LinkViews/LinkCard.tsx
rename to components/LinkViews/LinkComponents/LinkCard.tsx
index b6e764b..e228fb1 100644
--- a/components/LinkViews/LinkCard.tsx
+++ b/components/LinkViews/LinkComponents/LinkCard.tsx
@@ -12,12 +12,12 @@ import LinkCollection from "@/components/LinkViews/LinkComponents/LinkCollection
import Image from "next/image";
import { previewAvailable } from "@/lib/shared/getArchiveValidity";
import Link from "next/link";
-import LinkIcon from "./LinkComponents/LinkIcon";
+import LinkIcon from "./LinkIcon";
import useOnScreen from "@/hooks/useOnScreen";
import { generateLinkHref } from "@/lib/client/generateLinkHref";
import usePermissions from "@/hooks/usePermissions";
import toast from "react-hot-toast";
-import LinkTypeBadge from "./LinkComponents/LinkTypeBadge";
+import LinkTypeBadge from "./LinkTypeBadge";
import { useTranslation } from "next-i18next";
import { useCollections } from "@/hooks/store/collections";
import { useUser } from "@/hooks/store/user";
diff --git a/components/LinkViews/LinkList.tsx b/components/LinkViews/LinkComponents/LinkList.tsx
similarity index 98%
rename from components/LinkViews/LinkList.tsx
rename to components/LinkViews/LinkComponents/LinkList.tsx
index ac17c68..d3c8d40 100644
--- a/components/LinkViews/LinkList.tsx
+++ b/components/LinkViews/LinkComponents/LinkList.tsx
@@ -13,7 +13,7 @@ import { isPWA } from "@/lib/client/utils";
import { generateLinkHref } from "@/lib/client/generateLinkHref";
import usePermissions from "@/hooks/usePermissions";
import toast from "react-hot-toast";
-import LinkTypeBadge from "./LinkComponents/LinkTypeBadge";
+import LinkTypeBadge from "./LinkTypeBadge";
import { useTranslation } from "next-i18next";
import { useCollections } from "@/hooks/store/collections";
import { useUser } from "@/hooks/store/user";
diff --git a/components/LinkViews/LinkMasonry.tsx b/components/LinkViews/LinkComponents/LinkMasonry.tsx
similarity index 98%
rename from components/LinkViews/LinkMasonry.tsx
rename to components/LinkViews/LinkComponents/LinkMasonry.tsx
index 0c20395..3d327a1 100644
--- a/components/LinkViews/LinkMasonry.tsx
+++ b/components/LinkViews/LinkComponents/LinkMasonry.tsx
@@ -12,12 +12,12 @@ import LinkCollection from "@/components/LinkViews/LinkComponents/LinkCollection
import Image from "next/image";
import { previewAvailable } from "@/lib/shared/getArchiveValidity";
import Link from "next/link";
-import LinkIcon from "./LinkComponents/LinkIcon";
+import LinkIcon from "./LinkIcon";
import useOnScreen from "@/hooks/useOnScreen";
import { generateLinkHref } from "@/lib/client/generateLinkHref";
import usePermissions from "@/hooks/usePermissions";
import toast from "react-hot-toast";
-import LinkTypeBadge from "./LinkComponents/LinkTypeBadge";
+import LinkTypeBadge from "./LinkTypeBadge";
import { useTranslation } from "next-i18next";
import { useCollections } from "@/hooks/store/collections";
import { useUser } from "@/hooks/store/user";
diff --git a/components/LinkViews/Links.tsx b/components/LinkViews/Links.tsx
index a90cf77..11720dc 100644
--- a/components/LinkViews/Links.tsx
+++ b/components/LinkViews/Links.tsx
@@ -1,18 +1,16 @@
-import LinkCard from "@/components/LinkViews/LinkCard";
-import { useLinks } from "@/hooks/store/links";
+import LinkCard from "@/components/LinkViews/LinkComponents/LinkCard";
import {
LinkIncludingShortenedCollectionAndTags,
ViewMode,
} from "@/types/global";
-import { useEffect, useState } from "react";
+import { useEffect } from "react";
import { useInView } from "react-intersection-observer";
-import { GridLoader } from "react-spinners";
-import LinkMasonry from "@/components/LinkViews/LinkMasonry";
+import LinkMasonry from "@/components/LinkViews/LinkComponents/LinkMasonry";
import Masonry from "react-masonry-css";
import resolveConfig from "tailwindcss/resolveConfig";
import tailwindConfig from "../../tailwind.config.js";
import { useMemo } from "react";
-import LinkList from "@/components/LinkViews/LinkList";
+import LinkList from "@/components/LinkViews/LinkComponents/LinkList";
export function CardView({
links,
@@ -59,15 +57,6 @@ export function CardView({
);
})}
-
- {/* {isLoading && links.length > 0 && (
-
- )} */}
);
}
@@ -100,15 +89,6 @@ export function ListView({
/>
);
})}
-
- {/* {isLoading && links.length > 0 && (
-
- )} */}
);
}
@@ -157,15 +137,6 @@ export function MasonryView({
/>
);
})}
-
- {/* {isLoading && links.length > 0 && (
-
- )} */}
);
}
diff --git a/components/ModalContent/BulkEditLinksModal.tsx b/components/ModalContent/BulkEditLinksModal.tsx
index 5f3d31a..3797e38 100644
--- a/components/ModalContent/BulkEditLinksModal.tsx
+++ b/components/ModalContent/BulkEditLinksModal.tsx
@@ -6,6 +6,7 @@ import { LinkIncludingShortenedCollectionAndTags } from "@/types/global";
import toast from "react-hot-toast";
import Modal from "../Modal";
import { useTranslation } from "next-i18next";
+import { useBulkEditLinks } from "@/hooks/store/links";
type Props = {
onClose: Function;
@@ -13,13 +14,14 @@ type Props = {
export default function BulkEditLinksModal({ onClose }: Props) {
const { t } = useTranslation();
- const { updateLinks, selectedLinks, setSelectedLinks } = useLinkStore();
+ const { selectedLinks, setSelectedLinks } = useLinkStore();
const [submitLoader, setSubmitLoader] = useState(false);
const [removePreviousTags, setRemovePreviousTags] = useState(false);
const [updatedValues, setUpdatedValues] = useState<
Pick
>({ tags: [] });
+ const updateLinks = useBulkEditLinks();
const setCollection = (e: any) => {
const collectionId = e?.value || null;
setUpdatedValues((prevValues) => ({ ...prevValues, collectionId }));
@@ -34,24 +36,21 @@ export default function BulkEditLinksModal({ onClose }: Props) {
if (!submitLoader) {
setSubmitLoader(true);
- const load = toast.loading(t("updating"));
-
- const response = await updateLinks(
- selectedLinks,
- removePreviousTags,
- updatedValues
+ await updateLinks.mutateAsync(
+ {
+ links: selectedLinks,
+ newData: updatedValues,
+ removePreviousTags,
+ },
+ {
+ onSuccess: () => {
+ setSelectedLinks([]);
+ onClose();
+ },
+ }
);
- toast.dismiss(load);
-
- if (response.ok) {
- toast.success(t("updated"));
- setSelectedLinks([]);
- onClose();
- } else toast.error(response.data as string);
-
setSubmitLoader(false);
- return response;
}
};
diff --git a/components/ModalContent/PreservedFormatsModal.tsx b/components/ModalContent/PreservedFormatsModal.tsx
index 3d2e29d..7cd1df0 100644
--- a/components/ModalContent/PreservedFormatsModal.tsx
+++ b/components/ModalContent/PreservedFormatsModal.tsx
@@ -23,16 +23,14 @@ import { useGetLink } from "@/hooks/store/links";
type Props = {
onClose: Function;
- activeLink: LinkIncludingShortenedCollectionAndTags;
+ link: LinkIncludingShortenedCollectionAndTags;
};
-export default function PreservedFormatsModal({ onClose, activeLink }: Props) {
+export default function PreservedFormatsModal({ onClose, link }: Props) {
const { t } = useTranslation();
const session = useSession();
const getLink = useGetLink();
const { data: user = {} } = useUser();
- const [link, setLink] =
- useState(activeLink);
const router = useRouter();
let isPublic = router.pathname.startsWith("/public") ? true : undefined;
@@ -98,20 +96,14 @@ export default function PreservedFormatsModal({ onClose, activeLink }: Props) {
useEffect(() => {
(async () => {
- const data = await getLink.mutateAsync(link.id as number);
- setLink(
- (data as any).response as LinkIncludingShortenedCollectionAndTags
- );
+ await getLink.mutateAsync(link.id as number);
})();
let interval: any;
if (!isReady()) {
interval = setInterval(async () => {
- const data = await getLink.mutateAsync(link.id as number);
- setLink(
- (data as any).response as LinkIncludingShortenedCollectionAndTags
- );
+ await getLink.mutateAsync(link.id as number);
}, 5000);
} else {
if (interval) {
@@ -137,10 +129,8 @@ export default function PreservedFormatsModal({ onClose, activeLink }: Props) {
toast.dismiss(load);
if (response.ok) {
- const newLink = await getLink.mutateAsync(link?.id as number);
- setLink(
- (newLink as any).response as LinkIncludingShortenedCollectionAndTags
- );
+ await getLink.mutateAsync(link?.id as number);
+
toast.success(t("link_being_archived"));
} else toast.error(data.response);
};
@@ -164,7 +154,7 @@ export default function PreservedFormatsModal({ onClose, activeLink }: Props) {
name={t("webpage")}
icon={"bi-filetype-html"}
format={ArchivedFormat.monolith}
- activeLink={link}
+ link={link}
downloadable={true}
/>
) : undefined}
@@ -178,7 +168,7 @@ export default function PreservedFormatsModal({ onClose, activeLink }: Props) {
? ArchivedFormat.png
: ArchivedFormat.jpeg
}
- activeLink={link}
+ link={link}
downloadable={true}
/>
) : undefined}
@@ -188,7 +178,7 @@ export default function PreservedFormatsModal({ onClose, activeLink }: Props) {
name={t("pdf")}
icon={"bi-file-earmark-pdf"}
format={ArchivedFormat.pdf}
- activeLink={link}
+ link={link}
downloadable={true}
/>
) : undefined}
@@ -198,7 +188,7 @@ export default function PreservedFormatsModal({ onClose, activeLink }: Props) {
name={t("readable")}
icon={"bi-file-earmark-text"}
format={ArchivedFormat.readability}
- activeLink={link}
+ link={link}
/>
) : undefined}
diff --git a/components/PreserverdFormatRow.tsx b/components/PreserverdFormatRow.tsx
index 2e18e39..e8ddbd1 100644
--- a/components/PreserverdFormatRow.tsx
+++ b/components/PreserverdFormatRow.tsx
@@ -1,4 +1,3 @@
-import React, { useEffect, useState } from "react";
import {
ArchivedFormat,
LinkIncludingShortenedCollectionAndTags,
@@ -11,7 +10,7 @@ type Props = {
name: string;
icon: string;
format: ArchivedFormat;
- activeLink: LinkIncludingShortenedCollectionAndTags;
+ link: LinkIncludingShortenedCollectionAndTags;
downloadable?: boolean;
};
@@ -19,47 +18,15 @@ export default function PreservedFormatRow({
name,
icon,
format,
- activeLink,
+ link,
downloadable,
}: Props) {
const getLink = useGetLink();
- const [link, setLink] =
- useState(activeLink);
-
const router = useRouter();
let isPublic = router.pathname.startsWith("/public") ? true : undefined;
- useEffect(() => {
- (async () => {
- const data = await getLink.mutateAsync(link.id as number);
- setLink(
- (data as any).response as LinkIncludingShortenedCollectionAndTags
- );
- })();
-
- let interval: any;
- if (link?.image === "pending" || link?.pdf === "pending") {
- interval = setInterval(async () => {
- const data = await getLink.mutateAsync(link.id as number);
- setLink(
- (data as any).response as LinkIncludingShortenedCollectionAndTags
- );
- }, 5000);
- } else {
- if (interval) {
- clearInterval(interval);
- }
- }
-
- return () => {
- if (interval) {
- clearInterval(interval);
- }
- };
- }, [link?.image, link?.pdf, link?.readable, link?.monolith]);
-
const handleDownload = () => {
const path = `/api/v1/archives/${link?.id}?format=${format}`;
fetch(path)
diff --git a/hooks/store/links.tsx b/hooks/store/links.tsx
index 93b9b75..2fd7c2b 100644
--- a/hooks/store/links.tsx
+++ b/hooks/store/links.tsx
@@ -129,7 +129,7 @@ const useAddLink = () => {
return [data, ...oldData];
});
- queryClient.setQueryData(["links"], (oldData: any) => {
+ queryClient.setQueriesData({ queryKey: ["links"] }, (oldData: any) => {
if (!oldData) return undefined;
return {
pages: [[data, ...oldData?.pages[0]], ...oldData?.pages.slice(1)],
@@ -179,13 +179,12 @@ const useUpdateLink = () => {
return oldData.map((e: any) => (e.id === data.id ? data : e));
});
- queryClient.setQueryData(["links"], (oldData: any) => {
+ queryClient.setQueriesData({ queryKey: ["links"] }, (oldData: any) => {
if (!oldData) return undefined;
return {
- pages: [
- oldData.pages[0].map((e: any) => (e.id === data.id ? data : e)),
- ...oldData.pages.slice(1),
- ],
+ pages: oldData.pages.map((page: any) =>
+ page.map((item: any) => (item.id === data.id ? data : item))
+ ),
pageParams: oldData.pageParams,
};
});
@@ -228,13 +227,12 @@ const useDeleteLink = () => {
return oldData.filter((e: any) => e.id !== data.id);
});
- queryClient.setQueryData(["links"], (oldData: any) => {
+ queryClient.setQueriesData({ queryKey: ["links"] }, (oldData: any) => {
if (!oldData) return undefined;
return {
- pages: [
- oldData.pages[0].filter((e: any) => e.id !== data.id),
- ...oldData.pages.slice(1),
- ],
+ pages: oldData.pages.map((page: any) =>
+ page.filter((item: any) => item.id !== data.id)
+ ),
pageParams: oldData.pageParams,
};
});
@@ -267,13 +265,12 @@ const useGetLink = () => {
return oldData.map((e: any) => (e.id === data.id ? data : e));
});
- queryClient.setQueryData(["links"], (oldData: any) => {
+ queryClient.setQueriesData({ queryKey: ["links"] }, (oldData: any) => {
if (!oldData) return undefined;
return {
- pages: [
- oldData.pages[0].map((e: any) => (e.id === data.id ? data : e)),
- ...oldData.pages.slice(1),
- ],
+ pages: oldData.pages.map((page: any) =>
+ page.map((item: any) => (item.id === data.id ? data : item))
+ ),
pageParams: oldData.pageParams,
};
});
@@ -315,13 +312,12 @@ const useBulkDeleteLinks = () => {
return oldData.filter((e: any) => !data.includes(e.id));
});
- queryClient.setQueryData(["links"], (oldData: any) => {
+ queryClient.setQueriesData({ queryKey: ["links"] }, (oldData: any) => {
if (!oldData) return undefined;
return {
- pages: [
- oldData.pages[0].filter((e: any) => !data.includes(e.id)),
- ...oldData.pages.slice(1),
- ],
+ pages: oldData.pages.map((page: any) =>
+ page.filter((item: any) => !data.includes(item.id))
+ ),
pageParams: oldData.pageParams,
};
});
@@ -401,7 +397,7 @@ const useUploadFile = () => {
return [data, ...oldData];
});
- queryClient.setQueryData(["links"], (oldData: any) => {
+ queryClient.setQueriesData({ queryKey: ["links"] }, (oldData: any) => {
if (!oldData) return undefined;
return {
pages: [[data, ...oldData?.pages[0]], ...oldData?.pages.slice(1)],
@@ -454,7 +450,7 @@ const useBulkEditLinks = () => {
return data.response;
},
- onSuccess: (data) => {
+ onSuccess: (data, { links, newData, removePreviousTags }) => {
toast.success(t("updated"));
queryClient.setQueryData(["dashboardData"], (oldData: any) => {
@@ -464,18 +460,18 @@ const useBulkEditLinks = () => {
);
});
- queryClient.setQueryData(["links"], (oldData: any) => {
- if (!oldData) return undefined;
- return {
- pages: [
- oldData.pages[0].map((e: any) =>
- data.find((d: any) => d.id === e.id) ? data : e
- ),
- ...oldData.pages.slice(1),
- ],
- pageParams: oldData.pageParams,
- };
- });
+ // TODO: Fix this
+ // queryClient.setQueriesData({ queryKey: ["links"] }, (oldData: any) => {
+ // if (!oldData) return undefined;
+ // return {
+ // pages: oldData.pages.map((page: any) => for (item of links) {
+ // page.map((item: any) => (item.id === data.id ? data : item))
+ // }
+ // ),
+ // pageParams: oldData.pageParams,
+ // };
+ // });
+ queryClient.invalidateQueries({ queryKey: ["links"] }); // Temporary workaround
queryClient.invalidateQueries({ queryKey: ["collections"] });
queryClient.invalidateQueries({ queryKey: ["tags"] });
diff --git a/package.json b/package.json
index f25c334..f2a357e 100644
--- a/package.json
+++ b/package.json
@@ -72,7 +72,7 @@
"react-intersection-observer": "^9.13.0",
"react-masonry-css": "^1.0.16",
"react-select": "^5.7.4",
- "react-spinners": "^0.13.8",
+ "react-spinners": "^0.14.1",
"socks-proxy-agent": "^8.0.2",
"stripe": "^12.13.0",
"tailwind-merge": "^2.3.0",
diff --git a/yarn.lock b/yarn.lock
index 1aecfae..edf5040 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -5340,10 +5340,10 @@ react-select@^5.7.4:
react-transition-group "^4.3.0"
use-isomorphic-layout-effect "^1.1.2"
-react-spinners@^0.13.8:
- version "0.13.8"
- resolved "https://registry.yarnpkg.com/react-spinners/-/react-spinners-0.13.8.tgz#5262571be0f745d86bbd49a1e6b49f9f9cb19acc"
- integrity sha512-3e+k56lUkPj0vb5NDXPVFAOkPC//XyhKPJjvcGjyMNPWsBKpplfeyialP74G7H7+It7KzhtET+MvGqbKgAqpZA==
+react-spinners@^0.14.1:
+ version "0.14.1"
+ resolved "https://registry.yarnpkg.com/react-spinners/-/react-spinners-0.14.1.tgz#de7d7d6b3e6d4f29d9620c65495b502c7dd90812"
+ integrity sha512-2Izq+qgQ08HTofCVEdcAQCXFEYfqTDdfeDQJeo/HHQiQJD4imOicNLhkfN2eh1NYEWVOX4D9ok2lhuDB0z3Aag==
react-style-singleton@^2.2.1:
version "2.2.1"