Fix invite codes flash on desktop, use loading placeholder (#1591)

* Fix invite codes flashing untrue value before loaded

* Add loading placeholder for right nav invites
zio/stable
Patroll 2023-10-04 19:31:43 +02:00 committed by GitHub
parent 2ba0c6a711
commit 9278822088
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 142 additions and 89 deletions

View File

@ -25,13 +25,13 @@ export class MeModel {
savedFeeds: SavedFeedsModel savedFeeds: SavedFeedsModel
notifications: NotificationsFeedModel notifications: NotificationsFeedModel
follows: MyFollowsCache follows: MyFollowsCache
invites: ComAtprotoServerDefs.InviteCode[] = [] invites: ComAtprotoServerDefs.InviteCode[] | null = []
appPasswords: ComAtprotoServerListAppPasswords.AppPassword[] = [] appPasswords: ComAtprotoServerListAppPasswords.AppPassword[] = []
lastProfileStateUpdate = Date.now() lastProfileStateUpdate = Date.now()
lastNotifsUpdate = Date.now() lastNotifsUpdate = Date.now()
get invitesAvailable() { get invitesAvailable() {
return this.invites.filter(isInviteAvailable).length return this.invites?.filter(isInviteAvailable).length || null
} }
constructor(public rootStore: RootStoreModel) { constructor(public rootStore: RootStoreModel) {
@ -180,9 +180,11 @@ export class MeModel {
} catch (e) { } catch (e) {
this.rootStore.log.error('Failed to fetch user invite codes', e) this.rootStore.log.error('Failed to fetch user invite codes', e)
} }
if (this.invites) {
await this.rootStore.invitedUsers.fetch(this.invites) await this.rootStore.invitedUsers.fetch(this.invites)
} }
} }
}
async fetchAppPasswords() { async fetchAppPasswords() {
if (this.rootStore.session) { if (this.rootStore.session) {

View File

@ -26,6 +26,33 @@ export function Component({}: {}) {
store.shell.closeModal() store.shell.closeModal()
}, [store]) }, [store])
if (store.me.invites === null) {
return (
<View style={[styles.container, pal.view]} testID="inviteCodesModal">
<Text type="title-xl" style={[styles.title, pal.text]}>
Error
</Text>
<Text type="lg" style={[styles.description, pal.text]}>
An error occurred while loading invite codes.
</Text>
<View style={styles.flex1} />
<View
style={[
styles.btnContainer,
isTabletOrDesktop && styles.btnContainerDesktop,
]}>
<Button
type="primary"
label="Done"
style={styles.btn}
labelStyle={styles.btnLabel}
onPress={onClose}
/>
</View>
</View>
)
}
if (store.me.invites.length === 0) { if (store.me.invites.length === 0) {
return ( return (
<View style={[styles.container, pal.view]} testID="inviteCodesModal"> <View style={[styles.container, pal.view]} testID="inviteCodesModal">

View File

@ -322,12 +322,18 @@ export const SettingsScreen = withAuthRequired(
<View style={styles.spacer20} /> <View style={styles.spacer20} />
{store.me.invitesAvailable !== null && (
<>
<Text type="xl-bold" style={[pal.text, styles.heading]}> <Text type="xl-bold" style={[pal.text, styles.heading]}>
Invite a Friend Invite a Friend
</Text> </Text>
<TouchableOpacity <TouchableOpacity
testID="inviteFriendBtn" testID="inviteFriendBtn"
style={[styles.linkCard, pal.view, isSwitching && styles.dimmed]} style={[
styles.linkCard,
pal.view,
isSwitching && styles.dimmed,
]}
onPress={isSwitching ? undefined : onPressInviteCodes} onPress={isSwitching ? undefined : onPressInviteCodes}
accessibilityRole="button" accessibilityRole="button"
accessibilityLabel="Invite" accessibilityLabel="Invite"
@ -353,6 +359,8 @@ export const SettingsScreen = withAuthRequired(
{pluralize(store.me.invitesAvailable, 'code')} available {pluralize(store.me.invitesAvailable, 'code')} available
</Text> </Text>
</TouchableOpacity> </TouchableOpacity>
</>
)}
<View style={styles.spacer20} /> <View style={styles.spacer20} />

View File

@ -426,6 +426,7 @@ const InviteCodes = observer(function InviteCodesImpl({
store.shell.openModal({name: 'invite-codes'}) store.shell.openModal({name: 'invite-codes'})
}, [store, track]) }, [store, track])
return ( return (
store.me.invitesAvailable !== null && (
<TouchableOpacity <TouchableOpacity
testID="menuItemInviteCodes" testID="menuItemInviteCodes"
style={[styles.inviteCodes, style]} style={[styles.inviteCodes, style]}
@ -453,6 +454,7 @@ const InviteCodes = observer(function InviteCodesImpl({
</Text> </Text>
</TouchableOpacity> </TouchableOpacity>
) )
)
}) })
const styles = StyleSheet.create({ const styles = StyleSheet.create({

View File

@ -7,6 +7,7 @@ import {DesktopSearch} from './Search'
import {DesktopFeeds} from './Feeds' import {DesktopFeeds} from './Feeds'
import {Text} from 'view/com/util/text/Text' import {Text} from 'view/com/util/text/Text'
import {TextLink} from 'view/com/util/Link' import {TextLink} from 'view/com/util/Link'
import {LoadingPlaceholder} from 'view/com/util/LoadingPlaceholder'
import {FEEDBACK_FORM_URL, HELP_DESK_URL} from 'lib/constants' import {FEEDBACK_FORM_URL, HELP_DESK_URL} from 'lib/constants'
import {s} from 'lib/styles' import {s} from 'lib/styles'
import {useStores} from 'state/index' import {useStores} from 'state/index'
@ -89,9 +90,16 @@ const InviteCodes = observer(function InviteCodesImpl() {
const onPress = React.useCallback(() => { const onPress = React.useCallback(() => {
store.shell.openModal({name: 'invite-codes'}) store.shell.openModal({name: 'invite-codes'})
}, [store]) }, [store])
return ( return (
<View style={[styles.separator, pal.border]}>
{store.me.invitesAvailable === null ? (
<View style={[s.p10]}>
<LoadingPlaceholder width={186} height={32} style={[styles.br40]} />
</View>
) : (
<TouchableOpacity <TouchableOpacity
style={[styles.inviteCodes, pal.border]} style={[styles.inviteCodes]}
onPress={onPress} onPress={onPress}
accessibilityRole="button" accessibilityRole="button"
accessibilityLabel={ accessibilityLabel={
@ -115,6 +123,8 @@ const InviteCodes = observer(function InviteCodesImpl() {
{pluralize(store.me.invitesAvailable, 'code')} available {pluralize(store.me.invitesAvailable, 'code')} available
</Text> </Text>
</TouchableOpacity> </TouchableOpacity>
)}
</View>
) )
}) })
@ -131,16 +141,20 @@ const styles = StyleSheet.create({
message: { message: {
paddingVertical: 18, paddingVertical: 18,
paddingHorizontal: 10, paddingHorizontal: 12,
}, },
messageLine: { messageLine: {
marginBottom: 10, marginBottom: 10,
}, },
inviteCodes: { separator: {
borderTopWidth: 1, borderTopWidth: 1,
paddingHorizontal: 16, },
paddingVertical: 12, br40: {borderRadius: 40},
inviteCodes: {
paddingHorizontal: 12,
paddingVertical: 16,
flexDirection: 'row', flexDirection: 'row',
alignItems: 'center', alignItems: 'center',
}, },