bugs fixed

This commit is contained in:
daniel31x13 2024-08-13 03:01:02 -04:00
parent 80f366cd7b
commit bd34dacf21
14 changed files with 73 additions and 306 deletions

View File

@ -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 (
<div className="grid min-[1901px]:grid-cols-5 min-[1501px]:grid-cols-4 min-[881px]:grid-cols-3 min-[551px]:grid-cols-2 grid-cols-1 gap-5 pb-5">
{links.map((e, i) => {
return (
<LinkCard
key={i}
link={e}
count={i}
flipDropdown={i === links.length - 1}
editMode={editMode}
/>
);
})}
{data.hasNextPage && (
<div className="flex flex-col gap-4" ref={ref}>
<div className="skeleton h-32 w-full"></div>
<div className="skeleton h-4 w-28"></div>
<div className="skeleton h-4 w-full"></div>
<div className="skeleton h-4 w-full"></div>
</div>
)}
{isLoading && links.length > 0 && (
<GridLoader
color="oklch(var(--p))"
loading={true}
size={20}
className="fixed top-5 right-5 opacity-50 z-30"
/>
)}
</div>
);
}

View File

@ -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 (
<div className="flex gap-1 flex-col">
{links.map((e, i) => {
return (
<LinkList
key={i}
link={e}
count={i}
flipDropdown={i === links.length - 1}
editMode={editMode}
/>
);
})}
{isLoading && links.length > 0 && (
<GridLoader
color="oklch(var(--p))"
loading={true}
size={20}
className="fixed top-5 right-5 opacity-50 z-30"
/>
)}
</div>
);
}

View File

@ -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 (
<Masonry
breakpointCols={breakpointColumnsObj}
columnClassName="flex flex-col gap-5 !w-full"
className="grid min-[1901px]:grid-cols-5 min-[1501px]:grid-cols-4 min-[881px]:grid-cols-3 min-[551px]:grid-cols-2 grid-cols-1 gap-5 pb-5"
>
{links.map((e, i) => {
return (
<LinkMasonry
key={i}
link={e}
count={i}
flipDropdown={i === links.length - 1}
editMode={editMode}
/>
);
})}
{isLoading && links.length > 0 && (
<GridLoader
color="oklch(var(--p))"
loading={true}
size={20}
className="fixed top-5 right-5 opacity-50 z-30"
/>
)}
</Masonry>
);
}

View File

@ -162,7 +162,7 @@ export default function LinkActions({
{preservedFormatsModal ? (
<PreservedFormatsModal
onClose={() => setPreservedFormatsModal(false)}
activeLink={link}
link={link}
/>
) : undefined}
{/* {expandedLink ? (

View File

@ -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";

View File

@ -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";

View File

@ -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";

View File

@ -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({
</div>
);
})}
{/* {isLoading && links.length > 0 && (
<GridLoader
color="oklch(var(--p))"
loading={true}
size={20}
className="fixed top-5 right-5 opacity-50 z-30"
/>
)} */}
</div>
);
}
@ -100,15 +89,6 @@ export function ListView({
/>
);
})}
{/* {isLoading && links.length > 0 && (
<GridLoader
color="oklch(var(--p))"
loading={true}
size={20}
className="fixed top-5 right-5 opacity-50 z-30"
/>
)} */}
</div>
);
}
@ -157,15 +137,6 @@ export function MasonryView({
/>
);
})}
{/* {isLoading && links.length > 0 && (
<GridLoader
color="oklch(var(--p))"
loading={true}
size={20}
className="fixed top-5 right-5 opacity-50 z-30"
/>
)} */}
</Masonry>
);
}

View File

@ -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<LinkIncludingShortenedCollectionAndTags, "tags" | "collectionId">
>({ 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;
}
};

View File

@ -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<LinkIncludingShortenedCollectionAndTags>(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}

View File

@ -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<LinkIncludingShortenedCollectionAndTags>(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)

View File

@ -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"] });

View File

@ -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",

View File

@ -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"