aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIvan Chen <ivan@tagg.id>2021-03-11 18:22:24 -0500
committerIvan Chen <ivan@tagg.id>2021-03-11 18:22:24 -0500
commitb568f553c4ee2f0452f6bb7ab7b03c84d77c15ab (patch)
treeb8aab3b6720b111e57a8e543eb024ea7e7bdcc22
parente63394198f554c7a302c12d8c540c1d730f65d86 (diff)
new discover users screen
-rw-r--r--src/assets/images/shuffle-1.pngbin0 -> 157612 bytes
-rw-r--r--src/assets/images/shuffle-2.pngbin0 -> 149495 bytes
-rw-r--r--src/components/common/GradientBorderButton.tsx66
-rw-r--r--src/components/common/index.ts1
-rw-r--r--src/components/search/SearchCategories.tsx82
-rw-r--r--src/screens/search/DiscoverUsers.tsx117
-rw-r--r--src/utils/common.ts21
7 files changed, 233 insertions, 54 deletions
diff --git a/src/assets/images/shuffle-1.png b/src/assets/images/shuffle-1.png
new file mode 100644
index 00000000..d28ddc21
--- /dev/null
+++ b/src/assets/images/shuffle-1.png
Binary files differ
diff --git a/src/assets/images/shuffle-2.png b/src/assets/images/shuffle-2.png
new file mode 100644
index 00000000..a6a701b0
--- /dev/null
+++ b/src/assets/images/shuffle-2.png
Binary files differ
diff --git a/src/components/common/GradientBorderButton.tsx b/src/components/common/GradientBorderButton.tsx
new file mode 100644
index 00000000..0402c44b
--- /dev/null
+++ b/src/components/common/GradientBorderButton.tsx
@@ -0,0 +1,66 @@
+import MaskedView from '@react-native-community/masked-view';
+import React from 'react';
+import {StyleSheet, Text, View} from 'react-native';
+import {TouchableOpacity} from 'react-native-gesture-handler';
+import LinearGradient from 'react-native-linear-gradient';
+import {TAGG_LIGHT_BLUE_2, TAGG_PURPLE} from '../../constants';
+import {normalize} from '../../utils';
+
+interface GradientBorderButtonProps {
+ text: string;
+ darkStyle: boolean;
+ onPress: () => void;
+}
+
+const GradientBorderButton: React.FC<GradientBorderButtonProps> = ({
+ text,
+ darkStyle,
+ onPress,
+}) => {
+ const labelColor = darkStyle ? 'white' : '#828282';
+ const borderWidth = darkStyle ? 2 : 1;
+ return (
+ <TouchableOpacity style={styles.container} onPress={onPress}>
+ <MaskedView
+ maskElement={
+ <View
+ style={[styles.gradientContainer, styles.maskBorder, {borderWidth}]}
+ />
+ }>
+ <LinearGradient
+ colors={[TAGG_PURPLE, TAGG_LIGHT_BLUE_2]}
+ start={{x: 0.0, y: 1.0}}
+ end={{x: 1.0, y: 1.0}}
+ style={styles.gradientContainer}
+ />
+ </MaskedView>
+ <View style={styles.textContainer}>
+ <Text style={[styles.label, {color: labelColor}]}>{text}</Text>
+ </View>
+ </TouchableOpacity>
+ );
+};
+const styles = StyleSheet.create({
+ container: {
+ marginVertical: 15,
+ },
+ gradientContainer: {
+ width: 159,
+ height: 38,
+ },
+ label: {
+ fontWeight: '500',
+ fontSize: normalize(15),
+ },
+ maskBorder: {
+ borderRadius: 20,
+ },
+ textContainer: {
+ position: 'absolute',
+ width: 159,
+ height: 38,
+ justifyContent: 'center',
+ alignItems: 'center',
+ },
+});
+export default GradientBorderButton;
diff --git a/src/components/common/index.ts b/src/components/common/index.ts
index e1543cd8..8499dbfa 100644
--- a/src/components/common/index.ts
+++ b/src/components/common/index.ts
@@ -22,3 +22,4 @@ export {default as TaggPrompt} from './TaggPrompt';
export {default as AcceptDeclineButtons} from './AcceptDeclineButtons';
export {default as FriendsButton} from './FriendsButton';
export {default as TaggSquareButton} from './TaggSquareButton';
+export {default as GradientBorderButton} from './GradientBorderButton';
diff --git a/src/components/search/SearchCategories.tsx b/src/components/search/SearchCategories.tsx
index c3c4c518..f00debb5 100644
--- a/src/components/search/SearchCategories.tsx
+++ b/src/components/search/SearchCategories.tsx
@@ -1,47 +1,55 @@
import {useNavigation} from '@react-navigation/native';
import React, {useEffect, useState} from 'react';
-import {StyleSheet, Text, View} from 'react-native';
-import {TouchableOpacity} from 'react-native-gesture-handler';
-import LinearGradient from 'react-native-linear-gradient';
+import {StyleSheet, View} from 'react-native';
+import {GradientBorderButton} from '..';
import {getButtons} from '../../services/ExploreService';
import {SearchCategoryType} from '../../types';
-import {TAGG_LIGHT_BLUE_2, TAGG_PURPLE} from '../../constants';
import {SCREEN_WIDTH} from '../../utils';
-const SearchCategories: React.FC = () => {
- const [buttons, setButtons] = useState<SearchCategoryType[]>([]);
+interface SearchCategoriesProps {
+ darkStyle?: boolean;
+}
+
+const SearchCategories: React.FC<SearchCategoriesProps> = ({
+ darkStyle = false,
+}) => {
+ const navigation = useNavigation();
+ const mtSearchCategory: (key: number) => SearchCategoryType = (key) => ({
+ id: key,
+ name: '...',
+ category: '...',
+ });
+ const [buttons, setButtons] = useState<SearchCategoryType[]>([
+ mtSearchCategory(1),
+ mtSearchCategory(2),
+ mtSearchCategory(3),
+ mtSearchCategory(4),
+ ]);
useEffect(() => {
const loadButtons = async () => {
const localButtons = await getButtons();
- console.log('localButtons: ', localButtons);
- await setButtons(localButtons);
+ setButtons([]);
+ setButtons(localButtons);
};
loadButtons();
}, []);
- const navigation = useNavigation();
return (
<View style={styles.container}>
- {buttons &&
- buttons.map((searchCategory) => (
- <LinearGradient
- key={searchCategory.id}
- colors={[TAGG_PURPLE, TAGG_LIGHT_BLUE_2]}
- start={{x: 0.0, y: 1.0}}
- end={{x: 1.0, y: 1.0}}
- style={styles.gradientContainer}>
- <TouchableOpacity
- style={styles.buttonContainer}
- key={searchCategory.id}
- onPress={() => {
- navigation.navigate('DiscoverUsers', {
- searchCategory,
- });
- }}>
- <Text style={styles.buttonText}>{searchCategory.name}</Text>
- </TouchableOpacity>
- </LinearGradient>
- ))}
+ {buttons.map((searchCategory) => (
+ <GradientBorderButton
+ key={searchCategory.id}
+ text={searchCategory.name}
+ darkStyle={darkStyle}
+ onPress={() => {
+ if (searchCategory.name !== '...') {
+ navigation.push('DiscoverUsers', {
+ searchCategory,
+ });
+ }
+ }}
+ />
+ ))}
</View>
);
};
@@ -56,20 +64,8 @@ const styles = StyleSheet.create({
flexWrap: 'wrap',
justifyContent: 'space-evenly',
},
- gradientContainer: {
- width: 159,
- height: 38,
- alignItems: 'center',
- justifyContent: 'center',
- marginVertical: '2.5%',
- flexDirection: 'row',
- alignContent: 'center',
- borderRadius: 20,
- borderColor: 'transparent',
- borderWidth: 1,
- },
buttonContainer: {
- backgroundColor: 'white',
+ backgroundColor: 'transparent',
width: 158,
height: 37,
borderRadius: 20,
@@ -84,7 +80,7 @@ const styles = StyleSheet.create({
fontSize: 15,
lineHeight: 17.9,
alignSelf: 'center',
- color: '#828282',
+ color: 'white',
},
});
export default SearchCategories;
diff --git a/src/screens/search/DiscoverUsers.tsx b/src/screens/search/DiscoverUsers.tsx
index ce7507fc..a9856909 100644
--- a/src/screens/search/DiscoverUsers.tsx
+++ b/src/screens/search/DiscoverUsers.tsx
@@ -1,15 +1,26 @@
+import {RouteProp, useNavigation} from '@react-navigation/native';
import React, {useEffect, useState} from 'react';
import {FlatList, StatusBar, StyleSheet} from 'react-native';
-import {Text} from 'react-native-animatable';
+import {Image, Text} from 'react-native-animatable';
+import {TouchableOpacity} from 'react-native-gesture-handler';
import {SafeAreaView} from 'react-native-safe-area-context';
-import {HeaderHeight, SCREEN_HEIGHT, SCREEN_WIDTH} from '../../utils';
-import {SearchBackground, TabsGradient} from '../../components';
-import {RouteProp} from '@react-navigation/native';
-import {MainStackParams} from '../../routes';
-import {normalize} from '../../utils';
-import {ProfilePreviewType} from '../../types';
+import {
+ SearchBackground,
+ SearchCategories,
+ TabsGradient,
+ TaggLoadingIndicator,
+} from '../../components';
import ExploreSectionUser from '../../components/search/ExploreSectionUser';
+import {headerBarOptions, MainStackParams} from '../../routes';
import {getDiscoverUsers} from '../../services/ExploreService';
+import {ProfilePreviewType} from '../../types';
+import {
+ HeaderHeight,
+ normalize,
+ SCREEN_HEIGHT,
+ SCREEN_WIDTH,
+ shuffle,
+} from '../../utils';
type DiscoverUsersRouteProps = RouteProp<MainStackParams, 'DiscoverUsers'>;
@@ -20,14 +31,74 @@ interface DiscoverUsersProps {
const DiscoverUsers: React.FC<DiscoverUsersProps> = ({route}) => {
const {type: category_type} = route.params;
const {id, name} = route.params.searchCategory;
- const [users, setUsers] = useState<ProfilePreviewType[]>();
+ const [categoryName, setCategoryName] = useState<string | undefined>();
+ const [users, setUsers] = useState<ProfilePreviewType[]>([]);
+ const [shouldRefresh, setShouldRefresh] = useState(false);
+ const [showIcon1, setShowIcon1] = useState(true);
+ const mtUser = (key: number) => ({
+ id: key,
+ username: '...',
+ first_name: '',
+ last_name: '',
+ thumbnail_url: '',
+ });
+ const dummyUsers = [
+ mtUser(1),
+ mtUser(2),
+ mtUser(3),
+ mtUser(4),
+ mtUser(5),
+ mtUser(6),
+ mtUser(7),
+ mtUser(8),
+ mtUser(9),
+ ];
+ const [loading, setLoading] = useState(true);
+ const navigation = useNavigation();
+
+ navigation.setOptions({
+ ...headerBarOptions('white', name),
+ headerRight: () => (
+ <TouchableOpacity
+ onPress={() => {
+ setShowIcon1(!showIcon1);
+ setShouldRefresh(true);
+ }}>
+ <Image
+ source={
+ showIcon1
+ ? require('../../assets/images/shuffle-1.png')
+ : require('../../assets/images/shuffle-2.png')
+ }
+ style={styles.shuffleIcon}
+ />
+ </TouchableOpacity>
+ ),
+ });
+
+ useEffect(() => {
+ setCategoryName(name);
+ }, []);
+
+ useEffect(() => {
+ if (shouldRefresh) {
+ setLoading(true);
+ setTimeout(() => {
+ setUsers(shuffle(users));
+ setShouldRefresh(false);
+ setLoading(false);
+ }, 500);
+ }
+ }, [shouldRefresh, users]);
useEffect(() => {
const loadData = async () => {
+ setLoading(true);
setUsers(await getDiscoverUsers(id, category_type));
+ setLoading(false);
};
loadData();
- }, []);
+ }, [categoryName]);
const _renderItem = ({item: user}: {item: ProfilePreviewType}) => (
<ExploreSectionUser key={user.id} user={user} style={styles.user} />
@@ -37,16 +108,26 @@ const DiscoverUsers: React.FC<DiscoverUsersProps> = ({route}) => {
<SearchBackground>
<StatusBar barStyle="light-content" />
<SafeAreaView>
- <Text style={styles.headerText}>{name}</Text>
+ {loading && <TaggLoadingIndicator fullscreen={true} />}
<FlatList
- data={users}
+ data={loading ? dummyUsers : users.slice(0, 9)}
style={styles.scrollView}
+ scrollEnabled={false}
contentContainerStyle={styles.contentContainerStyle}
columnWrapperStyle={styles.columnWrapperStyle}
numColumns={3}
keyExtractor={(item) => item.id}
renderItem={_renderItem}
showsVerticalScrollIndicator={false}
+ ListFooterComponent={() => (
+ <>
+ <Text style={styles.otherGroups}>Other Groups</Text>
+ <SearchCategories
+ darkStyle={true}
+ // callBack={(category) => setCategoryName(category)}
+ />
+ </>
+ )}
/>
<TabsGradient />
</SafeAreaView>
@@ -67,6 +148,7 @@ const styles = StyleSheet.create({
},
scrollView: {
top: HeaderHeight,
+ marginTop: '10%',
width: SCREEN_WIDTH * 0.95,
height: SCREEN_HEIGHT - HeaderHeight,
alignSelf: 'center',
@@ -83,6 +165,19 @@ const styles = StyleSheet.create({
width: SCREEN_WIDTH * 0.95,
paddingBottom: SCREEN_HEIGHT * 0.2,
},
+ otherGroups: {
+ color: 'white',
+ fontSize: normalize(18),
+ fontWeight: '600',
+ lineHeight: normalize(35),
+ alignSelf: 'center',
+ marginTop: 20,
+ },
+ shuffleIcon: {
+ width: 40,
+ height: 40,
+ marginRight: 20,
+ },
});
export default DiscoverUsers;
diff --git a/src/utils/common.ts b/src/utils/common.ts
index 30122e79..c1049c42 100644
--- a/src/utils/common.ts
+++ b/src/utils/common.ts
@@ -94,3 +94,24 @@ export const haveUnreadNotifications = async (
}
return false;
};
+
+// https://stackoverflow.com/a/2450976
+export const shuffle = (array: any[]) => {
+ var currentIndex = array.length,
+ temporaryValue,
+ randomIndex;
+
+ // While there remain elements to shuffle...
+ while (currentIndex !== 0) {
+ // Pick a remaining element...
+ randomIndex = Math.floor(Math.random() * currentIndex);
+ currentIndex -= 1;
+
+ // And swap it with the current element.
+ temporaryValue = array[currentIndex];
+ array[currentIndex] = array[randomIndex];
+ array[randomIndex] = temporaryValue;
+ }
+
+ return array;
+};