diff --git a/app/globals.css b/app/globals.css index ed95a9b9..ef6d5673 100644 --- a/app/globals.css +++ b/app/globals.css @@ -244,6 +244,14 @@ input[type="number"] { @apply outline-transparent; } +.container { + @apply bg-bg-page; + @apply border; + @apply border-bg-page; + @apply bg-opacity-50; + @apply rounded-md; +} + .pwa-padding { padding-top: max(calc(env(safe-area-inset-top) - 8px)) !important; } diff --git a/app/home/Publications.tsx b/app/home/Publications.tsx new file mode 100644 index 00000000..9d407af0 --- /dev/null +++ b/app/home/Publications.tsx @@ -0,0 +1,69 @@ +"use client"; +import { ButtonPrimary } from "components/Buttons"; +import Link from "next/link"; +import { useState } from "react"; + +import { Input } from "components/Input"; +import { useIdentityData } from "components/IdentityProvider"; +import { NewDraftButton } from "app/lish/[handle]/[publication]/NewDraftButton"; +import { Popover } from "components/Popover"; +import { BlueskyLogin } from "app/login/LoginForm"; +export const MyPublicationList = () => { + let { identity } = useIdentityData(); + if (!identity) return null; + if (!identity.atp_did) + return ( +
+ + Log in with bluesky to create a publication! + + } + > + + +
+ ); + return ( +
+ + + New Publication + +
+ ); +}; + +const PublicationList = (props: { + publications: { + identity_did: string; + indexed_at: string; + name: string; + uri: string; + }[]; +}) => { + let { identity } = useIdentityData(); + + return ( +
+ {props.publications?.map((d) => ( +
+ +
{d.name}
+ +
+ ))} +
+ ); +}; diff --git a/app/home/page.tsx b/app/home/page.tsx index df485500..08a9ad2a 100644 --- a/app/home/page.tsx +++ b/app/home/page.tsx @@ -8,22 +8,13 @@ import { ThemeProvider, } from "components/ThemeManager/ThemeProvider"; import { EntitySetProvider } from "components/EntitySetProvider"; -import { ThemePopover } from "components/ThemeManager/ThemeSetter"; import { createIdentity } from "actions/createIdentity"; import postgres from "postgres"; import { drizzle } from "drizzle-orm/postgres-js"; import { IdentitySetter } from "./IdentitySetter"; -import { HomeHelp } from "./HomeHelp"; import { LeafletList } from "./LeafletList"; -import { CreateNewLeafletButton } from "./CreateNewButton"; import { getIdentityData } from "actions/getIdentityData"; -import { LoginButton } from "components/LoginButton"; -import { HelpPopover } from "components/HelpPopover"; -import { AccountSettings } from "./AccountSettings"; -import { LoggedOutWarning } from "./LoggedOutWarning"; import { getFactsFromHomeLeaflets } from "app/api/rpc/[command]/getFactsFromHomeLeaflets"; -import { Media } from "components/Media"; -import { Sidebar } from "components/ActionBar/Sidebar"; import { HomeSidebar } from "./HomeSidebar"; import { HomeFooter } from "./HomeFooter"; diff --git a/app/lish/AlphaBanner.tsx b/app/lish/AlphaBanner.tsx deleted file mode 100644 index 6a21bb01..00000000 --- a/app/lish/AlphaBanner.tsx +++ /dev/null @@ -1,10 +0,0 @@ -import Link from "next/link"; - -export const AlphaBanner = () => { - return ( -
- We're still in Early Alpha! Sign Up for - Updates :) -
- ); -}; diff --git a/app/lish/LishHome.tsx b/app/lish/LishHome.tsx deleted file mode 100644 index 773cf4c0..00000000 --- a/app/lish/LishHome.tsx +++ /dev/null @@ -1,214 +0,0 @@ -"use client"; -import { ButtonPrimary } from "components/Buttons"; -import Link from "next/link"; -import { useState } from "react"; -import { PostList } from "./PostList"; - -import { Input } from "components/Input"; -import { useIdentityData } from "components/IdentityProvider"; -import { NewDraftButton } from "./[handle]/[publication]/NewDraftButton"; - -export const LishHome = () => { - let [state, setState] = useState<"posts" | "subscriptions">("posts"); - return ( -
-
-
- -
- - {/*
-
- setState("posts")} - /> - setState("subscriptions")} - /> -
-
- {state === "posts" ? ( - - ) : ( - - )} -
*/} -
-
- ); -}; - -const Tab = (props: { name: string; active: boolean; onClick: () => void }) => { - return ( -
- {props.name} -
- ); -}; - -const MyPublicationList = () => { - let { identity } = useIdentityData(); - if (!identity || !identity?.atp_did) { - return ( -
-
- Connect to Bluesky
- to start publishing! -
- - We use the ATProtocol to store all your publication data on the open - web. That means we cannot lock you into our platform, you will ALWAYS - be free to easily move elsewhere. Learn More. - -
- - - Connect - -
-
- ); - } - if (Publications.length === 0) { - return ( -
- - Start a Publication! - -
- ); - } - return ( -
- - - New Publication - -
- ); -}; - -const PublicationList = (props: { - publications: { - identity_did: string; - indexed_at: string; - name: string; - uri: string; - }[]; -}) => { - let { identity } = useIdentityData(); - - return ( -
- {props.publications?.map((d) => ( -
- -
{d.name}
- - -
- ))} -
- ); -}; - -const SubscriptionList = (props: { - publications: { title: string; description: string }[]; -}) => { - if (props.publications.length === 0) - return ( -
- No subscriptions yet! -
- ); - return ( -
- {props.publications.map((pub) => { - return ; - })} -
- ); -}; - -const SubscriptionListItem = (props: { - title: string; - description: string; -}) => { - return ( - -

{props.title}

- -
{props.description}
-
- - ); -}; - -const PostFeed = () => { - return ; -}; - -let Subscriptions = [ - { - title: "vrk loves paper", - description: - "Exploring software that loves paper as much as I do. I'll be documenting my learnings, loves, confusions and creations in this newsletter!", - }, - { - title: "rhrizome r&d", - description: - "Design, research, and complexity. A field guide for novel problems.", - }, - { - title: "Dead Languages Society ", - description: - "A guided tour through the history of English and its relatives.", - }, -]; - -let Publications = [ - { - title: "Leaflet Explorers", - description: - "We're making Leaflet, a fast fun web app for making delightful documents. Sign up to follow along as we build Leaflet! We send updates every week or two", - }, -]; diff --git a/app/lish/[handle]/[publication]/DraftList.tsx b/app/lish/[handle]/[publication]/DraftList.tsx new file mode 100644 index 00000000..4145fa45 --- /dev/null +++ b/app/lish/[handle]/[publication]/DraftList.tsx @@ -0,0 +1,44 @@ +"use client"; + +import { Fact, ReplicacheProvider } from "src/replicache"; +import { usePublicationRelationship } from "./usePublicationRelationship"; +import { usePublicationContext } from "components/Providers/PublicationContext"; +import Link from "next/link"; + +export function DraftList(props: { + drafts: { id: string; initialFacts: Fact[]; root_entity: string }[]; +}) { + let rel = usePublicationRelationship(); + let { publication } = usePublicationContext(); + if (!publication) return null; + if (!rel?.isAuthor) return null; + return ( +
+

drafts

+ {props.drafts.map((d) => { + return ( + + + + ); + })} +
+ ); +} + +function Draft(props: { id: string }) { + return ( + + {props.id} + + ); +} diff --git a/app/lish/[handle]/[publication]/PostsList.tsx b/app/lish/[handle]/[publication]/PostsList.tsx new file mode 100644 index 00000000..e69de29b diff --git a/app/lish/[handle]/[publication]/page.tsx b/app/lish/[handle]/[publication]/page.tsx index 104bbc3f..b6b0a97f 100644 --- a/app/lish/[handle]/[publication]/page.tsx +++ b/app/lish/[handle]/[publication]/page.tsx @@ -2,14 +2,11 @@ import { Footer } from "../../Footer"; import { PostList } from "../../PostList"; import { getPds, IdResolver } from "@atproto/identity"; import { supabaseServerClient } from "supabase/serverClient"; -import { AtUri } from "@atproto/syntax"; -import { - AtpBaseClient, - PubLeafletDocument, - PubLeafletPublication, -} from "lexicons/api"; import { CallToActionButton } from "./CallToActionButton"; import { Metadata } from "next"; +import { Fact } from "src/replicache"; +import { Attributes } from "src/replicache/attributes"; +import { DraftList } from "./DraftList"; const idResolver = new IdResolver(); @@ -36,7 +33,6 @@ export default async function Publication(props: { }) { let did = await idResolver.handle.resolve((await props.params).handle); if (!did) return ; - let { data: publication } = await supabaseServerClient .from("publications") .select( @@ -47,23 +43,25 @@ export default async function Publication(props: { .single(); if (!publication) return ; - let repo = await idResolver.did.resolve(did); - if (!repo) return ; - const pds = getPds(repo); - let agent = new AtpBaseClient((url, init) => { - return fetch(new URL(url, pds), init); + let all_facts = await supabaseServerClient.rpc("get_facts_for_roots", { + max_depth: 2, + roots: publication.leaflets_in_publications.map( + (l) => l.permission_tokens?.root_entity!, + ), }); + let facts = + all_facts.data?.reduce( + (acc, fact) => { + if (!acc[fact.root_id]) acc[fact.root_id] = []; + acc[fact.root_id].push( + fact as unknown as Fact, + ); + return acc; + }, + {} as { [key: string]: Fact[] }, + ) || {}; try { - let uri = new AtUri(publication.uri); - let publication_record = await agent.pub.leaflet.publication.get({ - repo: (await props.params).handle, - rkey: uri.rkey, - }); - if (!PubLeafletPublication.isRecord(publication_record.value)) { - return
not a publication?
; - } - return (
@@ -77,6 +75,13 @@ export default async function Publication(props: {
+ ({ + ...d.permission_tokens!, + initialFacts: facts[d.permission_tokens?.root_entity!], + }))} + /> +