improvements to the pwa
This commit is contained in:
parent
834d25a99e
commit
d4f59d7f32
|
@ -9,6 +9,7 @@ import useAccountStore from "@/store/account";
|
||||||
import EditCollectionModal from "./ModalContent/EditCollectionModal";
|
import EditCollectionModal from "./ModalContent/EditCollectionModal";
|
||||||
import EditCollectionSharingModal from "./ModalContent/EditCollectionSharingModal";
|
import EditCollectionSharingModal from "./ModalContent/EditCollectionSharingModal";
|
||||||
import DeleteCollectionModal from "./ModalContent/DeleteCollectionModal";
|
import DeleteCollectionModal from "./ModalContent/DeleteCollectionModal";
|
||||||
|
import { dropdownTriggerer } from "@/lib/client/utils";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
collection: CollectionIncludingMembersAndLinkCount;
|
collection: CollectionIncludingMembersAndLinkCount;
|
||||||
|
@ -70,6 +71,7 @@ export default function CollectionCard({ collection, className }: Props) {
|
||||||
<div
|
<div
|
||||||
tabIndex={0}
|
tabIndex={0}
|
||||||
role="button"
|
role="button"
|
||||||
|
onMouseDown={dropdownTriggerer}
|
||||||
className="btn btn-ghost btn-sm btn-square text-neutral"
|
className="btn btn-ghost btn-sm btn-square text-neutral"
|
||||||
>
|
>
|
||||||
<i className="bi-three-dots text-xl" title="More"></i>
|
<i className="bi-three-dots text-xl" title="More"></i>
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import { dropdownTriggerer } from "@/lib/client/utils";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
|
@ -20,6 +21,7 @@ export default function FilterSearchDropdown({
|
||||||
<div
|
<div
|
||||||
tabIndex={0}
|
tabIndex={0}
|
||||||
role="button"
|
role="button"
|
||||||
|
onMouseDown={dropdownTriggerer}
|
||||||
className="btn btn-sm btn-square btn-ghost"
|
className="btn btn-sm btn-square btn-ghost"
|
||||||
>
|
>
|
||||||
<i className="bi-funnel text-neutral text-2xl"></i>
|
<i className="bi-funnel text-neutral text-2xl"></i>
|
||||||
|
|
|
@ -126,17 +126,12 @@ export default function LinkGrid({ link, count, className }: Props) {
|
||||||
{unescapeString(link.name || link.description) || link.url}
|
{unescapeString(link.name || link.description) || link.url}
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<Link
|
<div title={link.url || ""} className="w-fit">
|
||||||
href={link.url || ""}
|
|
||||||
target="_blank"
|
|
||||||
title={link.url || ""}
|
|
||||||
className="w-fit"
|
|
||||||
>
|
|
||||||
<div className="flex gap-1 item-center select-none text-neutral mt-1">
|
<div className="flex gap-1 item-center select-none text-neutral mt-1">
|
||||||
<i className="bi-link-45deg text-lg mt-[0.15rem] leading-none"></i>
|
<i className="bi-link-45deg text-lg mt-[0.15rem] leading-none"></i>
|
||||||
<p className="text-sm truncate">{shortendURL}</p>
|
<p className="text-sm truncate">{shortendURL}</p>
|
||||||
</div>
|
</div>
|
||||||
</Link>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<hr className="divider mt-2 mb-1 last:hidden border-t border-neutral-content h-[1px]" />
|
<hr className="divider mt-2 mb-1 last:hidden border-t border-neutral-content h-[1px]" />
|
||||||
|
|
|
@ -10,6 +10,7 @@ import PreservedFormatsModal from "@/components/ModalContent/PreservedFormatsMod
|
||||||
import useLinkStore from "@/store/links";
|
import useLinkStore from "@/store/links";
|
||||||
import { toast } from "react-hot-toast";
|
import { toast } from "react-hot-toast";
|
||||||
import useAccountStore from "@/store/account";
|
import useAccountStore from "@/store/account";
|
||||||
|
import { dropdownTriggerer } from "@/lib/client/utils";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
link: LinkIncludingShortenedCollectionAndTags;
|
link: LinkIncludingShortenedCollectionAndTags;
|
||||||
|
@ -71,6 +72,7 @@ export default function LinkActions({
|
||||||
<div
|
<div
|
||||||
tabIndex={0}
|
tabIndex={0}
|
||||||
role="button"
|
role="button"
|
||||||
|
onMouseDown={dropdownTriggerer}
|
||||||
className="btn btn-ghost btn-sm btn-square text-neutral"
|
className="btn btn-ghost btn-sm btn-square text-neutral"
|
||||||
>
|
>
|
||||||
<i title="More" className="bi-three-dots text-xl" />
|
<i title="More" className="bi-three-dots text-xl" />
|
||||||
|
|
|
@ -9,6 +9,7 @@ import usePermissions from "@/hooks/usePermissions";
|
||||||
import ProfilePhoto from "../ProfilePhoto";
|
import ProfilePhoto from "../ProfilePhoto";
|
||||||
import addMemberToCollection from "@/lib/client/addMemberToCollection";
|
import addMemberToCollection from "@/lib/client/addMemberToCollection";
|
||||||
import Modal from "../Modal";
|
import Modal from "../Modal";
|
||||||
|
import { dropdownTriggerer } from "@/lib/client/utils";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
onClose: Function;
|
onClose: Function;
|
||||||
|
@ -264,6 +265,7 @@ export default function EditCollectionSharingModal({
|
||||||
<div
|
<div
|
||||||
tabIndex={0}
|
tabIndex={0}
|
||||||
role="button"
|
role="button"
|
||||||
|
onMouseDown={dropdownTriggerer}
|
||||||
className="btn btn-sm btn-primary font-normal"
|
className="btn btn-sm btn-primary font-normal"
|
||||||
>
|
>
|
||||||
{roleLabel}
|
{roleLabel}
|
||||||
|
|
|
@ -13,6 +13,8 @@ import NewLinkModal from "./ModalContent/NewLinkModal";
|
||||||
import NewCollectionModal from "./ModalContent/NewCollectionModal";
|
import NewCollectionModal from "./ModalContent/NewCollectionModal";
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import UploadFileModal from "./ModalContent/UploadFileModal";
|
import UploadFileModal from "./ModalContent/UploadFileModal";
|
||||||
|
import { dropdownTriggerer } from "@/lib/client/utils";
|
||||||
|
import NewButtonMobile from "./NewButtonMobile";
|
||||||
|
|
||||||
export default function Navbar() {
|
export default function Navbar() {
|
||||||
const { settings, updateSettings } = useLocalSettingsStore();
|
const { settings, updateSettings } = useLocalSettingsStore();
|
||||||
|
@ -35,14 +37,12 @@ export default function Navbar() {
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setSidebar(false);
|
setSidebar(false);
|
||||||
}, [width]);
|
document.body.style.overflow = "auto";
|
||||||
|
}, [width, router]);
|
||||||
useEffect(() => {
|
|
||||||
setSidebar(false);
|
|
||||||
}, [router]);
|
|
||||||
|
|
||||||
const toggleSidebar = () => {
|
const toggleSidebar = () => {
|
||||||
setSidebar(!sidebar);
|
setSidebar(false);
|
||||||
|
document.body.style.overflow = "auto";
|
||||||
};
|
};
|
||||||
|
|
||||||
const [newLinkModal, setNewLinkModal] = useState(false);
|
const [newLinkModal, setNewLinkModal] = useState(false);
|
||||||
|
@ -52,7 +52,10 @@ export default function Navbar() {
|
||||||
return (
|
return (
|
||||||
<div className="flex justify-between gap-2 items-center pl-3 pr-4 py-2 border-solid border-b-neutral-content border-b">
|
<div className="flex justify-between gap-2 items-center pl-3 pr-4 py-2 border-solid border-b-neutral-content border-b">
|
||||||
<div
|
<div
|
||||||
onClick={toggleSidebar}
|
onClick={() => {
|
||||||
|
setSidebar(true);
|
||||||
|
document.body.style.overflow = "hidden";
|
||||||
|
}}
|
||||||
className="text-neutral btn btn-square btn-sm btn-ghost lg:hidden"
|
className="text-neutral btn btn-square btn-sm btn-ghost lg:hidden"
|
||||||
>
|
>
|
||||||
<i className="bi-list text-2xl leading-none"></i>
|
<i className="bi-list text-2xl leading-none"></i>
|
||||||
|
@ -61,11 +64,12 @@ export default function Navbar() {
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<ToggleDarkMode className="hidden sm:inline-grid" />
|
<ToggleDarkMode className="hidden sm:inline-grid" />
|
||||||
|
|
||||||
<div className="dropdown dropdown-end">
|
<div className="dropdown dropdown-end sm:inline-block hidden">
|
||||||
<div className="tooltip tooltip-bottom" data-tip="Create New...">
|
<div className="tooltip tooltip-bottom" data-tip="Create New...">
|
||||||
<div
|
<div
|
||||||
tabIndex={0}
|
tabIndex={0}
|
||||||
role="button"
|
role="button"
|
||||||
|
onMouseDown={dropdownTriggerer}
|
||||||
className="flex min-w-[3.4rem] items-center btn btn-accent dark:border-violet-400 text-white btn-sm max-h-[2rem] px-2 relative"
|
className="flex min-w-[3.4rem] items-center btn btn-accent dark:border-violet-400 text-white btn-sm max-h-[2rem] px-2 relative"
|
||||||
>
|
>
|
||||||
<span>
|
<span>
|
||||||
|
@ -117,7 +121,12 @@ export default function Navbar() {
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="dropdown dropdown-end">
|
<div className="dropdown dropdown-end">
|
||||||
<div tabIndex={0} role="button" className="btn btn-circle btn-ghost">
|
<div
|
||||||
|
tabIndex={0}
|
||||||
|
role="button"
|
||||||
|
onMouseDown={dropdownTriggerer}
|
||||||
|
className="btn btn-circle btn-ghost"
|
||||||
|
>
|
||||||
<ProfilePhoto
|
<ProfilePhoto
|
||||||
src={account.image ? account.image : undefined}
|
src={account.image ? account.image : undefined}
|
||||||
priority={true}
|
priority={true}
|
||||||
|
@ -134,7 +143,7 @@ export default function Navbar() {
|
||||||
Settings
|
Settings
|
||||||
</Link>
|
</Link>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li className="block sm:hidden">
|
||||||
<div
|
<div
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
(document?.activeElement as HTMLElement)?.blur();
|
(document?.activeElement as HTMLElement)?.blur();
|
||||||
|
@ -161,6 +170,9 @@ export default function Navbar() {
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<NewButtonMobile />
|
||||||
|
|
||||||
{sidebar ? (
|
{sidebar ? (
|
||||||
<div className="fixed top-0 bottom-0 right-0 left-0 bg-black bg-opacity-10 backdrop-blur-sm flex items-center fade-in z-40">
|
<div className="fixed top-0 bottom-0 right-0 left-0 bg-black bg-opacity-10 backdrop-blur-sm flex items-center fade-in z-40">
|
||||||
<ClickAwayHandler className="h-full" onClickOutside={toggleSidebar}>
|
<ClickAwayHandler className="h-full" onClickOutside={toggleSidebar}>
|
||||||
|
|
|
@ -0,0 +1,97 @@
|
||||||
|
import { dropdownTriggerer } from "@/lib/client/utils";
|
||||||
|
import React from "react";
|
||||||
|
import { useEffect, useState } from "react";
|
||||||
|
import NewLinkModal from "./ModalContent/NewLinkModal";
|
||||||
|
import NewCollectionModal from "./ModalContent/NewCollectionModal";
|
||||||
|
import UploadFileModal from "./ModalContent/UploadFileModal";
|
||||||
|
|
||||||
|
type Props = {};
|
||||||
|
|
||||||
|
export default function NewButtonMobile({}: Props) {
|
||||||
|
const [hasScrolled, setHasScrolled] = useState(false);
|
||||||
|
const [newLinkModal, setNewLinkModal] = useState(false);
|
||||||
|
const [newCollectionModal, setNewCollectionModal] = 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 (
|
||||||
|
<>
|
||||||
|
<div className="dropdown dropdown-end dropdown-top sm:hidden fixed bottom-10 right-10 z-30">
|
||||||
|
<div
|
||||||
|
tabIndex={0}
|
||||||
|
role="button"
|
||||||
|
onMouseDown={dropdownTriggerer}
|
||||||
|
className={`flex items-center btn btn-accent dark:border-violet-400 text-white btn-circle btn-lg px-2 relative ${
|
||||||
|
hasScrolled ? "opacity-50" : ""
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
<span>
|
||||||
|
<i className="bi-plus text-5xl pointer-events-none"></i>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<ul className="dropdown-content z-[1] menu shadow bg-base-200 border border-neutral-content rounded-box w-40 mb-1">
|
||||||
|
<li>
|
||||||
|
<div
|
||||||
|
onClick={() => {
|
||||||
|
(document?.activeElement as HTMLElement)?.blur();
|
||||||
|
setNewLinkModal(true);
|
||||||
|
}}
|
||||||
|
tabIndex={0}
|
||||||
|
role="button"
|
||||||
|
>
|
||||||
|
New Link
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
{/* <li>
|
||||||
|
<div
|
||||||
|
onClick={() => {
|
||||||
|
(document?.activeElement as HTMLElement)?.blur();
|
||||||
|
setUploadFileModal(true);
|
||||||
|
}}
|
||||||
|
tabIndex={0}
|
||||||
|
role="button"
|
||||||
|
>
|
||||||
|
Upload File
|
||||||
|
</div>
|
||||||
|
</li> */}
|
||||||
|
<li>
|
||||||
|
<div
|
||||||
|
onClick={() => {
|
||||||
|
(document?.activeElement as HTMLElement)?.blur();
|
||||||
|
setNewCollectionModal(true);
|
||||||
|
}}
|
||||||
|
tabIndex={0}
|
||||||
|
role="button"
|
||||||
|
>
|
||||||
|
New Collection
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
{newLinkModal ? (
|
||||||
|
<NewLinkModal onClose={() => setNewLinkModal(false)} />
|
||||||
|
) : undefined}
|
||||||
|
{newCollectionModal ? (
|
||||||
|
<NewCollectionModal onClose={() => setNewCollectionModal(false)} />
|
||||||
|
) : undefined}
|
||||||
|
{uploadFileModal ? (
|
||||||
|
<UploadFileModal onClose={() => setUploadFileModal(false)} />
|
||||||
|
) : undefined}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
|
@ -44,7 +44,7 @@ export default function Sidebar({ className }: { className?: string }) {
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
id="sidebar"
|
id="sidebar"
|
||||||
className={`bg-base-200 h-full w-72 lg:w-80 overflow-y-auto border-solid border border-base-200 border-r-neutral-content p-2 z-20 ${
|
className={`bg-base-200 h-full w-80 overflow-y-auto border-solid border border-base-200 border-r-neutral-content p-2 z-20 ${
|
||||||
className || ""
|
className || ""
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import React, { Dispatch, SetStateAction } from "react";
|
import React, { Dispatch, SetStateAction } from "react";
|
||||||
import { Sort } from "@/types/global";
|
import { Sort } from "@/types/global";
|
||||||
|
import { dropdownTriggerer } from "@/lib/client/utils";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
sortBy: Sort;
|
sortBy: Sort;
|
||||||
|
@ -12,6 +13,7 @@ export default function SortDropdown({ sortBy, setSort }: Props) {
|
||||||
<div
|
<div
|
||||||
tabIndex={0}
|
tabIndex={0}
|
||||||
role="button"
|
role="button"
|
||||||
|
onMouseDown={dropdownTriggerer}
|
||||||
className="btn btn-sm btn-square btn-ghost"
|
className="btn btn-sm btn-square btn-ghost"
|
||||||
>
|
>
|
||||||
<i className="bi-chevron-expand text-neutral text-2xl"></i>
|
<i className="bi-chevron-expand text-neutral text-2xl"></i>
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
export function isPWA() {
|
||||||
|
return (
|
||||||
|
window.matchMedia("(display-mode: standalone)").matches ||
|
||||||
|
(window.navigator as any).standalone ||
|
||||||
|
document.referrer.includes("android-app://")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function dropdownTriggerer(e: any) {
|
||||||
|
let targetEl = e.currentTarget;
|
||||||
|
if (targetEl && targetEl.matches(":focus")) {
|
||||||
|
setTimeout(function () {
|
||||||
|
targetEl.blur();
|
||||||
|
}, 0);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
import React from "react";
|
import React, { useEffect } from "react";
|
||||||
import "@/styles/globals.css";
|
import "@/styles/globals.css";
|
||||||
import "bootstrap-icons/font/bootstrap-icons.css";
|
import "bootstrap-icons/font/bootstrap-icons.css";
|
||||||
import { SessionProvider } from "next-auth/react";
|
import { SessionProvider } from "next-auth/react";
|
||||||
|
@ -7,6 +7,7 @@ import Head from "next/head";
|
||||||
import AuthRedirect from "@/layouts/AuthRedirect";
|
import AuthRedirect from "@/layouts/AuthRedirect";
|
||||||
import { Toaster } from "react-hot-toast";
|
import { Toaster } from "react-hot-toast";
|
||||||
import { Session } from "next-auth";
|
import { Session } from "next-auth";
|
||||||
|
import { isPWA } from "@/lib/client/utils";
|
||||||
|
|
||||||
export default function App({
|
export default function App({
|
||||||
Component,
|
Component,
|
||||||
|
@ -14,6 +15,15 @@ export default function App({
|
||||||
}: AppProps<{
|
}: AppProps<{
|
||||||
session: Session;
|
session: Session;
|
||||||
}>) {
|
}>) {
|
||||||
|
useEffect(() => {
|
||||||
|
if (isPWA()) {
|
||||||
|
const meta = document.createElement("meta");
|
||||||
|
meta.name = "viewport";
|
||||||
|
meta.content = "width=device-width, initial-scale=1, maximum-scale=1";
|
||||||
|
document.getElementsByTagName("head")[0].appendChild(meta);
|
||||||
|
}
|
||||||
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<SessionProvider
|
<SessionProvider
|
||||||
session={pageProps.session}
|
session={pageProps.session}
|
||||||
|
|
|
@ -23,6 +23,7 @@ import ViewDropdown from "@/components/ViewDropdown";
|
||||||
import CardView from "@/components/LinkViews/Layouts/CardView";
|
import CardView from "@/components/LinkViews/Layouts/CardView";
|
||||||
// import GridView from "@/components/LinkViews/Layouts/GridView";
|
// import GridView from "@/components/LinkViews/Layouts/GridView";
|
||||||
import ListView from "@/components/LinkViews/Layouts/ListView";
|
import ListView from "@/components/LinkViews/Layouts/ListView";
|
||||||
|
import { dropdownTriggerer } from "@/lib/client/utils";
|
||||||
|
|
||||||
export default function Index() {
|
export default function Index() {
|
||||||
const { settings } = useLocalSettingsStore();
|
const { settings } = useLocalSettingsStore();
|
||||||
|
@ -125,6 +126,7 @@ export default function Index() {
|
||||||
<div
|
<div
|
||||||
tabIndex={0}
|
tabIndex={0}
|
||||||
role="button"
|
role="button"
|
||||||
|
onMouseDown={dropdownTriggerer}
|
||||||
className="btn btn-ghost btn-sm btn-square text-neutral"
|
className="btn btn-ghost btn-sm btn-square text-neutral"
|
||||||
>
|
>
|
||||||
<i className="bi-three-dots text-xl" title="More"></i>
|
<i className="bi-three-dots text-xl" title="More"></i>
|
||||||
|
|
|
@ -11,7 +11,6 @@ import PageHeader from "@/components/PageHeader";
|
||||||
|
|
||||||
export default function Collections() {
|
export default function Collections() {
|
||||||
const { collections } = useCollectionStore();
|
const { collections } = useCollectionStore();
|
||||||
const [expandDropdown, setExpandDropdown] = useState(false);
|
|
||||||
const [sortBy, setSortBy] = useState<Sort>(Sort.DateNewestFirst);
|
const [sortBy, setSortBy] = useState<Sort>(Sort.DateNewestFirst);
|
||||||
const [sortedCollections, setSortedCollections] = useState(collections);
|
const [sortedCollections, setSortedCollections] = useState(collections);
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,7 @@ import PageHeader from "@/components/PageHeader";
|
||||||
import CardView from "@/components/LinkViews/Layouts/CardView";
|
import CardView from "@/components/LinkViews/Layouts/CardView";
|
||||||
import ListView from "@/components/LinkViews/Layouts/ListView";
|
import ListView from "@/components/LinkViews/Layouts/ListView";
|
||||||
import ViewDropdown from "@/components/ViewDropdown";
|
import ViewDropdown from "@/components/ViewDropdown";
|
||||||
|
import { dropdownTriggerer } from "@/lib/client/utils";
|
||||||
// import GridView from "@/components/LinkViews/Layouts/GridView";
|
// import GridView from "@/components/LinkViews/Layouts/GridView";
|
||||||
|
|
||||||
export default function Dashboard() {
|
export default function Dashboard() {
|
||||||
|
@ -200,6 +201,7 @@ export default function Dashboard() {
|
||||||
<div
|
<div
|
||||||
tabIndex={0}
|
tabIndex={0}
|
||||||
role="button"
|
role="button"
|
||||||
|
onMouseDown={dropdownTriggerer}
|
||||||
className="inline-flex items-center gap-2 text-sm btn btn-outline btn-neutral"
|
className="inline-flex items-center gap-2 text-sm btn btn-outline btn-neutral"
|
||||||
id="import-dropdown"
|
id="import-dropdown"
|
||||||
>
|
>
|
||||||
|
|
|
@ -25,8 +25,6 @@ export default function Search() {
|
||||||
tags: true,
|
tags: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
const [filterDropdown, setFilterDropdown] = useState(false);
|
|
||||||
|
|
||||||
const [viewMode, setViewMode] = useState<string>(
|
const [viewMode, setViewMode] = useState<string>(
|
||||||
localStorage.getItem("viewMode") || ViewMode.Card
|
localStorage.getItem("viewMode") || ViewMode.Card
|
||||||
);
|
);
|
||||||
|
|
|
@ -11,6 +11,7 @@ import React from "react";
|
||||||
import { MigrationFormat, MigrationRequest } from "@/types/global";
|
import { MigrationFormat, MigrationRequest } from "@/types/global";
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import Checkbox from "@/components/Checkbox";
|
import Checkbox from "@/components/Checkbox";
|
||||||
|
import { dropdownTriggerer } from "@/lib/client/utils";
|
||||||
|
|
||||||
export default function Account() {
|
export default function Account() {
|
||||||
const emailEnabled = process.env.NEXT_PUBLIC_EMAIL_PROVIDER;
|
const emailEnabled = process.env.NEXT_PUBLIC_EMAIL_PROVIDER;
|
||||||
|
@ -245,6 +246,7 @@ export default function Account() {
|
||||||
<div
|
<div
|
||||||
tabIndex={0}
|
tabIndex={0}
|
||||||
role="button"
|
role="button"
|
||||||
|
onMouseDown={dropdownTriggerer}
|
||||||
className="flex gap-2 text-sm btn btn-outline btn-neutral group"
|
className="flex gap-2 text-sm btn btn-outline btn-neutral group"
|
||||||
id="import-dropdown"
|
id="import-dropdown"
|
||||||
>
|
>
|
||||||
|
|
|
@ -11,6 +11,7 @@ import ViewDropdown from "@/components/ViewDropdown";
|
||||||
import CardView from "@/components/LinkViews/Layouts/CardView";
|
import CardView from "@/components/LinkViews/Layouts/CardView";
|
||||||
// import GridView from "@/components/LinkViews/Layouts/GridView";
|
// import GridView from "@/components/LinkViews/Layouts/GridView";
|
||||||
import ListView from "@/components/LinkViews/Layouts/ListView";
|
import ListView from "@/components/LinkViews/Layouts/ListView";
|
||||||
|
import { dropdownTriggerer } from "@/lib/client/utils";
|
||||||
|
|
||||||
export default function Index() {
|
export default function Index() {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
@ -153,6 +154,7 @@ export default function Index() {
|
||||||
<div
|
<div
|
||||||
tabIndex={0}
|
tabIndex={0}
|
||||||
role="button"
|
role="button"
|
||||||
|
onMouseDown={dropdownTriggerer}
|
||||||
className="btn btn-ghost btn-sm btn-square text-neutral"
|
className="btn btn-ghost btn-sm btn-square text-neutral"
|
||||||
>
|
>
|
||||||
<i
|
<i
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
{"name":"Linkwarden","short_name":"Linkwarden","icons":[{"src":"/android-chrome-192x192.png","sizes":"192x192","type":"image/png"},{"src":"/android-chrome-512x512.png","sizes":"512x512","type":"image/png"}],"theme_color":"#ffffff","background_color":"#ffffff","display":"standalone"}
|
{"name":"Linkwarden","short_name":"Linkwarden","icons":[{"src":"/android-chrome-192x192.png","sizes":"192x192","type":"image/png"},{"src":"/android-chrome-512x512.png","sizes":"512x512","type":"image/png"}],"theme_color":"#000000","background_color":"#000000","display":"standalone"}
|
Ŝarĝante…
Reference in New Issue