many more improvements to the PWA
This commit is contained in:
parent
86bcd5ef07
commit
4591f8ebc7
|
@ -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>
|
||||||
);
|
);
|
||||||
|
|
|
@ -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>
|
||||||
);
|
);
|
||||||
|
|
|
@ -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>
|
||||||
);
|
);
|
||||||
|
|
|
@ -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}
|
||||||
|
|
|
@ -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}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -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 ? (
|
||||||
|
|
|
@ -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`}
|
||||||
>
|
>
|
||||||
|
|
|
@ -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 = "";
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -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" : ""}`}
|
||||||
>
|
>
|
||||||
|
|
Ŝarĝante…
Reference in New Issue