From d97e75c62f39b874af97b40ebc7211841d9ce1b7 Mon Sep 17 00:00:00 2001
From: Paul Frazee <pfrazee@gmail.com>
Date: Thu, 4 May 2023 00:54:35 -0500
Subject: [APP-539] Rework lightbox and alt-image behaviors (#573)

* Replace the long press on the lightbox with footer controls

* Remove long-press from images in the feed

* Tune the lightbox footer control ui

* Replace the AltImageRead modal with the ability to view all alt text in the lightbox footer

* Tune lightbox footer for iOS

* Add alt text to the web lightbox

* Fix lint

* a11y slight changes

---------

Co-authored-by: renahlee <renahlee@outlook.com>
---
 src/view/com/lightbox/Lightbox.tsx | 106 ++++++++++++++++++++++++++++++-------
 1 file changed, 87 insertions(+), 19 deletions(-)

(limited to 'src/view/com/lightbox/Lightbox.tsx')

diff --git a/src/view/com/lightbox/Lightbox.tsx b/src/view/com/lightbox/Lightbox.tsx
index 06b48143b..c4bc88cf1 100644
--- a/src/view/com/lightbox/Lightbox.tsx
+++ b/src/view/com/lightbox/Lightbox.tsx
@@ -1,31 +1,75 @@
 import React from 'react'
+import {Pressable, StyleSheet, View} from 'react-native'
 import {observer} from 'mobx-react-lite'
+import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome'
 import ImageView from './ImageViewing'
 import {useStores} from 'state/index'
 import * as models from 'state/models/ui/shell'
 import {saveImageModal} from 'lib/media/manip'
-import {ImageSource} from './ImageViewing/@types'
+import {Text} from '../util/text/Text'
+import {s, colors} from 'lib/styles'
+import {Button} from '../util/forms/Button'
+import {isIOS} from 'platform/detection'
 
 export const Lightbox = observer(function Lightbox() {
   const store = useStores()
-  if (!store.shell.isLightboxActive) {
-    return null
-  }
+  const [isAltExpanded, setAltExpanded] = React.useState(false)
 
-  const onClose = () => {
+  const onClose = React.useCallback(() => {
     store.shell.closeLightbox()
-  }
-  const onLongPress = (image: ImageSource) => {
-    if (
-      typeof image === 'object' &&
-      'uri' in image &&
-      typeof image.uri === 'string'
-    ) {
-      saveImageModal({uri: image.uri})
-    }
-  }
+  }, [store])
+
+  const LightboxFooter = React.useCallback(
+    ({imageIndex}: {imageIndex: number}) => {
+      const lightbox = store.shell.activeLightbox
+      if (!lightbox) {
+        return null
+      }
 
-  if (store.shell.activeLightbox?.name === 'profile-image') {
+      let altText = ''
+      let uri
+      if (lightbox.name === 'images') {
+        const opts = store.shell.activeLightbox as models.ImagesLightbox
+        uri = opts.images[imageIndex].uri
+        altText = opts.images[imageIndex].alt
+      } else if (store.shell.activeLightbox.name === 'profile-image') {
+        const opts = store.shell.activeLightbox as models.ProfileImageLightbox
+        uri = opts.profileView.avatar
+      }
+
+      return (
+        <View style={[styles.footer]}>
+          {altText ? (
+            <Pressable
+              onPress={() => setAltExpanded(!isAltExpanded)}
+              accessibilityRole="button">
+              <Text
+                style={[s.gray3, styles.footerText]}
+                numberOfLines={isAltExpanded ? undefined : 3}>
+                {altText}
+              </Text>
+            </Pressable>
+          ) : null}
+          <View style={styles.footerBtns}>
+            <Button
+              type="primary-outline"
+              style={styles.footerBtn}
+              onPress={() => saveImageModal({uri})}>
+              <FontAwesomeIcon icon="arrow-up-from-bracket" style={s.white} />
+              <Text type="xl" style={s.white}>
+                Share
+              </Text>
+            </Button>
+          </View>
+        </View>
+      )
+    },
+    [store.shell.activeLightbox, isAltExpanded, setAltExpanded],
+  )
+
+  if (!store.shell.activeLightbox) {
+    return null
+  } else if (store.shell.activeLightbox.name === 'profile-image') {
     const opts = store.shell.activeLightbox as models.ProfileImageLightbox
     return (
       <ImageView
@@ -33,20 +77,44 @@ export const Lightbox = observer(function Lightbox() {
         imageIndex={0}
         visible
         onRequestClose={onClose}
+        FooterComponent={LightboxFooter}
       />
     )
-  } else if (store.shell.activeLightbox?.name === 'images') {
+  } else if (store.shell.activeLightbox.name === 'images') {
     const opts = store.shell.activeLightbox as models.ImagesLightbox
     return (
       <ImageView
-        images={opts.uris.map(uri => ({uri}))}
+        images={opts.images.map(({uri}) => ({uri}))}
         imageIndex={opts.index}
         visible
         onRequestClose={onClose}
-        onLongPress={onLongPress}
+        FooterComponent={LightboxFooter}
       />
     )
   } else {
     return null
   }
 })
+
+const styles = StyleSheet.create({
+  footer: {
+    paddingTop: 16,
+    paddingBottom: isIOS ? 40 : 24,
+    paddingHorizontal: 24,
+    backgroundColor: '#000d',
+  },
+  footerText: {
+    paddingBottom: isIOS ? 20 : 16,
+  },
+  footerBtns: {
+    flexDirection: 'row',
+    justifyContent: 'center',
+  },
+  footerBtn: {
+    flexDirection: 'row',
+    alignItems: 'center',
+    gap: 8,
+    backgroundColor: 'transparent',
+    borderColor: colors.white,
+  },
+})
-- 
cgit 1.4.1

