From 3b2191efeb9291d501a906b73cce8c962f98ad37 Mon Sep 17 00:00:00 2001 From: celine Date: Thu, 30 Apr 2026 14:32:32 -0400 Subject: [PATCH] Added logged out state to Reader Inbox, refactored reader to use new layout --- app/(home-pages)/page.tsx | 29 ++++---- app/(home-pages)/reader/InboxContent.tsx | 15 ++++ app/(home-pages)/reader/ReaderLayout.tsx | 47 +++++++++++++ app/(home-pages)/reader/layout.tsx | 69 ------------------- app/(home-pages)/reader/page.tsx | 15 ++-- app/lish/[did]/[publication]/UpgradeModal.tsx | 1 + .../dashboard/settings/ProSettings.tsx | 1 + components/ActionBar/DesktopNavigation.tsx | 10 ++- components/LoginButton.tsx | 13 +++- components/Modal.tsx | 2 +- components/Subscribe/HandleSubscribe.tsx | 6 +- components/ToggleGroup.tsx | 6 +- components/utils/DotLoader.tsx | 1 + src/hooks/isMobile.ts | 1 + 14 files changed, 118 insertions(+), 98 deletions(-) create mode 100644 app/(home-pages)/reader/ReaderLayout.tsx delete mode 100644 app/(home-pages)/reader/layout.tsx diff --git a/app/(home-pages)/page.tsx b/app/(home-pages)/page.tsx index 036e9562..7d8df18c 100644 --- a/app/(home-pages)/page.tsx +++ b/app/(home-pages)/page.tsx @@ -1,31 +1,36 @@ import { cookies } from "next/headers"; -import ReaderLayout from "./reader/layout"; -import ReaderPage from "./reader/page"; import HomePage from "./home/page"; +import { getReaderFeed } from "./reader/getReaderFeed"; +import { getHotFeed } from "./reader/getHotFeed"; +import { ReaderLayout } from "./reader/ReaderLayout"; export default async function RootPage() { const cookieStore = await cookies(); const hasAuth = - cookieStore.has("auth_token") || - cookieStore.has("external_auth_token"); + cookieStore.has("auth_token") || cookieStore.has("external_auth_token"); + // if the user isn't logged in, leaflet.pub redirects to reader if (!hasAuth) { return ( - - - + ); } const navState = cookieStore.get("nav-state")?.value; - + // if the user IS logged in and was last on reader, leaflet.pub redirects to reader if (navState === "reader") { return ( - - - + ); } - + // else redirect to writer home return ; } diff --git a/app/(home-pages)/reader/InboxContent.tsx b/app/(home-pages)/reader/InboxContent.tsx index 6d8f9169..8d774410 100644 --- a/app/(home-pages)/reader/InboxContent.tsx +++ b/app/(home-pages)/reader/InboxContent.tsx @@ -13,11 +13,15 @@ import { MobileInteractionPreviewDrawer, } from "./InteractionDrawers"; import { useSelectedPostListing } from "src/useSelectedPostState"; +import { getIdentityData } from "actions/getIdentityData"; +import { useIdentityData } from "components/IdentityProvider"; +import { LoginContent } from "components/LoginButton"; export const InboxContent = (props: { promise: Promise<{ posts: Post[]; nextCursor: Cursor | null }>; }) => { const { posts, nextCursor } = use(props.promise); + let { identity: identityData } = useIdentityData(); const getKey = ( pageIndex: number, previousPageData: { @@ -77,6 +81,17 @@ export const InboxContent = (props: { new Date(a.documents.data?.publishedAt || 0).getTime(), ); + if (!identityData) { + return ( +
+
+

Log in or sign up to see your subscriptions!

+ +
+
+ ); + } + if (allPosts.length === 0) return ; return ( diff --git a/app/(home-pages)/reader/ReaderLayout.tsx b/app/(home-pages)/reader/ReaderLayout.tsx new file mode 100644 index 00000000..c8be5af8 --- /dev/null +++ b/app/(home-pages)/reader/ReaderLayout.tsx @@ -0,0 +1,47 @@ +"use client"; +import { PageTitle } from "components/ActionBar/DesktopNavigation"; +import { DashboardLayout } from "components/PageLayouts/DashboardLayout"; +import { DashboardPageLayout } from "components/PageLayouts/DashboardPageLayout"; +import { ReaderUnreadSmall } from "components/Icons/ReaderSmall"; +import { GlobalContent } from "./GlobalContent"; +import { InboxContent } from "./InboxContent"; +import type { Cursor, Post } from "./getReaderFeed"; + +export function ReaderLayout(props: { + readerFeedPromise: Promise<{ posts: Post[]; nextCursor: Cursor | null }>; + hotFeedPromise: Promise<{ posts: Post[] }>; + defaultTab: "Inbox" | "Trending"; +}) { + return ( + } pageTitle="Reader" />} + tabs={{ + Inbox: { + content: ( + + + + ), + }, + Trending: { + content: ( + + + + ), + }, + }} + /> + ); +} diff --git a/app/(home-pages)/reader/layout.tsx b/app/(home-pages)/reader/layout.tsx deleted file mode 100644 index 762a063d..00000000 --- a/app/(home-pages)/reader/layout.tsx +++ /dev/null @@ -1,69 +0,0 @@ -"use client"; - -import { usePathname, useRouter } from "next/navigation"; -import { PageHeader } from "components/PageHeader"; -import { DesktopNavigation } from "components/ActionBar/DesktopNavigation"; -import { MediaContents } from "components/Media"; -import { DashboardIdContext } from "components/PageLayouts/DashboardLayout"; -import { useIdentityData } from "components/IdentityProvider"; -import { Tab } from "components/Tab"; - -const allTabs = [ - { name: "Subs", href: "/reader", requiresAuth: true }, - { name: "Trending", href: "/reader/hot", requiresAuth: false }, - { name: "New", href: "/reader/new", requiresAuth: false }, -]; - -export default function ReaderLayout({ - children, -}: { - children: React.ReactNode; -}) { - const pathname = usePathname(); - const router = useRouter(); - const { identity } = useIdentityData(); - const isLoggedIn = !!identity?.atp_did; - const tabs = allTabs.filter((tab) => !tab.requiresAuth || isLoggedIn); - - const isActive = (href: string) => { - if (href === "/reader") return pathname === "/reader" || pathname === "/"; - if ( - href === "/reader/hot" && - !isLoggedIn && - (pathname === "/reader" || pathname === "/") - ) - return true; - return pathname.startsWith(href); - }; - - return ( - -
- -
- -
-
-
- -
- {tabs.map((tab) => ( - router.push(tab.href)} - /> - ))} -
-
- - {children} -
-
- - ); -} diff --git a/app/(home-pages)/reader/page.tsx b/app/(home-pages)/reader/page.tsx index 3e5349fe..9abef7e4 100644 --- a/app/(home-pages)/reader/page.tsx +++ b/app/(home-pages)/reader/page.tsx @@ -3,14 +3,15 @@ import { getReaderFeed } from "./getReaderFeed"; import { getHotFeed } from "./getHotFeed"; import { InboxContent } from "./InboxContent"; import { GlobalContent } from "./GlobalContent"; +import { ReaderLayout } from "./ReaderLayout"; export default async function Reader() { let identityData = await getIdentityData(); - if (!identityData?.atp_did) { - const feedPromise = getHotFeed(); - return ; - } - - const feedPromise = getReaderFeed(); - return ; + return ( + + ); } diff --git a/app/lish/[did]/[publication]/UpgradeModal.tsx b/app/lish/[did]/[publication]/UpgradeModal.tsx index daa12094..6feb961c 100644 --- a/app/lish/[did]/[publication]/UpgradeModal.tsx +++ b/app/lish/[did]/[publication]/UpgradeModal.tsx @@ -1,3 +1,4 @@ +"use client"; import { ButtonPrimary } from "components/Buttons"; import { Modal } from "components/Modal"; import { useState } from "react"; diff --git a/app/lish/[did]/[publication]/dashboard/settings/ProSettings.tsx b/app/lish/[did]/[publication]/dashboard/settings/ProSettings.tsx index 0bca697e..3415b8ca 100644 --- a/app/lish/[did]/[publication]/dashboard/settings/ProSettings.tsx +++ b/app/lish/[did]/[publication]/dashboard/settings/ProSettings.tsx @@ -1,3 +1,4 @@ +"use client"; import { useEffect, useMemo, useState } from "react"; import { ButtonPrimary, ButtonSecondary } from "components/Buttons"; import { createBillingPortalSession } from "actions/createBillingPortalSession"; diff --git a/components/ActionBar/DesktopNavigation.tsx b/components/ActionBar/DesktopNavigation.tsx index e2beeeba..28af90ce 100644 --- a/components/ActionBar/DesktopNavigation.tsx +++ b/components/ActionBar/DesktopNavigation.tsx @@ -35,11 +35,16 @@ export const NavigationContent = (props: NavigationProps) => { return ( <> {props.pageTitle} +
-
{props.actions}
- {props.tabs && Object.keys(props.tabs).length > 1 && ( + {props.actions && ( <> +
{props.actions}

+ + )} + {props.tabs && Object.keys(props.tabs).length > 1 && ( + <> {Object.keys(props.tabs).map((t) => ( { asChild trigger={ } label="Log In/Sign Up" diff --git a/components/LoginButton.tsx b/components/LoginButton.tsx index a02c46be..308ff8ea 100644 --- a/components/LoginButton.tsx +++ b/components/LoginButton.tsx @@ -35,6 +35,7 @@ export const LoginModal = (props: { trigger={props.trigger} open={open} onOpenChange={setOpen} + className="w-full!" > void; + className?: string; }) => { let identityData = useIdentityData(); let [state, setState] = useState< @@ -117,7 +119,7 @@ export const LoginContent = (props: { }; return ( -
+
diff --git a/components/utils/DotLoader.tsx b/components/utils/DotLoader.tsx index 67571f22..8de50793 100644 --- a/components/utils/DotLoader.tsx +++ b/components/utils/DotLoader.tsx @@ -1,3 +1,4 @@ +"use client"; import { useEffect, useState } from "react"; export function DotLoader(props: { className?: string }) { diff --git a/src/hooks/isMobile.ts b/src/hooks/isMobile.ts index d223aa20..6067b863 100644 --- a/src/hooks/isMobile.ts +++ b/src/hooks/isMobile.ts @@ -1,3 +1,4 @@ +"use client"; import { useState, useEffect } from "react"; export function useIsMobile() { -- 2.51.2