a tool for shared writing and social publishing

streanlined shareButton, added archive data

+113 -89
+1
actions/getIdentityData.ts
··· 24 24 entity_sets(entities(facts(*))) 25 25 )), 26 26 permission_token_on_homepage( 27 + archived, 27 28 created_at, 28 29 permission_tokens!inner( 29 30 id,
+4 -1
app/(home-pages)/home/HomeLayout.tsx
··· 33 33 34 34 type Leaflet = { 35 35 added_at: string; 36 + archived?: boolean | null; 36 37 token: PermissionToken & { 37 38 leaflets_in_publications?: Exclude< 38 39 GetLeafletDataReturnType["result"]["data"], ··· 147 148 ? identity.permission_token_on_homepage.map((ptoh) => ({ 148 149 added_at: ptoh.created_at, 149 150 token: ptoh.permission_tokens as PermissionToken, 151 + archived: ptoh.archived, 150 152 })) 151 153 : localLeaflets 152 154 .sort((a, b) => (a.added_at > b.added_at ? -1 : 1)) ··· 204 206 w-full 205 207 ${display === "grid" ? "grid auto-rows-max md:grid-cols-4 sm:grid-cols-3 grid-cols-2 gap-y-4 gap-x-4 sm:gap-x-6 sm:gap-y-5 grow" : "flex flex-col gap-2 pt-2"} `} 206 208 > 207 - {props.leaflets.map(({ token: leaflet, added_at }, index) => ( 209 + {props.leaflets.map(({ token: leaflet, added_at, archived }, index) => ( 208 210 <ReplicacheProvider 209 211 disablePull 210 212 initialFactsOnly={!!identity} ··· 224 226 > 225 227 <LeafletListItem 226 228 title={props?.titles?.[leaflet.root_entity] || "Untitled"} 229 + archived={archived} 227 230 token={leaflet} 228 231 draft={!!leaflet.leaflets_in_publications?.length} 229 232 published={!!leaflet.leaflets_in_publications?.find((l) => l.doc)}
+3 -3
app/(home-pages)/home/LeafletList/LeafletInfo.tsx
··· 21 21 added_at: string; 22 22 publishedAt?: string; 23 23 document_uri?: string; 24 + archived?: boolean | null; 24 25 }) => { 25 26 let [prefetch, setPrefetch] = useState(false); 26 27 let prettyCreatedAt = props.added_at ? timeAgo(props.added_at) : ""; 27 28 28 29 let prettyPublishedAt = props.publishedAt ? timeAgo(props.publishedAt) : ""; 29 30 30 - let shareLink = usePublishLink(); 31 - console.log(shareLink); 32 31 return ( 33 32 <div 34 33 className={`leafletInfo w-full min-w-0 flex flex-col ${props.className}`} ··· 57 56 isTemplate={props.isTemplate} 58 57 draft={props.draft} 59 58 document_uri={props.document_uri} 60 - shareLink={shareLink} 59 + shareLink={`/${props.token.id}`} 60 + archived={props.archived} 61 61 /> 62 62 </div> 63 63 </div>
+1
app/(home-pages)/home/LeafletList/LeafletListItem.tsx
··· 7 7 8 8 export const LeafletListItem = (props: { 9 9 token: PermissionToken; 10 + archived?: boolean | null; 10 11 leaflet_id: string; 11 12 loggedIn: boolean; 12 13 display: "list" | "grid";
+93 -63
app/(home-pages)/home/LeafletList/LeafletOptions.tsx
··· 31 31 isTemplate?: boolean; 32 32 draft?: boolean; 33 33 document_uri?: string; 34 - shareLink: string | undefined | null; 34 + shareLink: string; 35 + archived?: boolean | null; 35 36 }) => { 36 - console.log("sharelink: " + props.shareLink); 37 - let { mutate: mutateIdentity } = useIdentityData(); 38 37 let [state, setState] = useState<"normal" | "template" | "areYouSure">( 39 38 "normal", 40 39 ); 41 40 let [open, setOpen] = useState(false); 42 - let smoker = useSmoker(); 43 41 return ( 44 42 <> 45 43 <Menu ··· 62 60 } 63 61 > 64 62 {state === "normal" ? ( 65 - <> 66 - <ShareButton 67 - className="" 68 - text={ 69 - <div className="flex gap-2"> 70 - <ShareSmall /> 71 - Copy {props.document_uri ? "Post" : "Edit"} Link 72 - </div> 73 - } 74 - subtext="" 75 - smokerText="Link copied!" 76 - id="get-link" 77 - link={`/${props.leaflet.id}`} 63 + props.document_uri ? ( 64 + <PublishedPostOptions 65 + setState={setState} 66 + document_uri={props.document_uri} 67 + {...props} 78 68 /> 79 - 80 - {!props.isTemplate ? ( 81 - <MenuItem 82 - onSelect={(e) => { 83 - e.preventDefault(); 84 - setState("template"); 85 - }} 86 - > 87 - <TemplateSmall /> Use as Template 88 - </MenuItem> 89 - ) : ( 90 - <MenuItem 91 - onSelect={(e) => { 92 - useTemplateState.getState().removeTemplate(props.leaflet); 93 - let newLeafletButton = 94 - document.getElementById("new-leaflet-button"); 95 - if (!newLeafletButton) return; 96 - let rect = newLeafletButton.getBoundingClientRect(); 97 - smoker({ 98 - static: true, 99 - text: <strong>Removed template!</strong>, 100 - position: { 101 - y: rect.top, 102 - x: rect.right + 5, 103 - }, 104 - }); 105 - }} 106 - > 107 - <TemplateRemoveSmall /> Remove from Templates 108 - </MenuItem> 109 - )} 110 - <hr className="border-border-light" /> 111 - {props.document_uri ? ( 112 - <PublishedPostOptions 113 - setState={setState} 114 - document_uri={props.document_uri} 115 - /> 116 - ) : ( 117 - <DefaultOptions setState={setState} draft={props.draft} /> 118 - )} 119 - </> 69 + ) : ( 70 + <DefaultOptions 71 + isTemplate={props.isTemplate} 72 + setState={setState} 73 + {...props} 74 + /> 75 + ) 120 76 ) : state === "template" ? ( 121 77 <AddTemplateForm 122 78 leaflet={props.leaflet} 123 79 close={() => setOpen(false)} 124 80 /> 125 81 ) : state === "areYouSure" ? ( 126 - <DeleteAreYouSure 82 + <DeleteAreYouSureForm 127 83 backToMenu={() => setState("normal")} 128 84 leaflet={props.leaflet} 129 85 document_uri={props.document_uri} ··· 136 92 }; 137 93 138 94 const DefaultOptions = (props: { 139 - setState: (s: "areYouSure") => void; 95 + setState: (s: "areYouSure" | "template") => void; 140 96 draft?: boolean; 97 + leaflet: PermissionToken; 98 + isTemplate: boolean | undefined; 99 + shareLink: string; 141 100 }) => { 142 101 return ( 143 102 <> 103 + <ShareButton 104 + text={ 105 + <div className="flex gap-2"> 106 + <ShareSmall /> 107 + Copy Edit Link 108 + </div> 109 + } 110 + smokerText="Link copied!" 111 + id="get-link" 112 + link={`/${props.shareLink}`} 113 + /> 114 + <TemplateOptions 115 + leaflet={props.leaflet} 116 + setState={props.setState} 117 + isTemplate={props.isTemplate} 118 + /> 119 + 120 + <hr className="border-border-light" /> 144 121 <MenuItem onSelect={() => {}}> 145 122 <ArchiveSmall /> 146 - Archive{props.draft && " Draft"} 123 + Archive{props.draft ? " Draft" : " Leaflet"} 147 124 </MenuItem> 148 125 <MenuItem 149 126 onSelect={(e) => { ··· 161 138 const PublishedPostOptions = (props: { 162 139 setState: (s: "areYouSure") => void; 163 140 document_uri: string; 141 + leaflet: PermissionToken; 142 + shareLink: string; 164 143 }) => { 165 144 let toaster = useToaster(); 166 - let { mutate, data } = usePublicationData(); 167 145 return ( 168 146 <> 147 + <ShareButton 148 + text={ 149 + <div className="flex gap-2"> 150 + <ShareSmall /> 151 + Copy Post Link 152 + </div> 153 + } 154 + smokerText="Link copied!" 155 + id="get-link" 156 + link={`/${props.shareLink}}`} 157 + /> 158 + 159 + <hr className="border-border-light" /> 169 160 <MenuItem 170 161 onSelect={async () => { 171 162 if (props.document_uri) { ··· 203 194 ); 204 195 }; 205 196 206 - const DeleteAreYouSure = (props: { 197 + const DeleteAreYouSureForm = (props: { 207 198 backToMenu: () => void; 208 199 document_uri?: string; 209 200 leaflet: PermissionToken; ··· 297 288 </div> 298 289 ); 299 290 }; 291 + 292 + const TemplateOptions = (props: { 293 + leaflet: PermissionToken; 294 + isTemplate: boolean | undefined; 295 + setState: (s: "template") => void; 296 + }) => { 297 + let smoker = useSmoker(); 298 + if (props.isTemplate) 299 + return ( 300 + <MenuItem 301 + onSelect={(e) => { 302 + useTemplateState.getState().removeTemplate(props.leaflet); 303 + let newLeafletButton = document.getElementById("new-leaflet-button"); 304 + if (!newLeafletButton) return; 305 + let rect = newLeafletButton.getBoundingClientRect(); 306 + smoker({ 307 + static: true, 308 + text: <strong>Removed template!</strong>, 309 + position: { 310 + y: rect.top, 311 + x: rect.right + 5, 312 + }, 313 + }); 314 + }} 315 + > 316 + <TemplateRemoveSmall /> Remove from Templates 317 + </MenuItem> 318 + ); 319 + return ( 320 + <MenuItem 321 + onSelect={(e) => { 322 + e.preventDefault(); 323 + props.setState("template"); 324 + }} 325 + > 326 + <TemplateSmall /> Use as Template 327 + </MenuItem> 328 + ); 329 + };
+1 -1
app/lish/[did]/[publication]/dashboard/PublishedPostsLists.tsx
··· 60 60 61 61 let postLink = data?.publication 62 62 ? `${getPublicationURL(data?.publication)}/${new AtUri(doc.documents.uri).rkey}` 63 - : null; 63 + : ""; 64 64 65 65 return ( 66 66 <Fragment key={doc.documents?.uri}>
+1
components/HomeButton.tsx
··· 52 52 permission_token_on_homepage: [ 53 53 ...identity.permission_token_on_homepage, 54 54 { 55 + archived: null, 55 56 created_at: new Date().toISOString(), 56 57 permission_tokens: { 57 58 ...permission_token,
+2 -4
components/Pages/PageShareMenu.tsx
··· 14 14 <div> 15 15 <ShareButton 16 16 text="Share Edit Link" 17 - subtext="" 18 - helptext="recipients can edit the full Leaflet" 17 + subtext="Recipients can edit the full Leaflet" 19 18 smokerText="Collab link copied!" 20 19 id="get-page-collab-link" 21 20 link={`${collabLink}?page=${props.entityID}`} 22 21 /> 23 22 <ShareButton 24 23 text="Share View Link" 25 - subtext="" 26 - helptext="recipients can view the full Leaflet" 24 + subtext="Recipients can view the full Leaflet" 27 25 smokerText="Publish link copied!" 28 26 id="get-page-publish-link" 29 27 fullLink={
+7 -17
components/ShareOptions/index.tsx
··· 182 182 183 183 export const ShareButton = (props: { 184 184 text: React.ReactNode; 185 - subtext: React.ReactNode; 186 - helptext?: string; 185 + subtext?: React.ReactNode; 187 186 smokerText: string; 188 187 id: string; 189 188 link: null | string; ··· 214 213 } 215 214 }} 216 215 > 217 - <div className={`group/${props.id} ${props.className}`}> 218 - <div className={`group-hover/${props.id}:text-accent-contrast`}> 219 - {props.text} 220 - </div> 221 - <div 222 - className={`text-sm font-normal text-tertiary group-hover/${props.id}:text-accent-contrast`} 223 - > 224 - {props.subtext} 225 - </div> 226 - {/* optional help text */} 227 - {props.helptext && ( 228 - <div 229 - className={`text-sm italic font-normal text-tertiary group-hover/${props.id}:text-accent-contrast`} 230 - > 231 - {props.helptext} 216 + <div className={`group/${props.id} ${props.className} leading-snug`}> 217 + {props.text} 218 + 219 + {props.subtext && ( 220 + <div className={`text-sm font-normal text-tertiary`}> 221 + {props.subtext} 232 222 </div> 233 223 )} 234 224 </div>