a tool for shared writing and social publishing

adjusting interaction button styles for consistency

+102 -63
+49 -38
app/lish/[did]/[publication]/[rkey]/Interactions/Interactions.tsx
··· 19 19 import { EditTiny } from "components/Icons/EditTiny"; 20 20 import { getPublicationURL } from "app/lish/createPub/getPublicationURL"; 21 21 import { RecommendButton } from "components/RecommendButton"; 22 + import { ButtonSecondary } from "components/Buttons"; 23 + import { Separator } from "components/Layout"; 22 24 23 25 export type InteractionState = { 24 26 drawerOpen: undefined | boolean; ··· 130 132 const tags = normalizedDocument.tags; 131 133 const tagCount = tags?.length || 0; 132 134 135 + let interactionsAvailable = props.showComments || props.showMentions; 136 + 133 137 return ( 134 - <div className={`flex gap-2 text-tertiary text-sm ${props.className}`}> 135 - {tagCount > 0 && <TagPopover tags={tags} tagCount={tagCount} />} 136 - 137 - <RecommendButton 138 - documentUri={document_uri} 139 - recommendsCount={props.recommendsCount} 140 - /> 138 + <div 139 + className={`flex gap-2 text-tertiary text-sm item-center ${props.className}`} 140 + > 141 + {/*COMMENT BUTTON*/} 142 + {props.showComments === false ? null : ( 143 + <button 144 + className="flex gap-2 items-center w-fit" 145 + onClick={() => { 146 + if (!drawerOpen || drawer !== "comments" || pageId !== props.pageId) 147 + openInteractionDrawer("comments", document_uri, props.pageId); 148 + else setInteractionState(document_uri, { drawerOpen: false }); 149 + }} 150 + aria-label="Post comments" 151 + > 152 + <CommentTiny aria-hidden /> {props.commentsCount} 153 + </button> 154 + )} 141 155 156 + {/*MENTIONS BUTTON*/} 142 157 {props.quotesCount === 0 || props.showMentions === false ? null : ( 143 158 <button 144 159 className="flex w-fit gap-2 items-center" ··· 154 169 <QuoteTiny aria-hidden /> {props.quotesCount} 155 170 </button> 156 171 )} 157 - {props.showComments === false ? null : ( 158 - <button 159 - className="flex gap-2 items-center w-fit" 160 - onClick={() => { 161 - if (!drawerOpen || drawer !== "comments" || pageId !== props.pageId) 162 - openInteractionDrawer("comments", document_uri, props.pageId); 163 - else setInteractionState(document_uri, { drawerOpen: false }); 164 - }} 165 - aria-label="Post comments" 166 - > 167 - <CommentTiny aria-hidden /> {props.commentsCount} 168 - </button> 169 - )} 172 + <RecommendButton 173 + documentUri={document_uri} 174 + recommendsCount={props.recommendsCount} 175 + /> 176 + <Separator classname="h-4!" /> 177 + {tagCount > 0 && <TagPopover tags={tags} tagCount={tagCount} />} 170 178 </div> 171 179 ); 172 180 }; ··· 209 217 (s) => s.identity === identity.atp_did, 210 218 ); 211 219 212 - let isAuthor = 213 - identity && identity.atp_did === publication?.identity_did && leafletId; 214 - 215 220 return ( 216 221 <div 217 222 className={`text-tertiary px-3 sm:px-4 flex flex-col ${props.className}`} ··· 231 236 <div /> 232 237 ) : ( 233 238 <> 234 - <div className="flex gap-2"> 239 + <div className="flex gap-2 sm:flex-row flex-col"> 235 240 <RecommendButton 236 241 documentUri={document_uri} 237 242 recommendsCount={props.recommendsCount} 243 + expanded 238 244 /> 239 245 {props.quotesCount === 0 || !props.showMentions ? null : ( 240 - <button 241 - className="flex w-fit gap-2 items-center px-1 py-0.5 border border-border-light rounded-lg trasparent-outline selected-outline" 246 + <ButtonSecondary 242 247 onClick={() => { 243 248 if (!drawerOpen || drawer !== "quotes") 244 249 openInteractionDrawer( ··· 253 258 onTouchStart={handleQuotePrefetch} 254 259 aria-label="Post quotes" 255 260 > 256 - <QuoteTiny aria-hidden /> {props.quotesCount}{" "} 261 + <QuoteTiny aria-hidden /> {props.quotesCount} 262 + {props.quotesCount > 0 && ( 263 + <> 264 + {props.quotesCount} 265 + <Separator classname="h-4! text-accent-contrast!" /> 266 + </> 267 + )} 268 + Mention 257 269 <span 258 270 aria-hidden 259 271 >{`Mention${props.quotesCount === 1 ? "" : "s"}`}</span> 260 - </button> 272 + </ButtonSecondary> 261 273 )} 262 274 {!props.showComments ? null : ( 263 - <button 264 - className="flex gap-2 items-center w-fit px-1 py-0.5 border border-border-light rounded-lg trasparent-outline selected-outline" 275 + <ButtonSecondary 265 276 onClick={() => { 266 277 if ( 267 278 !drawerOpen || ··· 279 290 aria-label="Post comments" 280 291 > 281 292 <CommentTiny aria-hidden />{" "} 282 - {props.commentsCount > 0 ? ( 283 - <span aria-hidden> 284 - {`${props.commentsCount} Comment${props.commentsCount === 1 ? "" : "s"}`} 285 - </span> 286 - ) : ( 287 - "Comment" 293 + {props.commentsCount > 0 && ( 294 + <> 295 + {props.commentsCount} 296 + <Separator classname="h-4! text-accent-contrast!" /> 297 + </> 288 298 )} 289 - </button> 299 + Comment 300 + </ButtonSecondary> 290 301 )} 291 302 </div> 292 303 </> ··· 388 399 return ( 389 400 <a 390 401 href={`https://leaflet.pub/${props.leafletId}`} 391 - className="flex gap-2 items-center hover:!no-underline selected-outline px-2 py-0.5 bg-accent-1 text-accent-2 font-bold w-fit rounded-lg !border-accent-1 !outline-accent-1" 402 + className="flex gap-2 items-center hover:!no-underline selected-outline px-2 py-0.5 bg-accent-1 text-accent-2 font-bold w-fit rounded-md !border-accent-1 !outline-accent-1 h-fit" 392 403 > 393 404 <EditTiny /> Edit Post 394 405 </a>
+2 -6
app/lish/[did]/[publication]/page.tsx
··· 148 148 </p> 149 149 </SpeedyLink> 150 150 151 - <div className="text-sm text-tertiary flex gap-1 flex-wrap pt-2 items-center"> 151 + <div className="justify-between w-full text-sm text-tertiary flex gap-1 flex-wrap pt-2 items-center"> 152 152 <p className="text-sm text-tertiary "> 153 153 {doc_record.publishedAt && ( 154 154 <LocalizedDate ··· 161 161 /> 162 162 )}{" "} 163 163 </p> 164 - {comments > 0 || quotes > 0 || tags.length > 0 ? ( 165 - <Separator classname="h-4! mx-1" /> 166 - ) : ( 167 - "" 168 - )} 164 + 169 165 <InteractionPreview 170 166 quotesCount={quotes} 171 167 commentsCount={comments}
+8 -12
components/InteractionsPreview.tsx
··· 30 30 31 31 return ( 32 32 <div className={`flex gap-2 text-tertiary text-sm items-center`}> 33 - {tagsCount === 0 ? null : ( 34 - <> 35 - <TagPopover tags={props.tags!} /> 36 - {interactionsAvailable || props.share ? ( 37 - <Separator classname="h-4!" /> 38 - ) : null} 39 - </> 40 - )} 41 - 42 33 <RecommendButton 43 34 documentUri={props.documentUri} 44 35 recommendsCount={props.recommendsCount} ··· 62 53 <CommentTiny /> {props.commentsCount} 63 54 </SpeedyLink> 64 55 )} 65 - {interactionsAvailable && props.share ? ( 66 - <Separator classname="h-4! !min-h-0" /> 67 - ) : null} 56 + {tagsCount === 0 ? null : ( 57 + <> 58 + {interactionsAvailable ? <Separator classname="h-4!" /> : null} 59 + <TagPopover tags={props.tags!} /> 60 + </> 61 + )} 68 62 {props.share && ( 69 63 <> 64 + <Separator classname="h-4!" /> 65 + 70 66 <button 71 67 id={`copy-post-link-${props.postUrl}`} 72 68 className="flex gap-1 items-center hover:text-accent-contrast relative"
+3 -1
components/PostListing.tsx
··· 89 89 > 90 90 <h3 className="text-primary truncate">{postRecord.title}</h3> 91 91 92 - <p className="text-secondary italic">{postRecord.description}</p> 92 + <p className="text-secondary italic line-clamp-3"> 93 + {postRecord.description} 94 + </p> 93 95 <div className="flex flex-col-reverse md:flex-row md gap-2 text-sm text-tertiary items-center justify-start pt-1.5 md:pt-3 w-full"> 94 96 {props.publication && pubRecord && ( 95 97 <PubInfo
+40 -6
components/RecommendButton.tsx
··· 11 11 import { callRPC } from "app/api/rpc/client"; 12 12 import { useToaster } from "./Toast"; 13 13 import { OAuthErrorMessage, isOAuthSessionError } from "./OAuthError"; 14 + import { ButtonSecondary } from "./Buttons"; 15 + import { Separator } from "./Layout"; 14 16 15 17 // Create a batcher for recommendation checks 16 18 // Batches requests made within 10ms window 17 19 const recommendationBatcher = create({ 18 20 fetcher: async (documentUris: string[]) => { 19 - const response = await callRPC("get_user_recommendations", { documentUris }); 21 + const response = await callRPC("get_user_recommendations", { 22 + documentUris, 23 + }); 20 24 return response.result; 21 25 }, 22 26 resolver: (results, documentUri) => results[documentUri] ?? false, ··· 52 56 documentUri: string; 53 57 recommendsCount: number; 54 58 className?: string; 55 - showCount?: boolean; 59 + expanded?: boolean; 56 60 }) { 57 - const { hasRecommended, isLoading } = useUserRecommendation(props.documentUri); 61 + const { hasRecommended, isLoading } = useUserRecommendation( 62 + props.documentUri, 63 + ); 58 64 const [count, setCount] = useState(props.recommendsCount); 59 65 const [isPending, setIsPending] = useState(false); 60 66 const [optimisticRecommended, setOptimisticRecommended] = useState< ··· 101 107 setIsPending(false); 102 108 }; 103 109 104 - const showCount = props.showCount !== false; 110 + if (props.expanded) 111 + return ( 112 + <ButtonSecondary 113 + onClick={(e) => { 114 + e.preventDefault(); 115 + e.stopPropagation(); 116 + handleClick(); 117 + }} 118 + > 119 + {displayRecommended ? ( 120 + <RecommendTinyFilled className="text-accent-contrast" /> 121 + ) : ( 122 + <RecommendTinyEmpty /> 123 + )} 124 + <div className="flex gap-2 items-center"> 125 + {count > 0 && ( 126 + <> 127 + <span 128 + className={`${displayRecommended && "text-accent-contrast"}`} 129 + > 130 + {count} 131 + </span> 132 + <Separator classname="h-4! text-accent-contrast!" /> 133 + </> 134 + )} 135 + {displayRecommended ? "You recommend!" : "Recommend"} 136 + </div> 137 + </ButtonSecondary> 138 + ); 105 139 106 140 return ( 107 141 <button ··· 111 145 handleClick(); 112 146 }} 113 147 disabled={isPending || isLoading} 114 - className={`recommendButton flex gap-1 items-center hover:text-accent-contrast ${props.className || ""}`} 148 + className={`recommendButton relative flex gap-1 items-center hover:text-accent-contrast ${props.className || ""}`} 115 149 aria-label={displayRecommended ? "Remove recommend" : "Recommend"} 116 150 > 117 151 {displayRecommended ? ( ··· 119 153 ) : ( 120 154 <RecommendTinyEmpty /> 121 155 )} 122 - {showCount && count > 0 && ( 156 + {count > 0 && ( 123 157 <span className={`${displayRecommended && "text-accent-contrast"}`}> 124 158 {count} 125 159 </span>