+115
-21
src/components/UniversalPostRenderer.tsx
+115
-21
src/components/UniversalPostRenderer.tsx
···
1
-
import * as ATPAPI from "@atproto/api"
1
+
import * as ATPAPI from "@atproto/api";
2
2
import { useNavigate } from "@tanstack/react-router";
3
3
import DOMPurify from "dompurify";
4
4
import { useAtom } from "jotai";
···
10
10
import {
11
11
composerAtom,
12
12
constellationURLAtom,
13
+
enableBridgyTextAtom,
14
+
enableWafrnTextAtom,
13
15
imgCDNAtom,
14
16
} from "~/utils/atoms";
15
17
import { useHydratedEmbed } from "~/utils/useHydrated";
···
162
164
isQuote,
163
165
filterNoReplies,
164
166
filterMustHaveMedia,
165
-
filterMustBeReply
167
+
filterMustBeReply,
166
168
}: UniversalPostRendererATURILoaderProps) {
167
169
// todo remove this once tree rendering is implemented, use a prop like isTree
168
170
const TEMPLINEAR = true;
···
526
528
? true
527
529
: maxReplies && !oldestOpsReplyElseNewestNonOpsReply
528
530
? false
529
-
: (maxReplies === 0 && (!replies || (!!replies && replies === 0))) ? false : bottomReplyLine
531
+
: maxReplies === 0 && (!replies || (!!replies && replies === 0))
532
+
? false
533
+
: bottomReplyLine
530
534
}
531
535
topReplyLine={topReplyLine}
532
536
//bottomBorder={maxReplies&&oldestOpsReplyElseNewestNonOpsReply ? false : bottomBorder}
···
553
557
filterMustBeReply={filterMustBeReply}
554
558
/>
555
559
<>
556
-
{(maxReplies && maxReplies === 0 && replies && replies > 0) ? (
560
+
{maxReplies && maxReplies === 0 && replies && replies > 0 ? (
557
561
<>
558
-
{/* <div>hello</div> */}
559
-
<MoreReplies atUri={atUri} />
562
+
{/* <div>hello</div> */}
563
+
<MoreReplies atUri={atUri} />
560
564
</>
561
-
) : (<></>)}
565
+
) : (
566
+
<></>
567
+
)}
562
568
</>
563
569
{!isQuote && oldestOpsReplyElseNewestNonOpsReply && (
564
570
<>
···
755
761
const hasImages = hasEmbed?.$type === "app.bsky.embed.images";
756
762
const hasVideo = hasEmbed?.$type === "app.bsky.embed.video";
757
763
const isquotewithmedia = hasEmbed?.$type === "app.bsky.embed.recordWithMedia";
758
-
const isQuotewithImages = isquotewithmedia && (hasEmbed as ATPAPI.AppBskyEmbedRecordWithMedia.Main)?.media?.$type === "app.bsky.embed.images";
759
-
const isQuotewithVideo = isquotewithmedia && (hasEmbed as ATPAPI.AppBskyEmbedRecordWithMedia.Main)?.media?.$type === "app.bsky.embed.video";
764
+
const isQuotewithImages =
765
+
isquotewithmedia &&
766
+
(hasEmbed as ATPAPI.AppBskyEmbedRecordWithMedia.Main)?.media?.$type ===
767
+
"app.bsky.embed.images";
768
+
const isQuotewithVideo =
769
+
isquotewithmedia &&
770
+
(hasEmbed as ATPAPI.AppBskyEmbedRecordWithMedia.Main)?.media?.$type ===
771
+
"app.bsky.embed.video";
760
772
761
-
const hasMedia = hasEmbed && (hasImages || hasVideo || isQuotewithImages || isQuotewithVideo);
773
+
const hasMedia =
774
+
hasEmbed &&
775
+
(hasImages || hasVideo || isQuotewithImages || isQuotewithVideo);
762
776
763
777
const {
764
778
data: hydratedEmbed,
···
854
868
// }, [fakepost, get, set]);
855
869
const thereply = (fakepost?.record as AppBskyFeedPost.Record)?.reply?.parent
856
870
?.uri;
857
-
const feedviewpostreplydid = thereply&&!filterNoReplies ? new AtUri(thereply).host : undefined;
871
+
const feedviewpostreplydid =
872
+
thereply && !filterNoReplies ? new AtUri(thereply).host : undefined;
858
873
const replyhookvalue = useQueryIdentity(
859
874
feedviewpost ? feedviewpostreplydid : undefined
860
875
);
···
1237
1252
1238
1253
import defaultpfp from "~/../public/favicon.png";
1239
1254
import { useAuth } from "~/providers/UnifiedAuthProvider";
1240
-
import { FeedItemRenderAturiLoader, FollowButton, Mutual } from "~/routes/profile.$did";
1255
+
import {
1256
+
FeedItemRenderAturiLoader,
1257
+
FollowButton,
1258
+
Mutual,
1259
+
} from "~/routes/profile.$did";
1241
1260
import type { LightboxProps } from "~/routes/profile.$did/post.$rkey.image.$i";
1242
1261
import { useFastLike } from "~/utils/likeMutationQueue";
1243
1262
// import type { OutputSchema } from "@atproto/api/dist/client/types/app/bsky/feed/getFeed";
···
1446
1465
: undefined;
1447
1466
1448
1467
const emergencySalt = randomString();
1449
-
const fedi = (post.record as { bridgyOriginalText?: string })
1468
+
1469
+
const [showBridgyText] = useAtom(enableBridgyTextAtom);
1470
+
const [showWafrnText] = useAtom(enableWafrnTextAtom);
1471
+
1472
+
const unfedibridgy = (post.record as { bridgyOriginalText?: string })
1450
1473
.bridgyOriginalText;
1474
+
const unfediwafrnPartial = (post.record as { fullText?: string }).fullText;
1475
+
const unfediwafrnTags = (post.record as { fullTags?: string }).fullTags;
1476
+
const unfediwafrnUnHost = (post.record as { fediverseId?: string })
1477
+
.fediverseId;
1478
+
1479
+
const undfediwafrnHost = unfediwafrnUnHost
1480
+
? new URL(unfediwafrnUnHost).hostname
1481
+
: undefined;
1482
+
1483
+
const tags = unfediwafrnTags
1484
+
? unfediwafrnTags
1485
+
.split("\n")
1486
+
.map((t) => t.trim())
1487
+
.filter(Boolean)
1488
+
: undefined;
1489
+
1490
+
const links = tags
1491
+
? tags
1492
+
.map((tag) => {
1493
+
const encoded = encodeURIComponent(tag);
1494
+
return `<a href="https://${undfediwafrnHost}/search/${encoded}" target="_blank">#${tag.replaceAll(' ','-')}</a>`;
1495
+
})
1496
+
.join("<br>")
1497
+
: "";
1498
+
1499
+
const unfediwafrn = unfediwafrnPartial
1500
+
? unfediwafrnPartial + (links ? `<br>${links}` : "")
1501
+
: undefined;
1502
+
1503
+
const fedi =
1504
+
(showBridgyText ? unfedibridgy : undefined) ??
1505
+
(showWafrnText ? unfediwafrn : undefined);
1451
1506
1452
1507
/* fuck you */
1453
1508
const isMainItem = false;
···
1586
1641
{post.author.displayName || post.author.handle}{" "}
1587
1642
</div>
1588
1643
<div className="text-gray-500 dark:text-gray-400 text-md flex flex-row gap-1">
1589
-
<Mutual targetdidorhandle={post.author.did} />@{post.author.handle}{" "}
1644
+
<Mutual targetdidorhandle={post.author.did} />@
1645
+
{post.author.handle}{" "}
1590
1646
</div>
1591
1647
</div>
1592
1648
{uprrrsauthor?.description && (
···
1834
1890
</div>
1835
1891
</>
1836
1892
)}
1837
-
<div style={{ paddingTop: post.embed && !concise && depth < 1 ? 4 : 0 }}>
1893
+
<div
1894
+
style={{
1895
+
paddingTop: post.embed && !concise && depth < 1 ? 4 : 0,
1896
+
}}
1897
+
>
1838
1898
<>
1839
1899
{expanded && (
1840
1900
<div
···
2203
2263
// <MaybeFeedCard view={embed.record} />
2204
2264
// </div>
2205
2265
// )
2206
-
} else if (!!reallybaduri && !!reallybadaturi && reallybadaturi.collection === "app.bsky.feed.generator") {
2207
-
return <div className="rounded-xl border"><FeedItemRenderAturiLoader aturi={reallybaduri} disableBottomBorder/></div>
2266
+
} else if (
2267
+
!!reallybaduri &&
2268
+
!!reallybadaturi &&
2269
+
reallybadaturi.collection === "app.bsky.feed.generator"
2270
+
) {
2271
+
return (
2272
+
<div className="rounded-xl border">
2273
+
<FeedItemRenderAturiLoader aturi={reallybaduri} disableBottomBorder />
2274
+
</div>
2275
+
);
2208
2276
}
2209
2277
2210
2278
// list embed
···
2216
2284
// <MaybeListCard view={embed.record} />
2217
2285
// </div>
2218
2286
// )
2219
-
} else if (!!reallybaduri && !!reallybadaturi && reallybadaturi.collection === "app.bsky.graph.list") {
2220
-
return <div className="rounded-xl border"><FeedItemRenderAturiLoader aturi={reallybaduri} disableBottomBorder listmode disablePropagation /></div>
2287
+
} else if (
2288
+
!!reallybaduri &&
2289
+
!!reallybadaturi &&
2290
+
reallybadaturi.collection === "app.bsky.graph.list"
2291
+
) {
2292
+
return (
2293
+
<div className="rounded-xl border">
2294
+
<FeedItemRenderAturiLoader
2295
+
aturi={reallybaduri}
2296
+
disableBottomBorder
2297
+
listmode
2298
+
disablePropagation
2299
+
/>
2300
+
</div>
2301
+
);
2221
2302
}
2222
2303
2223
2304
// starter pack embed
···
2229
2310
// <StarterPackCard starterPack={embed.record} />
2230
2311
// </div>
2231
2312
// )
2232
-
} else if (!!reallybaduri && !!reallybadaturi && reallybadaturi.collection === "app.bsky.graph.starterpack") {
2233
-
return <div className="rounded-xl border"><FeedItemRenderAturiLoader aturi={reallybaduri} disableBottomBorder listmode disablePropagation /></div>
2313
+
} else if (
2314
+
!!reallybaduri &&
2315
+
!!reallybadaturi &&
2316
+
reallybadaturi.collection === "app.bsky.graph.starterpack"
2317
+
) {
2318
+
return (
2319
+
<div className="rounded-xl border">
2320
+
<FeedItemRenderAturiLoader
2321
+
aturi={reallybaduri}
2322
+
disableBottomBorder
2323
+
listmode
2324
+
disablePropagation
2325
+
/>
2326
+
</div>
2327
+
);
2234
2328
}
2235
2329
2236
2330
// quote post
+30
-12
src/routes/settings.tsx
+30
-12
src/routes/settings.tsx
···
13
13
defaultslingshotURL,
14
14
defaultVideoCDN,
15
15
enableBitesAtom,
16
+
enableBridgyTextAtom,
17
+
enableWafrnTextAtom,
16
18
hueAtom,
17
19
imgCDNAtom,
18
20
slingshotURLAtom,
···
84
86
<SwitchSetting
85
87
atom={enableBitesAtom}
86
88
title={"Bites"}
87
-
description={"Enable Wafrn Bites to bite other people"}
89
+
description={"Enable Wafrn Bites to bite and be bitten by other people"}
90
+
//init={false}
91
+
/>
92
+
<div className="h-4" />
93
+
<SwitchSetting
94
+
atom={enableBridgyTextAtom}
95
+
title={"Bridgy Text"}
96
+
description={
97
+
"Show the original text of posts bridged from the Fediverse"
98
+
}
99
+
//init={false}
100
+
/>
101
+
<div className="h-4" />
102
+
<SwitchSetting
103
+
atom={enableWafrnTextAtom}
104
+
title={"Wafrn Text"}
105
+
description={
106
+
"Show the original text of posts from Wafrn instances"
107
+
}
88
108
//init={false}
89
109
/>
90
110
<p className="text-gray-500 dark:text-gray-400 py-4 px-4 text-sm border rounded-xl mx-4 mt-8 mb-4">
···
137
157
138
158
return (
139
159
<div className="flex items-center gap-4 px-4 ">
140
-
<div className="flex flex-col">
141
-
<label htmlFor="switch-demo" className="text-md">
142
-
{title}
143
-
</label>
144
-
<span className="text-sm text-gray-500 dark:text-gray-400">
145
-
{description}
146
-
</span>
147
-
</div>
148
-
149
-
<div className="flex-1" />
160
+
<label htmlFor={`switch-${title}`} className="flex flex-row flex-1">
161
+
<div className="flex flex-col">
162
+
<span className="text-md">{title}</span>
163
+
<span className="text-sm text-gray-500 dark:text-gray-400">
164
+
{description}
165
+
</span>
166
+
</div>
167
+
</label>
150
168
151
169
<Switch.Root
152
-
id="switch-demo"
170
+
id={`switch-${title}`}
153
171
checked={value}
154
172
onCheckedChange={(v) => setValue(v)}
155
173
className="m3switch root"
+10
src/utils/atoms.ts
+10
src/utils/atoms.ts
···
137
137
"enableBitesAtom",
138
138
false
139
139
);
140
+
141
+
export const enableBridgyTextAtom = atomWithStorage<boolean>(
142
+
"enableBridgyTextAtom",
143
+
false
144
+
);
145
+
146
+
export const enableWafrnTextAtom = atomWithStorage<boolean>(
147
+
"enableWafrnTextAtom",
148
+
false
149
+
);