many more improvements to the PWA

This commit is contained in:
daniel31x13 2024-01-20 00:34:49 -05:00
parent 86bcd5ef07
commit 4591f8ebc7
9 changed files with 106 additions and 78 deletions

View File

@ -9,7 +9,14 @@ export default function CardView({
return ( return (
<div className="grid min-[1900px]:grid-cols-4 xl:grid-cols-3 sm:grid-cols-2 grid-cols-1 gap-5"> <div className="grid min-[1900px]:grid-cols-4 xl:grid-cols-3 sm:grid-cols-2 grid-cols-1 gap-5">
{links.map((e, i) => { {links.map((e, i) => {
return <LinkCard key={i} link={e} count={i} />; return (
<LinkCard
key={i}
link={e}
count={i}
flipDropdown={i === links.length - 1}
/>
);
})} })}
</div> </div>
); );

View File

@ -9,7 +9,14 @@ export default function ListView({
return ( return (
<div className="flex flex-col"> <div className="flex flex-col">
{links.map((e, i) => { {links.map((e, i) => {
return <LinkList key={i} link={e} count={i} />; return (
<LinkList
key={i}
link={e}
count={i}
flipDropdown={i === links.length - 1}
/>
);
})} })}
</div> </div>
); );

View File

@ -21,9 +21,15 @@ type Props = {
link: LinkIncludingShortenedCollectionAndTags; link: LinkIncludingShortenedCollectionAndTags;
count: number; count: number;
className?: string; className?: string;
flipDropdown?: boolean;
}; };
export default function LinkGrid({ link, count, className }: Props) { export default function LinkGrid({
link,
count,
className,
flipDropdown,
}: Props) {
const { collections } = useCollectionStore(); const { collections } = useCollectionStore();
const { links, getLink } = useLinkStore(); const { links, getLink } = useLinkStore();
@ -199,6 +205,7 @@ export default function LinkGrid({ link, count, className }: Props) {
position="top-[10.75rem] right-3" position="top-[10.75rem] right-3"
toggleShowInfo={() => setShowInfo(!showInfo)} toggleShowInfo={() => setShowInfo(!showInfo)}
linkInfo={showInfo} linkInfo={showInfo}
flipDropdown={flipDropdown}
/> />
</div> </div>
); );

View File

@ -18,6 +18,7 @@ type Props = {
position?: string; position?: string;
toggleShowInfo?: () => void; toggleShowInfo?: () => void;
linkInfo?: boolean; linkInfo?: boolean;
flipDropdown?: boolean;
}; };
export default function LinkActions({ export default function LinkActions({
@ -25,6 +26,7 @@ export default function LinkActions({
toggleShowInfo, toggleShowInfo,
position, position,
linkInfo, linkInfo,
flipDropdown,
}: Props) { }: Props) {
const permissions = usePermissions(link.collection.id as number); const permissions = usePermissions(link.collection.id as number);
@ -65,9 +67,9 @@ export default function LinkActions({
return ( return (
<> <>
<div <div
className={`dropdown dropdown-end dropdown-bottom absolute ${ className={`dropdown dropdown-end dropdown-${
position || "top-3 right-3" flipDropdown ? "top" : "bottom"
} z-20`} } absolute ${position || "top-3 right-3"} z-20`}
> >
<div <div
tabIndex={0} tabIndex={0}

View File

@ -17,9 +17,15 @@ type Props = {
link: LinkIncludingShortenedCollectionAndTags; link: LinkIncludingShortenedCollectionAndTags;
count: number; count: number;
className?: string; className?: string;
flipDropdown?: boolean;
}; };
export default function LinkCardCompact({ link, count, className }: Props) { export default function LinkCardCompact({
link,
count,
className,
flipDropdown,
}: Props) {
const { collections } = useCollectionStore(); const { collections } = useCollectionStore();
const { links } = useLinkStore(); const { links } = useLinkStore();
@ -95,6 +101,7 @@ export default function LinkCardCompact({ link, count, className }: Props) {
link={link} link={link}
collection={collection} collection={collection}
position="top-3 right-3" position="top-3 right-3"
flipDropdown={flipDropdown}
// toggleShowInfo={() => setShowInfo(!showInfo)} // toggleShowInfo={() => setShowInfo(!showInfo)}
// linkInfo={showInfo} // linkInfo={showInfo}
/> />

View File

@ -1,6 +1,6 @@
import { dropdownTriggerer } from "@/lib/client/utils"; import { dropdownTriggerer, isPWA } from "@/lib/client/utils";
import React from "react"; import React from "react";
import { useEffect, useState } from "react"; import { useState } from "react";
import NewLinkModal from "./ModalContent/NewLinkModal"; import NewLinkModal from "./ModalContent/NewLinkModal";
import NewCollectionModal from "./ModalContent/NewCollectionModal"; import NewCollectionModal from "./ModalContent/NewCollectionModal";
import UploadFileModal from "./ModalContent/UploadFileModal"; import UploadFileModal from "./ModalContent/UploadFileModal";
@ -9,59 +9,50 @@ import MobileNavigationButton from "./MobileNavigationButton";
type Props = {}; type Props = {};
export default function MobileNavigation({}: Props) { export default function MobileNavigation({}: Props) {
const [hasScrolled, setHasScrolled] = useState(false);
const [newLinkModal, setNewLinkModal] = useState(false); const [newLinkModal, setNewLinkModal] = useState(false);
const [newCollectionModal, setNewCollectionModal] = useState(false); const [newCollectionModal, setNewCollectionModal] = useState(false);
const [uploadFileModal, setUploadFileModal] = useState(false); const [uploadFileModal, setUploadFileModal] = useState(false);
useEffect(() => {
const handleScroll = () => {
if (window.scrollY > 0) {
setHasScrolled(true);
} else {
setHasScrolled(false);
}
};
window.addEventListener("scroll", handleScroll);
return () => {
window.removeEventListener("scroll", handleScroll);
};
}, []);
return ( return (
<> <>
<div <div
className={`fixed bottom-0 left-0 right-0 z-30 duration-200 sm:hidden ${ className={`fixed bottom-0 left-0 right-0 z-30 duration-200 sm:hidden`}
hasScrolled ? "opacity-80" : ""
}`}
> >
<div className="dropdown dropdown-end dropdown-top absolute -top-20 right-5"> <div
<div className={`w-full flex bg-base-100 ${
tabIndex={0} isPWA() ? "pb-5" : ""
role="button" } border-solid border-t-neutral-content border-t`}
onMouseDown={dropdownTriggerer} >
className={`flex items-center btn btn-accent dark:border-violet-400 text-white btn-circle btn-lg px-2 relative`} <MobileNavigationButton href={`/dashboard`} icon={"bi-house"} />
> <MobileNavigationButton
<span> href={`/links/pinned`}
<i className="bi-plus text-5xl pointer-events-none"></i> icon={"bi-pin-angle"}
</span> />
</div> <div className="dropdown dropdown-top -mt-4">
<ul className="dropdown-content z-[1] menu shadow bg-base-200 border border-neutral-content rounded-box w-40 mb-1"> <div
<li> tabIndex={0}
<div role="button"
onClick={() => { onMouseDown={dropdownTriggerer}
(document?.activeElement as HTMLElement)?.blur(); className={`flex items-center btn btn-accent dark:border-violet-400 text-white btn-circle w-20 h-20 px-2 relative`}
setNewLinkModal(true); >
}} <span>
tabIndex={0} <i className="bi-plus text-5xl pointer-events-none"></i>
role="button" </span>
> </div>
New Link <ul className="dropdown-content z-[1] menu shadow bg-base-200 border border-neutral-content rounded-box w-40 mb-1 -ml-12">
</div> <li>
</li> <div
{/* <li> onClick={() => {
(document?.activeElement as HTMLElement)?.blur();
setNewLinkModal(true);
}}
tabIndex={0}
role="button"
>
New Link
</div>
</li>
{/* <li>
<div <div
onClick={() => { onClick={() => {
(document?.activeElement as HTMLElement)?.blur(); (document?.activeElement as HTMLElement)?.blur();
@ -73,30 +64,22 @@ export default function MobileNavigation({}: Props) {
Upload File Upload File
</div> </div>
</li> */} </li> */}
<li> <li>
<div <div
onClick={() => { onClick={() => {
(document?.activeElement as HTMLElement)?.blur(); (document?.activeElement as HTMLElement)?.blur();
setNewCollectionModal(true); setNewCollectionModal(true);
}} }}
tabIndex={0} tabIndex={0}
role="button" role="button"
> >
New Collection New Collection
</div> </div>
</li> </li>
</ul> </ul>
</div> </div>
<div className="w-full flex bg-base-100 pb-5 border-solid border-t-neutral-content border-t">
<MobileNavigationButton href={`/dashboard`} icon={"bi-house"} />
<MobileNavigationButton
href={`/links/pinned`}
icon={"bi-pin-angle"}
/>
<MobileNavigationButton href={`/links`} icon={"bi-link-45deg"} /> <MobileNavigationButton href={`/links`} icon={"bi-link-45deg"} />
<MobileNavigationButton href={`/collections`} icon={"bi-folder"} /> <MobileNavigationButton href={`/collections`} icon={"bi-folder"} />
<MobileNavigationButton href={`/tags`} icon={"bi-hash"} />
</div> </div>
</div> </div>
{newLinkModal ? ( {newLinkModal ? (

View File

@ -1,3 +1,4 @@
import { isPWA } from "@/lib/client/utils";
import Link from "next/link"; import Link from "next/link";
import { useRouter } from "next/router"; import { useRouter } from "next/router";
import { useEffect, useState } from "react"; import { useEffect, useState } from "react";
@ -17,7 +18,19 @@ export default function MobileNavigationButton({
}, [router]); }, [router]);
return ( return (
<Link href={href} className="w-full"> <Link
href={href}
className="w-full active:scale-[80%] duration-200 select-none"
draggable="false"
style={{ WebkitTouchCallout: "none" }}
onContextMenu={(e) => {
if (isPWA()) {
e.preventDefault();
e.stopPropagation();
return false;
} else return null;
}}
>
<div <div
className={`py-2 cursor-pointer gap-2 w-full rounded-full capitalize flex items-center justify-center`} className={`py-2 cursor-pointer gap-2 w-full rounded-full capitalize flex items-center justify-center`}
> >

View File

@ -10,8 +10,10 @@ type Props = {
export default function Modal({ toggleModal, className, children }: Props) { export default function Modal({ toggleModal, className, children }: Props) {
useEffect(() => { useEffect(() => {
document.body.style.overflow = "hidden"; document.body.style.overflow = "hidden";
document.body.style.position = "relative";
return () => { return () => {
document.body.style.overflow = "auto"; document.body.style.overflow = "auto";
document.body.style.position = "";
}; };
}); });

View File

@ -46,7 +46,7 @@ export default function MainLayout({ children }: Props) {
</div> </div>
<div <div
className={`w-full sm:pb-0 pb-40 flex flex-col min-h-${ className={`w-full sm:pb-0 pb-20 flex flex-col min-h-${
showAnnouncement ? "full" : "screen" showAnnouncement ? "full" : "screen"
} lg:ml-80 ${showAnnouncement ? "mt-10" : ""}`} } lg:ml-80 ${showAnnouncement ? "mt-10" : ""}`}
> >