a tool for shared writing and social publishing

changed styles for pub listing, added stuff to SubscriptionContent

+79 -25
+27 -9
app/discover/PubListing.tsx
··· 1 1 "use client"; 2 2 import { AtUri } from "@atproto/syntax"; 3 3 import { PubIcon } from "components/ActionBar/Publications"; 4 + import { Separator } from "components/Layout"; 4 5 import { usePubTheme } from "components/ThemeManager/PublicationThemeProvider"; 5 6 import { BaseThemeProvider } from "components/ThemeManager/ThemeProvider"; 6 7 import { PubLeafletPublication, PubLeafletThemeColor } from "lexicons/api"; ··· 9 10 import { Json } from "supabase/database.types"; 10 11 11 12 export const PubListing = (props: { 13 + resizeHeight?: boolean; 12 14 record: Json; 13 15 uri: string; 14 16 documents_in_publications: { 15 - indexed_at: string; 16 - documents: { data: Json } | null; 17 + documents: { data: Json; indexed_at: string } | null; 17 18 }[]; 18 19 }) => { 19 20 let record = props.record as PubLeafletPublication.Record; ··· 43 44 px-3 py-3 selected-outline 44 45 hover:outline-accent-contrast hover:border-accent-contrast`} 45 46 > 46 - <PubIcon record={record} uri={props.uri} /> 47 - 48 47 <div 49 - className={`flex w-full flex-col ${record.theme?.showPageBackground ? "bg-[rgba(var(--bg-page),var(--bg-page-alpha))] px-2 py-1 rounded-lg" : ""}`} 48 + className={`flex w-full flex-col justify-center text-center max-h-48 pt-4 pb-3 px-3 rounded-lg ${props.resizeHeight ? "" : "sm:h-48 h-full"}${record.theme?.showPageBackground ? "bg-[rgba(var(--bg-page),var(--bg-page-alpha))] " : ""}`} 50 49 > 51 - <h3>{record.name}</h3> 52 - <p className="text-secondary">{record.description}</p> 53 - <div className="flex gap-1 items-center text-sm text-tertiary pt-2 "> 50 + <div className="mx-auto pb-1"> 51 + <PubIcon record={record} uri={props.uri} large /> 52 + </div> 53 + 54 + <h4 className="truncate shrink-0 ">{record.name}</h4> 55 + {record.description && ( 56 + <p className="text-secondary text-sm max-h-full overflow-hidden pb-1"> 57 + {record.description} 58 + </p> 59 + )} 60 + <div className="flex flex-col items-center justify-center text-xs text-tertiary pt-2"> 61 + <div className="flex flex-row gap-2 items-center"> 62 + <div className="h-[14px] w-[14px] rounded-full bg-test shrink-0" /> 63 + <p>Name Here</p>{" "} 64 + </div> 54 65 <p> 55 - Updated {timeAgo(props.documents_in_publications[0].indexed_at)} 66 + Updated{" "} 67 + {timeAgo( 68 + props.documents_in_publications.sort((a, b) => { 69 + let dateA = new Date(a.documents?.indexed_at || 0); 70 + let dateB = new Date(b.documents?.indexed_at || 0); 71 + return dateB.getTime() - dateA.getTime(); 72 + })[0].documents?.indexed_at || "", 73 + )} 56 74 </p> 57 75 </div> 58 76 </div>
+1 -1
app/discover/SortedPublicationList.tsx
··· 39 39 ); 40 40 return bDate.getTime() - aDate.getTime(); 41 41 }) 42 - .map((pub) => <PubListing key={pub.uri} {...pub} />)} 42 + .map((pub) => <PubListing resizeHeight key={pub.uri} {...pub} />)} 43 43 </div> 44 44 </div> 45 45 );
+30 -2
app/reader/SubscriptionsContent.tsx
··· 1 - export const SubscriptionsContent = () => { 2 - return <div>subs here</div>; 1 + import { PubListing } from "app/discover/PubListing"; 2 + import { PublicationsList } from "app/discover/page"; 3 + import { ButtonPrimary } from "components/Buttons"; 4 + import { DiscoverSmall } from "components/Icons/DiscoverSmall"; 5 + import { Json } from "supabase/database.types"; 6 + 7 + export const SubscriptionsContent = (props: { 8 + publications: { 9 + record: Json; 10 + uri: string; 11 + documents_in_publications: { 12 + documents: { data: Json; indexed_at: string } | null; 13 + }[]; 14 + }[]; 15 + }) => { 16 + if (props.publications.length === 0) 17 + return ( 18 + <div className="flex flex-col gap-2 container bg-[rgba(var(--bg-page),.7)] sm:p-4 p-3 justify-between text-center font-bold text-tertiary"> 19 + Looks like you don't have any publication subscriptions yet! 20 + <ButtonPrimary className="mx-auto place-self-center"> 21 + <DiscoverSmall /> Discover Publications! 22 + </ButtonPrimary> 23 + </div> 24 + ); 25 + 26 + return ( 27 + <div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-2 lg:grid-cols-3 gap-3"> 28 + {props.publications?.map((p) => <PubListing {...p} />)} 29 + </div> 30 + ); 3 31 };
+17 -10
app/reader/page.tsx
··· 95 95 .select(`publications(*, documents_in_publications(documents(*)))`) 96 96 .eq("identity", auth_res?.atp_did); 97 97 98 + // get publications to fit PublicationList type 99 + let subbedPublications = 100 + publications 101 + ?.map((subscription) => subscription.publications) 102 + .filter((pub) => pub !== null) || []; 103 + 98 104 // Flatten all posts from all publications into a single array 99 105 let posts = 100 - publications?.flatMap((publication) => { 101 - const postsInPub = 102 - publication.publications?.documents_in_publications.filter( 103 - (d) => !!d?.documents, 104 - ); 106 + subbedPublications?.flatMap((pub) => { 107 + const postsInPub = pub.documents_in_publications.filter( 108 + (d) => !!d?.documents, 109 + ); 105 110 106 111 if (!postsInPub || postsInPub.length === 0) return []; 107 112 ··· 114 119 ) 115 120 .map((postInPub) => ({ 116 121 publication: { 117 - href: getPublicationURL(publication.publications!), 118 - pubRecord: publication.publications?.record || null, 119 - uri: publication.publications?.uri || "", 122 + href: getPublicationURL(pub!), 123 + pubRecord: pub?.record || null, 124 + uri: pub?.uri || "", 120 125 }, 121 126 documents: { 122 127 data: postInPub.documents!.data, ··· 162 167 /> 163 168 ), 164 169 }, 165 - subs: { 170 + subscriptions: { 166 171 controls: null, 167 - content: <SubscriptionsContent />, 172 + content: ( 173 + <SubscriptionsContent publications={subbedPublications} /> 174 + ), 168 175 }, 169 176 discover: { 170 177 controls: null,
+4 -3
components/ActionBar/Publications.tsx
··· 94 94 record: PubLeafletPublication.Record; 95 95 uri: string; 96 96 small?: boolean; 97 + large?: boolean; 97 98 className?: string; 98 99 }) => { 99 100 if (!props.record) return; ··· 106 107 backgroundSize: "cover", 107 108 backgroundImage: `url(/api/atproto_images?did=${new AtUri(props.uri).host}&cid=${(props.record.icon?.ref as unknown as { $link: string })["$link"]})`, 108 109 }} 109 - className={`${props.small ? "w-5 h-5" : "w-6 h-6"} rounded-full ${props.className}`} 110 + className={`${props.small ? "w-5 h-5" : props.large ? "w-12 h-12" : "w-6 h-6"} rounded-full ${props.className}`} 110 111 /> 111 112 ) : ( 112 113 <div 113 - className={`${props.small ? "w-5 h-5" : "w-6 h-6"} rounded-full bg-accent-1 relative`} 114 + className={`${props.small ? "w-5 h-5" : props.large ? "w-12 h-12" : "w-6 h-6"} rounded-full bg-accent-1 relative`} 114 115 > 115 116 <div 116 - className={`${props.small ? "text-xs" : "text-sm"} font-bold absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 text-accent-2`} 117 + className={`${props.small ? "text-xs" : props.large ? "text-2xl" : "text-sm"} font-bold absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 text-accent-2`} 117 118 > 118 119 {props.record?.name.slice(0, 1)} 119 120 </div>