diff options
Diffstat (limited to 'src/view/com/util')
-rw-r--r-- | src/view/com/util/LoadingPlaceholder.tsx | 73 | ||||
-rw-r--r-- | src/view/com/util/UserInfoText.tsx | 30 |
2 files changed, 91 insertions, 12 deletions
diff --git a/src/view/com/util/LoadingPlaceholder.tsx b/src/view/com/util/LoadingPlaceholder.tsx new file mode 100644 index 000000000..55b6ad1b3 --- /dev/null +++ b/src/view/com/util/LoadingPlaceholder.tsx @@ -0,0 +1,73 @@ +import React, {useEffect, useMemo} from 'react' +import { + Animated, + StyleProp, + useWindowDimensions, + View, + ViewStyle, +} from 'react-native' +import LinearGradient from 'react-native-linear-gradient' +import {colors} from '../../lib/styles' + +export function LoadingPlaceholder({ + width, + height, + style, +}: { + width: string | number + height: string | number + style?: StyleProp<ViewStyle> +}) { + const dim = useWindowDimensions() + const elWidth = typeof width === 'string' ? dim.width : width + const offset = useMemo(() => new Animated.Value(elWidth * -1), []) + useEffect(() => { + const anim = Animated.loop( + Animated.sequence([ + Animated.timing(offset, { + toValue: elWidth, + duration: 1e3, + useNativeDriver: true, + isInteraction: false, + }), + Animated.timing(offset, { + toValue: elWidth * -1, + duration: 0, + delay: 500, + useNativeDriver: true, + isInteraction: false, + }), + ]), + ) + anim.start() + return () => anim.stop() + }, []) + + return ( + <View + style={[ + { + width, + height, + backgroundColor: colors.gray2, + borderRadius: 6, + overflow: 'hidden', + }, + style, + ]}> + <Animated.View + style={{ + width, + height, + transform: [{translateX: offset}], + }}> + <LinearGradient + colors={[colors.gray2, '#d4d2d2', colors.gray2]} + start={{x: 0, y: 0}} + end={{x: 1, y: 0}} + style={{width: '100%', height: '100%'}} + /> + </Animated.View> + </View> + ) +} diff --git a/src/view/com/util/UserInfoText.tsx b/src/view/com/util/UserInfoText.tsx index f4dbd1fa4..d1292cc70 100644 --- a/src/view/com/util/UserInfoText.tsx +++ b/src/view/com/util/UserInfoText.tsx @@ -2,6 +2,7 @@ import React, {useState, useEffect} from 'react' import * as GetProfile from '../../../third-party/api/src/client/types/app/bsky/actor/getProfile' import {StyleProp, Text, TextStyle} from 'react-native' import {Link} from './Link' +import {LoadingPlaceholder} from './LoadingPlaceholder' import {useStores} from '../../../state' export function UserInfoText({ @@ -48,26 +49,31 @@ export function UserInfoText({ } }, [did, store.api.app.bsky]) + let inner + if (didFail) { + inner = <Text style={style}>{failed}</Text> + } else if (profile) { + inner = <Text style={style}>{`${prefix || ''}${profile[attr]}`}</Text> + } else { + inner = ( + <LoadingPlaceholder + width={80} + height={8} + style={{position: 'relative', top: 1, left: 2}} + /> + ) + } + if (asLink) { const title = profile?.displayName || profile?.handle || 'User' return ( <Link href={`/profile/${profile?.handle ? profile.handle : did}`} title={title}> - <Text style={style}> - {didFail - ? failed - : profile - ? `${prefix || ''}${profile[attr]}` - : loading} - </Text> + {inner} </Link> ) } - return ( - <Text style={style}> - {didFail ? failed : profile ? `${prefix || ''}${profile[attr]}` : loading} - </Text> - ) + return inner } |