From 88a49d47567201b3336247ead79a123330a9782d Mon Sep 17 00:00:00 2001 From: celine Date: Tue, 28 Apr 2026 18:39:19 -0400 Subject: [PATCH] added sidebar on mobile, refactored some stuff --- .../home/Actions/HomeThemeSetter.tsx | 2 +- app/(home-pages)/reader/layout.tsx | 11 +- app/globals.css | 23 +++ components/ActionBar/MobileNavigation.tsx | 188 ++++++++++-------- components/ActionBar/Sidebar.tsx | 4 +- components/PageHeader.tsx | 47 +---- components/PageLayouts/DashboardLayout.tsx | 13 -- .../PageLayouts/DashboardPageLayout.tsx | 9 +- components/ThemeManager/ThemeSetter.tsx | 15 -- 9 files changed, 135 insertions(+), 177 deletions(-) diff --git a/app/(home-pages)/home/Actions/HomeThemeSetter.tsx b/app/(home-pages)/home/Actions/HomeThemeSetter.tsx index 0053c2d3..37ae5169 100644 --- a/app/(home-pages)/home/Actions/HomeThemeSetter.tsx +++ b/app/(home-pages)/home/Actions/HomeThemeSetter.tsx @@ -8,7 +8,6 @@ import { PaintSmall } from "components/Icons/PaintSmall"; export const HomeThemeSetter = (props: { entityID: string }) => { let isMobile = useIsMobile(); - if (isMobile) return null; return ( { smallOnMobile icon= label="Theme" + className="sm:flex! hidden" /> } > diff --git a/app/(home-pages)/reader/layout.tsx b/app/(home-pages)/reader/layout.tsx index 8ba66de9..762a063d 100644 --- a/app/(home-pages)/reader/layout.tsx +++ b/app/(home-pages)/reader/layout.tsx @@ -1,10 +1,8 @@ "use client"; import { usePathname, useRouter } from "next/navigation"; -import { DesktopHeader } from "components/PageHeader"; -import { Footer } from "components/ActionBar/Footer"; +import { PageHeader } from "components/PageHeader"; import { DesktopNavigation } from "components/ActionBar/DesktopNavigation"; -import { MobileNavigation } from "components/ActionBar/MobileNavigation"; import { MediaContents } from "components/Media"; import { DashboardIdContext } from "components/PageLayouts/DashboardLayout"; import { useIdentityData } from "components/IdentityProvider"; @@ -50,7 +48,7 @@ export default function ReaderLayout({ className="w-full h-full flex flex-col gap-2 relative overflow-y-scroll pt-3 pb-3 px-3 sm:pt-8 sm:pb-3 sm:pl-6 sm:pr-4" id="home-content" > - +
{tabs.map((tab) => (
- + {children}
-
- -
); diff --git a/app/globals.css b/app/globals.css index 964ee432..bcf6c2ae 100644 --- a/app/globals.css +++ b/app/globals.css @@ -626,6 +626,29 @@ pre.shiki { } } +@keyframes mobile-sidebar-slide-in { + from { + transform: translateX(-100%); + } + to { + transform: translateX(0); + } +} +@keyframes mobile-sidebar-slide-out { + from { + transform: translateX(0); + } + to { + transform: translateX(-100%); + } +} +.mobile-sidebar-content[data-state="open"] { + animation: mobile-sidebar-slide-in 80ms ease-out; +} +.mobile-sidebar-content[data-state="closed"] { + animation: mobile-sidebar-slide-out 80ms ease-in; +} + .footnote-side-item { overflow: hidden; transition: diff --git a/components/ActionBar/MobileNavigation.tsx b/components/ActionBar/MobileNavigation.tsx index 40baab5d..24a9e407 100644 --- a/components/ActionBar/MobileNavigation.tsx +++ b/components/ActionBar/MobileNavigation.tsx @@ -1,106 +1,118 @@ -import { useIdentityData } from "components/IdentityProvider"; +"use client"; +import { useState } from "react"; +import * as Dialog from "@radix-ui/react-dialog"; +import { MediaContents } from "components/Media"; import { Separator } from "components/Layout"; +import { SearchSmall } from "components/Icons/SearchSmall"; +import { MenuSmall } from "components/Icons/MenuSmall"; +import { AccountSmall } from "components/Icons/AccountSmall"; +import { CloseTiny } from "components/Icons/CloseTiny"; +import { Sidebar } from "./Sidebar"; import { - navPages, - NotificationButton, - ReaderButton, WriterButton, + ReaderButton, + NotificationButton, } from "./NavigationButtons"; -import { PublicationNavigation } from "./PublicationNavigation"; -import { LoginModal } from "components/LoginButton"; +import { PublicationButtons } from "./Publications"; import { ProfileButton } from "./ProfileButton"; import { ActionButton } from "./ActionButton"; -import { AccountSmall } from "components/Icons/AccountSmall"; -import { TabsSmall } from "components/Icons/TabsSmall"; -import { Popover } from "components/Popover"; -import { MenuSmall } from "components/Icons/MenuSmall"; +import { LoginModal } from "components/LoginButton"; +import { useIdentityData } from "components/IdentityProvider"; +import { SearchTiny } from "components/Icons/SearchTiny"; export const MobileNavigation = (props: { - currentPage: navPages; - pubName?: string; - tabs?: { [name: string]: { icon?: React.ReactNode } }; - currentTab?: string; - onTabClick?: (tab: string) => void; - onTabHover?: (tab: string) => void; + controls?: React.ReactNode; + actions?: React.ReactNode; }) => { - let { identity } = useIdentityData(); - - let isWriterPage = - props.currentPage === "home" || - props.currentPage === "looseleafs" || - props.currentPage === "pub"; - - let tabClassName = - "font-bold text-secondary flex gap-2 items-center grow min-w-0 text-sm h-[34px] px-2 accent-container min-w-0"; - + let [state, setState] = useState<"search" | "default">("default"); return ( -
- {props.currentPage === "home" ? ( - - ) : props.currentPage === "pub" && - props.tabs && - Object.keys(props.tabs).length > 1 ? ( - - + {props.controls && state === "search" ? ( + <> + {props.controls} + + + + ) : ( + <> + +
+ +
{props.actions}
+ + )} + + ); +}; -
{props.pubName}
+const MobileSidebar = () => { + let { identity } = useIdentityData(); + return ( + + + + + + + + Navigation + +
+ PUBLICATIONS
- } - > - {Object.keys(props.tabs).map((t) => ( - } - label={t} - className={ - t === props.currentTab ? "bg-bg-page! border-border-light!" : "" + + +
+ + props.onTabClick?.(t)} - onMouseEnter={() => props.onTabHover?.(t)} - onPointerDown={() => props.onTabHover?.(t)} /> - ))} - - ) : null} -
- -
- - - - - {identity?.atp_did && ( - - )} - {identity ? ( - <> - - - - ) : ( - } - label="Log In/Sign Up" + {identity?.atp_did && } + {identity ? ( + <> +
+ + + ) : ( + } + label="Log In/Sign Up" + /> + } /> - } - /> - )} -
-
+ )} + + + + ); }; diff --git a/components/ActionBar/Sidebar.tsx b/components/ActionBar/Sidebar.tsx index cdff1d50..79d50984 100644 --- a/components/ActionBar/Sidebar.tsx +++ b/components/ActionBar/Sidebar.tsx @@ -1,5 +1,4 @@ "use client"; -import { uv } from "colorjs.io/fn"; import { Media } from "components/Media"; import { useCardBorderHidden } from "components/Pages/useCardBorderHidden"; import { createContext, useState } from "react"; @@ -12,6 +11,7 @@ export const SidebarContext = createContext({ export function Sidebar(props: { children?: React.ReactNode; alwaysOpen?: boolean; + mobile?: boolean; className?: string; }) { let [sidebarExpanded, setSidebarExpanded] = useState(false); @@ -19,7 +19,7 @@ export function Sidebar(props: { let open = sidebarExpanded || childForceOpen; let cardBorderHidden = useCardBorderHidden(); return ( - + { +export const PageHeader = (props: { children: React.ReactNode }) => { let cardBorderHidden = useCardBorderHidden(); let [scrollPos, setScrollPos] = useState(0); @@ -80,44 +76,3 @@ export const DesktopHeader = (props: { children: React.ReactNode }) => { ); }; - -export const MobileHeader = (props: { - controls?: React.ReactNode; - actions: React.ReactNode; -}) => { - let [state, setState] = useState<"search" | "default">("default"); - return ( - - {props.controls && state === "search" ? ( - <> - {props.controls} - - - - ) : ( - <> - Home -
- -
{props.actions}
- - )} - - ); -}; diff --git a/components/PageLayouts/DashboardLayout.tsx b/components/PageLayouts/DashboardLayout.tsx index 8242583b..6975bc56 100644 --- a/components/PageLayouts/DashboardLayout.tsx +++ b/components/PageLayouts/DashboardLayout.tsx @@ -1,14 +1,11 @@ "use client"; import { useState, createContext, useContext } from "react"; import { useSearchParams } from "next/navigation"; -import { Footer } from "components/ActionBar/Footer"; -import { MobileNavigation } from "components/ActionBar/MobileNavigation"; import { navPages } from "components/ActionBar/NavigationButtons"; import { DesktopNavigation } from "components/ActionBar/DesktopNavigation"; import { create } from "zustand"; import { InterfaceState, useIdentityData } from "components/IdentityProvider"; import { updateIdentityInterfaceState } from "actions/updateIdentityInterfaceState"; -export { MobileHeader } from "../PageHeader"; export type DashboardState = { display?: "grid" | "list"; @@ -158,16 +155,6 @@ export function DashboardLayout< onTabHover={props.onTabHover} /> {content} -
- setTabWithUrl(t as keyof T)} - onTabHover={props.onTabHover} - /> -
); diff --git a/components/PageLayouts/DashboardPageLayout.tsx b/components/PageLayouts/DashboardPageLayout.tsx index 395cc9fd..6746a0a4 100644 --- a/components/PageLayouts/DashboardPageLayout.tsx +++ b/components/PageLayouts/DashboardPageLayout.tsx @@ -1,5 +1,6 @@ "use client"; -import { DesktopHeader, MobileHeader } from "../PageHeader"; +import { PageHeader } from "../PageHeader"; +import { MobileNavigation } from "../ActionBar/MobileNavigation"; import { usePreserveScroll } from "src/hooks/usePreserveScroll"; export function DashboardPageLayout(props: { @@ -21,13 +22,13 @@ export function DashboardPageLayout(props: { > {props.showHeader && ( <> - + - +
{props.controls}
-
+ )} {props.children} diff --git a/components/ThemeManager/ThemeSetter.tsx b/components/ThemeManager/ThemeSetter.tsx index 6be12ece..2d22deb5 100644 --- a/components/ThemeManager/ThemeSetter.tsx +++ b/components/ThemeManager/ThemeSetter.tsx @@ -50,25 +50,10 @@ export function setColorAttribute( }); } export const ThemePopover = (props: { entityID: string; home?: boolean }) => { - let { rep } = useReplicache(); let { data: pub } = useLeafletPublicationData(); let isMobile = useIsMobile(); - // I need to get these variables from replicache and then write them to the DB. I also need to parse them into a state that can be used here. let permission = useEntitySetContext().permissions.write; - let leafletBGImage = useEntity(props.entityID, "theme/background-image"); - let leafletBGRepeat = useEntity( - props.entityID, - "theme/background-image-repeat", - ); - - let [openPicker, setOpenPicker] = useState( - props.home === true ? "leaflet" : "null", - ); - let set = useMemo(() => { - return setColorAttribute(rep, props.entityID); - }, [rep, props.entityID]); - if (!permission) return null; if (pub?.publications) return null; -- 2.51.2