This commit is contained in:
Zhiyuan Zheng 2021-05-09 22:27:12 +02:00
parent 0b659913dc
commit 46b63b33d6
No known key found for this signature in database
GPG Key ID: 078A93AB607D85E0
4 changed files with 91 additions and 30 deletions

View File

@ -3,7 +3,7 @@
"versions": { "versions": {
"native": "210317", "native": "210317",
"major": 1, "major": 1,
"minor": 0, "minor": 1,
"patch": 0, "patch": 0,
"expo": "40.0.0" "expo": "40.0.0"
}, },

View File

@ -10,8 +10,8 @@
"cancel": "$t(common:buttons.cancel)" "cancel": "$t(common:buttons.cancel)"
}, },
"save": { "save": {
"function": "Saving image", "succeed": "Image saved",
"success": "Image saved" "failed": "Saving image failed"
} }
} }
} }

View File

@ -1,28 +1,63 @@
import haptics from '@components/haptics' import haptics from '@components/haptics'
import { displayMessage } from '@components/Message'
import CameraRoll from '@react-native-community/cameraroll' import CameraRoll from '@react-native-community/cameraroll'
import i18next from 'i18next'
import { RefObject } from 'react'
import { Platform } from 'react-native'
import FlashMessage from 'react-native-flash-message'
import { FileSystem, Permissions } from 'react-native-unimodules' import { FileSystem, Permissions } from 'react-native-unimodules'
const saveIos = async ( type CommonProps = {
messageRef: RefObject<FlashMessage>
mode: 'light' | 'dark'
image: Nav.RootStackParamList['Screen-ImagesViewer']['imageUrls'][0] image: Nav.RootStackParamList['Screen-ImagesViewer']['imageUrls'][0]
) => { }
const saveIos = async ({ messageRef, mode, image }: CommonProps) => {
CameraRoll.save(image.url) CameraRoll.save(image.url)
.then(() => { .then(() => {
haptics('Success') haptics('Success')
displayMessage({
ref: messageRef,
mode,
type: 'success',
message: i18next.t('screenImageViewer:content.save.succeed')
})
}) })
.catch(() => { .catch(() => {
if (image.remote_url) { if (image.remote_url) {
CameraRoll.save(image.remote_url) CameraRoll.save(image.remote_url)
.then(() => haptics('Success')) .then(() => {
.catch(() => haptics('Error')) haptics('Success')
displayMessage({
ref: messageRef,
mode,
type: 'success',
message: i18next.t('screenImageViewer:content.save.succeed')
})
})
.catch(() => {
haptics('Error')
displayMessage({
ref: messageRef,
mode,
type: 'error',
message: i18next.t('screenImageViewer:content.save.failed')
})
})
} else { } else {
haptics('Error') haptics('Error')
displayMessage({
ref: messageRef,
mode,
type: 'error',
message: i18next.t('screenImageViewer:content.save.failed')
})
} }
}) })
} }
const saveAndroid = async ( const saveAndroid = async ({ messageRef, mode, image }: CommonProps) => {
image: Nav.RootStackParamList['Screen-ImagesViewer']['imageUrls'][0]
) => {
const fileUri: string = `${FileSystem.documentDirectory}test.jpg` const fileUri: string = `${FileSystem.documentDirectory}test.jpg`
const downloadedFile: FileSystem.FileSystemDownloadResult = await FileSystem.downloadAsync( const downloadedFile: FileSystem.FileSystemDownloadResult = await FileSystem.downloadAsync(
image.url, image.url,
@ -39,8 +74,35 @@ const saveAndroid = async (
} }
CameraRoll.save(downloadedFile.uri) CameraRoll.save(downloadedFile.uri)
.then(() => haptics('Success')) .then(() => {
.catch(() => haptics('Error')) haptics('Success')
displayMessage({
ref: messageRef,
mode,
type: 'success',
message: 'test'
})
})
.catch(() => {
haptics('Error')
displayMessage({
ref: messageRef,
mode,
type: 'error',
message: i18next.t('screenImageViewer:content.save.failed')
})
})
} }
export { saveIos, saveAndroid } const saveImage = async (props: CommonProps) => {
switch (Platform.OS) {
case 'ios':
saveIos(props)
break
case 'android':
saveAndroid(props)
break
}
}
export default saveImage

View File

@ -1,42 +1,35 @@
import analytics from '@components/analytics' import analytics from '@components/analytics'
import { HeaderCenter, HeaderLeft, HeaderRight } from '@components/Header' import { HeaderCenter, HeaderLeft, HeaderRight } from '@components/Header'
import { Message } from '@components/Message'
import { useActionSheet } from '@expo/react-native-action-sheet' import { useActionSheet } from '@expo/react-native-action-sheet'
import { StackScreenProps } from '@react-navigation/stack' import { StackScreenProps } from '@react-navigation/stack'
import { useTheme } from '@utils/styles/ThemeManager'
import { findIndex } from 'lodash' import { findIndex } from 'lodash'
import React, { useCallback, useState } from 'react' import React, { RefObject, useCallback, useRef, useState } from 'react'
import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next'
import { Platform, Share, StatusBar, View } from 'react-native' import { Platform, Share, StatusBar, View } from 'react-native'
import FlashMessage from 'react-native-flash-message'
import { import {
SafeAreaProvider, SafeAreaProvider,
useSafeAreaInsets useSafeAreaInsets
} from 'react-native-safe-area-context' } from 'react-native-safe-area-context'
import ImageViewer from './ImageViewer/Root' import ImageViewer from './ImageViewer/Root'
import { saveAndroid, saveIos } from './ImageViewer/save' import saveImage from './ImageViewer/save'
const saveImage = async (
image: Nav.RootStackParamList['Screen-ImagesViewer']['imageUrls'][0]
) => {
switch (Platform.OS) {
case 'ios':
saveIos(image)
break
case 'android':
saveAndroid(image)
break
}
}
const HeaderComponent = React.memo( const HeaderComponent = React.memo(
({ ({
messageRef,
navigation, navigation,
currentIndex, currentIndex,
imageUrls imageUrls
}: { }: {
messageRef: RefObject<FlashMessage>
navigation: ScreenImagesViewerProp['navigation'] navigation: ScreenImagesViewerProp['navigation']
currentIndex: number currentIndex: number
imageUrls: Nav.RootStackParamList['Screen-ImagesViewer']['imageUrls'] imageUrls: Nav.RootStackParamList['Screen-ImagesViewer']['imageUrls']
}) => { }) => {
const insets = useSafeAreaInsets() const insets = useSafeAreaInsets()
const { mode } = useTheme()
const { t } = useTranslation('screenImageViewer') const { t } = useTranslation('screenImageViewer')
const { showActionSheetWithOptions } = useActionSheet() const { showActionSheetWithOptions } = useActionSheet()
@ -55,7 +48,7 @@ const HeaderComponent = React.memo(
switch (buttonIndex) { switch (buttonIndex) {
case 0: case 0:
analytics('imageviewer_more_save_press') analytics('imageviewer_more_save_press')
saveImage(imageUrls[currentIndex]) saveImage({ messageRef, mode, image: imageUrls[currentIndex] })
break break
case 1: case 1:
analytics('imageviewer_more_share_press') analytics('imageviewer_more_share_press')
@ -121,9 +114,13 @@ const ScreenImagesViewer = ({
return null return null
} }
const { mode } = useTheme()
const initialIndex = findIndex(imageUrls, ['id', id]) const initialIndex = findIndex(imageUrls, ['id', id])
const [currentIndex, setCurrentIndex] = useState(initialIndex) const [currentIndex, setCurrentIndex] = useState(initialIndex)
const messageRef = useRef<FlashMessage>(null)
return ( return (
<SafeAreaProvider> <SafeAreaProvider>
<StatusBar backgroundColor='rgb(0,0,0)' /> <StatusBar backgroundColor='rgb(0,0,0)' />
@ -132,15 +129,17 @@ const ScreenImagesViewer = ({
imageIndex={initialIndex} imageIndex={initialIndex}
onImageIndexChange={index => setCurrentIndex(index)} onImageIndexChange={index => setCurrentIndex(index)}
onRequestClose={() => navigation.goBack()} onRequestClose={() => navigation.goBack()}
onLongPress={saveImage} onLongPress={image => saveImage({ messageRef, mode, image })}
HeaderComponent={() => ( HeaderComponent={() => (
<HeaderComponent <HeaderComponent
messageRef={messageRef}
navigation={navigation} navigation={navigation}
currentIndex={currentIndex} currentIndex={currentIndex}
imageUrls={imageUrls} imageUrls={imageUrls}
/> />
)} )}
/> />
<Message ref={messageRef} />
</SafeAreaProvider> </SafeAreaProvider>
) )
} }