+471
-400
src/components/UniversalPostRenderer.tsx
+471
-400
src/components/UniversalPostRenderer.tsx
···
2
2
import { useAtom } from "jotai";
3
3
import * as React from "react";
4
4
import { type SVGProps } from "react";
5
+
import { createPortal } from "react-dom";
5
6
7
+
import { ProfilePostComponent } from "~/routes/profile.$did/post.$rkey";
6
8
import { likedPostsAtom } from "~/utils/atoms";
7
9
import { useHydratedEmbed } from "~/utils/useHydrated";
8
10
import {
···
28
30
bottomBorder?: boolean;
29
31
feedviewpost?: boolean;
30
32
repostedby?: string;
33
+
style?: React.CSSProperties;
34
+
ref?: React.Ref<HTMLDivElement>;
35
+
dataIndexPropPass?: number;
36
+
nopics?: boolean;
31
37
}
32
38
33
39
// export async function cachedGetRecord({
···
132
138
bottomBorder = true,
133
139
feedviewpost = false,
134
140
repostedby,
141
+
style,
142
+
ref,
143
+
dataIndexPropPass,
144
+
nopics,
135
145
}: UniversalPostRendererATURILoaderProps) {
136
146
// /*mass comment*/ console.log("atUri", atUri);
137
147
//const { get, set } = usePersistentStore();
···
406
416
bottomBorder={bottomBorder}
407
417
feedviewpost={feedviewpost}
408
418
repostedby={repostedby}
419
+
style={style}
420
+
ref={ref}
421
+
dataIndexPropPass={dataIndexPropPass}
422
+
nopics={nopics}
409
423
/>
410
424
);
411
425
}
···
430
444
bottomBorder = true,
431
445
feedviewpost = false,
432
446
repostedby,
447
+
style,
448
+
ref,
449
+
dataIndexPropPass,
450
+
nopics,
433
451
}: {
434
452
postRecord: any;
435
453
profileRecord: any;
···
444
462
bottomBorder?: boolean;
445
463
feedviewpost?: boolean;
446
464
repostedby?: string;
465
+
style?: React.CSSProperties;
466
+
ref?: React.Ref<HTMLDivElement>;
467
+
dataIndexPropPass?: number;
468
+
nopics?: boolean;
447
469
}) {
448
470
// /*mass comment*/ console.log(`received aturi: ${aturi} of post content: ${postRecord}`);
449
471
const navigate = useNavigate();
···
638
660
//extraOptionalItemInfo={{reply: postRecord?.value?.reply as AppBskyFeedDefs.ReplyRef, post: fakepost}}
639
661
feedviewpostreplyhandle={feedviewpostreplyhandle}
640
662
repostedby={feedviewpostrepostedbyhandle}
663
+
style={style}
664
+
ref={ref}
665
+
dataIndexPropPass={dataIndexPropPass}
666
+
nopics={nopics}
641
667
/>
642
668
</>
643
669
);
···
1079
1105
feedviewpostreplyhandle,
1080
1106
depth = 0,
1081
1107
repostedby,
1108
+
style,
1109
+
ref,
1110
+
dataIndexPropPass,
1111
+
nopics,
1082
1112
}: {
1083
1113
post: PostView;
1084
1114
// optional for now because i havent ported every use to this yet
···
1098
1128
feedviewpostreplyhandle?: string;
1099
1129
depth?: number;
1100
1130
repostedby?: string;
1131
+
style?: React.CSSProperties;
1132
+
ref?: React.Ref<HTMLDivElement>;
1133
+
dataIndexPropPass?: number;
1134
+
nopics?: boolean;
1101
1135
}) {
1136
+
const parsed = new AtUri(post.uri);
1102
1137
const navigate = useNavigate();
1103
1138
const [likedPosts, setLikedPosts] = useAtom(likedPostsAtom);
1104
1139
const [hasRetweeted, setHasRetweeted] = useState<boolean>(
···
1171
1206
/* fuck you */
1172
1207
const isMainItem = false;
1173
1208
const setMainItem = (any: any) => {};
1209
+
// eslint-disable-next-line react-hooks/refs
1210
+
console.log("Received ref in UniversalPostRenderer:", ref);
1174
1211
return (
1175
-
<div
1176
-
key={salt + "-" + (post.uri || emergencySalt)}
1177
-
onClick={
1178
-
isMainItem
1179
-
? onPostClick
1180
-
: setMainItem
1181
-
? onPostClick
1182
-
? (e) => {
1183
-
setMainItem({ post: post });
1184
-
onPostClick(e);
1185
-
}
1186
-
: () => {
1187
-
setMainItem({ post: post });
1188
-
}
1189
-
: undefined
1190
-
}
1191
-
style={{
1192
-
//border: "1px solid #e1e8ed",
1193
-
//borderRadius: 12,
1194
-
opacity: "1 !important",
1195
-
background: "transparent",
1196
-
paddingLeft: isQuote ? 12 : 16,
1197
-
paddingRight: isQuote ? 12 : 16,
1198
-
//paddingTop: 16,
1199
-
paddingTop: isRepost ? 10 : isQuote ? 12 : 16,
1200
-
//paddingBottom: bottomReplyLine ? 0 : 16,
1201
-
paddingBottom: 0,
1202
-
fontFamily: "system-ui, sans-serif",
1203
-
//boxShadow: "0 2px 8px rgba(0,0,0,0.04)",
1204
-
position: "relative",
1205
-
// dont cursor: "pointer",
1206
-
borderBottomWidth: bottomBorder ? (isQuote ? 0 : 1) : 0,
1207
-
}}
1208
-
className="border-gray-300 dark:border-gray-600"
1209
-
>
1210
-
{isRepost && (
1211
-
<div
1212
-
style={{
1213
-
marginLeft: 36,
1214
-
display: "flex",
1215
-
borderRadius: 12,
1216
-
paddingBottom: "calc(22px - 1rem)",
1217
-
fontSize: 14,
1218
-
maxHeight: "1rem",
1219
-
justifyContent: "flex-start",
1220
-
//color: theme.textSecondary,
1221
-
gap: 4,
1222
-
alignItems: "center",
1223
-
}}
1224
-
className="text-gray-500 dark:text-gray-400"
1225
-
>
1226
-
<MdiRepost /> Reposted by @{isRepost}{" "}
1227
-
</div>
1228
-
)}
1229
-
{!isQuote && (
1230
-
<div
1231
-
style={{
1232
-
opacity:
1233
-
topReplyLine || isReply /*&& (true || expanded)*/ ? 0.5 : 0,
1234
-
position: "absolute",
1235
-
top: 0,
1236
-
left: 36, // why 36 ???
1237
-
//left: 16 + (42 / 2),
1238
-
width: 2,
1239
-
//height: "100%",
1240
-
height: isRepost ? "calc(16px + 1rem - 6px)" : 16 - 6,
1241
-
// background: theme.textSecondary,
1242
-
//opacity: 0.5,
1243
-
// no flex here
1244
-
}}
1245
-
className="bg-gray-500 dark:bg-gray-400"
1246
-
/>
1247
-
)}
1212
+
<div ref={ref} style={style} data-index={dataIndexPropPass}>
1248
1213
<div
1214
+
//ref={ref}
1215
+
key={salt + "-" + (post.uri || emergencySalt)}
1216
+
onClick={
1217
+
isMainItem
1218
+
? onPostClick
1219
+
: setMainItem
1220
+
? onPostClick
1221
+
? (e) => {
1222
+
setMainItem({ post: post });
1223
+
onPostClick(e);
1224
+
}
1225
+
: () => {
1226
+
setMainItem({ post: post });
1227
+
}
1228
+
: undefined
1229
+
}
1249
1230
style={{
1250
-
position: "absolute",
1251
-
//top: isRepost ? "calc(16px + 1rem)" : 16,
1252
-
//left: 16,
1253
-
zIndex: 1,
1254
-
top: isRepost ? "calc(16px + 1rem)" : isQuote ? 12 : 16,
1255
-
left: isQuote ? 12 : 16,
1231
+
//...style,
1232
+
//border: "1px solid #e1e8ed",
1233
+
//borderRadius: 12,
1234
+
opacity: "1 !important",
1235
+
background: "transparent",
1236
+
paddingLeft: isQuote ? 12 : 16,
1237
+
paddingRight: isQuote ? 12 : 16,
1238
+
//paddingTop: 16,
1239
+
paddingTop: isRepost ? 10 : isQuote ? 12 : 16,
1240
+
//paddingBottom: bottomReplyLine ? 0 : 16,
1241
+
paddingBottom: 0,
1242
+
fontFamily: "system-ui, sans-serif",
1243
+
//boxShadow: "0 2px 8px rgba(0,0,0,0.04)",
1244
+
position: "relative",
1245
+
// dont cursor: "pointer",
1246
+
borderBottomWidth: bottomBorder ? (isQuote ? 0 : 1) : 0,
1256
1247
}}
1257
-
onClick={onProfileClick}
1248
+
className="border-gray-300 dark:border-gray-600"
1258
1249
>
1259
-
<img
1260
-
src={post.author.avatar || defaultpfp}
1261
-
alt="avatar"
1262
-
// transition={{
1263
-
// type: "spring",
1264
-
// stiffness: 260,
1265
-
// damping: 20,
1266
-
// }}
1267
-
style={{
1268
-
borderRadius: "50%",
1269
-
marginRight: 12,
1270
-
objectFit: "cover",
1271
-
//background: theme.border,
1272
-
//border: `1px solid ${theme.border}`,
1273
-
width: isQuote ? 16 : 42,
1274
-
height: isQuote ? 16 : 42,
1275
-
}}
1276
-
className="border border-gray-300 dark:border-gray-600 bg-gray-300 dark:bg-gray-600"
1277
-
/>
1278
-
</div>
1279
-
<div style={{ display: "flex", alignItems: "flex-start", zIndex: 2 }}>
1250
+
{isRepost && (
1251
+
<div
1252
+
style={{
1253
+
marginLeft: 36,
1254
+
display: "flex",
1255
+
borderRadius: 12,
1256
+
paddingBottom: "calc(22px - 1rem)",
1257
+
fontSize: 14,
1258
+
maxHeight: "1rem",
1259
+
justifyContent: "flex-start",
1260
+
//color: theme.textSecondary,
1261
+
gap: 4,
1262
+
alignItems: "center",
1263
+
}}
1264
+
className="text-gray-500 dark:text-gray-400"
1265
+
>
1266
+
<MdiRepost /> Reposted by @{isRepost}{" "}
1267
+
</div>
1268
+
)}
1269
+
{!isQuote && (
1270
+
<div
1271
+
style={{
1272
+
opacity:
1273
+
topReplyLine || isReply /*&& (true || expanded)*/ ? 0.5 : 0,
1274
+
position: "absolute",
1275
+
top: 0,
1276
+
left: 36, // why 36 ???
1277
+
//left: 16 + (42 / 2),
1278
+
width: 2,
1279
+
//height: "100%",
1280
+
height: isRepost ? "calc(16px + 1rem - 6px)" : 16 - 6,
1281
+
// background: theme.textSecondary,
1282
+
//opacity: 0.5,
1283
+
// no flex here
1284
+
}}
1285
+
className="bg-gray-500 dark:bg-gray-400"
1286
+
/>
1287
+
)}
1280
1288
<div
1281
1289
style={{
1282
-
display: "flex",
1283
-
flexDirection: "column",
1284
-
alignSelf: "stretch",
1285
-
alignItems: "center",
1286
-
overflow: "hidden",
1287
-
width: expanded || isQuote ? 0 : "auto",
1288
-
marginRight: expanded || isQuote ? 0 : 12,
1290
+
position: "absolute",
1291
+
//top: isRepost ? "calc(16px + 1rem)" : 16,
1292
+
//left: 16,
1293
+
zIndex: 1,
1294
+
top: isRepost ? "calc(16px + 1rem)" : isQuote ? 12 : 16,
1295
+
left: isQuote ? 12 : 16,
1289
1296
}}
1297
+
onClick={onProfileClick}
1290
1298
>
1291
-
{/* dummy for later use */}
1292
-
<div style={{ width: 42, height: 42 + 8, minHeight: 42 + 8 }} />
1293
-
{/* reply line !!!! bottomReplyLine */}
1294
-
{bottomReplyLine && (
1295
-
<div
1296
-
style={{
1297
-
width: 2,
1298
-
height: "100%",
1299
-
//background: theme.textSecondary,
1300
-
opacity: 0.5,
1301
-
// no flex here
1302
-
//color: "Red",
1303
-
//zIndex: 99
1304
-
}}
1305
-
className="bg-gray-500 dark:bg-gray-400"
1306
-
/>
1307
-
)}
1308
-
{/* <div
1299
+
<img
1300
+
src={post.author.avatar || defaultpfp}
1301
+
alt="avatar"
1302
+
// transition={{
1303
+
// type: "spring",
1304
+
// stiffness: 260,
1305
+
// damping: 20,
1306
+
// }}
1307
+
style={{
1308
+
borderRadius: "50%",
1309
+
marginRight: 12,
1310
+
objectFit: "cover",
1311
+
//background: theme.border,
1312
+
//border: `1px solid ${theme.border}`,
1313
+
width: isQuote ? 16 : 42,
1314
+
height: isQuote ? 16 : 42,
1315
+
}}
1316
+
className="border border-gray-300 dark:border-gray-600 bg-gray-300 dark:bg-gray-600"
1317
+
/>
1318
+
</div>
1319
+
<div style={{ display: "flex", alignItems: "flex-start", zIndex: 2 }}>
1320
+
<div
1321
+
style={{
1322
+
display: "flex",
1323
+
flexDirection: "column",
1324
+
alignSelf: "stretch",
1325
+
alignItems: "center",
1326
+
overflow: "hidden",
1327
+
width: expanded || isQuote ? 0 : "auto",
1328
+
marginRight: expanded || isQuote ? 0 : 12,
1329
+
}}
1330
+
>
1331
+
{/* dummy for later use */}
1332
+
<div style={{ width: 42, height: 42 + 8, minHeight: 42 + 8 }} />
1333
+
{/* reply line !!!! bottomReplyLine */}
1334
+
{bottomReplyLine && (
1335
+
<div
1336
+
style={{
1337
+
width: 2,
1338
+
height: "100%",
1339
+
//background: theme.textSecondary,
1340
+
opacity: 0.5,
1341
+
// no flex here
1342
+
//color: "Red",
1343
+
//zIndex: 99
1344
+
}}
1345
+
className="bg-gray-500 dark:bg-gray-400"
1346
+
/>
1347
+
)}
1348
+
{/* <div
1309
1349
layout
1310
1350
transition={{ duration: 0.2 }}
1311
1351
animate={{ height: expanded ? 0 : '100%' }}
···
1315
1355
// no flex here
1316
1356
}}
1317
1357
/> */}
1318
-
</div>
1319
-
<div style={{ flex: 1, maxWidth: "100%" }}>
1320
-
<div
1321
-
style={{
1322
-
display: "flex",
1323
-
flexDirection: "row",
1324
-
alignItems: "center",
1325
-
flexWrap: "nowrap",
1326
-
maxWidth: `calc(100% - ${!expanded ? (isQuote ? 26 : 0) : 54}px)`,
1327
-
width: `calc(100% - ${!expanded ? (isQuote ? 26 : 0) : 54}px)`,
1328
-
marginLeft: !expanded ? (isQuote ? 26 : 0) : 54,
1329
-
marginBottom: !expanded ? 4 : 6,
1330
-
}}
1331
-
>
1358
+
</div>
1359
+
<div style={{ flex: 1, maxWidth: "100%" }}>
1332
1360
<div
1333
1361
style={{
1334
1362
display: "flex",
1335
-
//overflow: "hidden", // hey why is overflow hidden unapplied
1336
-
overflow: "hidden",
1337
-
textOverflow: "ellipsis",
1338
-
flexShrink: 1,
1339
-
flexGrow: 1,
1340
-
flexBasis: 0,
1341
-
width: 0,
1342
-
gap: expanded ? 0 : 6,
1343
-
alignItems: expanded ? "flex-start" : "center",
1344
-
flexDirection: expanded ? "column" : "row",
1345
-
height: expanded ? 42 : "1rem",
1363
+
flexDirection: "row",
1364
+
alignItems: "center",
1365
+
flexWrap: "nowrap",
1366
+
maxWidth: `calc(100% - ${!expanded ? (isQuote ? 26 : 0) : 54}px)`,
1367
+
width: `calc(100% - ${!expanded ? (isQuote ? 26 : 0) : 54}px)`,
1368
+
marginLeft: !expanded ? (isQuote ? 26 : 0) : 54,
1369
+
marginBottom: !expanded ? 4 : 6,
1346
1370
}}
1347
1371
>
1348
-
<span
1372
+
<div
1349
1373
style={{
1350
1374
display: "flex",
1351
-
fontWeight: 700,
1352
-
fontSize: 16,
1375
+
//overflow: "hidden", // hey why is overflow hidden unapplied
1353
1376
overflow: "hidden",
1354
1377
textOverflow: "ellipsis",
1355
-
whiteSpace: "nowrap",
1356
1378
flexShrink: 1,
1357
-
minWidth: 0,
1358
-
gap: 4,
1359
-
alignItems: "center",
1360
-
//color: theme.text,
1379
+
flexGrow: 1,
1380
+
flexBasis: 0,
1381
+
width: 0,
1382
+
gap: expanded ? 0 : 6,
1383
+
alignItems: expanded ? "flex-start" : "center",
1384
+
flexDirection: expanded ? "column" : "row",
1385
+
height: expanded ? 42 : "1rem",
1361
1386
}}
1362
-
className="text-gray-900 dark:text-gray-100"
1363
1387
>
1364
-
{/* verified checkmark */}
1365
-
{post.author.displayName || post.author.handle}{" "}
1366
-
{post.author.verification?.verifiedStatus == "valid" && (
1367
-
<MdiVerified />
1368
-
)}
1369
-
</span>
1388
+
<span
1389
+
style={{
1390
+
display: "flex",
1391
+
fontWeight: 700,
1392
+
fontSize: 16,
1393
+
overflow: "hidden",
1394
+
textOverflow: "ellipsis",
1395
+
whiteSpace: "nowrap",
1396
+
flexShrink: 1,
1397
+
minWidth: 0,
1398
+
gap: 4,
1399
+
alignItems: "center",
1400
+
//color: theme.text,
1401
+
}}
1402
+
className="text-gray-900 dark:text-gray-100"
1403
+
>
1404
+
{/* verified checkmark */}
1405
+
{post.author.displayName || post.author.handle}{" "}
1406
+
{post.author.verification?.verifiedStatus == "valid" && (
1407
+
<MdiVerified />
1408
+
)}
1409
+
</span>
1370
1410
1371
-
<span
1411
+
<span
1412
+
style={{
1413
+
//color: theme.textSecondary,
1414
+
fontSize: 16,
1415
+
overflowX: "hidden",
1416
+
textOverflow: "ellipsis",
1417
+
whiteSpace: "nowrap",
1418
+
flexShrink: 1,
1419
+
flexGrow: 0,
1420
+
minWidth: 0,
1421
+
}}
1422
+
className="text-gray-500 dark:text-gray-400"
1423
+
>
1424
+
@{post.author.handle}
1425
+
</span>
1426
+
</div>
1427
+
<div
1372
1428
style={{
1373
-
//color: theme.textSecondary,
1374
-
fontSize: 16,
1375
-
overflowX: "hidden",
1376
-
textOverflow: "ellipsis",
1377
-
whiteSpace: "nowrap",
1378
-
flexShrink: 1,
1379
-
flexGrow: 0,
1380
-
minWidth: 0,
1429
+
display: "flex",
1430
+
alignItems: "center",
1431
+
height: "1rem",
1381
1432
}}
1382
-
className="text-gray-500 dark:text-gray-400"
1383
1433
>
1384
-
@{post.author.handle}
1385
-
</span>
1434
+
<span
1435
+
style={{
1436
+
//color: theme.textSecondary,
1437
+
fontSize: 16,
1438
+
marginLeft: 8,
1439
+
whiteSpace: "nowrap",
1440
+
flexShrink: 0,
1441
+
maxWidth: "100%",
1442
+
}}
1443
+
className="text-gray-500 dark:text-gray-400"
1444
+
>
1445
+
· {/* time placeholder */}
1446
+
{shortTimeAgo(post.indexedAt)}
1447
+
</span>
1448
+
</div>
1386
1449
</div>
1387
-
<div
1388
-
style={{
1389
-
display: "flex",
1390
-
alignItems: "center",
1391
-
height: "1rem",
1392
-
}}
1393
-
>
1394
-
<span
1450
+
{/* reply indicator */}
1451
+
{!!feedviewpostreplyhandle && (
1452
+
<div
1395
1453
style={{
1454
+
display: "flex",
1455
+
borderRadius: 12,
1456
+
paddingBottom: 2,
1457
+
fontSize: 14,
1458
+
justifyContent: "flex-start",
1396
1459
//color: theme.textSecondary,
1397
-
fontSize: 16,
1398
-
marginLeft: 8,
1399
-
whiteSpace: "nowrap",
1400
-
flexShrink: 0,
1401
-
maxWidth: "100%",
1460
+
gap: 4,
1461
+
alignItems: "center",
1462
+
//marginLeft: 36,
1463
+
height:
1464
+
!(expanded || isQuote) && !!feedviewpostreplyhandle
1465
+
? "1rem"
1466
+
: 0,
1467
+
opacity:
1468
+
!(expanded || isQuote) && !!feedviewpostreplyhandle ? 1 : 0,
1402
1469
}}
1403
1470
className="text-gray-500 dark:text-gray-400"
1404
1471
>
1405
-
· {/* time placeholder */}
1406
-
{shortTimeAgo(post.indexedAt)}
1407
-
</span>
1408
-
</div>
1409
-
</div>
1410
-
{/* reply indicator */}
1411
-
{!!feedviewpostreplyhandle && (
1472
+
<MdiReply /> Reply to @{feedviewpostreplyhandle}
1473
+
</div>
1474
+
)}
1412
1475
<div
1413
1476
style={{
1414
-
display: "flex",
1415
-
borderRadius: 12,
1416
-
paddingBottom: 2,
1417
-
fontSize: 14,
1418
-
justifyContent: "flex-start",
1419
-
//color: theme.textSecondary,
1420
-
gap: 4,
1421
-
alignItems: "center",
1422
-
//marginLeft: 36,
1423
-
height:
1424
-
!(expanded || isQuote) && !!feedviewpostreplyhandle
1425
-
? "1rem"
1426
-
: 0,
1427
-
opacity:
1428
-
!(expanded || isQuote) && !!feedviewpostreplyhandle ? 1 : 0,
1477
+
fontSize: 16,
1478
+
marginBottom: !post.embed /*|| depth > 0*/ ? 0 : 8,
1479
+
whiteSpace: "pre-wrap",
1480
+
textAlign: "left",
1481
+
overflowWrap: "anywhere",
1482
+
wordBreak: "break-word",
1483
+
//color: theme.text,
1429
1484
}}
1430
-
className="text-gray-500 dark:text-gray-400"
1485
+
className="text-gray-900 dark:text-gray-100"
1431
1486
>
1432
-
<MdiReply /> Reply to @{feedviewpostreplyhandle}
1487
+
{renderTextWithFacets({
1488
+
text: (post.record as { text?: string }).text ?? "",
1489
+
facets: (post.record.facets as Facet[]) ?? [],
1490
+
navigate: navigate,
1491
+
})}
1492
+
{}
1433
1493
</div>
1434
-
)}
1435
-
<div
1436
-
style={{
1437
-
fontSize: 16,
1438
-
marginBottom: !post.embed /*|| depth > 0*/ ? 0 : 8,
1439
-
whiteSpace: "pre-wrap",
1440
-
textAlign: "left",
1441
-
overflowWrap: "anywhere",
1442
-
wordBreak: "break-word",
1443
-
//color: theme.text,
1444
-
}}
1445
-
className="text-gray-900 dark:text-gray-100"
1446
-
>
1447
-
{renderTextWithFacets({
1448
-
text: (post.record as { text?: string }).text ?? "",
1449
-
facets: (post.record.facets as Facet[]) ?? [],
1450
-
navigate: navigate,
1451
-
})}
1452
-
{}
1453
-
</div>
1454
-
{post.embed && depth < 1 ? (
1455
-
<PostEmbeds
1456
-
embed={post.embed}
1457
-
//moderation={moderation}
1458
-
viewContext={PostEmbedViewContext.Feed}
1459
-
salt={salt}
1460
-
navigate={navigate}
1461
-
/>
1462
-
) : null}
1463
-
{post.embed && depth > 0 && (
1464
-
/* pretty bad hack imo. its trying to sync up with how the embed shim doesnt
1494
+
{post.embed && depth < 1 ? (
1495
+
<PostEmbeds
1496
+
embed={post.embed}
1497
+
//moderation={moderation}
1498
+
viewContext={PostEmbedViewContext.Feed}
1499
+
salt={salt}
1500
+
navigate={navigate}
1501
+
postid={{ did: post.author.did, rkey: parsed.rkey }}
1502
+
nopics={nopics}
1503
+
/>
1504
+
) : null}
1505
+
{post.embed && depth > 0 && (
1506
+
/* pretty bad hack imo. its trying to sync up with how the embed shim doesnt
1465
1507
hydrate embeds this deep but the connection here is implicit
1466
1508
todo: idk make this a real part of the embed shim so its not implicit */
1467
-
<>
1468
-
<div className="border-gray-300 dark:border-gray-600 p-3 rounded-xl border italic text-gray-400 text-[14px]">
1469
-
(there is an embed here thats too deep to render)
1470
-
</div>
1471
-
</>
1472
-
)}
1473
-
<div style={{ paddingTop: post.embed && depth < 1 ? 4 : 0 }}>
1474
-
<>
1475
-
{expanded && (
1509
+
<>
1510
+
<div className="border-gray-300 dark:border-gray-600 p-3 rounded-xl border italic text-gray-400 text-[14px]">
1511
+
(there is an embed here thats too deep to render)
1512
+
</div>
1513
+
</>
1514
+
)}
1515
+
<div style={{ paddingTop: post.embed && depth < 1 ? 4 : 0 }}>
1516
+
<>
1517
+
{expanded && (
1518
+
<div
1519
+
style={{
1520
+
overflow: "hidden",
1521
+
//color: theme.textSecondary,
1522
+
fontSize: 14,
1523
+
display: "flex",
1524
+
borderBottomStyle: "solid",
1525
+
//borderBottomColor: theme.border,
1526
+
//background: "#f00",
1527
+
// height: "1rem",
1528
+
paddingTop: 4,
1529
+
paddingBottom: 8,
1530
+
borderBottomWidth: 1,
1531
+
marginBottom: 8,
1532
+
}} // important for height animation
1533
+
className="text-gray-500 dark:text-gray-400 border-gray-200 dark:border-gray-700"
1534
+
>
1535
+
{fullDateTimeFormat(post.indexedAt)}
1536
+
</div>
1537
+
)}
1538
+
</>
1539
+
{!isQuote && (
1476
1540
<div
1477
1541
style={{
1478
-
overflow: "hidden",
1479
-
//color: theme.textSecondary,
1480
-
fontSize: 14,
1481
1542
display: "flex",
1482
-
borderBottomStyle: "solid",
1483
-
//borderBottomColor: theme.border,
1484
-
//background: "#f00",
1485
-
// height: "1rem",
1486
-
paddingTop: 4,
1487
-
paddingBottom: 8,
1488
-
borderBottomWidth: 1,
1489
-
marginBottom: 8,
1490
-
}} // important for height animation
1491
-
className="text-gray-500 dark:text-gray-400 border-gray-200 dark:border-gray-700"
1492
-
>
1493
-
{fullDateTimeFormat(post.indexedAt)}
1494
-
</div>
1495
-
)}
1496
-
</>
1497
-
{!isQuote && (
1498
-
<div
1499
-
style={{
1500
-
display: "flex",
1501
-
gap: 32,
1502
-
paddingTop: 8,
1503
-
//color: theme.textSecondary,
1504
-
fontSize: 15,
1505
-
justifyContent: "space-between",
1506
-
//background: "#0f0",
1507
-
}}
1508
-
className="text-gray-500 dark:text-gray-400"
1509
-
>
1510
-
<span style={btnstyle}>
1511
-
<MdiCommentOutline />
1512
-
{post.replyCount}
1513
-
</span>
1514
-
<HitSlopButton
1515
-
onClick={() => {
1516
-
repostOrUnrepostPost();
1543
+
gap: 32,
1544
+
paddingTop: 8,
1545
+
//color: theme.textSecondary,
1546
+
fontSize: 15,
1547
+
justifyContent: "space-between",
1548
+
//background: "#0f0",
1517
1549
}}
1518
-
style={{
1519
-
...btnstyle,
1520
-
...(hasRetweeted ? { color: "#5CEFAA" } : {}),
1521
-
}}
1522
-
>
1523
-
{hasRetweeted ? <MdiRepeatGreen /> : <MdiRepeat />}
1524
-
{(post.repostCount || 0) + (hasRetweeted ? 1 : 0)}
1525
-
</HitSlopButton>
1526
-
<HitSlopButton
1527
-
onClick={() => {
1528
-
likeOrUnlikePost();
1529
-
}}
1530
-
style={{
1531
-
...btnstyle,
1532
-
...(hasLiked ? { color: "#EC4899" } : {}),
1533
-
}}
1550
+
className="text-gray-500 dark:text-gray-400"
1534
1551
>
1535
-
{hasLiked ? <MdiCardsHeart /> : <MdiCardsHeartOutline />}
1536
-
{(post.likeCount || 0) + (hasLiked ? 1 : 0)}
1537
-
</HitSlopButton>
1538
-
<div style={{ display: "flex", gap: 8 }}>
1552
+
<span style={btnstyle}>
1553
+
<MdiCommentOutline />
1554
+
{post.replyCount}
1555
+
</span>
1556
+
<HitSlopButton
1557
+
onClick={() => {
1558
+
repostOrUnrepostPost();
1559
+
}}
1560
+
style={{
1561
+
...btnstyle,
1562
+
...(hasRetweeted ? { color: "#5CEFAA" } : {}),
1563
+
}}
1564
+
>
1565
+
{hasRetweeted ? <MdiRepeatGreen /> : <MdiRepeat />}
1566
+
{(post.repostCount || 0) + (hasRetweeted ? 1 : 0)}
1567
+
</HitSlopButton>
1539
1568
<HitSlopButton
1540
-
onClick={async (e) => {
1541
-
e.stopPropagation();
1542
-
try {
1543
-
await navigator.clipboard.writeText(
1544
-
"https://bsky.app" +
1545
-
"/profile/" +
1546
-
post.author.handle +
1547
-
"/post/" +
1548
-
post.uri.split("/").pop()
1549
-
);
1550
-
} catch (_e) {
1551
-
// idk
1552
-
}
1569
+
onClick={() => {
1570
+
likeOrUnlikePost();
1553
1571
}}
1554
1572
style={{
1555
1573
...btnstyle,
1574
+
...(hasLiked ? { color: "#EC4899" } : {}),
1556
1575
}}
1557
1576
>
1558
-
<MdiShareVariant />
1577
+
{hasLiked ? <MdiCardsHeart /> : <MdiCardsHeartOutline />}
1578
+
{(post.likeCount || 0) + (hasLiked ? 1 : 0)}
1559
1579
</HitSlopButton>
1560
-
<span style={btnstyle}>
1561
-
<MdiMoreHoriz />
1562
-
</span>
1580
+
<div style={{ display: "flex", gap: 8 }}>
1581
+
<HitSlopButton
1582
+
onClick={async (e) => {
1583
+
e.stopPropagation();
1584
+
try {
1585
+
await navigator.clipboard.writeText(
1586
+
"https://bsky.app" +
1587
+
"/profile/" +
1588
+
post.author.handle +
1589
+
"/post/" +
1590
+
post.uri.split("/").pop()
1591
+
);
1592
+
} catch (_e) {
1593
+
// idk
1594
+
}
1595
+
}}
1596
+
style={{
1597
+
...btnstyle,
1598
+
}}
1599
+
>
1600
+
<MdiShareVariant />
1601
+
</HitSlopButton>
1602
+
<span style={btnstyle}>
1603
+
<MdiMoreHoriz />
1604
+
</span>
1605
+
</div>
1563
1606
</div>
1564
-
</div>
1565
-
)}
1607
+
)}
1608
+
</div>
1609
+
<div
1610
+
style={{
1611
+
//height: bottomReplyLine ? 16 : 0
1612
+
height: isQuote ? 12 : 16,
1613
+
}}
1614
+
/>
1566
1615
</div>
1567
-
<div
1568
-
style={{
1569
-
//height: bottomReplyLine ? 16 : 0
1570
-
height: isQuote ? 12 : 16,
1571
-
}}
1572
-
/>
1573
1616
</div>
1574
1617
</div>
1575
1618
</div>
···
1661
1704
viewContext,
1662
1705
salt,
1663
1706
navigate,
1707
+
postid,
1708
+
nopics,
1664
1709
}: {
1665
1710
embed?: Embed;
1666
1711
moderation?: ModerationDecision;
···
1669
1714
viewContext?: PostEmbedViewContext;
1670
1715
salt: string;
1671
1716
navigate: (_: any) => void;
1717
+
postid?: { did: string; rkey: string };
1718
+
nopics?: boolean;
1672
1719
}) {
1673
1720
const [lightboxIndex, setLightboxIndex] = useState<number | null>(null);
1674
1721
if (
···
1704
1751
viewContext={viewContext}
1705
1752
salt={salt}
1706
1753
navigate={navigate}
1754
+
postid={postid}
1755
+
nopics={nopics}
1707
1756
/>
1708
1757
{/* padding empty div of 8px height */}
1709
1758
<div style={{ height: 12 }} />
···
1871
1920
1872
1921
// image embed
1873
1922
// =
1874
-
if (AppBskyEmbedImages.isView(embed)) {
1923
+
if (AppBskyEmbedImages.isView(embed) && !nopics) {
1875
1924
const { images } = embed;
1876
1925
1877
1926
const lightboxImages = images.map((img) => ({
···
1915
1964
index={lightboxIndex}
1916
1965
onClose={() => setLightboxIndex(null)}
1917
1966
onNavigate={(newIndex) => setLightboxIndex(newIndex)}
1967
+
post={postid}
1918
1968
/>
1919
1969
)}
1920
1970
<img
···
1955
2005
index={lightboxIndex}
1956
2006
onClose={() => setLightboxIndex(null)}
1957
2007
onNavigate={(newIndex) => setLightboxIndex(newIndex)}
2008
+
post={postid}
1958
2009
/>
1959
2010
)}
1960
2011
{images.map((img, i) => (
···
2004
2055
index={lightboxIndex}
2005
2056
onClose={() => setLightboxIndex(null)}
2006
2057
onNavigate={(newIndex) => setLightboxIndex(newIndex)}
2058
+
post={postid}
2007
2059
/>
2008
2060
)}
2009
2061
{/* Left: 1:1 */}
···
2088
2140
index={lightboxIndex}
2089
2141
onClose={() => setLightboxIndex(null)}
2090
2142
onNavigate={(newIndex) => setLightboxIndex(newIndex)}
2143
+
post={postid}
2091
2144
/>
2092
2145
)}
2093
2146
{images.map((img, i) => (
···
2180
2233
return <div />;
2181
2234
}
2182
2235
2183
-
import { createPortal } from "react-dom";
2184
2236
type LightboxProps = {
2185
2237
images: { src: string; alt?: string }[];
2186
2238
index: number;
2187
2239
onClose: () => void;
2188
2240
onNavigate?: (newIndex: number) => void;
2241
+
post?: { did: string; rkey: string };
2189
2242
};
2190
2243
export function Lightbox({
2191
2244
images,
2192
2245
index,
2193
2246
onClose,
2194
2247
onNavigate,
2248
+
post,
2195
2249
}: LightboxProps) {
2196
2250
const image = images[index];
2197
2251
···
2208
2262
}, [index, images.length, onClose, onNavigate]);
2209
2263
2210
2264
return createPortal(
2211
-
<div
2212
-
className="fixed inset-0 z-50 flex items-center justify-center bg-black/80"
2213
-
onClick={(e) => {
2214
-
e.stopPropagation();
2215
-
onClose();
2216
-
}}
2217
-
>
2218
-
<img
2219
-
src={image.src}
2220
-
alt={image.alt}
2221
-
className="max-h-[90vh] max-w-[90vw] object-contain rounded-lg shadow-lg"
2222
-
onClick={(e) => e.stopPropagation()}
2223
-
/>
2265
+
<>
2266
+
{post && (
2267
+
<div
2268
+
onClick={(e) => {
2269
+
e.stopPropagation();
2270
+
e.nativeEvent.stopImmediatePropagation();
2271
+
}}
2272
+
className="lightbox-sidebar overscroll-none disablegutter border-l dark:border-gray-700 border-gray-300 fixed z-50 flex top-0 right-0 flex-col max-w-[350px] min-w-[350px] max-h-screen overflow-y-scroll dark:bg-gray-950 bg-white"
2273
+
>
2274
+
<ProfilePostComponent
2275
+
did={post.did}
2276
+
rkey={post.rkey}
2277
+
nopics={onClose}
2278
+
/>
2279
+
</div>
2280
+
)}
2281
+
<div
2282
+
className="lightbox fixed inset-0 z-50 flex items-center justify-center bg-black/80 w-screen lg:w-[calc(100vw-350px-var(--scrollbar-width)*0)] lg:max-w-[calc(100vw-350px-var(--scrollbar-width)*0)]"
2283
+
onClick={(e) => {
2284
+
e.stopPropagation();
2285
+
onClose();
2286
+
}}
2287
+
>
2288
+
<img
2289
+
src={image.src}
2290
+
alt={image.alt}
2291
+
className="max-h-[90%] max-w-[90%] object-contain rounded-lg shadow-lg"
2292
+
onClick={(e) => e.stopPropagation()}
2293
+
/>
2224
2294
2225
-
{images.length > 1 && (
2226
-
<>
2227
-
<button
2228
-
onClick={(e) => {
2229
-
e.stopPropagation();
2230
-
onNavigate?.((index - 1 + images.length) % images.length);
2231
-
}}
2232
-
className="absolute left-4 top-1/2 -translate-y-1/2 text-white text-4xl h-8 w-8 rounded-full bg-gray-900 flex items-center justify-center"
2233
-
>
2234
-
<svg
2235
-
xmlns="http://www.w3.org/2000/svg"
2236
-
width={28}
2237
-
height={28}
2238
-
viewBox="0 0 24 24"
2295
+
{images.length > 1 && (
2296
+
<>
2297
+
<button
2298
+
onClick={(e) => {
2299
+
e.stopPropagation();
2300
+
onNavigate?.((index - 1 + images.length) % images.length);
2301
+
}}
2302
+
className="absolute left-4 top-1/2 -translate-y-1/2 text-white text-4xl h-8 w-8 rounded-full bg-gray-900 flex items-center justify-center"
2239
2303
>
2240
-
<g fill="none" fillRule="evenodd">
2241
-
<path d="M24 0v24H0V0zM12.593 23.258l-.011.002l-.071.035l-.02.004l-.014-.004l-.071-.035q-.016-.005-.024.005l-.004.01l-.017.428l.005.02l.01.013l.104.074l.015.004l.012-.004l.104-.074l.012-.016l.004-.017l-.017-.427q-.004-.016-.017-.018m.265-.113l-.013.002l-.185.093l-.01.01l-.003.011l.018.43l.005.012l.008.007l.201.093q.019.005.029-.008l.004-.014l-.034-.614q-.005-.019-.02-.022m-.715.002a.02.02 0 0 0-.027.006l-.006.014l-.034.614q.001.018.017.024l.015-.002l.201-.093l.01-.008l.004-.011l.017-.43l-.003-.012l-.01-.01z"></path>
2242
-
<path
2243
-
fill="currentColor"
2244
-
d="M8.293 12.707a1 1 0 0 1 0-1.414l5.657-5.657a1 1 0 1 1 1.414 1.414L10.414 12l4.95 4.95a1 1 0 0 1-1.414 1.414z"
2245
-
></path>
2246
-
</g>
2247
-
</svg>
2248
-
</button>
2249
-
<button
2250
-
onClick={(e) => {
2251
-
e.stopPropagation();
2252
-
onNavigate?.((index + 1) % images.length);
2253
-
}}
2254
-
className="absolute right-4 top-1/2 -translate-y-1/2 text-white text-4xl h-8 w-8 rounded-full bg-gray-900 flex items-center justify-center"
2255
-
>
2256
-
<svg
2257
-
xmlns="http://www.w3.org/2000/svg"
2258
-
width={28}
2259
-
height={28}
2260
-
viewBox="0 0 24 24"
2304
+
<svg
2305
+
xmlns="http://www.w3.org/2000/svg"
2306
+
width={28}
2307
+
height={28}
2308
+
viewBox="0 0 24 24"
2309
+
>
2310
+
<g fill="none" fillRule="evenodd">
2311
+
<path d="M24 0v24H0V0zM12.593 23.258l-.011.002l-.071.035l-.02.004l-.014-.004l-.071-.035q-.016-.005-.024.005l-.004.01l-.017.428l.005.02l.01.013l.104.074l.015.004l.012-.004l.104-.074l.012-.016l.004-.017l-.017-.427q-.004-.016-.017-.018m.265-.113l-.013.002l-.185.093l-.01.01l-.003.011l.018.43l.005.012l.008.007l.201.093q.019.005.029-.008l.004-.014l-.034-.614q-.005-.019-.02-.022m-.715.002a.02.02 0 0 0-.027.006l-.006.014l-.034.614q.001.018.017.024l.015-.002l.201-.093l.01-.008l.004-.011l.017-.43l-.003-.012l-.01-.01z"></path>
2312
+
<path
2313
+
fill="currentColor"
2314
+
d="M8.293 12.707a1 1 0 0 1 0-1.414l5.657-5.657a1 1 0 1 1 1.414 1.414L10.414 12l4.95 4.95a1 1 0 0 1-1.414 1.414z"
2315
+
></path>
2316
+
</g>
2317
+
</svg>
2318
+
</button>
2319
+
<button
2320
+
onClick={(e) => {
2321
+
e.stopPropagation();
2322
+
onNavigate?.((index + 1) % images.length);
2323
+
}}
2324
+
className="absolute right-4 top-1/2 -translate-y-1/2 text-white text-4xl h-8 w-8 rounded-full bg-gray-900 flex items-center justify-center"
2261
2325
>
2262
-
<g fill="none" fillRule="evenodd">
2263
-
<path d="M24 0v24H0V0zM12.593 23.258l-.011.002l-.071.035l-.02.004l-.014-.004l-.071-.035q-.016-.005-.024.005l-.004.01l-.017.428l.005.02l.01.013l.104.074l.015.004l.012-.004l.104-.074l.012-.016l.004-.017l-.017-.427q-.004-.016-.017-.018m.265-.113l-.013.002l-.185.093l-.01.01l-.003.011l.018.43l.005.012l.008.007l.201.093q.019.005.029-.008l.004-.014l-.034-.614q-.005-.019-.02-.022m-.715.002a.02.02 0 0 0-.027.006l-.006.014l-.034.614q.001.018.017.024l.015-.002l.201-.093l.01-.008l.004-.011l.017-.43l-.003-.012l-.01-.01z"></path>
2264
-
<path
2265
-
fill="currentColor"
2266
-
d="M15.707 11.293a1 1 0 0 1 0 1.414l-5.657 5.657a1 1 0 1 1-1.414-1.414l4.95-4.95l-4.95-4.95a1 1 0 0 1 1.414-1.414z"
2267
-
></path>
2268
-
</g>
2269
-
</svg>
2270
-
</button>
2271
-
</>
2272
-
)}
2273
-
</div>,
2326
+
<svg
2327
+
xmlns="http://www.w3.org/2000/svg"
2328
+
width={28}
2329
+
height={28}
2330
+
viewBox="0 0 24 24"
2331
+
>
2332
+
<g fill="none" fillRule="evenodd">
2333
+
<path d="M24 0v24H0V0zM12.593 23.258l-.011.002l-.071.035l-.02.004l-.014-.004l-.071-.035q-.016-.005-.024.005l-.004.01l-.017.428l.005.02l.01.013l.104.074l.015.004l.012-.004l.104-.074l.012-.016l.004-.017l-.017-.427q-.004-.016-.017-.018m.265-.113l-.013.002l-.185.093l-.01.01l-.003.011l.018.43l.005.012l.008.007l.201.093q.019.005.029-.008l.004-.014l-.034-.614q-.005-.019-.02-.022m-.715.002a.02.02 0 0 0-.027.006l-.006.014l-.034.614q.001.018.017.024l.015-.002l.201-.093l.01-.008l.004-.011l.017-.43l-.003-.012l-.01-.01z"></path>
2334
+
<path
2335
+
fill="currentColor"
2336
+
d="M15.707 11.293a1 1 0 0 1 0 1.414l-5.657 5.657a1 1 0 1 1-1.414-1.414l4.95-4.95l-4.95-4.95a1 1 0 0 1 1.414-1.414z"
2337
+
></path>
2338
+
</g>
2339
+
</svg>
2340
+
</button>
2341
+
</>
2342
+
)}
2343
+
</div>
2344
+
</>,
2274
2345
document.body
2275
2346
);
2276
2347
}
+9
-9
src/main.tsx
+9
-9
src/main.tsx
···
1
-
import { StrictMode } from "react";
2
-
import ReactDOM from "react-dom/client";
3
-
import { RouterProvider, createRouter } from "@tanstack/react-router";
1
+
import "~/styles/app.css";
4
2
5
-
// Import the generated route tree
6
-
import { routeTree } from "./routeTree.gen";
7
-
8
-
import "~/styles/app.css";
9
-
import reportWebVitals from "./reportWebVitals.ts";
3
+
import { createSyncStoragePersister } from "@tanstack/query-sync-storage-persister";
10
4
import { QueryClient, QueryClientProvider, } from "@tanstack/react-query";
11
5
import {
12
6
persistQueryClient,
13
7
} from "@tanstack/react-query-persist-client";
14
-
import { createSyncStoragePersister } from "@tanstack/query-sync-storage-persister";
8
+
import { createRouter,RouterProvider } from "@tanstack/react-router";
9
+
//import { StrictMode } from "react";
10
+
import ReactDOM from "react-dom/client";
11
+
12
+
import reportWebVitals from "./reportWebVitals.ts";
13
+
// Import the generated route tree
14
+
import { routeTree } from "./routeTree.gen";
15
15
16
16
17
17
const queryClient = new QueryClient({
+42
-21
src/routes/profile.$did/post.$rkey.tsx
+42
-21
src/routes/profile.$did/post.$rkey.tsx
···
1
1
import { useQueryClient } from "@tanstack/react-query";
2
-
import { createFileRoute, Link } from "@tanstack/react-router";
2
+
import { createFileRoute } from "@tanstack/react-router";
3
3
import React, { useLayoutEffect } from "react";
4
4
5
5
import { UniversalPostRendererATURILoader } from "~/components/UniversalPostRenderer";
···
32
32
);
33
33
}
34
34
35
-
function ProfilePostComponent({ did, rkey }: { did: string; rkey: string }) {
35
+
export function ProfilePostComponent({
36
+
did,
37
+
rkey,
38
+
nopics,
39
+
}: {
40
+
did: string;
41
+
rkey: string;
42
+
nopics?: () => void;
43
+
}) {
36
44
//const { get, set } = usePersistentStore();
37
45
const queryClient = useQueryClient();
38
46
// const [resolvedDid, setResolvedDid] = React.useState<string | null>(null);
···
201
209
202
210
const scrollAnchor = React.useRef<{ top: number } | null>(null);
203
211
204
-
205
212
React.useEffect(() => {
206
213
const onScroll = () => {
207
-
208
214
if (window.scrollY > 50) {
209
215
userHasScrolled.current = true;
210
216
···
291
297
return (
292
298
<>
293
299
<div className="flex items-center gap-2 px-4 py-2 h-[52px] sticky top-0 bg-white dark:bg-gray-950 z-10 border-b border-gray-200 dark:border-gray-700">
294
-
<Link
295
-
to=".."
296
-
className="px-3 py-1 rounded hover:bg-gray-100 dark:hover:bg-gray-900 font-bold text-lg"
297
-
onClick={(e) => {
298
-
e.preventDefault();
299
-
if (window.history.length > 1) {
300
-
window.history.back();
301
-
} else {
302
-
window.location.assign("/");
303
-
}
304
-
}}
305
-
aria-label="Go back"
306
-
>
307
-
←
308
-
</Link>
300
+
{!nopics ? (
301
+
<button
302
+
//to=".."
303
+
className="px-3 py-1 rounded hover:bg-gray-100 dark:hover:bg-gray-900 font-bold text-lg"
304
+
onClick={(e) => {
305
+
e.preventDefault();
306
+
if (window.history.length > 1) {
307
+
window.history.back();
308
+
} else {
309
+
window.location.assign("/");
310
+
}
311
+
}}
312
+
aria-label="Go back"
313
+
>
314
+
←
315
+
</button>
316
+
) : (
317
+
<button
318
+
//to=".."
319
+
className="px-3 py-1 rounded hover:bg-gray-100 dark:hover:bg-gray-900 font-bold text-lg"
320
+
onClick={(e) => {
321
+
e.preventDefault();
322
+
nopics();
323
+
}}
324
+
aria-label="Go back"
325
+
>
326
+
←
327
+
</button>
328
+
)}
309
329
<span className="text-xl font-bold ml-2">Post</span>
310
330
</div>
311
331
···
322
342
)}
323
343
324
344
{/* we should use the reply lines here thats provided by UPR*/}
325
-
<div style={{ maxWidth: 600, margin: "0px auto 0", padding: 0 }}>
345
+
<div style={{ maxWidth: 600, padding: 0 }}>
326
346
{parents.map((parent, index) => (
327
347
<UniversalPostRendererATURILoader
328
348
key={parent.uri}
···
338
358
atUri={atUri}
339
359
detailed={true}
340
360
topReplyLine={parentsLoading || parents.length > 0}
361
+
nopics={!!nopics}
341
362
/>
342
363
</div>
343
364
<div
344
365
style={{
345
366
maxWidth: 600,
346
-
margin: "0px auto 0",
367
+
//margin: "0px auto 0",
347
368
padding: 0,
348
369
minHeight: "100dvh",
349
370
}}
+12
-2
src/styles/app.css
+12
-2
src/styles/app.css
···
48
48
}
49
49
50
50
@media (width >= 64rem /* 1024px */) {
51
-
html,
52
-
body {
51
+
html:not(:has(.disablegutter)),
52
+
body:not(:has(.disablegutter)) {
53
53
scrollbar-gutter: stable both-edges !important;
54
54
}
55
+
html:has(.disablegutter),
56
+
body:has(.disablegutter) {
57
+
scrollbar-width: none;
58
+
overflow-y: hidden;
59
+
}
55
60
}
61
+
62
+
.lightbox:has(+.lightbox-sidebar){
63
+
opacity: 0;
64
+
}
65
+
56
66
.scroll-thin {
57
67
scrollbar-width: thin;
58
68
/*scrollbar-gutter: stable both-edges !important;*/