tooot/src/screens/Shared/ImagesViewer.tsx

132 lines
3.7 KiB
TypeScript
Raw Normal View History

2020-12-30 14:33:33 +01:00
import haptics from '@root/components/haptics'
2020-12-25 18:20:09 +01:00
import { HeaderLeft, HeaderRight } from '@root/components/Header'
import { StyleConstants } from '@root/utils/styles/constants'
import { findIndex } from 'lodash'
import React, { useCallback, useState } from 'react'
import { ActionSheetIOS, Image, StyleSheet, Text } from 'react-native'
import ImageViewer from 'react-native-image-zoom-viewer'
import { IImageInfo } from 'react-native-image-zoom-viewer/built/image-viewer.type'
import { useSafeAreaInsets } from 'react-native-safe-area-context'
import { createNativeStackNavigator } from 'react-native-screens/native-stack'
const Stack = createNativeStackNavigator()
export interface Props {
route: {
params: {
imageUrls: (IImageInfo & {
preview_url: Mastodon.AttachmentImage['preview_url']
remote_url: Mastodon.AttachmentImage['remote_url']
imageIndex: number
})[]
imageIndex: number
}
}
}
const TheImage = ({
style,
source,
imageUrls,
imageIndex
}: {
style: any
source: { uri: string }
imageUrls: (IImageInfo & {
preview_url: Mastodon.AttachmentImage['preview_url']
remote_url: Mastodon.AttachmentImage['remote_url']
imageIndex: number
})[]
imageIndex: number
}) => {
const [imageVisible, setImageVisible] = useState(false)
Image.getSize(source.uri, () => setImageVisible(true))
return (
<Image
style={style}
source={{
uri: imageVisible
? source.uri
: imageUrls[findIndex(imageUrls, ['imageIndex', imageIndex])]
.preview_url
}}
/>
)
}
const ScreenSharedImagesViewer: React.FC<Props> = ({
route: {
params: { imageUrls, imageIndex }
},
navigation
}) => {
const safeAreaInsets = useSafeAreaInsets()
const initialIndex = findIndex(imageUrls, ['imageIndex', imageIndex])
const [currentIndex, setCurrentIndex] = useState(initialIndex)
const component = useCallback(
() => (
<ImageViewer
style={{ flex: 1, marginBottom: 44 + safeAreaInsets.bottom }}
imageUrls={imageUrls}
index={initialIndex}
onSwipeDown={() => navigation.goBack()}
enableSwipeDown={true}
swipeDownThreshold={100}
useNativeDriver={true}
saveToLocalByLongPress={false}
renderIndicator={() => <></>}
onChange={index => index !== undefined && setCurrentIndex(index)}
renderImage={props => (
<TheImage {...props} imageUrls={imageUrls} imageIndex={imageIndex} />
)}
/>
),
[]
)
return (
2020-12-25 21:51:46 +01:00
<Stack.Navigator screenOptions={{ headerHideShadow: true }}>
2020-12-25 18:20:09 +01:00
<Stack.Screen
name='Screen-Shared-ImagesViewer-Root'
component={component}
options={{
contentStyle: { backgroundColor: 'black' },
headerStyle: { backgroundColor: 'black' },
headerLeft: () => (
<HeaderLeft content='X' onPress={() => navigation.goBack()} />
2020-12-25 18:20:09 +01:00
),
headerCenter: () => (
<Text style={styles.headerCenter}>
{currentIndex + 1} / {imageUrls.length}
</Text>
),
headerRight: () => (
<HeaderRight
content='Share'
2020-12-25 18:20:09 +01:00
onPress={() =>
ActionSheetIOS.showShareActionSheetWithOptions(
{
url: imageUrls[currentIndex].url
},
2021-01-01 16:48:16 +01:00
() => haptics('Error'),
() => haptics('Success')
2020-12-25 18:20:09 +01:00
)
}
/>
)
}}
/>
</Stack.Navigator>
)
}
const styles = StyleSheet.create({
headerCenter: {
color: 'white',
...StyleConstants.FontStyle.M
2020-12-25 18:20:09 +01:00
}
})
export default React.memo(ScreenSharedImagesViewer, () => true)