diff --git a/components/ActionBar/DesktopNavigation.tsx b/components/ActionBar/DesktopNavigation.tsx --- a/components/ActionBar/DesktopNavigation.tsx +++ b/components/ActionBar/DesktopNavigation.tsx @@ -25,22 +25,34 @@ tabs?: { [name: string]: { href: string; icon?: React.ReactNode } }; }; +function safeDecode(p: string): string { + try { + return decodeURIComponent(p); + } catch { + return p; + } +} + function pickActiveTabHref( pathname: string, tabs: { [name: string]: { href: string } }, ): string | null { + const decodedPathname = safeDecode(pathname); const hrefs = Object.values(tabs).map((t) => t.href); let best: string | null = null; for (const href of hrefs) { + const decodedHref = safeDecode(href); // If this href is a strict prefix of another tab's href, only allow exact // match — otherwise a parent tab would always swallow sibling-but-unmatched // paths (e.g. /reader/new highlighting /reader's Inbox tab). const isPrefixOfAnother = hrefs.some( - (other) => other !== href && other.startsWith(href + "/"), + (other) => + other !== href && safeDecode(other).startsWith(decodedHref + "/"), ); const matches = isPrefixOfAnother - ? pathname === href - : pathname === href || pathname.startsWith(href + "/"); + ? decodedPathname === decodedHref + : decodedPathname === decodedHref || + decodedPathname.startsWith(decodedHref + "/"); if (matches) { if (!best || href.length > best.length) best = href; } diff --git a/components/ActionBar/NavigationButtons.tsx b/components/ActionBar/NavigationButtons.tsx --- a/components/ActionBar/NavigationButtons.tsx +++ b/components/ActionBar/NavigationButtons.tsx @@ -77,6 +77,7 @@ export function NotificationButton() { let { identity } = useIdentityData(); let unreads = identity?.notifications[0]?.count; + let pathname = usePathname(); let searchParams = useSearchParams(); let router = useRouter(); @@ -94,24 +95,20 @@ } return ( - + labelOnMobile={false} + icon={ + unreads ? ( + + ) : ( + + ) + } + label="Notifications" + active={active} + className={unreads ? "text-accent-contrast! font-bold" : ""} + /> ); } diff --git a/components/PageLayouts/DashboardPageLayout.tsx b/components/PageLayouts/DashboardPageLayout.tsx --- a/components/PageLayouts/DashboardPageLayout.tsx +++ b/components/PageLayouts/DashboardPageLayout.tsx @@ -1,5 +1,5 @@ "use client"; -import { PageHeader } from "../PageHeader"; +import { PageHeader } from "components/PageHeader"; import { MobileNavigation } from "../ActionBar/MobileNavigation"; import { usePreserveScroll } from "src/hooks/usePreserveScroll"; @@ -21,9 +21,9 @@ id="home-content" > {props.showHeader && ( diff --git a/app/(home-pages)/(writer)/WriterShell.tsx b/app/(home-pages)/(writer)/WriterShell.tsx --- a/app/(home-pages)/(writer)/WriterShell.tsx +++ b/app/(home-pages)/(writer)/WriterShell.tsx @@ -18,6 +18,7 @@ prefix: "/looseleafs", id: "looseleafs", title: "Looseleafs", + showBackButton: true, }, { prefix: "/notifications", @@ -33,7 +34,14 @@ return ( } + pageTitle={ + meta && ( + + ) + } actions={} > {props.children} diff --git a/app/(home-pages)/reader/layout.tsx b/app/(home-pages)/reader/layout.tsx --- a/app/(home-pages)/reader/layout.tsx +++ b/app/(home-pages)/reader/layout.tsx @@ -10,6 +10,7 @@ const tabs: { [name: string]: { href: string } } = {}; if (identity?.atp_did) tabs.Inbox = { href: "/reader" }; tabs.Trending = { href: "/reader/trending" }; + tabs.New = { href: "/reader/new" }; return ( {props.children}