diff options
Diffstat (limited to 'src/view')
-rw-r--r-- | src/view/com/notifications/Feed.tsx | 12 | ||||
-rw-r--r-- | src/view/com/post-thread/PostRepostedBy.tsx | 21 | ||||
-rw-r--r-- | src/view/com/post-thread/PostThread.tsx | 8 | ||||
-rw-r--r-- | src/view/com/post-thread/PostVotedBy.tsx | 12 | ||||
-rw-r--r-- | src/view/com/posts/Feed.tsx | 18 | ||||
-rw-r--r-- | src/view/com/profile/ProfileFollowers.tsx | 12 | ||||
-rw-r--r-- | src/view/com/profile/ProfileFollows.tsx | 12 | ||||
-rw-r--r-- | src/view/com/profile/ProfileMembers.tsx | 14 | ||||
-rw-r--r-- | src/view/com/util/ErrorMessage.tsx | 51 | ||||
-rw-r--r-- | src/view/lib/strings.ts | 7 | ||||
-rw-r--r-- | src/view/lib/styles.ts | 1 | ||||
-rw-r--r-- | src/view/screens/Home.tsx | 4 | ||||
-rw-r--r-- | src/view/screens/Notifications.tsx | 6 |
13 files changed, 150 insertions, 28 deletions
diff --git a/src/view/com/notifications/Feed.tsx b/src/view/com/notifications/Feed.tsx index a3cac0cdf..2b7bb878f 100644 --- a/src/view/com/notifications/Feed.tsx +++ b/src/view/com/notifications/Feed.tsx @@ -6,11 +6,14 @@ import { NotificationsViewItemModel, } from '../../../state/models/notifications-view' import {FeedItem} from './FeedItem' +import {ErrorMessage} from '../util/ErrorMessage' export const Feed = observer(function Feed({ view, + onPressTryAgain, }: { view: NotificationsViewModel + onPressTryAgain?: () => void }) { // TODO optimize renderItem or FeedItem, we're getting this notice from RN: -prf // VirtualizedList: You have a large list that is slow to update - make sure your @@ -30,7 +33,14 @@ export const Feed = observer(function Feed({ {view.isLoading && !view.isRefreshing && !view.hasContent && ( <Text>Loading...</Text> )} - {view.hasError && <Text>{view.error}</Text>} + {view.hasError && ( + <ErrorMessage + dark + message={view.error} + style={{margin: 6}} + onPressTryAgain={onPressTryAgain} + /> + )} {view.hasContent && ( <FlatList data={view.notifications} diff --git a/src/view/com/post-thread/PostRepostedBy.tsx b/src/view/com/post-thread/PostRepostedBy.tsx index 53f0e0b35..ca5cc476a 100644 --- a/src/view/com/post-thread/PostRepostedBy.tsx +++ b/src/view/com/post-thread/PostRepostedBy.tsx @@ -1,18 +1,12 @@ import React, {useState, useEffect} from 'react' import {observer} from 'mobx-react-lite' -import { - ActivityIndicator, - FlatList, - Image, - StyleSheet, - Text, - View, -} from 'react-native' +import {ActivityIndicator, FlatList, StyleSheet, Text, View} from 'react-native' import { RepostedByViewModel, RepostedByViewItemModel, } from '../../../state/models/reposted-by-view' import {UserAvatar} from '../util/UserAvatar' +import {ErrorMessage} from '../util/ErrorMessage' import {Link} from '../util/Link' import {useStores} from '../../../state' import {s, colors} from '../../lib/styles' @@ -38,6 +32,10 @@ export const PostRepostedBy = observer(function PostRepostedBy({ .catch(err => console.error('Failed to fetch reposted by', err)) }, [uri, view?.params.uri, store]) + const onRefresh = () => { + view?.refresh() + } + // loading // = if ( @@ -57,7 +55,12 @@ export const PostRepostedBy = observer(function PostRepostedBy({ if (view.hasError) { return ( <View> - <Text>{view.error}</Text> + <ErrorMessage + dark + message={view.error} + style={{margin: 6}} + onPressTryAgain={onRefresh} + /> </View> ) } diff --git a/src/view/com/post-thread/PostThread.tsx b/src/view/com/post-thread/PostThread.tsx index 0349d3428..ee87a6bff 100644 --- a/src/view/com/post-thread/PostThread.tsx +++ b/src/view/com/post-thread/PostThread.tsx @@ -8,6 +8,7 @@ import { import {useStores} from '../../../state' import {SharePostModel} from '../../../state/models/shell-ui' import {PostThreadItem} from './PostThreadItem' +import {ErrorMessage} from '../util/ErrorMessage' export const PostThread = observer(function PostThread({uri}: {uri: string}) { const store = useStores() @@ -50,7 +51,12 @@ export const PostThread = observer(function PostThread({uri}: {uri: string}) { if (view.hasError) { return ( <View> - <Text>{view.error}</Text> + <ErrorMessage + dark + message={view.error} + style={{margin: 6}} + onPressTryAgain={onRefresh} + /> </View> ) } diff --git a/src/view/com/post-thread/PostVotedBy.tsx b/src/view/com/post-thread/PostVotedBy.tsx index 596a6a1db..ad85d077f 100644 --- a/src/view/com/post-thread/PostVotedBy.tsx +++ b/src/view/com/post-thread/PostVotedBy.tsx @@ -6,6 +6,7 @@ import { VotesViewItemModel, } from '../../../state/models/votes-view' import {Link} from '../util/Link' +import {ErrorMessage} from '../util/ErrorMessage' import {UserAvatar} from '../util/UserAvatar' import {useStores} from '../../../state' import {s, colors} from '../../lib/styles' @@ -31,6 +32,10 @@ export const PostVotedBy = observer(function PostVotedBy({ newView.setup().catch(err => console.error('Failed to fetch voted by', err)) }, [uri, view?.params.uri, store]) + const onRefresh = () => { + view?.refresh() + } + // loading // = if ( @@ -50,7 +55,12 @@ export const PostVotedBy = observer(function PostVotedBy({ if (view.hasError) { return ( <View> - <Text>{view.error}</Text> + <ErrorMessage + dark + message={view.error} + style={{margin: 6}} + onPressTryAgain={onRefresh} + /> </View> ) } diff --git a/src/view/com/posts/Feed.tsx b/src/view/com/posts/Feed.tsx index dc341ddd5..75b48fad8 100644 --- a/src/view/com/posts/Feed.tsx +++ b/src/view/com/posts/Feed.tsx @@ -1,6 +1,7 @@ import React, {MutableRefObject} from 'react' import {observer} from 'mobx-react-lite' import {Text, View, FlatList, StyleProp, ViewStyle} from 'react-native' +import {ErrorMessage} from '../util/ErrorMessage' import {FeedModel, FeedItemModel} from '../../../state/models/feed-view' import {FeedItem} from './FeedItem' @@ -8,10 +9,12 @@ export const Feed = observer(function Feed({ feed, style, scrollElRef, + onPressTryAgain, }: { feed: FeedModel style?: StyleProp<ViewStyle> scrollElRef?: MutableRefObject<FlatList<any> | null> + onPressTryAgain?: () => void }) { // TODO optimize renderItem or FeedItem, we're getting this notice from RN: -prf // VirtualizedList: You have a large list that is slow to update - make sure your @@ -29,7 +32,14 @@ export const Feed = observer(function Feed({ {feed.isLoading && !feed.isRefreshing && !feed.hasContent && ( <Text>Loading...</Text> )} - {feed.hasError && <Text>{feed.error}</Text>} + {feed.hasError && ( + <ErrorMessage + dark + message={feed.error} + style={{margin: 6}} + onPressTryAgain={onPressTryAgain} + /> + )} {feed.hasContent && ( <FlatList ref={scrollElRef} @@ -41,7 +51,11 @@ export const Feed = observer(function Feed({ onEndReached={onEndReached} /> )} - {feed.isEmpty && <Text>This feed is empty!</Text>} + {feed.isEmpty && !feed.hasError && ( + <View> + <Text>This feed is empty!</Text> + </View> + )} </View> ) }) diff --git a/src/view/com/profile/ProfileFollowers.tsx b/src/view/com/profile/ProfileFollowers.tsx index 65297ccc6..c4e9435d6 100644 --- a/src/view/com/profile/ProfileFollowers.tsx +++ b/src/view/com/profile/ProfileFollowers.tsx @@ -6,6 +6,7 @@ import { FollowerItem, } from '../../../state/models/user-followers-view' import {Link} from '../util/Link' +import {ErrorMessage} from '../util/ErrorMessage' import {UserAvatar} from '../util/UserAvatar' import {useStores} from '../../../state' import {s, colors} from '../../lib/styles' @@ -31,6 +32,10 @@ export const ProfileFollowers = observer(function ProfileFollowers({ .catch(err => console.error('Failed to fetch user followers', err)) }, [name, view?.params.user, store]) + const onRefresh = () => { + view?.refresh() + } + // loading // = if ( @@ -50,7 +55,12 @@ export const ProfileFollowers = observer(function ProfileFollowers({ if (view.hasError) { return ( <View> - <Text>{view.error}</Text> + <ErrorMessage + dark + message={view.error} + style={{margin: 6}} + onPressTryAgain={onRefresh} + /> </View> ) } diff --git a/src/view/com/profile/ProfileFollows.tsx b/src/view/com/profile/ProfileFollows.tsx index 1bdd18f66..9efd58f8c 100644 --- a/src/view/com/profile/ProfileFollows.tsx +++ b/src/view/com/profile/ProfileFollows.tsx @@ -7,6 +7,7 @@ import { } from '../../../state/models/user-follows-view' import {useStores} from '../../../state' import {Link} from '../util/Link' +import {ErrorMessage} from '../util/ErrorMessage' import {UserAvatar} from '../util/UserAvatar' import {s, colors} from '../../lib/styles' @@ -31,6 +32,10 @@ export const ProfileFollows = observer(function ProfileFollows({ .catch(err => console.error('Failed to fetch user follows', err)) }, [name, view?.params.user, store]) + const onRefresh = () => { + view?.refresh() + } + // loading // = if ( @@ -50,7 +55,12 @@ export const ProfileFollows = observer(function ProfileFollows({ if (view.hasError) { return ( <View> - <Text>{view.error}</Text> + <ErrorMessage + dark + message={view.error} + style={{margin: 6}} + onPressTryAgain={onRefresh} + /> </View> ) } diff --git a/src/view/com/profile/ProfileMembers.tsx b/src/view/com/profile/ProfileMembers.tsx index 11db02054..75ef18caa 100644 --- a/src/view/com/profile/ProfileMembers.tsx +++ b/src/view/com/profile/ProfileMembers.tsx @@ -1,8 +1,9 @@ import React, {useState, useEffect} from 'react' import {observer} from 'mobx-react-lite' -import {ActivityIndicator, FlatList, Text, View} from 'react-native' +import {ActivityIndicator, FlatList, View} from 'react-native' import {MembersViewModel, MemberItem} from '../../../state/models/members-view' import {ProfileCard} from './ProfileCard' +import {ErrorMessage} from '../util/ErrorMessage' import {useStores} from '../../../state' export const ProfileMembers = observer(function ProfileMembers({ @@ -24,6 +25,10 @@ export const ProfileMembers = observer(function ProfileMembers({ newView.setup().catch(err => console.error('Failed to fetch members', err)) }, [name, view?.params.actor, store]) + const onRefresh = () => { + view?.refresh() + } + // loading // = if ( @@ -43,7 +48,12 @@ export const ProfileMembers = observer(function ProfileMembers({ if (view.hasError) { return ( <View> - <Text>{view.error}</Text> + <ErrorMessage + dark + message={view.error} + style={{margin: 6}} + onPressTryAgain={onRefresh} + /> </View> ) } diff --git a/src/view/com/util/ErrorMessage.tsx b/src/view/com/util/ErrorMessage.tsx index 834cd598f..3f6522b86 100644 --- a/src/view/com/util/ErrorMessage.tsx +++ b/src/view/com/util/ErrorMessage.tsx @@ -1,40 +1,66 @@ import React from 'react' -import {StyleSheet, Text, TouchableOpacity, View} from 'react-native' +import { + StyleSheet, + Text, + TouchableOpacity, + StyleProp, + View, + ViewStyle, +} from 'react-native' import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome' -import {colors} from '../../lib/styles' +import LinearGradient from 'react-native-linear-gradient' +import {colors, gradients} from '../../lib/styles' export function ErrorMessage({ message, numberOfLines, + dark, + style, onPressTryAgain, }: { message: string numberOfLines?: number + dark?: boolean + style?: StyleProp<ViewStyle> onPressTryAgain?: () => void }) { - return ( - <View style={styles.outer}> - <View style={styles.errorIcon}> + const inner = ( + <> + <View style={[styles.errorIcon, dark ? styles.darkErrorIcon : undefined]}> <FontAwesomeIcon icon="exclamation" - style={{color: colors.white}} + style={{color: dark ? colors.red3 : colors.white}} size={16} /> </View> - <Text style={styles.message} numberOfLines={numberOfLines}> + <Text + style={[styles.message, dark ? styles.darkMessage : undefined]} + numberOfLines={numberOfLines}> {message} </Text> {onPressTryAgain && ( <TouchableOpacity style={styles.btn} onPress={onPressTryAgain}> <FontAwesomeIcon icon="arrows-rotate" - style={{color: colors.red4}} + style={{color: dark ? colors.white : colors.red4}} size={16} /> </TouchableOpacity> )} - </View> + </> ) + if (dark) { + return ( + <LinearGradient + colors={[gradients.error.start, gradients.error.end]} + start={{x: 0.5, y: 0}} + end={{x: 1, y: 1}} + style={[styles.outer, style]}> + {inner} + </LinearGradient> + ) + } + return <View style={[styles.outer, style]}>{inner}</View> } const styles = StyleSheet.create({ @@ -57,11 +83,18 @@ const styles = StyleSheet.create({ justifyContent: 'center', marginRight: 8, }, + darkErrorIcon: { + backgroundColor: colors.white, + }, message: { flex: 1, color: colors.red4, paddingRight: 10, }, + darkMessage: { + color: colors.white, + fontWeight: '600', + }, btn: { paddingHorizontal: 4, paddingVertical: 4, diff --git a/src/view/lib/strings.ts b/src/view/lib/strings.ts index 19bd5c473..e47863d50 100644 --- a/src/view/lib/strings.ts +++ b/src/view/lib/strings.ts @@ -96,3 +96,10 @@ export function enforceLen(str: string, len: number): string { } return str } + +export function cleanError(str: string): string { + if (str.startsWith('Error: ')) { + return str.slice('Error: '.length) + } + return str +} diff --git a/src/view/lib/styles.ts b/src/view/lib/styles.ts index dfcaeef92..4bea6443c 100644 --- a/src/view/lib/styles.ts +++ b/src/view/lib/styles.ts @@ -45,6 +45,7 @@ export const colors = { export const gradients = { primary: {start: '#db00ff', end: '#ff007a'}, + error: {start: '#ff007a', end: '#ed0d78'}, purple: {start: colors.pink3, end: colors.purple3}, blue: {start: colors.purple3, end: colors.blue3}, green: {start: colors.blue3, end: colors.green3}, diff --git a/src/view/screens/Home.tsx b/src/view/screens/Home.tsx index c16eff805..036f7d148 100644 --- a/src/view/screens/Home.tsx +++ b/src/view/screens/Home.tsx @@ -51,6 +51,9 @@ export const Home = observer(function Home({ const onCreatePost = () => { defaultFeedView.loadLatest() } + const onPressTryAgain = () => { + defaultFeedView.refresh() + } return ( <View style={s.flex1}> @@ -63,6 +66,7 @@ export const Home = observer(function Home({ feed={defaultFeedView} scrollElRef={scrollElRef} style={{flex: 1}} + onPressTryAgain={onPressTryAgain} /> <FAB icon="pen-nib" onPress={onComposePress} /> </View> diff --git a/src/view/screens/Notifications.tsx b/src/view/screens/Notifications.tsx index c82e7cc7c..f1084540c 100644 --- a/src/view/screens/Notifications.tsx +++ b/src/view/screens/Notifications.tsx @@ -36,10 +36,14 @@ export const Notifications = ({visible}: ScreenParams) => { } }, [visible, store]) + const onPressTryAgain = () => { + notesView?.refresh() + } + return ( <View style={{flex: 1}}> <ViewHeader title="Notifications" /> - {notesView && <Feed view={notesView} />} + {notesView && <Feed view={notesView} onPressTryAgain={onPressTryAgain} />} </View> ) } |