+35
-1
lib/renderers/BlueskyPostRenderer.tsx
+35
-1
lib/renderers/BlueskyPostRenderer.tsx
···
531
531
}
532
532
533
533
const PostImage: React.FC<PostImageProps> = ({ image, did }) => {
534
+
const [showAltText, setShowAltText] = React.useState(false);
534
535
const imageBlob = image.image;
535
536
const cdnUrl = isBlobWithCdn(imageBlob) ? imageBlob.cdnUrl : undefined;
536
537
const cid = cdnUrl ? undefined : extractCidFromBlob(imageBlob);
537
538
const { url: urlFromBlob, loading, error } = useBlob(did, cid);
538
539
const url = cdnUrl || urlFromBlob;
539
540
const alt = image.alt?.trim() || "Bluesky attachment";
541
+
const hasAlt = image.alt && image.alt.trim().length > 0;
540
542
541
543
const aspect =
542
544
image.aspectRatio && image.aspectRatio.height > 0
···
573
575
: "Image unavailable"}
574
576
</div>
575
577
)}
578
+
{hasAlt && (
579
+
<button
580
+
onClick={() => setShowAltText(!showAltText)}
581
+
style={{
582
+
...imagesBase.altBadge,
583
+
background: showAltText
584
+
? `var(--atproto-color-text)`
585
+
: `var(--atproto-color-bg-secondary)`,
586
+
color: showAltText
587
+
? `var(--atproto-color-bg)`
588
+
: `var(--atproto-color-text)`,
589
+
}}
590
+
title="Toggle alt text"
591
+
aria-label="Toggle alt text"
592
+
>
593
+
ALT
594
+
</button>
595
+
)}
576
596
</div>
577
-
{image.alt && image.alt.trim().length > 0 && (
597
+
{hasAlt && showAltText && (
578
598
<figcaption
579
599
style={{
580
600
...imagesBase.caption,
···
621
641
caption: {
622
642
fontSize: 12,
623
643
lineHeight: 1.3,
644
+
} satisfies React.CSSProperties,
645
+
altBadge: {
646
+
position: "absolute",
647
+
bottom: 8,
648
+
right: 8,
649
+
padding: "4px 8px",
650
+
fontSize: 10,
651
+
fontWeight: 600,
652
+
letterSpacing: "0.5px",
653
+
border: "none",
654
+
borderRadius: 4,
655
+
cursor: "pointer",
656
+
transition: "background 150ms ease, color 150ms ease",
657
+
fontFamily: "system-ui, sans-serif",
624
658
} satisfies React.CSSProperties,
625
659
};
626
660