Improve loading remote images

This commit is contained in:
Zhiyuan Zheng 2021-05-30 22:12:22 +02:00
parent ecb9ce0c3a
commit 8aa84f7568
5 changed files with 32 additions and 33 deletions

View File

@ -1,5 +1,5 @@
import { useTheme } from '@utils/styles/ThemeManager' import { useTheme } from '@utils/styles/ThemeManager'
import React, { useCallback, useMemo, useRef, useState } from 'react' import React, { useCallback, useMemo, useState } from 'react'
import { import {
AccessibilityProps, AccessibilityProps,
Image, Image,
@ -52,32 +52,30 @@ const GracefullyImage = React.memo(
setImageDimensions setImageDimensions
}: Props) => { }: Props) => {
const { theme } = useTheme() const { theme } = useTheme()
const originalFailed = useRef(false) const [originalFailed, setOriginalFailed] = useState(false)
const [imageLoaded, setImageLoaded] = useState(false) const [imageLoaded, setImageLoaded] = useState(false)
const source = useMemo(() => { const source = useMemo(() => {
if (originalFailed.current) { if (originalFailed) {
return { uri: uri.remote || undefined } return { uri: uri.remote || undefined }
} else { } else {
return { uri: uri.original } return { uri: uri.original }
} }
}, [originalFailed.current]) }, [originalFailed])
const onLoad = useCallback(
({ nativeEvent }) => { const onLoad = useCallback(() => {
setImageLoaded(true) setImageLoaded(true)
setImageDimensions && if (setImageDimensions && source.uri) {
setImageDimensions({ Image.getSize(source.uri, (width, height) =>
width: nativeEvent.source.width, setImageDimensions({ width, height })
height: nativeEvent.source.height )
})
},
[source.uri]
)
const onError = useCallback(() => {
if (!originalFailed.current) {
originalFailed.current = true
} }
}, [originalFailed.current]) }, [source.uri])
const onError = useCallback(() => {
if (!originalFailed) {
setOriginalFailed(true)
}
}, [originalFailed])
const previewView = useMemo( const previewView = useMemo(
() => () =>

View File

@ -76,11 +76,10 @@ const ParseEmojis = React.memo(
: emojis[emojiIndex].url : emojis[emojiIndex].url
if (validUrl.isHttpsUri(uri)) { if (validUrl.isHttpsUri(uri)) {
return ( return (
<FastImage <Text key={emojiShortcode + i}>
key={emojiShortcode + i} {i === 0 ? ' ' : undefined}
source={{ uri }} <FastImage source={{ uri }} style={styles.image} />
style={styles.image} </Text>
/>
) )
} else { } else {
return null return null

View File

@ -8,7 +8,7 @@ import AttachmentVideo from '@components/Timeline/Shared/Attachment/Video'
import { useNavigation } from '@react-navigation/native' import { useNavigation } from '@react-navigation/native'
import { StyleConstants } from '@utils/styles/constants' import { StyleConstants } from '@utils/styles/constants'
import layoutAnimation from '@utils/styles/layoutAnimation' import layoutAnimation from '@utils/styles/layoutAnimation'
import React, { useCallback, useMemo, useState } from 'react' import React, { useCallback, useMemo, useRef, useState } from 'react'
import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next'
import { Pressable, StyleSheet, View } from 'react-native' import { Pressable, StyleSheet, View } from 'react-native'
@ -33,11 +33,13 @@ const TimelineAttachment = React.memo(
haptics('Light') haptics('Light')
}, []) }, [])
let imageUrls: Nav.RootStackParamList['Screen-ImagesViewer']['imageUrls'] = [] const imageUrls = useRef<
Nav.RootStackParamList['Screen-ImagesViewer']['imageUrls']
>([])
const navigation = useNavigation() const navigation = useNavigation()
const navigateToImagesViewer = (id: string) => const navigateToImagesViewer = (id: string) =>
navigation.navigate('Screen-ImagesViewer', { navigation.navigate('Screen-ImagesViewer', {
imageUrls, imageUrls: imageUrls.current,
id id
}) })
const attachments = useMemo( const attachments = useMemo(
@ -45,7 +47,7 @@ const TimelineAttachment = React.memo(
status.media_attachments.map((attachment, index) => { status.media_attachments.map((attachment, index) => {
switch (attachment.type) { switch (attachment.type) {
case 'image': case 'image':
imageUrls.push({ imageUrls.current.push({
id: attachment.id, id: attachment.id,
preview_url: attachment.preview_url, preview_url: attachment.preview_url,
url: attachment.url, url: attachment.url,
@ -106,7 +108,7 @@ const TimelineAttachment = React.memo(
attachment.remote_url?.endsWith('.png') || attachment.remote_url?.endsWith('.png') ||
attachment.remote_url?.endsWith('.gif') attachment.remote_url?.endsWith('.gif')
) { ) {
imageUrls.push({ imageUrls.current.push({
id: attachment.id, id: attachment.id,
preview_url: attachment.preview_url, preview_url: attachment.preview_url,
url: attachment.url, url: attachment.url,

View File

@ -52,8 +52,8 @@ const ImageItem = ({
const scrollViewRef = useRef<ScrollView>(null) const scrollViewRef = useRef<ScrollView>(null)
const [scaled, setScaled] = useState(false) const [scaled, setScaled] = useState(false)
const [imageDimensions, setImageDimensions] = useState({ const [imageDimensions, setImageDimensions] = useState({
width: imageSrc.width || 0, width: imageSrc.width || 1,
height: imageSrc.height || 0 height: imageSrc.height || 1
}) })
const handleDoubleTap = useDoubleTapToZoom(scrollViewRef, scaled, SCREEN) const handleDoubleTap = useDoubleTapToZoom(scrollViewRef, scaled, SCREEN)

View File

@ -58,7 +58,7 @@ const saveIos = async ({ messageRef, mode, image }: CommonProps) => {
} }
const saveAndroid = async ({ messageRef, mode, image }: CommonProps) => { const saveAndroid = async ({ messageRef, mode, image }: CommonProps) => {
const fileUri: string = `${FileSystem.documentDirectory}test.jpg` const fileUri: string = `${FileSystem.documentDirectory}${image.id}.jpg`
const downloadedFile: FileSystem.FileSystemDownloadResult = await FileSystem.downloadAsync( const downloadedFile: FileSystem.FileSystemDownloadResult = await FileSystem.downloadAsync(
image.url, image.url,
fileUri fileUri
@ -80,7 +80,7 @@ const saveAndroid = async ({ messageRef, mode, image }: CommonProps) => {
ref: messageRef, ref: messageRef,
mode, mode,
type: 'success', type: 'success',
message: 'test' message: i18next.t('screenImageViewer:content.save.succeed')
}) })
}) })
.catch(() => { .catch(() => {