From bd92da54d372a73b661da0cf4e1ab791020c81ec Mon Sep 17 00:00:00 2001 From: celine Date: Tue, 7 Oct 2025 10:33:17 -0400 Subject: [PATCH] started the reader --- app/discover/page.tsx | 2 +- app/home/HomeEmpty/HomeEmpty.tsx | 4 +- app/home/HomeLayout.tsx | 3 +- .../dashboard/PublicationDashboard.tsx | 2 +- app/reader/ReaderContent.tsx | 92 +++++++++++ app/reader/SubscriptionsContent.tsx | 3 + app/reader/page.tsx | 147 ++++++++++++++++++ components/ActionBar/Navigation.tsx | 32 ++-- components/ActionBar/Publications.tsx | 1 - components/Icons/ExternalLinkTiny.tsx | 19 +++ components/PageHeader.tsx | 21 +-- components/PageLayouts/DashboardLayout.tsx | 57 +++++-- feeds/index.ts | 2 +- 13 files changed, 340 insertions(+), 45 deletions(-) create mode 100644 app/reader/ReaderContent.tsx create mode 100644 app/reader/SubscriptionsContent.tsx create mode 100644 app/reader/page.tsx create mode 100644 components/Icons/ExternalLinkTiny.tsx diff --git a/app/discover/page.tsx b/app/discover/page.tsx index 2e2a8cd8..f050732e 100644 --- a/app/discover/page.tsx +++ b/app/discover/page.tsx @@ -40,7 +40,7 @@ export default async function Discover(props: {
{ export const DiscoverBanner = (props: { small?: boolean }) => { return (
{props.small ? ( - + ) : (
diff --git a/app/home/HomeLayout.tsx b/app/home/HomeLayout.tsx index 47d34a81..8cd426fa 100644 --- a/app/home/HomeLayout.tsx +++ b/app/home/HomeLayout.tsx @@ -95,7 +95,7 @@ export const HomeLayout = (props: { return ( } @@ -192,7 +192,6 @@ export function HomeLeafletList(props: { {leaflets.filter((l) => !!l.token.leaflets_in_publications).length === 0 && } -
); } diff --git a/app/lish/[did]/[publication]/dashboard/PublicationDashboard.tsx b/app/lish/[did]/[publication]/dashboard/PublicationDashboard.tsx index 4a8c3bf1..a5524c70 100644 --- a/app/lish/[did]/[publication]/dashboard/PublicationDashboard.tsx +++ b/app/lish/[did]/[publication]/dashboard/PublicationDashboard.tsx @@ -39,7 +39,7 @@ export default function PublicationDashboard({ return ( { + let cardBorderHidden = useCardBorderHidden(props.root_entity); + return ( +
+ {dummyPosts.map((p) => ( + + ))} +
+ ); +}; + +const Post = (props: { + title: string; + description: string; + date: string; + read: boolean; + author: string; + pub: string; + cardBorderHidden: boolean; +}) => { + return ( +
+
+
+ + {props.pub} + + +
+

{props.title}

+ +

{props.description}

+
+
+
+ {props.author} +
+ + {props.date} +
+
+
+ ); +}; + +let dummyPosts: { + title: string; + description: string; + date: string; + read: boolean; + author: string; + pub: string; +}[] = [ + { + title: "First Post", + description: "this is a description", + date: "Oct 2", + read: false, + author: "jared", + pub: "a warm space", + }, + { + title: "This is a second Tost", + description: "It has another description, as you can see", + date: "Oct 2", + read: false, + author: "celine", + pub: "Celine's Super Soliloquy", + }, + { + title: "A Third Post, A Burnt Toast", + description: + "If the first post is bread, the second is toast, and inevitably the third is a plate of charcoal.", + date: "Oct 2", + read: false, + author: "brendan", + pub: "Scraps", + }, +]; diff --git a/app/reader/SubscriptionsContent.tsx b/app/reader/SubscriptionsContent.tsx new file mode 100644 index 00000000..b4537f52 --- /dev/null +++ b/app/reader/SubscriptionsContent.tsx @@ -0,0 +1,3 @@ +export const SubscriptionsContent = () => { + return
subs here
; +}; diff --git a/app/reader/page.tsx b/app/reader/page.tsx new file mode 100644 index 00000000..f2de1d5e --- /dev/null +++ b/app/reader/page.tsx @@ -0,0 +1,147 @@ +import { cookies } from "next/headers"; +import { Fact, ReplicacheProvider, useEntity } from "src/replicache"; +import type { Attribute } from "src/replicache/attributes"; +import { + ThemeBackgroundProvider, + ThemeProvider, +} from "components/ThemeManager/ThemeProvider"; +import { EntitySetProvider } from "components/EntitySetProvider"; +import { createIdentity } from "actions/createIdentity"; +import { drizzle } from "drizzle-orm/node-postgres"; +import { IdentitySetter } from "app/home/IdentitySetter"; +import { getIdentityData } from "actions/getIdentityData"; +import { getFactsFromHomeLeaflets } from "app/api/rpc/[command]/getFactsFromHomeLeaflets"; +import { supabaseServerClient } from "supabase/serverClient"; +import { pool } from "supabase/pool"; + +import { NotFoundLayout } from "components/PageLayouts/NotFoundLayout"; +import { DashboardLayout } from "components/PageLayouts/DashboardLayout"; +import { ReaderContent } from "./ReaderContent"; +import { SubscriptionsContent } from "./SubscriptionsContent"; + +export default async function Reader(props: {}) { + let cookieStore = await cookies(); + let auth_res = await getIdentityData(); + let identity: string | undefined; + if (auth_res) identity = auth_res.id; + else identity = cookieStore.get("identity")?.value; + let needstosetcookie = false; + if (!identity) { + const client = await pool.connect(); + const db = drizzle(client); + let newIdentity = await createIdentity(db); + client.release(); + identity = newIdentity.id; + needstosetcookie = true; + } + + async function setCookie() { + "use server"; + + (await cookies()).set("identity", identity as string, { + sameSite: "strict", + }); + } + + let permission_token = auth_res?.home_leaflet; + if (!permission_token) { + let res = await supabaseServerClient + .from("identities") + .select( + `*, + permission_tokens!identities_home_page_fkey(*, permission_token_rights(*)) + `, + ) + .eq("id", identity) + .single(); + permission_token = res.data?.permission_tokens; + } + + if (!permission_token) + return ( + +

Sorry, we can't find this page!

+

+ This may be a glitch on our end. If the issue persists please{" "} + send us a note. +

+
+ ); + let [homeLeafletFacts, allLeafletFacts] = await Promise.all([ + supabaseServerClient.rpc("get_facts", { + root: permission_token.root_entity, + }), + auth_res + ? getFactsFromHomeLeaflets.handler( + { + tokens: auth_res.permission_token_on_homepage.map( + (r) => r.permission_tokens.root_entity, + ), + }, + { supabase: supabaseServerClient }, + ) + : undefined, + ]); + let initialFacts = + (homeLeafletFacts.data as unknown as Fact[]) || []; + let root_entity = permission_token.root_entity; + + if (!auth_res?.atp_did) return; + let { data: publications } = await supabaseServerClient + .from("publication_subscriptions") + .select(`publications(*, documents_in_publications(documents(*)))`) + .eq("identity", auth_res?.atp_did); + + let subbedPubs = publications?.map((pub) => { + let subbedPubsArr: string[] = []; + pub.publications?.name && subbedPubsArr.push(pub.publications?.name); + return subbedPubsArr; + }); + + console.log(subbedPubs); + + return ( + + + + + + , + content: , + }, + subs: { + controls: null, + content: , + }, + discover: { + controls: null, + content: <>, + href: "/discover", + }, + }} + /> + + + + + ); +} + +const FocusToggle = () => { + return
focus
; +}; diff --git a/components/ActionBar/Navigation.tsx b/components/ActionBar/Navigation.tsx index b834c715..6818bebb 100644 --- a/components/ActionBar/Navigation.tsx +++ b/components/ActionBar/Navigation.tsx @@ -7,6 +7,10 @@ import { DiscoverSmall } from "components/Icons/DiscoverSmall"; import { PublicationButtons } from "./Publications"; import { Popover } from "components/Popover"; import { MenuSmall } from "components/Icons/MenuSmall"; +import { + ReaderReadSmall, + ReaderUnreadSmall, +} from "components/Icons/ReaderSmall"; export type navPages = "home" | "reader" | "pub" | "discover"; @@ -110,20 +114,22 @@ const HomeButton = (props: { current?: boolean }) => { }; const ReaderButton = (props: { current?: boolean }) => { - // let readerUnreads = true; - // let subs = false; + let readerUnreads = true; + let subs = true; - // if (subs) - // return ( - // : } - // label="Reader" - // className={` - // ${readerUnreads ? "text-accent-contrast! border-accent-contrast" : props.current ? "bg-border-light! border-border" : ""} - // `} - // /> - // ); + if (subs) + return ( + + : } + label="Reader" + className={` + ${readerUnreads ? "text-accent-contrast! border-accent-contrast" : props.current ? "bg-border-light! border-border" : ""} + `} + /> + + ); return ( { // console.log("thisURI : " + d.uri); // console.log("currentURI : " + props.currentPubUri); - console.log(d.uri === props.currentPubUri); return ( { + return ( + + + + ); +}; diff --git a/components/PageHeader.tsx b/components/PageHeader.tsx index 356af898..0c41ccfe 100644 --- a/components/PageHeader.tsx +++ b/components/PageHeader.tsx @@ -3,9 +3,10 @@ import { useState, useEffect } from "react"; export const Header = (props: { children: React.ReactNode; - hasBackgroundImage: boolean; + cardBorderHidden: boolean; }) => { let [scrollPos, setScrollPos] = useState(0); + console.log(props.cardBorderHidden); useEffect(() => { const homeContent = document.getElementById("home-content"); @@ -22,9 +23,9 @@ export const Header = (props: { } }, []); - let headerBGColor = props.hasBackgroundImage - ? "var(--bg-page)" - : "var(--bg-leaflet)"; + let headerBGColor = props.cardBorderHidden + ? "var(--bg-leaflet)" + : "var(--bg-page)"; return (
{ export function DashboardLayout< T extends { - [name: string]: { content: React.ReactNode; controls: React.ReactNode }; + [name: string]: { + content: React.ReactNode; + controls: React.ReactNode; + href?: string; + }; }, >(props: { id: string; - hasBackgroundImage: boolean; + cardBorderHidden: boolean; tabs: T; defaultTab: keyof T; currentPage: navPages; @@ -129,7 +135,7 @@ export function DashboardLayout< actions: React.ReactNode; }) { let [tab, setTab] = useState(props.defaultTab); - let { content, controls } = props.tabs[tab]; + let { content, controls, href } = props.tabs[tab]; let [headerState, setHeaderState] = useState<"default" | "controls">( "default", @@ -154,19 +160,36 @@ export function DashboardLayout< > {Object.keys(props.tabs).length <= 1 && !controls ? null : ( <> -
+
{headerState === "default" ? ( <> {Object.keys(props.tabs).length > 1 && (
- {Object.keys(props.tabs).map((t) => ( - setTab(t)} - /> - ))} + {Object.keys(props.tabs).map((t) => { + if (props.tabs[t].href) + return ( + + setTab(t)} + /> + + ); + return ( + setTab(t)} + /> + ); + })}
)} {props.publication && ( @@ -326,13 +349,19 @@ const DisplayToggle = (props: { ); }; -function Tab(props: { name: string; selected: boolean; onSelect: () => void }) { +function Tab(props: { + name: string; + selected: boolean; + onSelect: () => void; + href?: string; +}) { return (
props.onSelect()} > {props.name} + {props.href && }
); } diff --git a/feeds/index.ts b/feeds/index.ts index bc7f6e59..074e3018 100644 --- a/feeds/index.ts +++ b/feeds/index.ts @@ -33,7 +33,7 @@ app.get("/xrpc/app.bsky.feed.getFeedSkeleton", async (c) => { let { data: publications } = await supabaseServerClient .from("publication_subscriptions") - .select(`publications(documents_in_publications(documents(*)))`) + .select(`publications(*, documents_in_publications(documents(*)))`) .eq("identity", auth); const allPosts = (publications || []) -- 2.51.2