aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/assets/images/no_chats.pngbin0 -> 28760 bytes
-rw-r--r--src/assets/images/no_chats@2x.pngbin0 -> 12709 bytes
-rw-r--r--src/assets/images/no_chats@3x.pngbin0 -> 46139 bytes
-rw-r--r--src/components/comments/AddComment.tsx11
-rw-r--r--src/components/common/Avatar.tsx18
-rw-r--r--src/components/common/AvatarTitle.tsx14
-rw-r--r--src/components/common/EmptyContentView.tsx132
-rw-r--r--src/components/common/index.ts1
-rw-r--r--src/components/messages/ChannelPreview.tsx9
-rw-r--r--src/components/messages/ChatHeader.tsx11
-rw-r--r--src/components/messages/ChatInput.tsx12
-rw-r--r--src/components/messages/MessageAvatar.tsx15
-rw-r--r--src/components/moments/MomentPostHeader.tsx4
-rw-r--r--src/components/notifications/Notification.tsx10
-rw-r--r--src/components/profile/ProfileHeader.tsx17
-rw-r--r--src/components/profile/ProfilePreview.tsx13
-rw-r--r--src/components/profile/TaggAvatar.tsx (renamed from src/components/profile/Avatar.tsx)21
-rw-r--r--src/components/profile/index.ts1
-rw-r--r--src/components/search/ExploreSectionUser.tsx16
-rw-r--r--src/components/search/SearchResultCell.tsx8
-rw-r--r--src/components/taggs/TwitterTaggPost.tsx21
-rw-r--r--src/constants/strings.ts2
-rw-r--r--src/screens/badge/BadgeScreenHeader.tsx4
-rw-r--r--src/screens/chat/ChatListScreen.tsx4
-rw-r--r--src/screens/chat/ChatResultsCell.tsx10
-rw-r--r--src/screens/main/NotificationsScreen.tsx4
-rw-r--r--src/screens/main/notification/EmptyNotificationView.tsx48
-rw-r--r--src/screens/onboarding/Login.tsx2
-rw-r--r--src/screens/onboarding/OnboardingStepThree.tsx5
-rw-r--r--src/screens/profile/SocialMediaTaggs.tsx2
-rw-r--r--src/types/types.ts3
-rw-r--r--src/utils/users.ts5
32 files changed, 225 insertions, 198 deletions
diff --git a/src/assets/images/no_chats.png b/src/assets/images/no_chats.png
new file mode 100644
index 00000000..4e321f17
--- /dev/null
+++ b/src/assets/images/no_chats.png
Binary files differ
diff --git a/src/assets/images/no_chats@2x.png b/src/assets/images/no_chats@2x.png
new file mode 100644
index 00000000..d906df09
--- /dev/null
+++ b/src/assets/images/no_chats@2x.png
Binary files differ
diff --git a/src/assets/images/no_chats@3x.png b/src/assets/images/no_chats@3x.png
new file mode 100644
index 00000000..f0f05c7b
--- /dev/null
+++ b/src/assets/images/no_chats@3x.png
Binary files differ
diff --git a/src/components/comments/AddComment.tsx b/src/components/comments/AddComment.tsx
index 3b195a2b..2a8c773e 100644
--- a/src/components/comments/AddComment.tsx
+++ b/src/components/comments/AddComment.tsx
@@ -1,6 +1,5 @@
import React, {useEffect, useRef} from 'react';
import {
- Image,
Keyboard,
KeyboardAvoidingView,
Platform,
@@ -15,6 +14,7 @@ import {postComment} from '../../services';
import {updateReplyPosted} from '../../store/actions';
import {RootState} from '../../store/rootreducer';
import {SCREEN_HEIGHT, SCREEN_WIDTH} from '../../utils';
+import {Avatar} from '../common';
/**
* This file provides the add comment view for a user.
@@ -101,14 +101,7 @@ const AddComment: React.FC<AddCommentProps> = ({
keyboardVisible ? styles.whiteBackround : {},
]}>
<View style={styles.textContainer}>
- <Image
- style={styles.avatar}
- source={
- avatar
- ? {uri: avatar}
- : require('../../assets/images/avatar-placeholder.png')
- }
- />
+ <Avatar style={styles.avatar} uri={avatar} />
<TextInput
style={styles.text}
placeholder={placeholderText}
diff --git a/src/components/common/Avatar.tsx b/src/components/common/Avatar.tsx
new file mode 100644
index 00000000..831cf906
--- /dev/null
+++ b/src/components/common/Avatar.tsx
@@ -0,0 +1,18 @@
+import React, {FC} from 'react';
+import {Image, ImageStyle, StyleProp} from 'react-native';
+
+type AvatarProps = {
+ style: StyleProp<ImageStyle>;
+ uri: string | undefined;
+};
+const Avatar: FC<AvatarProps> = ({style, uri}) => {
+ return (
+ <Image
+ style={style}
+ defaultSource={require('../../assets/images/avatar-placeholder.png')}
+ source={{uri, cache: 'reload'}}
+ />
+ );
+};
+
+export default Avatar;
diff --git a/src/components/common/AvatarTitle.tsx b/src/components/common/AvatarTitle.tsx
index 81351327..a2a7c0aa 100644
--- a/src/components/common/AvatarTitle.tsx
+++ b/src/components/common/AvatarTitle.tsx
@@ -1,10 +1,11 @@
import React from 'react';
-import {Image, StyleSheet, View} from 'react-native';
+import {StyleSheet, View} from 'react-native';
import LinearGradient from 'react-native-linear-gradient';
import {TAGGS_GRADIENT} from '../../constants';
+import Avatar from './Avatar';
type AvatarTitleProps = {
- avatar: string | null;
+ avatar: string | undefined;
};
const AvatarTitle: React.FC<AvatarTitleProps> = ({avatar}) => {
return (
@@ -16,14 +17,7 @@ const AvatarTitle: React.FC<AvatarTitleProps> = ({avatar}) => {
angleCenter={{x: 0.5, y: 0.5}}
style={styles.gradient}
/>
- <Image
- style={styles.avatar}
- source={
- avatar
- ? {uri: avatar}
- : require('../../assets/images/avatar-placeholder.png')
- }
- />
+ <Avatar style={styles.avatar} uri={avatar} />
</View>
);
};
diff --git a/src/components/common/EmptyContentView.tsx b/src/components/common/EmptyContentView.tsx
new file mode 100644
index 00000000..14ad4af1
--- /dev/null
+++ b/src/components/common/EmptyContentView.tsx
@@ -0,0 +1,132 @@
+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,
+ FIRST_MESSAGE,
+ START_CHATTING,
+} from '../../constants/strings';
+import {NOTIFICATION_GRADIENT} from '../../constants/constants';
+import {SCREEN_HEIGHT, normalize, SCREEN_WIDTH} from '../../utils';
+import {EmptyViewProps} from '../../types/index';
+
+const EmptyContentView: React.FC<EmptyViewProps> = ({viewType}) => {
+ const _getNotificationImage = () => {
+ return (
+ <LinearGradient
+ style={styles.backgroundLinearView}
+ useAngle={true}
+ angle={180}
+ colors={NOTIFICATION_GRADIENT}>
+ <Image
+ source={require('../../assets/images/empty_notifications.png')}
+ />
+ </LinearGradient>
+ );
+ };
+
+ const _getChatImage = () => {
+ return (
+ <LinearGradient
+ style={styles.backgroundLinearView}
+ useAngle={true}
+ angle={180}
+ colors={NOTIFICATION_GRADIENT}>
+ <Image
+ style={styles.imageStyles}
+ source={require('../../assets/images/no_chats.png')}
+ />
+ </LinearGradient>
+ );
+ };
+
+ const _getImageForType = () => {
+ switch (viewType) {
+ case 'Notification':
+ return _getNotificationImage();
+ case 'ChatList':
+ return _getChatImage();
+ }
+ };
+
+ const _getTextForNotification = () => {
+ return (
+ <>
+ <View style={styles.topMargin}>
+ <Text style={styles.upperTextStyle}>{UP_TO_DATE}</Text>
+ </View>
+ <View>
+ <Text style={styles.bottomTextStyle}>{NO_NEW_NOTIFICATIONS}</Text>
+ </View>
+ </>
+ );
+ };
+
+ const _getTextForChat = () => {
+ return (
+ <View style={styles.chatTextStyles}>
+ <View style={styles.topMargin}>
+ <Text style={styles.upperTextStyle}>{START_CHATTING}</Text>
+ </View>
+ <View>
+ <Text style={styles.bottomTextStyle}>{FIRST_MESSAGE}</Text>
+ </View>
+ </View>
+ );
+ };
+
+ const _getTextForType = () => {
+ switch (viewType) {
+ case 'Notification':
+ return _getTextForNotification();
+ case 'ChatList':
+ return _getTextForChat();
+ }
+ };
+
+ return (
+ <View style={styles.container}>
+ {_getImageForType()}
+ {_getTextForType()}
+ </View>
+ );
+};
+
+const styles = StyleSheet.create({
+ container: {
+ flex: 1,
+ flexDirection: 'column',
+ justifyContent: 'center',
+ alignItems: 'center',
+ },
+ topMargin: {
+ marginTop: SCREEN_HEIGHT * 0.025,
+ paddingBottom: '5%',
+ },
+ upperTextStyle: {
+ textAlign: 'center',
+ fontWeight: '700',
+ fontSize: normalize(23),
+ lineHeight: normalize(40),
+ },
+ chatTextStyles: {
+ width: '85%',
+ },
+ bottomTextStyle: {
+ textAlign: 'center',
+ color: '#808080',
+ fontWeight: '600',
+ fontSize: normalize(20),
+ lineHeight: normalize(30),
+ },
+ imageStyles: {
+ width: SCREEN_WIDTH * 0.72,
+ height: SCREEN_WIDTH * 0.72,
+ },
+ backgroundLinearView: {
+ borderRadius: (SCREEN_WIDTH * 0.72) / 2,
+ },
+});
+
+export default EmptyContentView;
diff --git a/src/components/common/index.ts b/src/components/common/index.ts
index 5a601f1d..802cf505 100644
--- a/src/components/common/index.ts
+++ b/src/components/common/index.ts
@@ -23,3 +23,4 @@ export {default as FriendsButton} from './FriendsButton';
export {default as TaggSquareButton} from './TaggSquareButton';
export {default as GradientBorderButton} from './GradientBorderButton';
export {default as BasicButton} from './BasicButton';
+export {default as Avatar} from './Avatar';
diff --git a/src/components/messages/ChannelPreview.tsx b/src/components/messages/ChannelPreview.tsx
index 3d31d42a..878e5a6b 100644
--- a/src/components/messages/ChannelPreview.tsx
+++ b/src/components/messages/ChannelPreview.tsx
@@ -22,6 +22,7 @@ import {
} from '../../types';
import {normalize, SCREEN_HEIGHT, SCREEN_WIDTH} from '../../utils';
import {getMember, isOnline} from '../../utils/messages';
+import {Avatar} from '../common';
const ChannelPreview: React.FC<
ChannelPreviewMessengerProps<
@@ -87,13 +88,9 @@ const ChannelPreview: React.FC<
navigation.navigate('Chat');
}}>
<View>
- <Image
+ <Avatar
style={styles.avatar}
- source={
- member
- ? {uri: member.user?.thumbnail_url}
- : require('../../assets/images/avatar-placeholder.png')
- }
+ uri={member?.user?.thumbnail_url as string}
/>
{online && <View style={styles.online} />}
</View>
diff --git a/src/components/messages/ChatHeader.tsx b/src/components/messages/ChatHeader.tsx
index 7ddaa7e6..37dab0fd 100644
--- a/src/components/messages/ChatHeader.tsx
+++ b/src/components/messages/ChatHeader.tsx
@@ -1,6 +1,6 @@
import {useNavigation} from '@react-navigation/native';
import React, {useContext} from 'react';
-import {Image, StyleSheet, View} from 'react-native';
+import {StyleSheet, View} from 'react-native';
import {Text} from 'react-native-animatable';
import {TouchableOpacity} from 'react-native-gesture-handler';
import {useDispatch, useStore} from 'react-redux';
@@ -15,6 +15,7 @@ import {
userXInStore,
} from '../../utils';
import {formatLastSeenText, getMember, isOnline} from '../../utils/messages';
+import {Avatar} from '../common';
type ChatHeaderProps = {
screenType: ScreenType;
@@ -50,13 +51,9 @@ const ChatHeader: React.FC<ChatHeaderProps> = (props) => {
<View style={styles.container}>
<TouchableOpacity style={styles.tappables} onPress={toProfile}>
<View>
- <Image
+ <Avatar
style={styles.avatar}
- source={
- member
- ? {uri: member.user?.thumbnail_url}
- : require('../../assets/images/avatar-placeholder.png')
- }
+ uri={member?.user?.thumbnail_url as string}
/>
{online && <View style={styles.online} />}
</View>
diff --git a/src/components/messages/ChatInput.tsx b/src/components/messages/ChatInput.tsx
index a6e5c458..5585d246 100644
--- a/src/components/messages/ChatInput.tsx
+++ b/src/components/messages/ChatInput.tsx
@@ -1,5 +1,5 @@
import React from 'react';
-import {Image, StyleSheet, View} from 'react-native';
+import {StyleSheet, View} from 'react-native';
import {useStore} from 'react-redux';
import {
AutoCompleteInput,
@@ -17,6 +17,7 @@ import {
LocalUserType,
} from '../../types';
import {normalize} from '../../utils';
+import {Avatar} from '../common';
import {ChatInputSubmit} from '../messages';
const ChatInput: React.FC<
@@ -65,14 +66,7 @@ const ChatInput: React.FC<
return (
<View style={styles.container}>
<View style={styles.textContainer}>
- <Image
- style={styles.avatar}
- source={
- avatar
- ? {uri: avatar}
- : require('../../assets/images/avatar-placeholder.png')
- }
- />
+ <Avatar style={styles.avatar} uri={avatar} />
<AutoCompleteInput />
<View style={styles.actionButtons}>
{/* TODO: Not working, toggled off for now */}
diff --git a/src/components/messages/MessageAvatar.tsx b/src/components/messages/MessageAvatar.tsx
index d275eae5..bcd4e7a8 100644
--- a/src/components/messages/MessageAvatar.tsx
+++ b/src/components/messages/MessageAvatar.tsx
@@ -1,9 +1,10 @@
import React, {useContext} from 'react';
-import {Image, StyleSheet, View} from 'react-native';
-import {getMember, normalize} from '../../utils';
-import {useMessageContext} from 'stream-chat-react-native-core';
+import {StyleSheet, View} from 'react-native';
import {useStore} from 'react-redux';
+import {useMessageContext} from 'stream-chat-react-native-core';
import {ChatContext} from '../../App';
+import {getMember, normalize} from '../../utils';
+import {Avatar} from '../common';
const MessageAvatar: React.FC = () => {
const {channel} = useContext(ChatContext);
@@ -14,13 +15,9 @@ const MessageAvatar: React.FC = () => {
return (
<View style={styles.messageAvatarContainer}>
{message.lastGroupMessage === true && (
- <Image
+ <Avatar
style={styles.messageAvatar}
- source={
- member
- ? {uri: member.user?.thumbnail_url}
- : require('../../assets/images/avatar-placeholder.png')
- }
+ uri={member?.user?.thumbnail_url as string}
/>
)}
</View>
diff --git a/src/components/moments/MomentPostHeader.tsx b/src/components/moments/MomentPostHeader.tsx
index 8cf509ab..20d9150a 100644
--- a/src/components/moments/MomentPostHeader.tsx
+++ b/src/components/moments/MomentPostHeader.tsx
@@ -10,7 +10,7 @@ import {MomentMoreInfoDrawer} from '../profile';
import {loadUserMoments} from '../../store/actions';
import {useDispatch, useSelector, useStore} from 'react-redux';
import {ScreenType} from '../../types';
-import Avatar from '../profile/Avatar';
+import TaggAvatar from '../profile/TaggAvatar';
import {useNavigation} from '@react-navigation/native';
import {RootState} from '../../store/rootReducer';
import {fetchUserX, userXInStore} from '../../utils';
@@ -54,7 +54,7 @@ const MomentPostHeader: React.FC<MomentPostHeaderProps> = ({
return (
<View style={[styles.container, style]}>
<TouchableOpacity onPress={navigateToProfile} style={styles.header}>
- <Avatar
+ <TaggAvatar
style={styles.avatar}
userXId={userXId}
screenType={screenType}
diff --git a/src/components/notifications/Notification.tsx b/src/components/notifications/Notification.tsx
index 3cc1c7f1..a74480b4 100644
--- a/src/components/notifications/Notification.tsx
+++ b/src/components/notifications/Notification.tsx
@@ -30,6 +30,7 @@ import {
SCREEN_WIDTH,
userXInStore,
} from '../../utils';
+import {Avatar} from '../common';
import AcceptDeclineButtons from '../common/AcceptDeclineButtons';
interface NotificationProps {
@@ -225,14 +226,7 @@ const Notification: React.FC<NotificationProps> = (props) => {
<TouchableWithoutFeedback
onPress={navigateToProfile}
style={styles.avatarContainer}>
- <Image
- style={styles.avatar}
- source={
- avatar
- ? {uri: avatar, cache: 'reload'}
- : require('../../assets/images/avatar-placeholder.png')
- }
- />
+ <Avatar style={styles.avatar} uri={avatar} />
</TouchableWithoutFeedback>
{notification_type === 'SYSTEM_MSG' ? (
// Only verbage
diff --git a/src/components/profile/ProfileHeader.tsx b/src/components/profile/ProfileHeader.tsx
index 1231717f..14f7dc71 100644
--- a/src/components/profile/ProfileHeader.tsx
+++ b/src/components/profile/ProfileHeader.tsx
@@ -8,7 +8,7 @@ import {RootState} from '../../store/rootreducer';
import {ScreenType} from '../../types';
import {hasSeenBadgeTutorial, normalize} from '../../utils';
import BadgeDetailView from '../common/BadgeDetailView';
-import Avatar from './Avatar';
+import TaggAvatar from './TaggAvatar';
import BadgeTutorial from './BadgeTutorial';
import FriendsCount from './FriendsCount';
import ProfileMoreInfoDrawer from './ProfileMoreInfoDrawer';
@@ -45,7 +45,6 @@ const ProfileHeader: React.FC<ProfileHeaderProps> = ({
const [drawerVisible, setDrawerVisible] = useState(false);
const [showBadgeView, setBadgeViewVisible] = useState(false);
- const [firstName, lastName] = [...name.split(' ')];
const containerRef = useRef(null);
const childRef = useRef(null);
@@ -112,21 +111,15 @@ const ProfileHeader: React.FC<ProfileHeaderProps> = ({
/>
)}
<View style={styles.row}>
- <Avatar
+ <TaggAvatar
style={styles.avatar}
userXId={userXId}
screenType={screenType}
/>
<View style={styles.header}>
- {name.length <= 16 ? (
- <Text style={styles.name}>{name}</Text>
- ) : (
- <View>
- <Text style={styles.name}>{firstName}</Text>
- <Text style={styles.name}>{lastName}</Text>
- </View>
- )}
-
+ <Text style={styles.name} numberOfLines={2}>
+ {name}
+ </Text>
<View style={styles.friendsAndUniversity}>
<FriendsCount screenType={screenType} userXId={userXId} />
<TouchableOpacity
diff --git a/src/components/profile/ProfilePreview.tsx b/src/components/profile/ProfilePreview.tsx
index bea989d9..66d68d8f 100644
--- a/src/components/profile/ProfilePreview.tsx
+++ b/src/components/profile/ProfilePreview.tsx
@@ -2,7 +2,6 @@ import {useNavigation} from '@react-navigation/native';
import React, {useEffect, useState} from 'react';
import {
Alert,
- Image,
StyleSheet,
Text,
TouchableOpacity,
@@ -23,6 +22,7 @@ import {
userXInStore,
} from '../../utils';
import {addUserToRecentlySearched} from '../../utils/search';
+import {Avatar} from '../common';
/**
* This component returns user's profile picture friended by username as a touchable component.
@@ -48,7 +48,7 @@ const ProfilePreview: React.FC<ProfilePreviewProps> = ({
}) => {
const navigation = useNavigation();
const {user: loggedInUser} = useSelector((state: RootState) => state.user);
- const [avatar, setAvatar] = useState<string | null>(null);
+ const [avatar, setAvatar] = useState<string>();
const dispatch = useDispatch();
useEffect(() => {
@@ -187,14 +187,7 @@ const ProfilePreview: React.FC<ProfilePreviewProps> = ({
<TouchableOpacity
onPress={addToRecentlyStoredAndNavigateToProfile}
style={containerStyle}>
- <Image
- style={avatarStyle}
- source={
- avatar
- ? {uri: avatar}
- : require('../../assets/images/avatar-placeholder.png')
- }
- />
+ <Avatar style={avatarStyle} uri={avatar} />
<View style={nameContainerStyle}>
{(previewType === 'Search' || previewType === 'Recent') && (
<>
diff --git a/src/components/profile/Avatar.tsx b/src/components/profile/TaggAvatar.tsx
index e57a56a3..ea0bdb65 100644
--- a/src/components/profile/Avatar.tsx
+++ b/src/components/profile/TaggAvatar.tsx
@@ -1,28 +1,27 @@
import React from 'react';
-import {Image, StyleSheet} from 'react-native';
+import {StyleSheet} from 'react-native';
import {useSelector} from 'react-redux';
import {RootState} from '../../store/rootreducer';
import {ScreenType} from '../../types';
+import {Avatar} from '../common';
const PROFILE_DIM = 100;
-interface AvatarProps {
+interface TaggAvatarProps {
style?: object;
userXId: string | undefined;
screenType: ScreenType;
}
-const Avatar: React.FC<AvatarProps> = ({style, screenType, userXId}) => {
+const TaggAvatar: React.FC<TaggAvatarProps> = ({
+ style,
+ screenType,
+ userXId,
+}) => {
const {avatar} = useSelector((state: RootState) =>
userXId ? state.userX[screenType][userXId] : state.user,
);
- return (
- <Image
- style={[styles.image, style]}
- defaultSource={require('../../assets/images/avatar-placeholder.png')}
- source={{uri: avatar, cache: 'reload'}}
- />
- );
+ return <Avatar style={[styles.image, style]} uri={avatar} />;
};
const styles = StyleSheet.create({
@@ -33,4 +32,4 @@ const styles = StyleSheet.create({
},
});
-export default Avatar;
+export default TaggAvatar;
diff --git a/src/components/profile/index.ts b/src/components/profile/index.ts
index 260f4217..c544c3f2 100644
--- a/src/components/profile/index.ts
+++ b/src/components/profile/index.ts
@@ -8,3 +8,4 @@ export {default as Friends} from './Friends';
export {default as ProfileMoreInfoDrawer} from './ProfileMoreInfoDrawer';
export {default as MomentMoreInfoDrawer} from './MomentMoreInfoDrawer';
export {default as UniversityIcon} from './UniversityIcon';
+export {default as TaggAvatar} from './TaggAvatar';
diff --git a/src/components/search/ExploreSectionUser.tsx b/src/components/search/ExploreSectionUser.tsx
index d8c92be2..c949acd4 100644
--- a/src/components/search/ExploreSectionUser.tsx
+++ b/src/components/search/ExploreSectionUser.tsx
@@ -1,13 +1,13 @@
import {useNavigation} from '@react-navigation/native';
import React, {useEffect, useState} from 'react';
-import {TextStyle, ViewStyle} from 'react-native';
import {
- Image,
StyleProp,
StyleSheet,
Text,
+ TextStyle,
TouchableOpacity,
ViewProps,
+ ViewStyle,
} from 'react-native';
import LinearGradient from 'react-native-linear-gradient';
import {useDispatch, useSelector, useStore} from 'react-redux';
@@ -15,6 +15,7 @@ import {loadImageFromURL} from '../../services';
import {RootState} from '../../store/rootReducer';
import {ProfilePreviewType, ScreenType} from '../../types';
import {fetchUserX, normalize, userXInStore} from '../../utils';
+import {Avatar} from '../common';
/**
* Search Screen for user recommendations and a search
@@ -30,7 +31,7 @@ const ExploreSectionUser: React.FC<ExploreSectionUserProps> = ({
externalStyles,
}) => {
const {id, username, first_name, last_name} = user;
- const [avatar, setAvatar] = useState<string | null>(null);
+ const [avatar, setAvatar] = useState<string>();
const navigation = useNavigation();
const {user: loggedInUser} = useSelector((state: RootState) => state.user);
const state: RootState = useStore().getState();
@@ -71,14 +72,7 @@ const ExploreSectionUser: React.FC<ExploreSectionUserProps> = ({
angle={90}
angleCenter={{x: 0.5, y: 0.5}}
style={styles.gradient}>
- <Image
- source={
- avatar
- ? {uri: avatar}
- : require('../../assets/images/avatar-placeholder.png')
- }
- style={styles.profile}
- />
+ <Avatar style={styles.profile} uri={avatar} />
</LinearGradient>
<Text style={[styles.name, externalStyles?.name]} numberOfLines={2}>
{first_name} {last_name}
diff --git a/src/components/search/SearchResultCell.tsx b/src/components/search/SearchResultCell.tsx
index 5a6ea110..16e62a53 100644
--- a/src/components/search/SearchResultCell.tsx
+++ b/src/components/search/SearchResultCell.tsx
@@ -22,10 +22,10 @@ import {
} from '../../utils';
import {
checkIfUserIsBlocked,
- defaultUserProfile,
fetchUserX,
userXInStore,
} from '../../utils/users';
+import {Avatar} from '../common';
interface SearchResults {
profileData: ProfilePreviewType;
@@ -129,11 +129,7 @@ const SearchResultsCell: React.FC<SearchResults> = ({
<TouchableOpacity
onPress={addToRecentlyStoredAndNavigateToProfile}
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/components/taggs/TwitterTaggPost.tsx b/src/components/taggs/TwitterTaggPost.tsx
index 0a6f53d8..db07ba66 100644
--- a/src/components/taggs/TwitterTaggPost.tsx
+++ b/src/components/taggs/TwitterTaggPost.tsx
@@ -11,7 +11,7 @@ import {
} from '../../constants';
import {TwitterPostType} from '../../types';
import {handleOpenSocialUrlOnBrowser, SCREEN_WIDTH} from '../../utils';
-import {DateLabel, PostCarousel} from '../common';
+import {Avatar, DateLabel, PostCarousel} from '../common';
interface TwitterTaggPostProps {
ownerHandle: string;
@@ -31,14 +31,7 @@ const TwitterTaggPost: React.FC<TwitterTaggPostProps> = ({
)}
{/* Post header (avatar and handle) */}
<View style={styles.header}>
- <Image
- style={styles.avatar}
- source={
- post.profile_pic
- ? {uri: post.profile_pic}
- : require('../../assets/images/avatar-placeholder.png')
- }
- />
+ <Avatar style={styles.avatar} uri={post.profile_pic} />
<Text
style={styles.headerText}
onPress={() => handleOpenSocialUrlOnBrowser(post.handle, 'Twitter')}>
@@ -84,13 +77,9 @@ const TwitterTaggPost: React.FC<TwitterTaggPostProps> = ({
<View style={styles.replyHeader}>
{post.in_reply_to.text !== 'This tweet is unavailable' && (
<>
- <Image
- style={styles.replyAvatar}
- source={
- post.in_reply_to.profile_pic
- ? {uri: post.in_reply_to.profile_pic}
- : require('../../assets/images/avatar-placeholder.png')
- }
+ <Avatar
+ style={styles.avatar}
+ uri={post.in_reply_to.profile_pic}
/>
<Text
style={styles.replyHandleText}
diff --git a/src/constants/strings.ts b/src/constants/strings.ts
index 50e4518b..e8f2725d 100644
--- a/src/constants/strings.ts
+++ b/src/constants/strings.ts
@@ -56,6 +56,8 @@ export const ERROR_UPLOAD_MOMENT = 'Unable to upload moment. Please retry';
export const ERROR_UPLOAD_SMALL_PROFILE_PIC = "Can't have a profile without a pic to represent you, please upload a small profile picture";
export const ERROR_UPLOAD_SP_PHOTO = 'Unable to update suggested people photo. Please retry!';
export const ERROR_VERIFICATION_FAILED_SHORT = 'Verification failed 😓';
+export const FIRST_MESSAGE = 'How about sending your first message to your friend';
+export const START_CHATTING = 'Let’s Start Chatting!';
export const MARKED_AS_MSG = (str: string) => `Marked as ${str}`;
export const MOMENT_DELETED_MSG = 'Moment deleted....Some moments have to go, to create space for greater ones';
export const NO_NEW_NOTIFICATIONS = 'You have no new notifications';
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/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/main/NotificationsScreen.tsx b/src/screens/main/NotificationsScreen.tsx
index 3efd9af8..9fbc4cfe 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/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]);
diff --git a/src/types/types.ts b/src/types/types.ts
index e7f651dc..ce39947c 100644
--- a/src/types/types.ts
+++ b/src/types/types.ts
@@ -23,6 +23,9 @@ export interface CategoryPreviewType {
}
export type FriendshipStatusType = 'friends' | 'requested' | 'no_record';
+export interface EmptyViewProps {
+ viewType: 'Notification' | 'ChatList';
+}
export enum UniversityType {
Brown = 'Brown University',
diff --git a/src/utils/users.ts b/src/utils/users.ts
index 7148eb79..abadaf6e 100644
--- a/src/utils/users.ts
+++ b/src/utils/users.ts
@@ -168,11 +168,6 @@ export const checkIfUserIsBlocked = async (
return await isUserBlocked(userId, loggedInUser.userId, token);
};
-export const defaultUserProfile = () => {
- const defaultImage = require('../assets/images/avatar-placeholder.png');
- return defaultImage;
-};
-
/**
* Used to determine whether the logged-in user is able to view userX's private
* information or not.