diff options
author | Paul Frazee <pfrazee@gmail.com> | 2023-01-26 21:54:47 -0600 |
---|---|---|
committer | Paul Frazee <pfrazee@gmail.com> | 2023-01-26 21:54:47 -0600 |
commit | 20eaac6acd9e7b310ace864f6661c1a0e3ea169b (patch) | |
tree | b1a4711bb939d07781c38073bf56c63a0ad877e8 /src/view/com/lightbox/Lightbox.web.tsx | |
parent | 883d5749ed41608d6934217df315826002769e85 (diff) | |
download | voidsky-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.tsx | 121 |
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%', + }, +}) |