a tool for shared writing and social publishing
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

move publicationbuttons into separate compoennt, added state to handle jsut one pub or looseleaf

celine 1d68145d 78ce577e

+158 -130
+1 -1
components/ActionBar/Footer.tsx
··· 8 8 actionFooter touch-none shrink-0 9 9 w-full z-10 10 10 px-2 pt-1 pwa-padding-bottom 11 - flex justify-between gap-1 11 + flex justify-between 12 12 h-[calc(38px+var(--safe-padding-bottom))] 13 13 bg-[rgba(var(--bg-page),0.5)] border-top border-bg-page`} 14 14 >
+3 -5
components/ActionBar/MobileNavigation.tsx
··· 6 6 ReaderButton, 7 7 WriterButton, 8 8 } from "./NavigationButtons"; 9 - import { PublicationNavigation } from "./Publications"; 9 + import { PublicationNavigation } from "./PublicationNavigation"; 10 10 import { LoginActionButton } from "components/LoginButton"; 11 11 12 12 export const MobileNavigation = (props: { ··· 23 23 24 24 return ( 25 25 <div 26 - className={`mobileFooter flex gap-2 px-1 text-secondary grow items-center justify-between`} 26 + className={`mobileFooter w-full flex gap-4 px-1 text-secondary grow items-center justify-between`} 27 27 > 28 - <div className="mobileNav flex gap-2 items-center justify-start"> 28 + <div className="mobileNav flex gap-2 items-center justify-start min-w-0"> 29 29 <ReaderButton 30 30 compactOnMobile={compactOnMobile} 31 31 current={props.currentPage === "reader"} ··· 42 42 43 43 {compactOnMobile && ( 44 44 <> 45 - {identity && <Separator classname="h-6!" />} 46 45 <PublicationNavigation 47 46 currentPage={props.currentPage} 48 47 currentPubUri={props.currentPublicationUri} ··· 52 51 </div> 53 52 {identity?.atp_did ? ( 54 53 <> 55 - {compactOnMobile && <Separator classname="h-6!" />} 56 54 <NotificationButton /> 57 55 </> 58 56 ) : (
+1 -1
components/ActionBar/NavigationButtons.tsx
··· 30 30 nav 31 31 icon={<HomeSmall />} 32 32 label="Write" 33 - className={`${props.current ? "bg-bg-page! border-border-light!" : ""} ${props.className}`} 33 + className={`${props.current ? "bg-bg-page! border-border-light!" : ""} w-full! ${props.className}`} 34 34 /> 35 35 </SpeedyLink> 36 36 );
+148
components/ActionBar/PublicationNavigation.tsx
··· 1 + "use client"; 2 + import { useIdentityData } from "components/IdentityProvider"; 3 + import { getBasePublicationURL } from "app/lish/createPub/getPublicationURL"; 4 + import { 5 + normalizePublicationRecord, 6 + type NormalizedPublication, 7 + } from "src/utils/normalizeRecords"; 8 + import { SpeedyLink } from "components/SpeedyLink"; 9 + import { Popover } from "components/Popover"; 10 + import { ButtonPrimary } from "components/Buttons"; 11 + import { LooseLeafSmall } from "components/Icons/LooseleafSmall"; 12 + import { HomeButton, type navPages } from "./NavigationButtons"; 13 + import { HomeSmall } from "components/Icons/HomeSmall"; 14 + import { MoreOptionsVerticalTiny } from "components/Icons/MoreOptionsVerticalTiny"; 15 + import { PubIcon, PublicationButtons } from "./Publications"; 16 + import { HomeTiny } from "components/Icons/HomeTiny"; 17 + import { LooseleafTiny } from "components/Icons/LooseleafTiny"; 18 + import { Separator } from "components/Layout"; 19 + import { Menu, MenuItem } from "components/Menu"; 20 + import { AddTiny } from "components/Icons/AddTiny"; 21 + 22 + export const PublicationNavigation = (props: { 23 + currentPage: navPages; 24 + currentPubUri?: string; 25 + }) => { 26 + let { identity } = useIdentityData(); 27 + 28 + if (!identity) return; 29 + 30 + let hasLooseleafs = !!identity?.permission_token_on_homepage.find( 31 + (f) => 32 + f.permission_tokens.leaflets_to_documents && 33 + f.permission_tokens.leaflets_to_documents[0]?.document, 34 + ); 35 + 36 + let pubCount = identity?.publications.length ?? 0; 37 + let onlyOnePub = pubCount === 1 && hasLooseleafs; 38 + let onlyLooseleafs = pubCount === 0 && hasLooseleafs; 39 + let className = 40 + "font-bold text-secondary flex gap-2 items-center grow min-w-0 text-sm h-[34px] px-2 accent-container"; 41 + 42 + // if not publications or looseleafs 43 + if (!identity.publications && !hasLooseleafs) { 44 + return ( 45 + <SpeedyLink href="/lish/createPub"> 46 + <ButtonPrimary compact className="text-sm!"> 47 + Create a Publication! 48 + </ButtonPrimary> 49 + </SpeedyLink> 50 + ); 51 + } 52 + 53 + switch (props.currentPage) { 54 + case "looseleafs": 55 + case "pub": 56 + if (onlyLooseleafs || onlyOnePub) 57 + return ( 58 + <> 59 + <SpeedyLink href={`/home`} className={className}> 60 + <HomeTiny className="shrink-0" /> 61 + Home 62 + </SpeedyLink> 63 + </> 64 + ); 65 + break; 66 + case "home": { 67 + if (onlyLooseleafs || onlyOnePub) { 68 + let pub = identity.publications[0]; 69 + return ( 70 + <div className={className}> 71 + <Menu trigger={<MoreOptionsVerticalTiny className="shrink-0" />}> 72 + <SpeedyLink href="/createPub"> 73 + <MenuItem className="items-center! text-sm" onSelect={() => {}}> 74 + <AddTiny /> 75 + Create New Publication 76 + </MenuItem> 77 + </SpeedyLink> 78 + </Menu> 79 + <Separator classname="h-6!" /> 80 + {onlyLooseleafs ? ( 81 + <SpeedyLink 82 + href="/looseleafs" 83 + className="hover:no-underline! text-inherit flex gap-2 items-center pr-2 w-full min-w-0" 84 + > 85 + <LooseleafTiny className="shrink-0" /> Looseleafs 86 + </SpeedyLink> 87 + ) : ( 88 + <SpeedyLink 89 + href={`${getBasePublicationURL(pub)}/dashboard`} 90 + className="hover:no-underline! text-inherit flex gap-2 items-center pr-2 w0ull min-w-0" 91 + > 92 + <PubIcon 93 + small 94 + record={normalizePublicationRecord(pub.record)} 95 + uri={pub.uri} 96 + /> 97 + <div className="truncate min-w-0">{pub.name}</div> 98 + </SpeedyLink> 99 + )} 100 + </div> 101 + ); 102 + } 103 + break; 104 + } 105 + } 106 + 107 + return ( 108 + <Popover 109 + trigger={ 110 + <div className={className}> 111 + <PubIcons 112 + publications={identity.publications.map((pub) => ({ 113 + record: normalizePublicationRecord(pub.record), 114 + uri: pub.uri, 115 + }))} 116 + />{" "} 117 + Publications 118 + </div> 119 + } 120 + className="pt-1 px-2!" 121 + > 122 + <HomeButton current={props.currentPage === "home"} /> 123 + <hr className="my-1 border-border-light" /> 124 + <PublicationButtons 125 + currentPage={props.currentPage} 126 + currentPubUri={props.currentPubUri} 127 + /> 128 + </Popover> 129 + ); 130 + }; 131 + 132 + function PubIcons(props: { 133 + publications: { record: NormalizedPublication | null; uri: string }[]; 134 + }) { 135 + if (props.publications.length < 1) return null; 136 + return ( 137 + <div className="flex"> 138 + {props.publications.map((pub, index) => { 139 + if (index <= 2) 140 + return ( 141 + <div className="-ml-[6px] first:ml-0" key={pub.uri}> 142 + <PubIcon small record={pub.record} uri={pub.uri} /> 143 + </div> 144 + ); 145 + })} 146 + </div> 147 + ); 148 + }
+4 -123
components/ActionBar/Publications.tsx
··· 15 15 import { PublishSmall } from "components/Icons/PublishSmall"; 16 16 import { Popover } from "components/Popover"; 17 17 import { BlueskyLogin } from "app/login/LoginForm"; 18 - import { ButtonPrimary, ButtonSecondary } from "components/Buttons"; 18 + import { ButtonSecondary } from "components/Buttons"; 19 19 import { useIsMobile } from "src/hooks/isMobile"; 20 20 import { useState } from "react"; 21 21 import { LooseLeafSmall } from "components/Icons/LooseleafSmall"; 22 - import { HomeButton, type navPages } from "./NavigationButtons"; 23 - import { AddTiny } from "components/Icons/AddTiny"; 24 - import { HomeSmall } from "components/Icons/HomeSmall"; 25 - import { HomeTiny } from "components/Icons/HomeTiny"; 26 - import { LooseleafTiny } from "components/Icons/LooseleafTiny"; 22 + import { type navPages } from "./NavigationButtons"; 27 23 28 24 export const PublicationButtons = (props: { 29 25 currentPage: navPages; ··· 59 55 label="Looseleafs" 60 56 icon={<LooseLeafSmall />} 61 57 nav 62 - className={`${ 58 + className={`w-full! ${ 63 59 props.currentPage === "looseleafs" 64 60 ? "bg-bg-page! border-border!" 65 61 : "" ··· 122 118 label={record.name} 123 119 icon={<PubIcon record={record} uri={props.uri} />} 124 120 nav 125 - className={`${props.current ? "bg-bg-page! border-border!" : ""} ${props.className}`} 121 + className={`w-full! ${props.current ? "bg-bg-page! border-border!" : ""} ${props.className}`} 126 122 /> 127 123 </SpeedyLink> 128 124 ); ··· 236 232 {props.record?.name.slice(0, 1).toUpperCase()} 237 233 </div> 238 234 </div> 239 - ); 240 - }; 241 - 242 - export const PublicationNavigation = (props: { 243 - currentPage: navPages; 244 - currentPubUri?: string; 245 - }) => { 246 - let { identity } = useIdentityData(); 247 - 248 - if (!identity) return; 249 - 250 - let hasLooseleafs = !!identity?.permission_token_on_homepage.find( 251 - (f) => 252 - f.permission_tokens.leaflets_to_documents && 253 - f.permission_tokens.leaflets_to_documents[0]?.document, 254 - ); 255 - 256 - let pubCount = identity?.publications.length ?? 0; 257 - let onlyOnePub = pubCount === 1 && !hasLooseleafs; 258 - let onlyLooseleafs = pubCount === 0 && hasLooseleafs; 259 - 260 - function getTriggerIcons() { 261 - if (identity && pubCount >= 1) { 262 - return ( 263 - <div className="flex gap-1"> 264 - {identity.publications.map((pub, index) => { 265 - if (index <= 2) 266 - return ( 267 - <PubIcon 268 - key={pub.uri} 269 - record={normalizePublicationRecord(pub.record)} 270 - uri={pub.uri} 271 - /> 272 - ); 273 - })} 274 - </div> 275 - ); 276 - } 277 - if (identity && hasLooseleafs) { 278 - return ( 279 - <div className="bg-bg-leaflet rounded-full"> 280 - <LooseLeafSmall className="scale-[75%]" /> 281 - </div> 282 - ); 283 - } else 284 - return ( 285 - <SpeedyLink href="/lish/createPub"> 286 - <ButtonPrimary compact className="text-sm!"> 287 - Create a Publication! 288 - </ButtonPrimary> 289 - </SpeedyLink> 290 - ); 291 - } 292 - 293 - // Single pub, no looseleafs - just link to that pub 294 - if (onlyOnePub && identity) { 295 - let pub = identity.publications[0]; 296 - if (props.currentPage === "pub") 297 - return ( 298 - <SpeedyLink 299 - href={`/home`} 300 - className="hover:no-underline! text-tertiary text-bold flex gap-2 text-sm border border-border-light rounded-md px-1 py-[px] items-center" 301 - > 302 - Home <HomeTiny /> 303 - </SpeedyLink> 304 - ); 305 - return ( 306 - <SpeedyLink 307 - href={`${getBasePublicationURL(pub)}/dashboard`} 308 - className="hover:no-underline! text-tertiary text-bold flex gap-2 text-sm border border-border-light rounded-md px-1 py-[px] items-center max-w-32 " 309 - > 310 - <div className="truncate">{pub.name}</div> 311 - <PubIcon 312 - small 313 - record={normalizePublicationRecord(pub.record)} 314 - uri={pub.uri} 315 - /> 316 - </SpeedyLink> 317 - ); 318 - } 319 - 320 - // Only looseleafs, no pubs - just link to looseleafs 321 - if (onlyLooseleafs) { 322 - if (props.currentPage === "looseleafs") 323 - return ( 324 - <SpeedyLink 325 - href={`/home`} 326 - className="hover:no-underline! text-tertiary text-bold flex gap-2 text-sm border border-border-light rounded-md px-1 py-[px] items-center" 327 - > 328 - Home <HomeTiny /> 329 - </SpeedyLink> 330 - ); 331 - return ( 332 - <SpeedyLink href="/looseleafs" className="hover:no-underline!"> 333 - <div className="hover:no-underline! text-tertiary text-bold flex gap-2 text-sm border border-border-light rounded-md px-1 py-[px] items-center max-w-32 "> 334 - Looseleafs <LooseleafTiny /> 335 - </div> 336 - </SpeedyLink> 337 - ); 338 - } 339 - 340 - return ( 341 - <Popover trigger={<div>{getTriggerIcons()}</div>} className="pt-1 px-2!"> 342 - <HomeButton 343 - current={props.currentPage === "home"} 344 - className="flex-row-reverse! justify-end!" 345 - /> 346 - <hr className="my-1 border-border-light" /> 347 - <PublicationButtons 348 - currentPage={props.currentPage} 349 - currentPubUri={props.currentPubUri} 350 - className="justify-end!" 351 - optionClassName=" flex-row-reverse!" 352 - /> 353 - </Popover> 354 235 ); 355 236 }; 356 237
+1
components/Icons/MoreOptionsVerticalTiny.tsx
··· 8 8 viewBox="0 0 12 24" 9 9 fill="none" 10 10 xmlns="http://www.w3.org/2000/svg" 11 + {...props} 11 12 > 12 13 <path 13 14 d="M6 15.5C6.82843 15.5 7.5 16.1716 7.5 17C7.5 17.8284 6.82843 18.5 6 18.5C5.17157 18.5 4.5 17.8284 4.5 17C4.5 16.1716 5.17157 15.5 6 15.5ZM6 10.5C6.82843 10.5 7.5 11.1716 7.5 12C7.5 12.8284 6.82843 13.5 6 13.5C5.17157 13.5 4.5 12.8284 4.5 12C4.5 11.1716 5.17157 10.5 6 10.5ZM6 5.5C6.82843 5.5 7.5 6.17157 7.5 7C7.5 7.82843 6.82843 8.5 6 8.5C5.17157 8.5 4.5 7.82843 4.5 7C4.5 6.17157 5.17157 5.5 6 5.5Z"