a tool for shared writing and social publishing

styling the quotepage

+92 -76
+11 -6
app/lish/[did]/[publication]/[rkey]/BlueskyQuotesPage.tsx
··· 45 45 pageOptions={pageOptions} 46 46 > 47 47 <div className="flex flex-col sm:px-4 px-3 sm:pt-3 pt-2 pb-1 sm:pb-4"> 48 - <div className="text-secondary font-bold mb-3 flex items-center gap-2"> 49 - <QuoteTiny /> 48 + <h3 className="text-secondary font-bold flex items-center gap-2"> 50 49 Bluesky Quotes 51 - </div> 50 + </h3> 52 51 {isLoading ? ( 53 52 <div className="flex items-center justify-center gap-1 text-tertiary italic text-sm py-8"> 54 53 <span>loading quotes</span> ··· 75 74 76 75 return ( 77 76 <div className="flex flex-col gap-0"> 78 - {posts.map((post) => ( 79 - <QuotePost key={post.uri} post={post} quotesUri={postUri} /> 77 + {posts.map((post, index) => ( 78 + <> 79 + <QuotePost key={post.uri} post={post} quotesUri={postUri} /> 80 + {posts.length !== index + 1 && ( 81 + <hr className="border-border-light my-2" /> 82 + )} 83 + </> 80 84 ))} 81 85 </div> 82 86 ); ··· 91 95 post={post} 92 96 parent={parent} 93 97 showEmbed={true} 98 + compactEmbed 94 99 showBlueskyLink={true} 95 100 quoteEnabled 96 101 replyEnabled 97 102 onEmbedClick={(e) => e.stopPropagation()} 98 - className="relative py-2 px-2 hover:bg-bg-page rounded cursor-pointer" 103 + className="relative py-2 px-2 hover:bg-bg-page rounded cursor-pointer text-sm" 99 104 /> 100 105 ); 101 106 }
+47 -38
app/lish/[did]/[publication]/[rkey]/BskyPostContent.tsx
··· 92 92 openPage(parent, { type: "thread", uri: post.uri }); 93 93 }} 94 94 > 95 - <div 96 - className={`postInfo flex justify-between items-center gap-2 leading-tight `} 97 - > 98 - <div className={`flex gap-2 items-center `}> 99 - <div className="font-bold text-secondary"> 100 - {post.author.displayName} 101 - </div> 102 - <ProfilePopover 103 - trigger={ 104 - <div className="text-sm text-tertiary hover:underline"> 105 - @{post.author.handle} 106 - </div> 107 - } 108 - didOrHandle={post.author.handle} 109 - /> 110 - </div> 111 - <div className="text-sm text-tertiary"> 112 - {timeAgo(record.createdAt, { compact: true })} 113 - </div> 114 - </div> 95 + <PostInfo 96 + displayName={post.author.displayName} 97 + handle={post.author.handle} 98 + createdAt={record.createdAt} 99 + /> 115 100 116 101 <div className={`postContent flex flex-col gap-2 mt-0.5`}> 117 102 <div className="text-secondary text-sm"> ··· 210 195 openPage(parent, { type: "thread", uri: post.uri }); 211 196 }} 212 197 > 213 - <div className="postInfo flex justify-between items-center gap-2 leading-tight"> 214 - <div className="flex gap-2 items-center"> 215 - <div className="font-bold text-secondary"> 216 - {post.author.displayName} 217 - </div> 218 - <ProfilePopover 219 - trigger={ 220 - <div className="text-xs text-tertiary hover:underline"> 221 - @{post.author.handle} 222 - </div> 223 - } 224 - didOrHandle={post.author.handle} 225 - /> 226 - </div> 227 - <div className="text-xs text-tertiary"> 228 - {timeAgo(record.createdAt, { compact: true })} 229 - </div> 230 - </div> 198 + <PostInfo 199 + displayName={post.author.displayName} 200 + handle={post.author.handle} 201 + createdAt={record.createdAt} 202 + compact 203 + /> 231 204 232 205 <div className="postContent flex flex-col gap-2 mt-0.5"> 233 206 <div className="line-clamp-3 text-tertiary text-xs"> ··· 250 223 </div> 251 224 ) : null} 252 225 </div> 226 + </div> 227 + </div> 228 + ); 229 + } 230 + 231 + function PostInfo(props: { 232 + displayName?: string; 233 + handle: string; 234 + createdAt: string; 235 + compact?: boolean; 236 + }) { 237 + const { displayName, handle, createdAt, compact = false } = props; 238 + 239 + return ( 240 + <div className="postInfo flex justify-between items-center gap-4 leading-tight w-full"> 241 + <div className="flex gap-2 items-center grow min-w-0"> 242 + <div className={`font-bold text-secondary truncate`}> 243 + {displayName} 244 + </div> 245 + <div className="truncate items-end flex"> 246 + <ProfilePopover 247 + trigger={ 248 + <div 249 + className={`${compact ? "text-xs" : "text-sm"} text-tertiary hover:underline w-full truncate `} 250 + > 251 + @{handle} 252 + </div> 253 + } 254 + didOrHandle={handle} 255 + /> 256 + </div> 257 + </div> 258 + <div 259 + className={`${compact ? "text-xs" : "text-sm"} text-tertiary shrink-0`} 260 + > 261 + {timeAgo(createdAt, { compact: true })} 253 262 </div> 254 263 </div> 255 264 );
+1 -1
app/lish/[did]/[publication]/[rkey]/ThreadPage.tsx
··· 49 49 pageType="doc" 50 50 fullPageScroll={false} 51 51 id={`post-page-${pageId}`} 52 - drawerOpen={!!drawer} 52 + drawerOpen={false} 53 53 pageOptions={pageOptions} 54 54 > 55 55 <div className="flex flex-col sm:px-4 px-3 sm:pt-3 pt-2 pb-1 sm:pb-4 w-full">
+33 -31
components/Blocks/BlueskyPostBlock/BlueskyEmbed.tsx
··· 10 10 AppBskyGraphDefs, 11 11 AppBskyLabelerDefs, 12 12 } from "@atproto/api"; 13 + import { Avatar } from "components/Avatar"; 13 14 14 15 export const BlueskyEmbed = (props: { 15 16 embed: Exclude<AppBskyFeedDefs.PostView["embed"], undefined>; ··· 154 155 text = (record.value as AppBskyFeedPost.Record).text; 155 156 } 156 157 return ( 157 - <div 158 - className={`bskyPostEmbed flex flex-col gap-0.5 relative w-full overflow-hidden p-2! text-xs block-border`} 159 - > 160 - <div className="bskyAuthor w-full flex items-center "> 161 - {record.author.avatar && ( 162 - <img 163 - src={record.author?.avatar} 164 - alt={`${record.author?.displayName}'s avatar`} 165 - className="shink-0 w-6 h-6 rounded-full border border-border-light mr-[6px]" 166 - /> 167 - )} 168 - <div className=" font-bold text-secondary mr-1"> 169 - {record.author?.displayName} 158 + <div className="bskyPostEmbed w-full flex gap-2 items-start relative overflow-hidden p-2! text-xs block-border"> 159 + <Avatar 160 + src={record.author?.avatar} 161 + displayName={record.author?.displayName} 162 + size="small" 163 + /> 164 + <div className="flex flex-col "> 165 + <div className="flex gap-1"> 166 + <div className=" font-bold text-secondary mr-1"> 167 + {record.author?.displayName} 168 + </div> 169 + <a 170 + className="text-xs text-tertiary hover:underline" 171 + target="_blank" 172 + href={`https://bsky.app/profile/${record.author?.handle}`} 173 + > 174 + @{record.author?.handle} 175 + </a> 176 + </div> 177 + <div className="flex flex-col gap-2 "> 178 + {text && ( 179 + <pre 180 + className={`whitespace-pre-wrap text-secondary ${props.compact ? "line-clamp-6" : ""}`} 181 + > 182 + {text} 183 + </pre> 184 + )} 185 + {/*{record.embeds !== undefined 186 + ? record.embeds.map((embed, index) => ( 187 + <BlueskyEmbed embed={embed} key={index} compact /> 188 + )) 189 + : null}*/} 170 190 </div> 171 - <a 172 - className="text-xs text-tertiary hover:underline" 173 - target="_blank" 174 - href={`https://bsky.app/profile/${record.author?.handle}`} 175 - > 176 - @{record.author?.handle} 177 - </a> 178 - </div> 179 - 180 - <div className="flex flex-col gap-2 "> 181 - {text && ( 182 - <pre className="whitespace-pre-wrap text-secondary">{text}</pre> 183 - )} 184 - {record.embeds !== undefined 185 - ? record.embeds.map((embed, index) => ( 186 - <BlueskyEmbed embed={embed} key={index} /> 187 - )) 188 - : null} 189 191 </div> 190 192 </div> 191 193 );