about summary refs log tree commit diff
path: root/src/view/com/lightbox/Lightbox.web.tsx
diff options
context:
space:
mode:
authorPaul Frazee <pfrazee@gmail.com>2023-01-26 21:54:47 -0600
committerPaul Frazee <pfrazee@gmail.com>2023-01-26 21:54:47 -0600
commit20eaac6acd9e7b310ace864f6661c1a0e3ea169b (patch)
treeb1a4711bb939d07781c38073bf56c63a0ad877e8 /src/view/com/lightbox/Lightbox.web.tsx
parent883d5749ed41608d6934217df315826002769e85 (diff)
downloadvoidsky-20eaac6acd9e7b310ace864f6661c1a0e3ea169b.tar.zst
Add lightbox for web
Diffstat (limited to 'src/view/com/lightbox/Lightbox.web.tsx')
-rw-r--r--src/view/com/lightbox/Lightbox.web.tsx121
1 files changed, 121 insertions, 0 deletions
diff --git a/src/view/com/lightbox/Lightbox.web.tsx b/src/view/com/lightbox/Lightbox.web.tsx
new file mode 100644
index 000000000..4062ddef7
--- /dev/null
+++ b/src/view/com/lightbox/Lightbox.web.tsx
@@ -0,0 +1,121 @@
+import React from 'react'
+import {
+  Image,
+  TouchableOpacity,
+  TouchableWithoutFeedback,
+  StyleSheet,
+  View,
+} from 'react-native'
+import {observer} from 'mobx-react-lite'
+import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome'
+import {useStores} from '../../../state'
+import * as models from '../../../state/models/shell-ui'
+import {colors} from '../../lib/styles'
+
+interface Img {
+  uri: string
+}
+
+export const Lightbox = observer(function Lightbox() {
+  const store = useStores()
+  if (!store.shell.isLightboxActive) {
+    return null
+  }
+
+  const onClose = () => store.shell.closeLightbox()
+
+  let imgs: Img[] | undefined
+  if (store.shell.activeLightbox?.name === 'profile-image') {
+    const opts = store.shell.activeLightbox as models.ProfileImageLightbox
+    if (opts.profileView.avatar) {
+      imgs = [{uri: opts.profileView.avatar}]
+    }
+  } else if (store.shell.activeLightbox?.name === 'images') {
+    const opts = store.shell.activeLightbox as models.ImagesLightbox
+    imgs = opts.uris.map(uri => ({uri}))
+  }
+
+  if (!imgs) {
+    return null
+  }
+
+  return <LightboxInner imgs={imgs} onClose={onClose} />
+})
+
+function LightboxInner({imgs, onClose}: {imgs: Img[]; onClose: () => void}) {
+  const [index, setIndex] = React.useState<number>(0)
+
+  const canGoLeft = index >= 1
+  const canGoRight = index < imgs.length - 1
+  const onPressLeft = () => {
+    if (canGoLeft) {
+      setIndex(index - 1)
+    }
+  }
+  const onPressRight = () => {
+    if (canGoRight) {
+      setIndex(index + 1)
+    }
+  }
+
+  return (
+    <TouchableWithoutFeedback onPress={onClose}>
+      <View style={styles.mask}>
+        <Image source={imgs[index]} style={styles.image} />
+        {canGoLeft && (
+          <TouchableOpacity
+            onPress={onPressLeft}
+            style={[styles.btn, styles.leftBtn]}>
+            <FontAwesomeIcon icon="angle-left" style={styles.icon} size={40} />
+          </TouchableOpacity>
+        )}
+        {canGoRight && (
+          <TouchableOpacity
+            onPress={onPressRight}
+            style={[styles.btn, styles.rightBtn]}>
+            <FontAwesomeIcon icon="angle-right" style={styles.icon} size={40} />
+          </TouchableOpacity>
+        )}
+      </View>
+    </TouchableWithoutFeedback>
+  )
+}
+
+const styles = StyleSheet.create({
+  mask: {
+    position: 'absolute',
+    top: 0,
+    left: 0,
+    width: '100%',
+    height: '100%',
+    backgroundColor: '#000c',
+    alignItems: 'center',
+    justifyContent: 'center',
+  },
+  image: {
+    width: '100%',
+    height: '100%',
+    resizeMode: 'contain',
+  },
+  icon: {
+    color: colors.white,
+  },
+  btn: {
+    position: 'absolute',
+    backgroundColor: '#000',
+    width: 50,
+    height: 50,
+    justifyContent: 'center',
+    alignItems: 'center',
+    borderRadius: 25,
+  },
+  leftBtn: {
+    left: 30,
+    top: '50%',
+  },
+  rightBtn: {
+    position: 'absolute',
+    right: 30,
+    top: '50%',
+  },
+})