tangled
alpha
login
or
join now
leaflet.pub
/
leaflet
289
fork
atom
a tool for shared writing and social publishing
289
fork
atom
overview
issues
28
pulls
pipelines
styling the quotepage
cozylittle.house
1 month ago
c7c1b52e
f95827cd
+92
-76
4 changed files
expand all
collapse all
unified
split
app
lish
[did]
[publication]
[rkey]
BlueskyQuotesPage.tsx
BskyPostContent.tsx
ThreadPage.tsx
components
Blocks
BlueskyPostBlock
BlueskyEmbed.tsx
+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
48
-
<div className="text-secondary font-bold mb-3 flex items-center gap-2">
49
49
-
<QuoteTiny />
48
48
+
<h3 className="text-secondary font-bold flex items-center gap-2">
50
49
Bluesky Quotes
51
51
-
</div>
50
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
78
-
{posts.map((post) => (
79
79
-
<QuotePost key={post.uri} post={post} quotesUri={postUri} />
77
77
+
{posts.map((post, index) => (
78
78
+
<>
79
79
+
<QuotePost key={post.uri} post={post} quotesUri={postUri} />
80
80
+
{posts.length !== index + 1 && (
81
81
+
<hr className="border-border-light my-2" />
82
82
+
)}
83
83
+
</>
80
84
))}
81
85
</div>
82
86
);
···
91
95
post={post}
92
96
parent={parent}
93
97
showEmbed={true}
98
98
+
compactEmbed
94
99
showBlueskyLink={true}
95
100
quoteEnabled
96
101
replyEnabled
97
102
onEmbedClick={(e) => e.stopPropagation()}
98
98
-
className="relative py-2 px-2 hover:bg-bg-page rounded cursor-pointer"
103
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
95
-
<div
96
96
-
className={`postInfo flex justify-between items-center gap-2 leading-tight `}
97
97
-
>
98
98
-
<div className={`flex gap-2 items-center `}>
99
99
-
<div className="font-bold text-secondary">
100
100
-
{post.author.displayName}
101
101
-
</div>
102
102
-
<ProfilePopover
103
103
-
trigger={
104
104
-
<div className="text-sm text-tertiary hover:underline">
105
105
-
@{post.author.handle}
106
106
-
</div>
107
107
-
}
108
108
-
didOrHandle={post.author.handle}
109
109
-
/>
110
110
-
</div>
111
111
-
<div className="text-sm text-tertiary">
112
112
-
{timeAgo(record.createdAt, { compact: true })}
113
113
-
</div>
114
114
-
</div>
95
95
+
<PostInfo
96
96
+
displayName={post.author.displayName}
97
97
+
handle={post.author.handle}
98
98
+
createdAt={record.createdAt}
99
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
213
-
<div className="postInfo flex justify-between items-center gap-2 leading-tight">
214
214
-
<div className="flex gap-2 items-center">
215
215
-
<div className="font-bold text-secondary">
216
216
-
{post.author.displayName}
217
217
-
</div>
218
218
-
<ProfilePopover
219
219
-
trigger={
220
220
-
<div className="text-xs text-tertiary hover:underline">
221
221
-
@{post.author.handle}
222
222
-
</div>
223
223
-
}
224
224
-
didOrHandle={post.author.handle}
225
225
-
/>
226
226
-
</div>
227
227
-
<div className="text-xs text-tertiary">
228
228
-
{timeAgo(record.createdAt, { compact: true })}
229
229
-
</div>
230
230
-
</div>
198
198
+
<PostInfo
199
199
+
displayName={post.author.displayName}
200
200
+
handle={post.author.handle}
201
201
+
createdAt={record.createdAt}
202
202
+
compact
203
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
226
+
</div>
227
227
+
</div>
228
228
+
);
229
229
+
}
230
230
+
231
231
+
function PostInfo(props: {
232
232
+
displayName?: string;
233
233
+
handle: string;
234
234
+
createdAt: string;
235
235
+
compact?: boolean;
236
236
+
}) {
237
237
+
const { displayName, handle, createdAt, compact = false } = props;
238
238
+
239
239
+
return (
240
240
+
<div className="postInfo flex justify-between items-center gap-4 leading-tight w-full">
241
241
+
<div className="flex gap-2 items-center grow min-w-0">
242
242
+
<div className={`font-bold text-secondary truncate`}>
243
243
+
{displayName}
244
244
+
</div>
245
245
+
<div className="truncate items-end flex">
246
246
+
<ProfilePopover
247
247
+
trigger={
248
248
+
<div
249
249
+
className={`${compact ? "text-xs" : "text-sm"} text-tertiary hover:underline w-full truncate `}
250
250
+
>
251
251
+
@{handle}
252
252
+
</div>
253
253
+
}
254
254
+
didOrHandle={handle}
255
255
+
/>
256
256
+
</div>
257
257
+
</div>
258
258
+
<div
259
259
+
className={`${compact ? "text-xs" : "text-sm"} text-tertiary shrink-0`}
260
260
+
>
261
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
52
-
drawerOpen={!!drawer}
52
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
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
157
-
<div
158
158
-
className={`bskyPostEmbed flex flex-col gap-0.5 relative w-full overflow-hidden p-2! text-xs block-border`}
159
159
-
>
160
160
-
<div className="bskyAuthor w-full flex items-center ">
161
161
-
{record.author.avatar && (
162
162
-
<img
163
163
-
src={record.author?.avatar}
164
164
-
alt={`${record.author?.displayName}'s avatar`}
165
165
-
className="shink-0 w-6 h-6 rounded-full border border-border-light mr-[6px]"
166
166
-
/>
167
167
-
)}
168
168
-
<div className=" font-bold text-secondary mr-1">
169
169
-
{record.author?.displayName}
158
158
+
<div className="bskyPostEmbed w-full flex gap-2 items-start relative overflow-hidden p-2! text-xs block-border">
159
159
+
<Avatar
160
160
+
src={record.author?.avatar}
161
161
+
displayName={record.author?.displayName}
162
162
+
size="small"
163
163
+
/>
164
164
+
<div className="flex flex-col ">
165
165
+
<div className="flex gap-1">
166
166
+
<div className=" font-bold text-secondary mr-1">
167
167
+
{record.author?.displayName}
168
168
+
</div>
169
169
+
<a
170
170
+
className="text-xs text-tertiary hover:underline"
171
171
+
target="_blank"
172
172
+
href={`https://bsky.app/profile/${record.author?.handle}`}
173
173
+
>
174
174
+
@{record.author?.handle}
175
175
+
</a>
176
176
+
</div>
177
177
+
<div className="flex flex-col gap-2 ">
178
178
+
{text && (
179
179
+
<pre
180
180
+
className={`whitespace-pre-wrap text-secondary ${props.compact ? "line-clamp-6" : ""}`}
181
181
+
>
182
182
+
{text}
183
183
+
</pre>
184
184
+
)}
185
185
+
{/*{record.embeds !== undefined
186
186
+
? record.embeds.map((embed, index) => (
187
187
+
<BlueskyEmbed embed={embed} key={index} compact />
188
188
+
))
189
189
+
: null}*/}
170
190
</div>
171
171
-
<a
172
172
-
className="text-xs text-tertiary hover:underline"
173
173
-
target="_blank"
174
174
-
href={`https://bsky.app/profile/${record.author?.handle}`}
175
175
-
>
176
176
-
@{record.author?.handle}
177
177
-
</a>
178
178
-
</div>
179
179
-
180
180
-
<div className="flex flex-col gap-2 ">
181
181
-
{text && (
182
182
-
<pre className="whitespace-pre-wrap text-secondary">{text}</pre>
183
183
-
)}
184
184
-
{record.embeds !== undefined
185
185
-
? record.embeds.map((embed, index) => (
186
186
-
<BlueskyEmbed embed={embed} key={index} />
187
187
-
))
188
188
-
: null}
189
191
</div>
190
192
</div>
191
193
);