diff --git a/src/components/Lightbox/chrome/PagerDots.tsx b/src/components/Lightbox/chrome/PagerDots.tsx
index a5fea5d4de..ea3cbc7f17 100644
--- a/src/components/Lightbox/chrome/PagerDots.tsx
+++ b/src/components/Lightbox/chrome/PagerDots.tsx
@@ -1,6 +1,5 @@
import {StyleSheet, View} from 'react-native'
-
-import {atoms as a} from '#/alf'
+import {BlurView} from 'expo-blur'
type Props = {
count: number
@@ -14,26 +13,38 @@ const GAP = 5
export function PagerDots({count, activeIndex}: Props) {
if (count <= 1) return null
return (
-
- {Array.from({length: count}).map((_, i) => {
- const isActive = i === activeIndex
- return (
-
- )
- })}
+
+
+ {Array.from({length: count}).map((_, i) => {
+ const isActive = i === activeIndex
+ return (
+
+ )
+ })}
+
)
}
const styles = StyleSheet.create({
- row: {
+ root: {
+ borderRadius: 999,
+ overflow: 'hidden',
+ },
+ inner: {
+ flexDirection: 'row',
+ alignItems: 'center',
+ justifyContent: 'center',
gap: GAP,
+ paddingHorizontal: 10,
+ paddingVertical: 6,
+ backgroundColor: 'rgba(0, 0, 0, 0.5)',
},
activeDot: {
width: ACTIVE,
diff --git a/src/components/Lightbox/chrome/PagerDots.web.tsx b/src/components/Lightbox/chrome/PagerDots.web.tsx
new file mode 100644
index 0000000000..370917254f
--- /dev/null
+++ b/src/components/Lightbox/chrome/PagerDots.web.tsx
@@ -0,0 +1,62 @@
+import {StyleSheet, View} from 'react-native'
+
+type Props = {
+ count: number
+ activeIndex: number
+}
+
+const ACTIVE = 6
+const INACTIVE = 4
+const GAP = 5
+
+export function PagerDots({count, activeIndex}: Props) {
+ if (count <= 1) return null
+ return (
+
+ {Array.from({length: count}).map((_, i) => {
+ const isActive = i === activeIndex
+ return (
+
+ )
+ })}
+
+ )
+}
+
+const styles = StyleSheet.create({
+ root: {
+ flexDirection: 'row',
+ alignItems: 'center',
+ justifyContent: 'center',
+ gap: GAP,
+ paddingHorizontal: 10,
+ paddingVertical: 6,
+ borderRadius: 999,
+ backgroundColor: 'rgba(0, 0, 0, 0.75)',
+ // @ts-expect-error web-only
+ backdropFilter: 'blur(8px)',
+ WebkitBackdropFilter: 'blur(8px)',
+ },
+ activeDot: {
+ width: ACTIVE,
+ height: ACTIVE,
+ borderRadius: ACTIVE / 2,
+ },
+ inactiveDot: {
+ width: INACTIVE,
+ height: INACTIVE,
+ borderRadius: INACTIVE / 2,
+ },
+ active: {
+ backgroundColor: '#fff',
+ },
+ inactive: {
+ backgroundColor: 'rgba(255, 255, 255, 0.4)',
+ },
+})
diff --git a/src/components/images/Gallery/index.tsx b/src/components/images/Gallery/index.tsx
index 8f722959cf..58df7fe431 100644
--- a/src/components/images/Gallery/index.tsx
+++ b/src/components/images/Gallery/index.tsx
@@ -165,13 +165,6 @@ export function Gallery({
const containerRefsRef = useRef
)
}
-/*
- * Top-right "{n}/{total}" badge for the in-feed carousel. The visible pill is
- * decorative (accessible={false}) since the digits are redundant for screen
- * reader users.
- *
- * On native, screen reader users never reach this carousel branch - the Gallery
- * renders a separate per-image stack early when screenReaderEnabled is true,
- * and each slide there is labelled "Image N of M". So the live region only
- * needs to exist on web, where screenReaderEnabled is always false and the
- * carousel is the only branch. There we announce position changes via a
- * visually-hidden aria-live region.
- */
-function GalleryCounter({
- currentIndex,
- imageCount,
-}: {
- currentIndex: number
- imageCount: number
-}) {
- const {t: l} = useLingui()
-
- return (
- <>
-
-
- {currentIndex + 1}/{imageCount}
-
-
-
- {IS_WEB ? (
-
- {l`Image ${currentIndex + 1} of ${imageCount}`}
-
- ) : null}
- >
- )
-}
-
function computeDims({
height,
aspectRatio,
@@ -551,6 +483,34 @@ function GalleryImage({
useAppleWebpCodec
/>
+ {!hideBadges && imageCount > 1 ? (
+
+
+ {index + 1}/{imageCount}
+
+
+ ) : null}
+
{(hasAlt || isCropped) && !hideBadges ? (