Prevent image loading flashing in conversation

This commit is contained in:
xmflsct 2023-02-17 22:19:04 +01:00
parent d2eb7156a4
commit 73e4bdb290
7 changed files with 26 additions and 7 deletions

View File

@ -23,6 +23,7 @@ export interface Props {
imageStyle?: ImageStyle imageStyle?: ImageStyle
dim?: boolean dim?: boolean
withoutTransition?: boolean
enableLiveTextInteraction?: boolean enableLiveTextInteraction?: boolean
} }
@ -36,6 +37,7 @@ const GracefullyImage = ({
style, style,
imageStyle, imageStyle,
dim, dim,
withoutTransition = false,
enableLiveTextInteraction = false enableLiveTextInteraction = false
}: Props) => { }: Props) => {
const { reduceMotionEnabled } = useAccessibility() const { reduceMotionEnabled } = useAccessibility()
@ -59,7 +61,7 @@ const GracefullyImage = ({
placeholderContentFit='cover' placeholderContentFit='cover'
placeholder={sources.blurhash || connectMedia(sources.preview)} placeholder={sources.blurhash || connectMedia(sources.preview)}
source={hidden ? undefined : connectMedia(source)} source={hidden ? undefined : connectMedia(source)}
transition={{ duration: 80 }} {...((!withoutTransition || !reduceMotionEnabled) && { transition: { duration: 120 } })}
style={{ flex: 1, ...imageStyle }} style={{ flex: 1, ...imageStyle }}
onError={() => { onError={() => {
if ( if (

View File

@ -5,8 +5,9 @@ import { connectMedia } from '@utils/api/helpers/connect'
import { StyleConstants } from '@utils/styles/constants' import { StyleConstants } from '@utils/styles/constants'
import { useTheme } from '@utils/styles/ThemeManager' import { useTheme } from '@utils/styles/ThemeManager'
import { Audio } from 'expo-av' import { Audio } from 'expo-av'
import React, { useCallback, useEffect, useRef, useState } from 'react' import React, { useCallback, useContext, useEffect, useRef, useState } from 'react'
import { AppState, AppStateStatus, View } from 'react-native' import { AppState, AppStateStatus, View } from 'react-native'
import StatusContext from '../Context'
import AttachmentAltText from './AltText' import AttachmentAltText from './AltText'
import { aspectRatio } from './dimensions' import { aspectRatio } from './dimensions'
@ -18,6 +19,7 @@ export interface Props {
} }
const AttachmentAudio: React.FC<Props> = ({ total, index, sensitiveShown, audio }) => { const AttachmentAudio: React.FC<Props> = ({ total, index, sensitiveShown, audio }) => {
const { inThread } = useContext(StatusContext)
const { colors } = useTheme() const { colors } = useTheme()
const [audioPlayer, setAudioPlayer] = useState<Audio.Sound>() const [audioPlayer, setAudioPlayer] = useState<Audio.Sound>()
@ -88,6 +90,7 @@ const AttachmentAudio: React.FC<Props> = ({ total, index, sensitiveShown, audio
height: '100%' height: '100%'
}} }}
dim dim
withoutTransition={inThread}
/> />
) : null ) : null
) : ( ) : (
@ -100,6 +103,7 @@ const AttachmentAudio: React.FC<Props> = ({ total, index, sensitiveShown, audio
}} }}
style={{ position: 'absolute', width: '100%', height: '100%' }} style={{ position: 'absolute', width: '100%', height: '100%' }}
dim dim
withoutTransition={inThread}
/> />
) : null} ) : null}
<Button <Button

View File

@ -1,8 +1,9 @@
import GracefullyImage from '@components/GracefullyImage' import GracefullyImage from '@components/GracefullyImage'
import { StyleConstants } from '@utils/styles/constants' import { StyleConstants } from '@utils/styles/constants'
import { useTheme } from '@utils/styles/ThemeManager' import { useTheme } from '@utils/styles/ThemeManager'
import React from 'react' import React, { useContext } from 'react'
import { View } from 'react-native' import { View } from 'react-native'
import StatusContext from '../Context'
import AttachmentAltText from './AltText' import AttachmentAltText from './AltText'
import { aspectRatio } from './dimensions' import { aspectRatio } from './dimensions'
@ -21,6 +22,7 @@ const AttachmentImage = ({
image, image,
navigateToImagesViewer navigateToImagesViewer
}: Props) => { }: Props) => {
const { inThread } = useContext(StatusContext)
const { colors } = useTheme() const { colors } = useTheme()
return ( return (
@ -45,6 +47,7 @@ const AttachmentImage = ({
onPress={() => navigateToImagesViewer(image.id)} onPress={() => navigateToImagesViewer(image.id)}
style={{ aspectRatio: aspectRatio({ total, index, ...image.meta?.original }) }} style={{ aspectRatio: aspectRatio({ total, index, ...image.meta?.original }) }}
dim dim
withoutTransition={inThread}
/> />
<AttachmentAltText sensitiveShown={sensitiveShown} text={image.description} /> <AttachmentAltText sensitiveShown={sensitiveShown} text={image.description} />
</View> </View>

View File

@ -4,9 +4,10 @@ import openLink from '@components/openLink'
import CustomText from '@components/Text' import CustomText from '@components/Text'
import { StyleConstants } from '@utils/styles/constants' import { StyleConstants } from '@utils/styles/constants'
import { useTheme } from '@utils/styles/ThemeManager' import { useTheme } from '@utils/styles/ThemeManager'
import React from 'react' import React, { useContext } from 'react'
import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next'
import { View } from 'react-native' import { View } from 'react-native'
import StatusContext from '../Context'
import AttachmentAltText from './AltText' import AttachmentAltText from './AltText'
import { aspectRatio } from './dimensions' import { aspectRatio } from './dimensions'
@ -18,6 +19,7 @@ export interface Props {
} }
const AttachmentUnsupported: React.FC<Props> = ({ total, index, sensitiveShown, attachment }) => { const AttachmentUnsupported: React.FC<Props> = ({ total, index, sensitiveShown, attachment }) => {
const { inThread } = useContext(StatusContext)
const { t } = useTranslation('componentTimeline') const { t } = useTranslation('componentTimeline')
const { colors } = useTheme() const { colors } = useTheme()
@ -36,6 +38,8 @@ const AttachmentUnsupported: React.FC<Props> = ({ total, index, sensitiveShown,
<GracefullyImage <GracefullyImage
sources={{ blurhash: attachment.blurhash }} sources={{ blurhash: attachment.blurhash }}
style={{ position: 'absolute', width: '100%', height: '100%' }} style={{ position: 'absolute', width: '100%', height: '100%' }}
dim
withoutTransition={inThread}
/> />
) : null} ) : null}
{!sensitiveShown ? ( {!sensitiveShown ? (

View File

@ -8,8 +8,9 @@ import { useTheme } from '@utils/styles/ThemeManager'
import { ResizeMode, Video, VideoFullscreenUpdate } from 'expo-av' import { ResizeMode, Video, VideoFullscreenUpdate } from 'expo-av'
import { Platform } from 'expo-modules-core' import { Platform } from 'expo-modules-core'
import * as ScreenOrientation from 'expo-screen-orientation' import * as ScreenOrientation from 'expo-screen-orientation'
import React, { useRef, useState } from 'react' import React, { useContext, useRef, useState } from 'react'
import { Pressable, View } from 'react-native' import { Pressable, View } from 'react-native'
import StatusContext from '../Context'
import AttachmentAltText from './AltText' import AttachmentAltText from './AltText'
import { aspectRatio } from './dimensions' import { aspectRatio } from './dimensions'
@ -28,6 +29,7 @@ const AttachmentVideo: React.FC<Props> = ({
video, video,
gifv = false gifv = false
}) => { }) => {
const { inThread } = useContext(StatusContext)
const { colors } = useTheme() const { colors } = useTheme()
const { reduceMotionEnabled } = useAccessibility() const { reduceMotionEnabled } = useAccessibility()
const [shouldAutoplayGifv] = useGlobalStorage.boolean('app.auto_play_gifv') const [shouldAutoplayGifv] = useGlobalStorage.boolean('app.auto_play_gifv')
@ -127,6 +129,8 @@ const AttachmentVideo: React.FC<Props> = ({
<GracefullyImage <GracefullyImage
sources={{ blurhash: video.blurhash }} sources={{ blurhash: video.blurhash }}
style={{ width: '100%', height: '100%' }} style={{ width: '100%', height: '100%' }}
dim
withoutTransition={inThread}
/> />
) : null ) : null
) : !gifv || (gifv && (reduceMotionEnabled || !shouldAutoplayGifv)) ? ( ) : !gifv || (gifv && (reduceMotionEnabled || !shouldAutoplayGifv)) ? (

View File

@ -12,7 +12,7 @@ export interface Props {
} }
const TimelineAvatar: React.FC<Props> = ({ account }) => { const TimelineAvatar: React.FC<Props> = ({ account }) => {
const { status, highlighted, disableDetails, disableOnPress, isConversation } = const { status, highlighted, disableDetails, disableOnPress, isConversation, inThread } =
useContext(StatusContext) useContext(StatusContext)
const actualAccount = account || status?.account const actualAccount = account || status?.account
if (!actualAccount) return null if (!actualAccount) return null
@ -54,6 +54,7 @@ const TimelineAvatar: React.FC<Props> = ({ account }) => {
marginRight: StyleConstants.Spacing.S marginRight: StyleConstants.Spacing.S
}} }}
dim dim
withoutTransition={inThread}
/> />
) )
} }

View File

@ -16,7 +16,7 @@ import TimelineDefault from '../Default'
import StatusContext from './Context' import StatusContext from './Context'
const TimelineCard: React.FC = () => { const TimelineCard: React.FC = () => {
const { status, spoilerHidden, disableDetails } = useContext(StatusContext) const { status, spoilerHidden, disableDetails, inThread } = useContext(StatusContext)
if (!status || !status.card) return null if (!status || !status.card) return null
const { colors } = useTheme() const { colors } = useTheme()
@ -86,6 +86,7 @@ const TimelineCard: React.FC = () => {
style={{ flexBasis: StyleConstants.Font.LineHeight.M * 5 }} style={{ flexBasis: StyleConstants.Font.LineHeight.M * 5 }}
imageStyle={{ borderTopLeftRadius: 6, borderBottomLeftRadius: 6 }} imageStyle={{ borderTopLeftRadius: 6, borderBottomLeftRadius: 6 }}
dim dim
withoutTransition={inThread}
/> />
) : null} ) : null}
<View style={{ flex: 1, padding: StyleConstants.Spacing.S }}> <View style={{ flex: 1, padding: StyleConstants.Spacing.S }}>