diff options
Diffstat (limited to 'src/screens')
| -rw-r--r-- | src/screens/badge/BadgeScreenHeader.tsx | 4 | ||||
| -rw-r--r-- | src/screens/badge/BadgeSelection.tsx | 47 | ||||
| -rw-r--r-- | src/screens/chat/ChatListScreen.tsx | 4 | ||||
| -rw-r--r-- | src/screens/chat/ChatResultsCell.tsx | 10 | ||||
| -rw-r--r-- | src/screens/chat/ChatScreen.tsx | 39 | ||||
| -rw-r--r-- | src/screens/chat/ChatSearchBar.tsx | 6 | ||||
| -rw-r--r-- | src/screens/main/NotificationsScreen.tsx | 4 | ||||
| -rw-r--r-- | src/screens/main/notification/EmptyNotificationView.tsx | 48 | ||||
| -rw-r--r-- | src/screens/onboarding/Login.tsx | 2 | ||||
| -rw-r--r-- | src/screens/onboarding/OnboardingStepThree.tsx | 5 | ||||
| -rw-r--r-- | src/screens/profile/CaptionScreen.tsx | 17 | ||||
| -rw-r--r-- | src/screens/profile/MomentCommentsScreen.tsx | 124 | ||||
| -rw-r--r-- | src/screens/profile/SocialMediaTaggs.tsx | 2 |
13 files changed, 140 insertions, 172 deletions
diff --git a/src/screens/badge/BadgeScreenHeader.tsx b/src/screens/badge/BadgeScreenHeader.tsx index aef49c85..81bbf42b 100644 --- a/src/screens/badge/BadgeScreenHeader.tsx +++ b/src/screens/badge/BadgeScreenHeader.tsx @@ -15,9 +15,7 @@ const BadgeScreenHeader: React.FC<BadgeScreenHeaderProps> = ({university}) => { style={styles.icon} /> <View style={styles.universityTextContainer}> - <Text style={styles.universityText}> - {university} University Badges - </Text> + <Text style={styles.universityText}>{university} Badges</Text> </View> <View style={styles.searchTextContainer}> <Text style={styles.searchText}> diff --git a/src/screens/badge/BadgeSelection.tsx b/src/screens/badge/BadgeSelection.tsx index 38a2b01c..d0dcfa4c 100644 --- a/src/screens/badge/BadgeSelection.tsx +++ b/src/screens/badge/BadgeSelection.tsx @@ -8,14 +8,20 @@ import LinearGradient from 'react-native-linear-gradient'; import {useDispatch, useSelector} from 'react-redux'; import {BACKGROUND_GRADIENT_MAP} from '../../constants'; import {BADGE_DATA} from '../../constants/badges'; -import {ERROR_BADGES_EXCEED_LIMIT} from '../../constants/strings'; +import { + ERROR_BADGES_EXCEED_LIMIT, + SUCCESS_BADGES_UPDATE, +} from '../../constants/strings'; import {MainStackParams} from '../../routes'; import { addBadgesService, - getSuggestedPeopleProfile, + getBadgesService, updateBadgesService, } from '../../services'; -import {suggestedPeopleBadgesFinished} from '../../store/actions'; +import { + suggestedPeopleBadgesFinished, + updateUserBadges, +} from '../../store/actions'; import {RootState} from '../../store/rootReducer'; import {BackgroundGradientType} from '../../types'; import {SCREEN_HEIGHT, StatusBarHeight} from '../../utils'; @@ -36,37 +42,47 @@ const BadgeSelection: React.FC<BadgeSelectionProps> = ({route}) => { const {editing} = route.params; const { user: {userId: loggedInUserId}, - profile: {university}, + profile: {university, badges}, } = useSelector((state: RootState) => state.user); const [selectedBadges, setSelectedBadges] = useState<string[]>([]); const dispatch = useDispatch(); const navigation = useNavigation(); - // Loading badges data and extracting into a string [] + // Extracting badges data into a string [] useEffect(() => { const loadData = async () => { - const response = await getSuggestedPeopleProfile(loggedInUserId); - if (response) { - const data = response.badges; - let extractedBadgeNames: string[] = []; - data.forEach((badge) => { - extractedBadgeNames.push(badge.name); - }); - setSelectedBadges(extractedBadgeNames); - } + let extractedBadgeNames: string[] = []; + badges.forEach((badge) => { + extractedBadgeNames.push(badge.name); + }); + setSelectedBadges(extractedBadgeNames); }; if (editing) { loadData(); } }, []); + // Retrieve updated badges using get badges service and udpate the store + const loadUserBadges = async () => { + const newBadges = await getBadgesService(loggedInUserId); + dispatch(updateUserBadges(newBadges)); + }; + navigation.setOptions({ headerRight: () => ( <TouchableOpacity style={styles.rightButtonContainer} onPress={async () => { if (editing) { - await updateBadgesService(selectedBadges, university); + const success = await updateBadgesService( + selectedBadges, + university, + ); + if (success === true) { + // Load updated badges to store + loadUserBadges(); + Alert.alert(SUCCESS_BADGES_UPDATE); + } if (navigation.canGoBack()) { navigation.goBack(); } else { @@ -82,6 +98,7 @@ const BadgeSelection: React.FC<BadgeSelectionProps> = ({route}) => { ); if (success) { dispatch(suggestedPeopleBadgesFinished()); + loadUserBadges(); navigation.navigate('SuggestedPeople'); } } else { diff --git a/src/screens/chat/ChatListScreen.tsx b/src/screens/chat/ChatListScreen.tsx index d2cfcb5d..1df5c2da 100644 --- a/src/screens/chat/ChatListScreen.tsx +++ b/src/screens/chat/ChatListScreen.tsx @@ -9,6 +9,7 @@ import {TabsGradient} from '../../components'; import {ChannelPreview, MessagesHeader} from '../../components/messages'; import {MainStackParams} from '../../routes'; import {RootState} from '../../store/rootReducer'; +import EmptyContentView from '../../components/common/EmptyContentView'; import { LocalAttachmentType, LocalChannelType, @@ -99,6 +100,9 @@ const ChatListScreen: React.FC<ChatListScreenProps> = () => { sort={{last_message_at: -1}} maxUnreadCount={99} Preview={ChannelPreview} + EmptyStateIndicator={() => { + return <EmptyContentView viewType={'ChatList'} />; + }} /> </View> </Chat> diff --git a/src/screens/chat/ChatResultsCell.tsx b/src/screens/chat/ChatResultsCell.tsx index e1eb97dd..14062810 100644 --- a/src/screens/chat/ChatResultsCell.tsx +++ b/src/screens/chat/ChatResultsCell.tsx @@ -1,13 +1,13 @@ import {useNavigation} from '@react-navigation/native'; import React, {useContext, useEffect, useState} from 'react'; -import {Alert, Image, StyleSheet, Text, View} from 'react-native'; +import {Alert, StyleSheet, Text, View} from 'react-native'; import {TouchableOpacity} from 'react-native-gesture-handler'; import {ChatContext} from '../../App'; +import {Avatar} from '../../components'; import {ERROR_FAILED_TO_CREATE_CHANNEL} from '../../constants/strings'; import {loadImageFromURL} from '../../services'; import {ProfilePreviewType, UserType} from '../../types'; import {createChannel, normalize, SCREEN_WIDTH} from '../../utils'; -import {defaultUserProfile} from '../../utils/users'; interface ChatResults { profileData: ProfilePreviewType; @@ -58,11 +58,7 @@ const ChatResultsCell: React.FC<ChatResults> = ({ <TouchableOpacity onPress={createChannelIfNotPresentAndNavigate} style={styles.cellContainer}> - <Image - defaultSource={defaultUserProfile()} - source={{uri: avatar}} - style={styles.imageContainer} - /> + <Avatar style={styles.imageContainer} uri={avatar} /> <View style={[styles.initialTextContainer, styles.multiText]}> <Text style={styles.initialTextStyle}>{`@${username}`}</Text> <Text style={styles.secondaryTextStyle}> diff --git a/src/screens/chat/ChatScreen.tsx b/src/screens/chat/ChatScreen.tsx index 5874b8b6..ee0686d1 100644 --- a/src/screens/chat/ChatScreen.tsx +++ b/src/screens/chat/ChatScreen.tsx @@ -1,6 +1,6 @@ -import {useBottomTabBarHeight} from '@react-navigation/bottom-tabs'; +import {useFocusEffect} from '@react-navigation/core'; import {StackNavigationProp} from '@react-navigation/stack'; -import React, {useContext, useEffect} from 'react'; +import React, {useCallback, useContext, useEffect} from 'react'; import {StyleSheet} from 'react-native'; import {SafeAreaView, useSafeAreaInsets} from 'react-native-safe-area-context'; import { @@ -9,8 +9,8 @@ import { DeepPartial, MessageInput, MessageList, - useAttachmentPickerContext, Theme, + useAttachmentPickerContext, } from 'stream-chat-react-native'; import {ChatContext} from '../../App'; import { @@ -19,12 +19,11 @@ import { DateHeader, MessageAvatar, MessageFooter, - TabsGradient, TypingIndicator, } from '../../components'; import {MainStackParams} from '../../routes'; import {ScreenType} from '../../types'; -import {HeaderHeight, isIPhoneX, normalize, SCREEN_WIDTH} from '../../utils'; +import {HeaderHeight, normalize, SCREEN_WIDTH} from '../../utils'; type ChatScreenNavigationProp = StackNavigationProp<MainStackParams, 'Chat'>; interface ChatScreenProps { @@ -33,9 +32,8 @@ interface ChatScreenProps { /* * Screen that displays all of the user's active conversations. */ -const ChatScreen: React.FC<ChatScreenProps> = () => { +const ChatScreen: React.FC<ChatScreenProps> = ({navigation}) => { const {channel, chatClient} = useContext(ChatContext); - const tabbarHeight = useBottomTabBarHeight(); const {setTopInset} = useAttachmentPickerContext(); const insets = useSafeAreaInsets(); const chatTheme: DeepPartial<Theme> = { @@ -54,6 +52,9 @@ const ChatScreen: React.FC<ChatScreenProps> = () => { backgroundColor: '#f8f8f8', height: 70, }, + inputBox: { + fontSize: 16, + }, }, avatar: { container: { @@ -105,6 +106,11 @@ const ChatScreen: React.FC<ChatScreenProps> = () => { borderBottomRightRadius: 10, borderTopRightRadius: 10, }, + markdown: { + text: { + fontSize: 16, + } + }, }, status: { statusContainer: {}, @@ -129,12 +135,25 @@ const ChatScreen: React.FC<ChatScreenProps> = () => { setTopInset(insets.top + HeaderHeight); }); + //Function to get the parent TabBar navigator and setting the option for this screen. + useFocusEffect( + useCallback(() => { + navigation.dangerouslyGetParent()?.setOptions({ + tabBarVisible: false, + }); + return () => { + navigation.dangerouslyGetParent()?.setOptions({ + tabBarVisible: true, + }); + }; + }, [navigation]), + ); + return ( <SafeAreaView style={[ styles.container, - // unable to figure out the padding issue, a hacky solution - {paddingBottom: isIPhoneX() ? tabbarHeight + 20 : tabbarHeight + 50}, + styles.textBoxStyles, // Update : removed hacky soln for a common height. Original : unable to figure out the padding issue, a hacky solution {paddingBottom: isIPhoneX() ? tabbarHeight + 20 : tabbarHeight + 50}, ]}> <ChatHeader screenType={ScreenType.Chat} /> <Chat client={chatClient} style={chatTheme}> @@ -157,7 +176,6 @@ const ChatScreen: React.FC<ChatScreenProps> = () => { <MessageInput Input={ChatInput} /> </Channel> </Chat> - <TabsGradient /> </SafeAreaView> ); }; @@ -167,6 +185,7 @@ const styles = StyleSheet.create({ backgroundColor: 'white', flex: 1, }, + textBoxStyles: {paddingBottom: 60}, }); export default ChatScreen; diff --git a/src/screens/chat/ChatSearchBar.tsx b/src/screens/chat/ChatSearchBar.tsx index 3531111b..91018d4c 100644 --- a/src/screens/chat/ChatSearchBar.tsx +++ b/src/screens/chat/ChatSearchBar.tsx @@ -10,8 +10,8 @@ import { TouchableOpacity, View, } from 'react-native'; -import {normalize} from 'react-native-elements'; import Animated from 'react-native-reanimated'; +import {normalize} from '../../utils'; interface SearchBarProps extends TextInputProps { onCancel: () => void; @@ -76,9 +76,9 @@ const styles = StyleSheet.create({ }, input: { flex: 1, - fontSize: 16, + fontSize: normalize(16), color: '#000', - letterSpacing: normalize(0.5), + letterSpacing: 0.5, }, cancelButton: { justifyContent: 'center', diff --git a/src/screens/main/NotificationsScreen.tsx b/src/screens/main/NotificationsScreen.tsx index 2f8e8e7d..7e2f082c 100644 --- a/src/screens/main/NotificationsScreen.tsx +++ b/src/screens/main/NotificationsScreen.tsx @@ -28,7 +28,7 @@ import { import {RootState} from '../../store/rootReducer'; import {NotificationType, ScreenType} from '../../types'; import {getDateAge, normalize, SCREEN_HEIGHT, SCREEN_WIDTH} from '../../utils'; -import EmptyNotificationView from './notification/EmptyNotificationView'; +import EmptyContentView from '../../components/common/EmptyContentView'; const NotificationsScreen: React.FC = () => { const {newNotificationReceived} = useSelector( @@ -304,7 +304,7 @@ const NotificationsScreen: React.FC = () => { extraData={requestLimit} ListEmptyComponent={ <View style={styles.emptyViewContainer}> - <EmptyNotificationView /> + <EmptyContentView viewType={'Notification'} /> </View> } /> diff --git a/src/screens/main/notification/EmptyNotificationView.tsx b/src/screens/main/notification/EmptyNotificationView.tsx deleted file mode 100644 index f43cfb2a..00000000 --- a/src/screens/main/notification/EmptyNotificationView.tsx +++ /dev/null @@ -1,48 +0,0 @@ -import React from 'react'; -import {Image, Text, StyleSheet, View} from 'react-native'; -import LinearGradient from 'react-native-linear-gradient'; -import {UP_TO_DATE, NO_NEW_NOTIFICATIONS} from '../../../constants/strings'; -import {NOTIFICATION_GRADIENT} from '../../../constants/constants'; -import {SCREEN_HEIGHT, normalize} from '../../../utils'; -const EmptyNotificationView: React.FC = () => { - return ( - <View style={styles.container}> - <LinearGradient - style={styles.backgroundLinearView} - useAngle={true} - angle={180} - colors={NOTIFICATION_GRADIENT}> - <Image - source={require('../../../assets/images/empty_notifications.png')} - /> - </LinearGradient> - <View style={styles.topMargin}> - <Text style={styles.upperTextStyle}>{UP_TO_DATE}</Text> - </View> - <View> - <Text style={styles.bottomTextStyle}>{NO_NEW_NOTIFICATIONS}</Text> - </View> - </View> - ); -}; - -const styles = StyleSheet.create({ - container: {alignItems: 'center'}, - topMargin: {marginTop: SCREEN_HEIGHT * 0.025}, - upperTextStyle: { - fontWeight: '700', - fontSize: normalize(23), - lineHeight: normalize(40), - }, - bottomTextStyle: { - color: '#2D3B45', - fontWeight: '600', - fontSize: normalize(20), - lineHeight: normalize(40), - }, - backgroundLinearView: { - borderRadius: 135.5, - }, -}); - -export default EmptyNotificationView; diff --git a/src/screens/onboarding/Login.tsx b/src/screens/onboarding/Login.tsx index 041fba05..3b970864 100644 --- a/src/screens/onboarding/Login.tsx +++ b/src/screens/onboarding/Login.tsx @@ -168,7 +168,7 @@ const Login: React.FC<LoginProps> = ({navigation}: LoginProps) => { //Stores token received in the response into client's AsynStorage try { userLogin(dispatch, {userId: data.UserID, username}); - fcmService.sendFcmTokenToServer(); + fcmService.sendFcmTokenToServer(chatClient); connectChatAccount(data.UserID, chatClient); } catch (err) { Alert.alert(ERROR_INVALID_LOGIN); diff --git a/src/screens/onboarding/OnboardingStepThree.tsx b/src/screens/onboarding/OnboardingStepThree.tsx index 638f0889..34173b39 100644 --- a/src/screens/onboarding/OnboardingStepThree.tsx +++ b/src/screens/onboarding/OnboardingStepThree.tsx @@ -27,7 +27,6 @@ import { ERROR_SELECT_CLASS_YEAR, ERROR_SELECT_GENDER, ERROR_SELECT_UNIVERSITY, - ERROR_UPLOAD_SMALL_PROFILE_PIC, } from '../../constants/strings'; import {OnboardingStackParams} from '../../routes/onboarding'; import {patchEditProfile} from '../../services'; @@ -160,10 +159,6 @@ const OnboardingStepThree: React.FC<OnboardingStepThreeProps> = ({ }; const handleSubmit = async () => { - if (!form.smallPic) { - Alert.alert(ERROR_UPLOAD_SMALL_PROFILE_PIC); - return; - } if (form.classYear === -1) { Alert.alert(ERROR_SELECT_CLASS_YEAR); return; diff --git a/src/screens/profile/CaptionScreen.tsx b/src/screens/profile/CaptionScreen.tsx index 156ee41c..a41abba6 100644 --- a/src/screens/profile/CaptionScreen.tsx +++ b/src/screens/profile/CaptionScreen.tsx @@ -11,9 +11,10 @@ import { TouchableWithoutFeedback, View, } from 'react-native'; +import {MentionInput} from 'react-native-controlled-mentions'; import {Button} from 'react-native-elements'; import {useDispatch, useSelector} from 'react-redux'; -import {SearchBackground, TaggBigInput} from '../../components'; +import {SearchBackground} from '../../components'; import {CaptionScreenHeader} from '../../components/'; import TaggLoadingIndicator from '../../components/common/TaggLoadingIndicator'; import {TAGG_LIGHT_BLUE_2} from '../../constants'; @@ -26,6 +27,7 @@ import { } from '../../store/actions'; import {RootState} from '../../store/rootReducer'; import {SCREEN_WIDTH, StatusBarHeight} from '../../utils'; +import {mentionPartTypes} from '../../utils/comments'; /** * Upload Screen to allow users to upload posts to Tagg @@ -49,10 +51,6 @@ const CaptionScreen: React.FC<CaptionScreenProps> = ({route, navigation}) => { const [caption, setCaption] = useState(''); const [loading, setLoading] = useState(false); - const handleCaptionUpdate = (newCaption: string) => { - setCaption(newCaption); - }; - const navigateToProfile = () => { //Since the logged In User is navigating to own profile, useXId is not required navigation.navigate('Profile', { @@ -112,12 +110,13 @@ const CaptionScreen: React.FC<CaptionScreenProps> = ({route, navigation}) => { source={{uri: image.path}} resizeMode={'cover'} /> - <TaggBigInput - style={styles.text} - multiline + <MentionInput + containerStyle={styles.text} placeholder="Write something....." placeholderTextColor="gray" - onChangeText={handleCaptionUpdate} + value={caption} + onChange={setCaption} + partTypes={mentionPartTypes('blue')} /> </View> </KeyboardAvoidingView> diff --git a/src/screens/profile/MomentCommentsScreen.tsx b/src/screens/profile/MomentCommentsScreen.tsx index b0208f6f..1a913e58 100644 --- a/src/screens/profile/MomentCommentsScreen.tsx +++ b/src/screens/profile/MomentCommentsScreen.tsx @@ -7,13 +7,8 @@ import {AddComment} from '../../components/'; import CommentsContainer from '../../components/comments/CommentsContainer'; import {ADD_COMMENT_TEXT} from '../../constants/strings'; import {headerBarOptions, MainStackParams} from '../../routes/main'; -import {CommentType} from '../../types'; -import { - HeaderHeight, - normalize, - SCREEN_HEIGHT, - SCREEN_WIDTH, -} from '../../utils'; +import {CommentThreadType, CommentType} from '../../types'; +import {HeaderHeight, SCREEN_HEIGHT, SCREEN_WIDTH} from '../../utils'; /** * Comments Screen for an image uploaded @@ -30,18 +25,35 @@ interface MomentCommentsScreenProps { route: MomentCommentsScreenRouteProps; } +type MomentCommentContextType = { + commentTapped: CommentType | CommentThreadType | undefined; + setCommentTapped: ( + comment: CommentType | CommentThreadType | undefined, + ) => void; + shouldUpdateAllComments: boolean; + setShouldUpdateAllComments: (available: boolean) => void; + commentsLength: number; + setCommentsLength: (length: number) => void; +}; + +export const CommentContext = React.createContext( + {} as MomentCommentContextType, +); + const MomentCommentsScreen: React.FC<MomentCommentsScreenProps> = ({route}) => { const navigation = useNavigation(); const {moment_id, screenType, comment_id} = route.params; //Receives comment length from child CommentsContainer const [commentsLength, setCommentsLength] = useState<number>(0); - const [newCommentsAvailable, setNewCommentsAvailable] = React.useState(true); + const [shouldUpdateAllComments, setShouldUpdateAllComments] = React.useState( + true, + ); //Keeps track of the current comments object in focus so that the application knows which comment to post a reply to - const [commentObjectInFocus, setCommentObjectInFocus] = useState< - CommentType | undefined - >(undefined); + const [commentTapped, setCommentTapped] = useState< + CommentType | CommentThreadType | undefined + >(); useEffect(() => { navigation.setOptions({ @@ -50,36 +62,39 @@ const MomentCommentsScreen: React.FC<MomentCommentsScreenProps> = ({route}) => { }, [commentsLength, navigation]); return ( - <View style={styles.background}> - <SafeAreaView> - <View style={styles.body}> - <CommentsContainer - objectId={moment_id} - commentId={comment_id} - screenType={screenType} - setCommentsLength={setCommentsLength} - newCommentsAvailable={newCommentsAvailable} - setNewCommentsAvailable={setNewCommentsAvailable} - setCommentObjectInFocus={setCommentObjectInFocus} - commentObjectInFocus={commentObjectInFocus} - typeOfComment={'Comment'} - /> - <AddComment - placeholderText={ - commentObjectInFocus - ? ADD_COMMENT_TEXT(commentObjectInFocus.commenter.username) - : ADD_COMMENT_TEXT() - } - setNewCommentsAvailable={setNewCommentsAvailable} - objectId={ - commentObjectInFocus ? commentObjectInFocus.comment_id : moment_id - } - isCommentInFocus={commentObjectInFocus ? true : false} - /> - </View> - </SafeAreaView> - <TabsGradient /> - </View> + <CommentContext.Provider + value={{ + commentTapped, + setCommentTapped, + shouldUpdateAllComments, + setShouldUpdateAllComments, + commentsLength, + setCommentsLength, + }}> + <View style={styles.background}> + <SafeAreaView> + <View style={styles.body}> + <CommentsContainer + objectId={moment_id} + commentId={comment_id} + screenType={screenType} + shouldUpdate={shouldUpdateAllComments} + setShouldUpdate={setShouldUpdateAllComments} + isThread={false} + /> + <AddComment + placeholderText={ + !commentTapped + ? ADD_COMMENT_TEXT() + : ADD_COMMENT_TEXT(commentTapped.commenter.username) + } + momentId={moment_id} + /> + </View> + </SafeAreaView> + <TabsGradient /> + </View> + </CommentContext.Provider> ); }; @@ -88,39 +103,12 @@ const styles = StyleSheet.create({ backgroundColor: 'white', height: '100%', }, - header: {justifyContent: 'center', padding: '3%'}, - headerText: { - position: 'absolute', - alignSelf: 'center', - fontSize: normalize(18), - fontWeight: '700', - lineHeight: normalize(21.48), - letterSpacing: normalize(1.3), - }, - headerButton: { - width: '5%', - aspectRatio: 1, - padding: 0, - marginLeft: '5%', - alignSelf: 'flex-start', - }, - headerButtonText: { - color: 'black', - fontSize: 18, - fontWeight: '400', - }, body: { marginTop: HeaderHeight, width: SCREEN_WIDTH * 0.9, height: SCREEN_HEIGHT * 0.8, paddingTop: '3%', }, - scrollView: { - paddingHorizontal: 20, - }, - scrollViewContent: { - justifyContent: 'center', - }, }); export default MomentCommentsScreen; diff --git a/src/screens/profile/SocialMediaTaggs.tsx b/src/screens/profile/SocialMediaTaggs.tsx index 9186f187..52d20683 100644 --- a/src/screens/profile/SocialMediaTaggs.tsx +++ b/src/screens/profile/SocialMediaTaggs.tsx @@ -59,7 +59,7 @@ const SocialMediaTaggs: React.FC<SocialMediaTaggsProps> = ({ useEffect(() => { navigation.setOptions({ headerTitle: () => { - return <AvatarTitle avatar={avatar ?? null} />; + return <AvatarTitle avatar={avatar} />; }, }); }, [avatar, navigation]); |
