diff --git a/src/state/models/post.ts b/src/state/models/post.ts index 7ecd6228..767182a9 100644 --- a/src/state/models/post.ts +++ b/src/state/models/post.ts @@ -2,6 +2,7 @@ import {makeAutoObservable} from 'mobx' import * as Post from '../../third-party/api/src/client/types/app/bsky/feed/post' import {AtUri} from '../../third-party/uri' import {RootStoreModel} from './root-store' +import {cleanError} from '../../view/lib/strings' export type PostEntities = Post.Record['entities'] export type PostReply = Post.Record['reply'] @@ -67,7 +68,7 @@ export class PostModel implements RemoveIndex { private _xIdle(err: string = '') { this.isLoading = false this.hasLoaded = true - this.error = err + this.error = cleanError(err) } // loader functions @@ -88,7 +89,7 @@ export class PostModel implements RemoveIndex { this._replaceAll(res.value) this._xIdle() } catch (e: any) { - this._xIdle(`Failed to load post: ${e.toString()}`) + this._xIdle(e.toString()) } } diff --git a/src/view/com/post/PostText.tsx b/src/view/com/post/PostText.tsx index 541f2fc1..5d6c4511 100644 --- a/src/view/com/post/PostText.tsx +++ b/src/view/com/post/PostText.tsx @@ -1,6 +1,8 @@ import React, {useState, useEffect} from 'react' import {observer} from 'mobx-react-lite' -import {ActivityIndicator, Text, View} from 'react-native' +import {Text, View} from 'react-native' +import {LoadingPlaceholder} from '../util/LoadingPlaceholder' +import {ErrorMessage} from '../util/ErrorMessage' import {PostModel} from '../../../state/models/post' import {useStores} from '../../../state' @@ -28,7 +30,9 @@ export const PostText = observer(function PostText({ if (!model || model.isLoading || model.uri !== uri) { return ( - + + + ) } @@ -38,7 +42,7 @@ export const PostText = observer(function PostText({ if (model.hasError) { return ( - {model.error} + ) } diff --git a/src/view/com/util/LoadingPlaceholder.tsx b/src/view/com/util/LoadingPlaceholder.tsx new file mode 100644 index 00000000..55b6ad1b --- /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 +}) { + 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 ( + + + + + + ) +} diff --git a/src/view/com/util/UserInfoText.tsx b/src/view/com/util/UserInfoText.tsx index f4dbd1fa..d1292cc7 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 = {failed} + } else if (profile) { + inner = {`${prefix || ''}${profile[attr]}`} + } else { + inner = ( + + ) + } + if (asLink) { const title = profile?.displayName || profile?.handle || 'User' return ( - - {didFail - ? failed - : profile - ? `${prefix || ''}${profile[attr]}` - : loading} - + {inner} ) } - return ( - - {didFail ? failed : profile ? `${prefix || ''}${profile[attr]}` : loading} - - ) + return inner }