Allow users to choose what clicking links opens

This commit is contained in:
Isaac Wise 2024-02-08 00:42:58 -06:00
parent 7d9cc1f1f0
commit cc915c8a64
6 changed files with 82 additions and 38 deletions

View File

@ -14,8 +14,8 @@ import Image from "next/image";
import { previewAvailable } from "@/lib/shared/getArchiveValidity"; import { previewAvailable } from "@/lib/shared/getArchiveValidity";
import Link from "next/link"; import Link from "next/link";
import LinkIcon from "./LinkComponents/LinkIcon"; import LinkIcon from "./LinkComponents/LinkIcon";
import LinkGroupedIconURL from "./LinkComponents/LinkGroupedIconURL";
import useOnScreen from "@/hooks/useOnScreen"; import useOnScreen from "@/hooks/useOnScreen";
import { generateHrefBasedOnUserPreference } from "@/lib/client/generateHrefBasedOnUserPreference ";
type Props = { type Props = {
link: LinkIncludingShortenedCollectionAndTags; link: LinkIncludingShortenedCollectionAndTags;
@ -26,8 +26,6 @@ type Props = {
export default function LinkGrid({ export default function LinkGrid({
link, link,
count,
className,
flipDropdown, flipDropdown,
}: Props) { }: Props) {
const { collections } = useCollectionStore(); const { collections } = useCollectionStore();
@ -88,7 +86,7 @@ export default function LinkGrid({
className="border border-solid border-neutral-content bg-base-200 shadow-md hover:shadow-none duration-100 rounded-2xl relative" className="border border-solid border-neutral-content bg-base-200 shadow-md hover:shadow-none duration-100 rounded-2xl relative"
> >
<Link <Link
href={link.url || ""} href={generateHrefBasedOnUserPreference(link)}
target="_blank" target="_blank"
className="rounded-2xl cursor-pointer" className="rounded-2xl cursor-pointer"
> >

View File

@ -18,7 +18,7 @@ type Props = {
className?: string; className?: string;
}; };
export default function LinkGrid({ link, count, className }: Props) { export default function LinkGrid({ link }: Props) {
const { collections } = useCollectionStore(); const { collections } = useCollectionStore();
const { links } = useLinkStore(); const { links } = useLinkStore();
@ -101,7 +101,7 @@ export default function LinkGrid({ link, count, className }: Props) {
</div> </div>
<LinkActions <LinkActions
toggleShowInfo={() => {}} toggleShowInfo={() => { }}
linkInfo={false} linkInfo={false}
link={link} link={link}
collection={collection} collection={collection}

View File

@ -1,4 +1,5 @@
import { import {
ArchivedFormat,
CollectionIncludingMembersAndLinkCount, CollectionIncludingMembersAndLinkCount,
LinkIncludingShortenedCollectionAndTags, LinkIncludingShortenedCollectionAndTags,
} from "@/types/global"; } from "@/types/global";
@ -12,6 +13,7 @@ import LinkCollection from "@/components/LinkViews/LinkComponents/LinkCollection
import LinkIcon from "@/components/LinkViews/LinkComponents/LinkIcon"; import LinkIcon from "@/components/LinkViews/LinkComponents/LinkIcon";
import Link from "next/link"; import Link from "next/link";
import { isPWA } from "@/lib/client/utils"; import { isPWA } from "@/lib/client/utils";
import { generateLinkHrefBasedOnUserPreference } from "@/lib/client/generateHrefBasedOnUserPreference ";
type Props = { type Props = {
link: LinkIncludingShortenedCollectionAndTags; link: LinkIncludingShortenedCollectionAndTags;
@ -22,12 +24,9 @@ type Props = {
export default function LinkCardCompact({ export default function LinkCardCompact({
link, link,
count,
className,
flipDropdown, flipDropdown,
}: Props) { }: Props) {
const { collections } = useCollectionStore(); const { collections } = useCollectionStore();
const { links } = useLinkStore(); const { links } = useLinkStore();
let shortendURL; let shortendURL;
@ -58,12 +57,11 @@ export default function LinkCardCompact({
return ( return (
<> <>
<div <div
className={`border-neutral-content relative ${ className={`border-neutral-content relative ${!showInfo && !isPWA() ? "hover:bg-base-300 p-3" : "py-3"
!showInfo && !isPWA() ? "hover:bg-base-300 p-3" : "py-3" } duration-200 rounded-lg`}
} duration-200 rounded-lg`}
> >
<Link <Link
href={link.url || ""} href={generateLinkHrefBasedOnUserPreference(link)}
target="_blank" target="_blank"
className="flex items-start cursor-pointer" className="flex items-start cursor-pointer"
> >
@ -102,8 +100,8 @@ export default function LinkCardCompact({
collection={collection} collection={collection}
position="top-3 right-3" position="top-3 right-3"
flipDropdown={flipDropdown} flipDropdown={flipDropdown}
// toggleShowInfo={() => setShowInfo(!showInfo)} // toggleShowInfo={() => setShowInfo(!showInfo)}
// linkInfo={showInfo} // linkInfo={showInfo}
/> />
{showInfo ? ( {showInfo ? (
<div> <div>

View File

@ -97,18 +97,18 @@ export default async function updateUserById(
id: { not: userId }, id: { not: userId },
OR: emailEnabled OR: emailEnabled
? [ ? [
{ {
username: data.username.toLowerCase(), username: data.username.toLowerCase(),
}, },
{ {
email: data.email?.toLowerCase(), email: data.email?.toLowerCase(),
}, },
] ]
: [ : [
{ {
username: data.username.toLowerCase(), username: data.username.toLowerCase(),
}, },
], ],
}, },
}); });
@ -186,6 +186,7 @@ export default async function updateUserById(
archiveAsScreenshot: data.archiveAsScreenshot, archiveAsScreenshot: data.archiveAsScreenshot,
archiveAsPDF: data.archiveAsPDF, archiveAsPDF: data.archiveAsPDF,
archiveAsWaybackMachine: data.archiveAsWaybackMachine, archiveAsWaybackMachine: data.archiveAsWaybackMachine,
linksRouteTo: data.linksRouteTo,
password: password:
data.newPassword && data.newPassword !== "" data.newPassword && data.newPassword !== ""
? newHashedPassword ? newHashedPassword

View File

@ -0,0 +1,20 @@
import useAccountStore from "@/store/account";
import { ArchivedFormat, LinkIncludingShortenedCollectionAndTags } from "@/types/global";
import { LinksRouteTo } from "@prisma/client";
export const generateLinkHrefBasedOnUserPreference = (link: LinkIncludingShortenedCollectionAndTags): string => {
const { account } = useAccountStore();
switch (account.linksRouteTo) {
case LinksRouteTo.ORIGINAL:
return link.url || '';
case LinksRouteTo.PDF:
return `/preserved/${link?.id}?format=${ArchivedFormat.pdf}`;
case LinksRouteTo.READABLE:
return `/preserved/${link?.id}?format=${ArchivedFormat.readability}`;
case LinksRouteTo.SCREENSHOT:
return `/preserved/${link?.id}?format=${link?.image?.endsWith("png") ? ArchivedFormat.png : ArchivedFormat.jpeg}`;
default:
return link.url || '';
}
};

View File

@ -7,6 +7,7 @@ import React from "react";
import useLocalSettingsStore from "@/store/localSettings"; import useLocalSettingsStore from "@/store/localSettings";
import Checkbox from "@/components/Checkbox"; import Checkbox from "@/components/Checkbox";
import SubmitButton from "@/components/SubmitButton"; import SubmitButton from "@/components/SubmitButton";
import { LinksRouteTo } from "@prisma/client";
export default function Appearance() { export default function Appearance() {
const { updateSettings } = useLocalSettingsStore(); const { updateSettings } = useLocalSettingsStore();
@ -20,6 +21,7 @@ export default function Appearance() {
const [archiveAsPDF, setArchiveAsPDF] = useState<boolean>(false); const [archiveAsPDF, setArchiveAsPDF] = useState<boolean>(false);
const [archiveAsWaybackMachine, setArchiveAsWaybackMachine] = const [archiveAsWaybackMachine, setArchiveAsWaybackMachine] =
useState<boolean>(false); useState<boolean>(false);
const [linksRouteTo, setLinksRouteTo] = useState<LinksRouteTo>(user.linksRouteTo);
useEffect(() => { useEffect(() => {
setUser({ setUser({
@ -27,8 +29,9 @@ export default function Appearance() {
archiveAsScreenshot, archiveAsScreenshot,
archiveAsPDF, archiveAsPDF,
archiveAsWaybackMachine, archiveAsWaybackMachine,
linksRouteTo
}); });
}, [account, archiveAsScreenshot, archiveAsPDF, archiveAsWaybackMachine]); }, [account, archiveAsScreenshot, archiveAsPDF, archiveAsWaybackMachine, linksRouteTo]);
function objectIsEmpty(obj: object) { function objectIsEmpty(obj: object) {
return Object.keys(obj).length === 0; return Object.keys(obj).length === 0;
@ -39,6 +42,7 @@ export default function Appearance() {
setArchiveAsScreenshot(account.archiveAsScreenshot); setArchiveAsScreenshot(account.archiveAsScreenshot);
setArchiveAsPDF(account.archiveAsPDF); setArchiveAsPDF(account.archiveAsPDF);
setArchiveAsWaybackMachine(account.archiveAsWaybackMachine); setArchiveAsWaybackMachine(account.archiveAsWaybackMachine);
setLinksRouteTo(account.linksRouteTo);
} }
}, [account]); }, [account]);
@ -70,11 +74,10 @@ export default function Appearance() {
<p className="mb-3">Select Theme</p> <p className="mb-3">Select Theme</p>
<div className="flex gap-3 w-full"> <div className="flex gap-3 w-full">
<div <div
className={`w-full text-center outline-solid outline-neutral-content outline dark:outline-neutral-700 h-36 duration-100 rounded-md flex items-center justify-center cursor-pointer select-none bg-black ${ className={`w-full text-center outline-solid outline-neutral-content outline dark:outline-neutral-700 h-36 duration-100 rounded-md flex items-center justify-center cursor-pointer select-none bg-black ${localStorage.getItem("theme") === "dark"
localStorage.getItem("theme") === "dark" ? "dark:outline-primary text-primary"
? "dark:outline-primary text-primary" : "text-white"
: "text-white" }`}
}`}
onClick={() => updateSettings({ theme: "dark" })} onClick={() => updateSettings({ theme: "dark" })}
> >
<i className="bi-moon-fill text-6xl"></i> <i className="bi-moon-fill text-6xl"></i>
@ -83,11 +86,10 @@ export default function Appearance() {
{/* <hr className="my-3 outline-1 outline-neutral-content dark:outline-neutral-700" /> */} {/* <hr className="my-3 outline-1 outline-neutral-content dark:outline-neutral-700" /> */}
</div> </div>
<div <div
className={`w-full text-center outline-solid outline-neutral-content outline dark:outline-neutral-700 h-36 duration-100 rounded-md flex items-center justify-center cursor-pointer select-none bg-white ${ className={`w-full text-center outline-solid outline-neutral-content outline dark:outline-neutral-700 h-36 duration-100 rounded-md flex items-center justify-center cursor-pointer select-none bg-white ${localStorage.getItem("theme") === "light"
localStorage.getItem("theme") === "light" ? "outline-primary text-primary"
? "outline-primary text-primary" : "text-black"
: "text-black" }`}
}`}
onClick={() => updateSettings({ theme: "light" })} onClick={() => updateSettings({ theme: "light" })}
> >
<i className="bi-sun-fill text-6xl"></i> <i className="bi-sun-fill text-6xl"></i>
@ -133,7 +135,32 @@ export default function Appearance() {
<div className="divider my-3"></div> <div className="divider my-3"></div>
<p>Clicking on Links should:</p> <p>Clicking on Links should open:</p>
<div className="p-3">
<Checkbox
label="Original"
state={linksRouteTo === LinksRouteTo.ORIGINAL}
onClick={() => setLinksRouteTo(LinksRouteTo.ORIGINAL)}
/>
<Checkbox
label="PDF"
state={linksRouteTo === LinksRouteTo.PDF}
onClick={() => setLinksRouteTo(LinksRouteTo.PDF)}
/>
<Checkbox
label="Readable"
state={linksRouteTo === LinksRouteTo.READABLE}
onClick={() => setLinksRouteTo(LinksRouteTo.READABLE)}
/>
<Checkbox
label="Screenshot"
state={linksRouteTo === LinksRouteTo.SCREENSHOT}
onClick={() => setLinksRouteTo(LinksRouteTo.SCREENSHOT)}
/>
</div>
</div> </div>
<SubmitButton <SubmitButton