diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/assets/images/mute.png | bin | 0 -> 1560 bytes | |||
-rw-r--r-- | src/assets/images/unmute.png | bin | 0 -> 1279 bytes | |||
-rw-r--r-- | src/components/common/BadgeDetailView.tsx | 2 | ||||
-rw-r--r-- | src/components/messages/ChannelPreview.tsx | 144 | ||||
-rw-r--r-- | src/components/profile/Content.tsx | 8 | ||||
-rw-r--r-- | src/components/profile/ProfileHeader.tsx | 9 | ||||
-rw-r--r-- | src/routes/main/MainStackScreen.tsx | 47 | ||||
-rw-r--r-- | src/screens/chat/ChatScreen.tsx | 1 | ||||
-rw-r--r-- | src/screens/suggestedPeople/SuggestedPeopleScreen.tsx | 9 |
9 files changed, 146 insertions, 74 deletions
diff --git a/src/assets/images/mute.png b/src/assets/images/mute.png Binary files differnew file mode 100644 index 00000000..b330e259 --- /dev/null +++ b/src/assets/images/mute.png diff --git a/src/assets/images/unmute.png b/src/assets/images/unmute.png Binary files differnew file mode 100644 index 00000000..7fe1782d --- /dev/null +++ b/src/assets/images/unmute.png diff --git a/src/components/common/BadgeDetailView.tsx b/src/components/common/BadgeDetailView.tsx index 32cc7aa4..437b1914 100644 --- a/src/components/common/BadgeDetailView.tsx +++ b/src/components/common/BadgeDetailView.tsx @@ -78,7 +78,7 @@ const BadgeDetailView: React.FC<BadgeDetailModalProps> = ({ setTimeout(() => { setSelectedBadgesWithImage(badgesWithImage); setIsLoading(false); - }, 500); + }, 250); }, [selectedBadges]); const removeBadgeCell = async (badge: string) => { diff --git a/src/components/messages/ChannelPreview.tsx b/src/components/messages/ChannelPreview.tsx index 8bd3a745..3d31d42a 100644 --- a/src/components/messages/ChannelPreview.tsx +++ b/src/components/messages/ChannelPreview.tsx @@ -1,10 +1,15 @@ import {useNavigation} from '@react-navigation/core'; -import React, {useContext} from 'react'; +import React, {useContext, useState} from 'react'; import {Image, StyleSheet, Text, View} from 'react-native'; -import {TouchableOpacity} from 'react-native-gesture-handler'; +import { + RectButton, + Swipeable, + TouchableOpacity, +} from 'react-native-gesture-handler'; import {useStore} from 'react-redux'; import {ChannelPreviewMessengerProps} from 'stream-chat-react-native'; import {ChatContext} from '../../App'; +import Trash from '../../assets/ionicons/trash-outline.svg'; import {TAGG_LIGHT_BLUE_2} from '../../constants'; import { LocalAttachmentType, @@ -36,41 +41,79 @@ const ChannelPreview: React.FC< const member = getMember(channel, state); const online = isOnline(member?.user?.last_active); const unread = channel.state.unreadCount > 0; + const [isMuted, setIsMuted] = useState(channel.muteStatus().muted); + const mutedImage = isMuted + ? require('../../assets/images/unmute.png') + : require('../../assets/images/mute.png'); + + // Hide channel if no message was exchanged + if (channel.state.messages.length === 0) { + return null; + } return ( - <TouchableOpacity - style={styles.container} - onPress={() => { - setChannel(channel); - navigation.navigate('Chat'); - }}> - <View> - <Image - style={styles.avatar} - source={ - member - ? {uri: member.user?.thumbnail_url} - : require('../../assets/images/avatar-placeholder.png') - } - /> - {online && <View style={styles.online} />} - </View> - <View style={styles.content}> - <Text - style={[styles.name, unread ? styles.unread : {}]} - numberOfLines={1}> - {member?.user?.first_name} {member?.user?.last_name} - </Text> - <Text - style={[styles.lastMessage, unread ? styles.unread : {}]} - numberOfLines={1}> - {channel.state.messages.length > 0 - ? channel.state.messages[channel.state.messages.length - 1].text - : ''} - </Text> - </View> - {unread && <View style={styles.purpleDot} />} - </TouchableOpacity> + <Swipeable + overshootLeft={false} + overshootRight={false} + renderRightActions={() => ( + <View style={styles.swipeableContainer}> + <RectButton + style={styles.muteButton} + onPress={() => { + if (isMuted) { + channel.unmute(); + } else { + channel.mute(); + } + setIsMuted(!isMuted); + }}> + <Image source={mutedImage} style={styles.icon} /> + <Text style={styles.actionText}>{isMuted ? 'Unmute' : 'Mute'}</Text> + </RectButton> + <RectButton + style={styles.deleteButton} + onPress={() => { + channel.hide(); + }}> + <Trash style={styles.icon} color={'white'} /> + <Text style={styles.actionText}>Delete</Text> + </RectButton> + </View> + )}> + <TouchableOpacity + style={styles.container} + onPress={() => { + setChannel(channel); + navigation.navigate('Chat'); + }}> + <View> + <Image + style={styles.avatar} + source={ + member + ? {uri: member.user?.thumbnail_url} + : require('../../assets/images/avatar-placeholder.png') + } + /> + {online && <View style={styles.online} />} + </View> + <View style={styles.content}> + <Text + style={[styles.name, unread ? styles.unread : {}]} + numberOfLines={1}> + {member?.user?.first_name} {member?.user?.last_name} + </Text> + <Text + style={[styles.lastMessage, unread ? styles.unread : {}]} + numberOfLines={1}> + {channel.state.messages.length > 0 + ? channel.state.messages[channel.state.messages.length - 1].text + : ''} + </Text> + </View> + {unread && <View style={styles.purpleDot} />} + </TouchableOpacity> + </Swipeable> ); }; @@ -128,6 +171,37 @@ const styles = StyleSheet.create({ borderRadius: normalize(10) / 2, marginLeft: '5%', }, + swipeableContainer: { + alignItems: 'center', + justifyContent: 'center', + flexDirection: 'row', + }, + muteButton: { + width: 72, + height: '100%', + justifyContent: 'center', + alignItems: 'center', + backgroundColor: '#C4C4C4', + }, + deleteButton: { + width: 72, + height: '100%', + justifyContent: 'center', + alignItems: 'center', + backgroundColor: '#C42634', + }, + actionText: { + color: 'white', + fontSize: normalize(12), + fontWeight: '500', + backgroundColor: 'transparent', + paddingHorizontal: '5%', + marginTop: '5%', + }, + icon: { + width: normalize(25), + height: normalize(25), + }, }); export default ChannelPreview; diff --git a/src/components/profile/Content.tsx b/src/components/profile/Content.tsx index c70d6df5..8298dc9a 100644 --- a/src/components/profile/Content.tsx +++ b/src/components/profile/Content.tsx @@ -145,7 +145,13 @@ const Content: React.FC<ContentProps> = ({userXId, screenType}) => { <Cover {...{userXId, screenType}} /> <ProfileCutout /> <ProfileHeader - {...{userXId, screenType, handleBlockUnblock, isBlocked}} + {...{ + userXId, + screenType, + handleBlockUnblock, + isBlocked, + isPrivate: !canViewProfile(state, userXId, screenType), + }} /> <ProfileBody {...{ diff --git a/src/components/profile/ProfileHeader.tsx b/src/components/profile/ProfileHeader.tsx index 9dc58501..494b33bd 100644 --- a/src/components/profile/ProfileHeader.tsx +++ b/src/components/profile/ProfileHeader.tsx @@ -17,6 +17,7 @@ type ProfileHeaderProps = { screenType: ScreenType; isBlocked: boolean; handleBlockUnblock: () => void; + isPrivate?: boolean; }; const ProfileHeader: React.FC<ProfileHeaderProps> = ({ @@ -24,6 +25,7 @@ const ProfileHeader: React.FC<ProfileHeaderProps> = ({ screenType, isBlocked, handleBlockUnblock, + isPrivate, }) => { const { profile: {name = '', university_class = 2021, university}, @@ -67,7 +69,12 @@ const ProfileHeader: React.FC<ProfileHeaderProps> = ({ )} <View style={styles.friendsAndUniversity}> <FriendsCount screenType={screenType} userXId={userXId} /> - <TouchableOpacity onPress={() => setBadgeViewVisible(true)}> + <TouchableOpacity + onPress={() => { + if (!isPrivate) { + setBadgeViewVisible(true); + } + }}> <UniversityIcon {...{university, university_class, needsShadow: true}} /> diff --git a/src/routes/main/MainStackScreen.tsx b/src/routes/main/MainStackScreen.tsx index 37867151..f5100e58 100644 --- a/src/routes/main/MainStackScreen.tsx +++ b/src/routes/main/MainStackScreen.tsx @@ -1,7 +1,6 @@ -import AsyncStorage from '@react-native-community/async-storage'; import {RouteProp} from '@react-navigation/native'; import {StackNavigationOptions} from '@react-navigation/stack'; -import React, {useEffect, useState} from 'react'; +import React from 'react'; import {StyleSheet, Text} from 'react-native'; import {normalize} from 'react-native-elements'; import BackIcon from '../../assets/icons/back-arrow.svg'; @@ -56,28 +55,9 @@ interface MainStackProps { const MainStackScreen: React.FC<MainStackProps> = ({route}) => { const {screenType} = route.params; - // const isProfileTab = screenType === ScreenType.Profile; const isSearchTab = screenType === ScreenType.Search; const isNotificationsTab = screenType === ScreenType.Notifications; const isSuggestedPeopleTab = screenType === ScreenType.SuggestedPeople; - const [respondedToAccessContacts, setRespondedToAccessContacts] = useState( - 'true', - ); - - useEffect(() => { - loadResponseToAccessContacts(); - }, []); - - const loadResponseToAccessContacts = () => { - AsyncStorage.getItem('respondedToAccessContacts') - .then((value) => { - setRespondedToAccessContacts(value ? value : 'false'); - }) - .catch((error) => { - console.log('Something went wrong', error); - setRespondedToAccessContacts('true'); - }); - }; const initialRouteName = (() => { switch (screenType) { @@ -131,20 +111,13 @@ const MainStackScreen: React.FC<MainStackProps> = ({route}) => { ...headerBarOptions('white', ''), }} /> - {isSuggestedPeopleTab && - (respondedToAccessContacts && respondedToAccessContacts === 'true' ? ( - <MainStack.Screen - name="SuggestedPeople" - component={SuggestedPeopleScreen} - initialParams={{screenType}} - /> - ) : ( - <MainStack.Screen - name="SuggestedPeople" - component={RequestContactsAccess} - initialParams={{screenType}} - /> - ))} + {isSuggestedPeopleTab && ( + <MainStack.Screen + name="SuggestedPeople" + component={SuggestedPeopleScreen} + initialParams={{screenType}} + /> + )} {isNotificationsTab && ( <MainStack.Screen name="Notifications" @@ -271,6 +244,10 @@ const MainStackScreen: React.FC<MainStackProps> = ({route}) => { name="RequestContactsAccess" component={RequestContactsAccess} initialParams={{screenType}} + options={{ + ...modalStyle, + gestureEnabled: false, + }} /> <MainStack.Screen name="EditProfile" diff --git a/src/screens/chat/ChatScreen.tsx b/src/screens/chat/ChatScreen.tsx index 57f2232e..5874b8b6 100644 --- a/src/screens/chat/ChatScreen.tsx +++ b/src/screens/chat/ChatScreen.tsx @@ -154,7 +154,6 @@ const ChatScreen: React.FC<ChatScreenProps> = () => { myMessageTheme={loggedInUsersMessageTheme} MessageAvatar={MessageAvatar}> <MessageList onThreadSelect={() => {}} /> - {/* <MessageInput /> */} <MessageInput Input={ChatInput} /> </Channel> </Chat> diff --git a/src/screens/suggestedPeople/SuggestedPeopleScreen.tsx b/src/screens/suggestedPeople/SuggestedPeopleScreen.tsx index 388a1ba7..f1981111 100644 --- a/src/screens/suggestedPeople/SuggestedPeopleScreen.tsx +++ b/src/screens/suggestedPeople/SuggestedPeopleScreen.tsx @@ -1,3 +1,4 @@ +import AsyncStorage from '@react-native-community/async-storage'; import {useFocusEffect, useNavigation} from '@react-navigation/native'; import React, {useCallback, useEffect, useRef, useState} from 'react'; import {FlatList, RefreshControl, StatusBar, ViewToken} from 'react-native'; @@ -57,6 +58,14 @@ const SuggestedPeopleScreen: React.FC = () => { const stausBarRef = useRef(hideStatusBar); + useEffect(() => { + AsyncStorage.getItem('respondedToAccessContacts').then((value) => { + if (value === null) { + navigation.navigate('RequestContactsAccess'); + } + }); + }, []); + // loads data and append it to users based on current page useEffect(() => { loadMore(); |