From b449ab842fc64177f8ba1e17199911f02cb99526 Mon Sep 17 00:00:00 2001 From: Paul Frazee Date: Tue, 17 Jan 2023 19:34:12 -0600 Subject: Switch to a better lightbox implementation (close #42) --- src/state/models/shell-ui.ts | 43 +-------- src/view/com/composer/PhotoCarouselPicker.tsx | 7 +- src/view/com/lightbox/Lightbox.tsx | 131 ++++---------------------- src/view/com/profile/ProfileHeader.tsx | 31 +++--- 4 files changed, 45 insertions(+), 167 deletions(-) (limited to 'src') diff --git a/src/state/models/shell-ui.ts b/src/state/models/shell-ui.ts index 1af74f56a..7628e068f 100644 --- a/src/state/models/shell-ui.ts +++ b/src/state/models/shell-ui.ts @@ -52,55 +52,22 @@ export class ReportAccountModal { } } -interface LightboxModel { - canSwipeLeft: boolean - canSwipeRight: boolean - onSwipeLeft: () => void - onSwipeRight: () => void -} +interface LightboxModel {} export class ProfileImageLightbox implements LightboxModel { name = 'profile-image' - canSwipeLeft = false - canSwipeRight = false constructor(public profileView: ProfileViewModel) { makeAutoObservable(this) } - onSwipeLeft() {} - onSwipeRight() {} -} - -export class ImageLightbox implements LightboxModel { - name = 'image' - canSwipeLeft = true - canSwipeRight = true - constructor(public uri: string) { - makeAutoObservable(this) - } - onSwipeLeft() {} - onSwipeRight() {} } export class ImagesLightbox implements LightboxModel { name = 'images' - get canSwipeLeft() { - return this.index > 0 - } - get canSwipeRight() { - return this.index < this.uris.length - 1 - } constructor(public uris: string[], public index: number) { makeAutoObservable(this) } - onSwipeLeft() { - if (this.canSwipeLeft) { - this.index = this.index - 1 - } - } - onSwipeRight() { - if (this.canSwipeRight) { - this.index = this.index + 1 - } + setIndex(index: number) { + this.index = index } } @@ -187,9 +154,7 @@ export class ShellUiModel { this.activeModal = undefined } - openLightbox( - lightbox: ProfileImageLightbox | ImageLightbox | ImagesLightbox, - ) { + openLightbox(lightbox: ProfileImageLightbox | ImagesLightbox) { this.isLightboxActive = true this.activeLightbox = lightbox } diff --git a/src/view/com/composer/PhotoCarouselPicker.tsx b/src/view/com/composer/PhotoCarouselPicker.tsx index 64f34a0b7..440e7d38f 100644 --- a/src/view/com/composer/PhotoCarouselPicker.tsx +++ b/src/view/com/composer/PhotoCarouselPicker.tsx @@ -16,6 +16,7 @@ import {useStores} from '../../../state' const MAX_WIDTH = 1000 const MAX_HEIGHT = 1000 +const MAX_SIZE = 300000 const IMAGE_PARAMS = { width: 1000, @@ -43,7 +44,7 @@ export const PhotoCarouselPicker = ({ cropping: true, ...IMAGE_PARAMS, }) - const img = await compressIfNeeded(cameraRes, 300000) + const img = await compressIfNeeded(cameraRes, MAX_SIZE) onSelectPhotos([...selectedPhotos, img.path]) } catch (err: any) { // ignore @@ -67,7 +68,7 @@ export const PhotoCarouselPicker = ({ width, height, }) - const img = await compressIfNeeded(cropperRes, 300000) + const img = await compressIfNeeded(cropperRes, MAX_SIZE) onSelectPhotos([...selectedPhotos, img.path]) } catch (err: any) { // ignore @@ -99,7 +100,7 @@ export const PhotoCarouselPicker = ({ width, height, }) - const finalImg = await compressIfNeeded(cropperRes, 300000) + const finalImg = await compressIfNeeded(cropperRes, MAX_SIZE) result.push(finalImg.path) } onSelectPhotos([...selectedPhotos, ...result]) diff --git a/src/view/com/lightbox/Lightbox.tsx b/src/view/com/lightbox/Lightbox.tsx index 849354aea..ed4cf90b8 100644 --- a/src/view/com/lightbox/Lightbox.tsx +++ b/src/view/com/lightbox/Lightbox.tsx @@ -1,139 +1,42 @@ -import React, {useState} from 'react' -import { - Animated, - StyleSheet, - TouchableWithoutFeedback, - useWindowDimensions, - View, -} from 'react-native' +import React from 'react' +import {View} from 'react-native' import {observer} from 'mobx-react-lite' -import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome' -import {SwipeAndZoom, Dir} from '../util/gestures/SwipeAndZoom' +import ImageView from 'react-native-image-viewing' import {useStores} from '../../../state' -import {useAnimatedValue} from '../../lib/hooks/useAnimatedValue' import * as models from '../../../state/models/shell-ui' -import * as ProfileImageLightbox from './ProfileImage' -import * as ImageLightbox from './Image' -import * as ImagesLightbox from './Images' - export const Lightbox = observer(function Lightbox() { const store = useStores() - const winDim = useWindowDimensions() - const [isZooming, setIsZooming] = useState(false) - const panX = useAnimatedValue(0) - const panY = useAnimatedValue(0) - const zoom = useAnimatedValue(0) - const onClose = () => { store.shell.closeLightbox() } - const onSwipeStartDirection = (dir: Dir) => { - setIsZooming(dir === Dir.Zoom) - } - const onSwipeEnd = (dir: Dir) => { - if (dir === Dir.Up || dir === Dir.Down) { - onClose() - } else if (dir === Dir.Left) { - store.shell.activeLightbox?.onSwipeLeft() - } else if (dir === Dir.Right) { - store.shell.activeLightbox?.onSwipeRight() - } - } if (!store.shell.isLightboxActive) { return } - let element if (store.shell.activeLightbox?.name === 'profile-image') { - element = ( - - ) - } else if (store.shell.activeLightbox?.name === 'image') { - element = ( - ) } else if (store.shell.activeLightbox?.name === 'images') { - element = ( - ({uri}))} + imageIndex={opts.index} + visible + onRequestClose={onClose} /> ) } else { return } - - const translateX = Animated.multiply(panX, winDim.width * -1) - const translateY = Animated.multiply(panY, winDim.height * -1) - const scale = Animated.add(zoom, 1) - const swipeTransform = { - transform: [ - {translateY: winDim.height / 2}, - {scale}, - {translateY: winDim.height / -2}, - {translateX}, - {translateY}, - ], - } - const swipeOpacity = { - opacity: panY.interpolate({ - inputRange: [-1, 0, 1], - outputRange: [0, 1, 0], - }), - } - - return ( - - - - - - - - - - - {element} - - - ) -}) - -const styles = StyleSheet.create({ - bg: { - position: 'absolute', - top: 0, - left: 0, - bottom: 0, - right: 0, - backgroundColor: '#000', - opacity: 0.9, - }, - xIcon: { - position: 'absolute', - top: 30, - right: 30, - }, - container: { - position: 'absolute', - }, }) diff --git a/src/view/com/profile/ProfileHeader.tsx b/src/view/com/profile/ProfileHeader.tsx index d9151afd0..52a4400a5 100644 --- a/src/view/com/profile/ProfileHeader.tsx +++ b/src/view/com/profile/ProfileHeader.tsx @@ -1,6 +1,11 @@ import React from 'react' import {observer} from 'mobx-react-lite' -import {StyleSheet, TouchableOpacity, View} from 'react-native' +import { + StyleSheet, + TouchableOpacity, + TouchableWithoutFeedback, + View, +} from 'react-native' import LinearGradient from 'react-native-linear-gradient' import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome' import {ProfileViewModel} from '../../../state/models/profile-view' @@ -33,7 +38,9 @@ export const ProfileHeader = observer(function ProfileHeader({ const store = useStores() const onPressAvi = () => { - store.shell.openLightbox(new ProfileImageLightbox(view)) + if (view.avatar) { + store.shell.openLightbox(new ProfileImageLightbox(view)) + } } const onPressToggleFollow = () => { view?.toggleFollowing().then( @@ -254,17 +261,19 @@ export const ProfileHeader = observer(function ProfileHeader({ ) : undefined} - - - + + + + ) }) -- cgit 1.4.1