From 594de4668248bac9b744e6882329183c95ac339c Mon Sep 17 00:00:00 2001 From: Leon Jiang <35908040+leonyjiang@users.noreply.github.com> Date: Wed, 10 Mar 2021 18:15:26 -0500 Subject: Add utils, fix ordering of recent searches --- src/components/search/SearchResultCell.tsx | 4 +- src/components/search/SearchResults.tsx | 34 ++++++---- src/screens/search/SearchScreen.tsx | 52 +++++++-------- src/utils/users.ts | 102 +++++++++++++++++++++-------- 4 files changed, 120 insertions(+), 72 deletions(-) (limited to 'src') diff --git a/src/components/search/SearchResultCell.tsx b/src/components/search/SearchResultCell.tsx index 5cba6d2f..f274bfb9 100644 --- a/src/components/search/SearchResultCell.tsx +++ b/src/components/search/SearchResultCell.tsx @@ -14,11 +14,11 @@ import { } from '../../types'; import {normalize, SCREEN_WIDTH} from '../../utils'; import { - addUserToRecentlyViewed, checkIfUserIsBlocked, defaultUserProfile, fetchUserX, userXInStore, + addUserToRecentlySearched, addCategoryToRecentlySearched, } from '../../utils/users'; @@ -74,7 +74,7 @@ const SearchResultsCell: React.FC = ({ return; } - addUserToRecentlyViewed({ + addUserToRecentlySearched({ id, first_name, last_name, diff --git a/src/components/search/SearchResults.tsx b/src/components/search/SearchResults.tsx index 277b3454..ef518d8b 100644 --- a/src/components/search/SearchResults.tsx +++ b/src/components/search/SearchResults.tsx @@ -23,20 +23,26 @@ const SearchResults: React.FC = ({results, categories}) => { const {user: loggedInUser} = useSelector((state: RootState) => state.user); return ( - {categories.map((category: CategoryPreviewType) => ( - - ))} - {results.map((profile: ProfilePreviewType) => ( - - ))} + {categories + .slice(0) + .reverse() + .map((category: CategoryPreviewType) => ( + + ))} + {results + .slice(0) + .reverse() + .map((profile: ProfilePreviewType) => ( + + ))} ); }; diff --git a/src/screens/search/SearchScreen.tsx b/src/screens/search/SearchScreen.tsx index 728510c5..089e0d27 100644 --- a/src/screens/search/SearchScreen.tsx +++ b/src/screens/search/SearchScreen.tsx @@ -18,7 +18,13 @@ import {loadSearchResults} from '../../services'; import {resetScreenType} from '../../store/actions'; import {RootState} from '../../store/rootReducer'; import {ProfilePreviewType, ScreenType, CategoryPreviewType} from '../../types'; -import {normalize, SCREEN_HEIGHT, SCREEN_WIDTH} from '../../utils'; +import { + normalize, + SCREEN_HEIGHT, + SCREEN_WIDTH, + getRecentlySearchedCategories, + getRecentlySearchedUsers, +} from '../../utils'; /** * Search Screen for user recommendations and a search @@ -58,9 +64,8 @@ const SearchScreen: React.FC = () => { */ useEffect(() => { if (!searching) return; - if (!query.length) loadRecentSearches(); if (query.length < 3) { - setResults(undefined); + loadRecentlySearched().then(() => setResults(undefined)); return; } (async () => { @@ -101,7 +106,9 @@ const SearchScreen: React.FC = () => { // when searching state changes, run animation and reset query accordingly useEffect(() => { if (searching) { - timing(top, topInConfig).start(); + loadRecentlySearched().then(() => { + timing(top, topInConfig).start(); + }); } else { setQuery(''); handleBlur(); @@ -109,36 +116,23 @@ const SearchScreen: React.FC = () => { } }, [searching]); - const loadRecentlySearchedUsers = async () => { - try { - const asyncCache = await AsyncStorage.getItem('@recently_searched_users'); - asyncCache != null ? setRecents(JSON.parse(asyncCache)) : setRecents([]); - } catch (e) { - console.log(e); - } - }; - const loadRecentlySearchedCategories = async () => { - try { - const recentCategoriesJSON = await AsyncStorage.getItem( - '@recently_searched_categories', - ); - setRecentCategories( - recentCategoriesJSON ? JSON.parse(recentCategoriesJSON) : [], - ); - } catch (e) { - console.log(e); - } - }; - const loadRecentSearches = () => { - loadRecentlySearchedUsers(); - loadRecentlySearchedCategories(); + // loads recent searches (users & categories) from AsyncStorage + const loadRecentlySearched = async () => { + return Promise.all([ + getRecentlySearchedUsers(), + getRecentlySearchedCategories(), + ]).then( + ([users, categories]: [ProfilePreviewType[], CategoryPreviewType[]]) => { + setRecents(users); + setRecentCategories(categories); + }, + ); }; const clearRecentlySearched = async () => { try { AsyncStorage.removeItem('@recently_searched_users'); AsyncStorage.removeItem('@recently_searched_categories'); - loadRecentlySearchedUsers(); - loadRecentlySearchedCategories(); + loadRecentlySearched(); } catch (e) { console.log(e); } diff --git a/src/utils/users.ts b/src/utils/users.ts index 15107c99..3e0d9eef 100644 --- a/src/utils/users.ts +++ b/src/utils/users.ts @@ -166,55 +166,86 @@ export const defaultUserProfile = () => { return defaultImage; }; -export const addUserToRecentlyViewed = async (user: ProfilePreviewType) => { - const jsonValue = await AsyncStorage.getItem('@recently_searched_users'); - let recentlySearchedList = jsonValue != null ? JSON.parse(jsonValue) : null; - if (recentlySearchedList) { - if (recentlySearchedList.length > 0) { - if ( - recentlySearchedList.some( - (saved_user: ProfilePreviewType) => saved_user.id === user.id, - ) - ) { - console.log('User already in recently searched.'); - } else { - if (recentlySearchedList.length >= 10) { - recentlySearchedList.pop(); +/* + * AsyncStorage key for list of recently-searched users. + */ +const recentlySearchedUsersKey = '@recently_searched_users'; + +/* + * Stores `user` in AsyncStorage as a recently-searched user. + */ +export const addUserToRecentlySearched = async (user: ProfilePreviewType) => { + let users: ProfilePreviewType[]; + // retrieve and update recently-searched categories list + try { + const usersJSON = await AsyncStorage.getItem(recentlySearchedUsersKey); + if (usersJSON) { + users = JSON.parse(usersJSON); + // if category already exists, move it to the end + for (let i = 0; i < users.length; i++) { + // TODO: speed up comparison by adding some id field to category + if (users[i].id === user.id) { + users.splice(i, 1); + break; } - recentlySearchedList.unshift(user); } + users.push(user); + } else { + users = [user]; + } + // store updated list of recently-searched categories + try { + AsyncStorage.setItem(recentlySearchedUsersKey, JSON.stringify(users)); + } catch (e) { + console.log(e); } - } else { - recentlySearchedList = [user]; + } catch (e) { + console.log(e); } +}; + +/* + * Retrieves and returns user's recently-searched categories from AsyncStorage. + */ +export const getRecentlySearchedUsers = async (): Promise< + ProfilePreviewType[] +> => { try { - let recentlySearchedListString = JSON.stringify(recentlySearchedList); - await AsyncStorage.setItem( - '@recently_searched_users', - recentlySearchedListString, - ); + const usersJSON = await AsyncStorage.getItem(recentlySearchedUsersKey); + if (usersJSON) return JSON.parse(usersJSON); } catch (e) { console.log(e); } + return []; }; /* - * Stores `category` in AsyncStorage as a recently searched category. + * AsyncStorage key for list of recently-searched categories. + */ +const recentlySearchedCategoriesKey = '@recently_searched_categories'; + +/* + * Stores `category` in AsyncStorage as a recently-searched category. */ export const addCategoryToRecentlySearched = async ( category: CategoryPreviewType, ) => { - const recentlySearchedCategoriesKey = '@recently_searched_categories'; let categories: CategoryPreviewType[]; - // retrieve recently-searched categories and set new list + // retrieve and update recently-searched categories list try { const categoriesJSON = await AsyncStorage.getItem( recentlySearchedCategoriesKey, ); if (categoriesJSON) { categories = JSON.parse(categoriesJSON); - // TODO: make this more efficient by comparing shorter key - if (categories.find((c) => c.name === category.name)) return; + // if category already exists, move it to the end + for (let i = 0; i < categories.length; i++) { + // TODO: speed up comparison by adding some id field to category + if (categories[i].name === category.name) { + categories.splice(i, 1); + break; + } + } categories.push(category); } else { categories = [category]; @@ -232,3 +263,20 @@ export const addCategoryToRecentlySearched = async ( console.log(e); } }; + +/* + * Retrieves and returns user's recently-searched categories from AsyncStorage. + */ +export const getRecentlySearchedCategories = async (): Promise< + CategoryPreviewType[] +> => { + try { + const categoriesJSON = await AsyncStorage.getItem( + '@recently_searched_categories', + ); + if (categoriesJSON) return JSON.parse(categoriesJSON); + } catch (e) { + console.log(e); + } + return []; +}; -- cgit v1.2.3-70-g09d2 From f7557073cc3a5a70b8514c7cb041952d54aa31a1 Mon Sep 17 00:00:00 2001 From: Leon Jiang <35908040+leonyjiang@users.noreply.github.com> Date: Wed, 10 Mar 2021 19:02:29 -0500 Subject: Add simple, non-animated dynamic placeholder --- src/components/search/SearchBar.tsx | 83 +++++++++++++++++++++++++++++++++++-- src/screens/search/SearchScreen.tsx | 2 +- 2 files changed, 80 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/components/search/SearchBar.tsx b/src/components/search/SearchBar.tsx index 5e3a1e64..61d7582f 100644 --- a/src/components/search/SearchBar.tsx +++ b/src/components/search/SearchBar.tsx @@ -1,4 +1,4 @@ -import React, {useState} from 'react'; +import React, {useState, useEffect} from 'react'; import { StyleSheet, TextInput, @@ -20,6 +20,7 @@ const AnimatedIcon = Animated.createAnimatedComponent(Icon); interface SearchBarProps extends TextInputProps { onCancel: () => void; top: Animated.Value; + searching: boolean; } const SearchBar: React.FC = ({ onFocus, @@ -27,6 +28,7 @@ const SearchBar: React.FC = ({ onChangeText, value, onCancel, + searching, top, }) => { const handleSubmit = ( @@ -35,9 +37,83 @@ const SearchBar: React.FC = ({ e.preventDefault(); Keyboard.dismiss(); }; + const DEFAULT_PLACEHOLDER: string = 'Search'; + // the list of suggestions to cycle through. TODO: get this from the backend + const SEARCH_SUGGESTIONS: string[] = [ + "Brown '21", + "Brown '22", + "Brown '23", + "Brown '24", + 'Trending on Tagg', + 'New to Tagg', + ]; + /* + * index & id of current placeholder, used in selecting next placeholder. -1 + * indicates DEFAULT_PLACEHOLDER. TODO: make it appear more random by tracking + * last 3-5 ids & use longer list of placeholders + */ + const [placeholderId, setPlaceholderId] = useState(-1); + // the current placeholder + const [placeholder, setPlaceholder] = useState(DEFAULT_PLACEHOLDER); + + /* + * Utility function that generates a random integer in [0, xCeil). + * + * @param xCeil - the exclusive ceiling (getRandomInt(2) => 0 or 1, not 2) + * @returns a random integer in the range [0, xCeil) + */ + const getRandomInt = (xCeil: number): number => { + return Math.floor(Math.random() * Math.floor(xCeil)); + }; + + /* + * Handler for `placeholderChangeInterval` that sets the next placeholderId. + */ + const updatePlaceholder = () => { + let nextId: number = getRandomInt(SEARCH_SUGGESTIONS.length); + while (nextId === placeholderId) { + nextId = getRandomInt(SEARCH_SUGGESTIONS.length); + } + // TODO: FIGURE OUT WHY CHANGES IN placeholderId ARE NOT REFLECTED HERE + // my thought: the value is set when the function is defined, so it keeps + // its inital value of -1 forever. + console.log(`Previous ID: ${placeholderId}`); + console.log(`Next ID: ${nextId}`); + setPlaceholderId(nextId); + }; + + /* + * Update `placeholder` when `placeholderId` is updated by the interval handler. + */ + useEffect(() => { + if (placeholderId === -1) { + setPlaceholder(DEFAULT_PLACEHOLDER); + return; + } + setPlaceholder( + DEFAULT_PLACEHOLDER.concat(` '${SEARCH_SUGGESTIONS[placeholderId]}'`), + ); + }, [placeholderId]); + + /* + * Sets the interval when the user begins searching and clears it when the user is done. + */ + useEffect(() => { + if (!searching) { + return; + } + updatePlaceholder(); + const updateInterval = setInterval(() => { + updatePlaceholder(); + }, 4000); + return () => { + clearInterval(updateInterval); + setPlaceholderId(-1); + }; + }, [searching]); /* - * CSS properties for width change animation. + * Animated nodes used in search bar activation animation. */ const marginRight: Animated.Node = interpolate(top, { inputRange: [-SCREEN_HEIGHT, 0], @@ -59,13 +135,12 @@ const SearchBar: React.FC = ({ /> diff --git a/src/screens/search/SearchScreen.tsx b/src/screens/search/SearchScreen.tsx index 089e0d27..59b17f57 100644 --- a/src/screens/search/SearchScreen.tsx +++ b/src/screens/search/SearchScreen.tsx @@ -167,7 +167,7 @@ const SearchScreen: React.FC = () => { onBlur={handleBlur} onFocus={handleFocus} value={query} - {...{top}} + {...{top, searching}} /> Date: Wed, 10 Mar 2021 22:59:36 -0500 Subject: Refactor utils --- src/utils/index.ts | 1 + src/utils/search.ts | 132 ++++++++++++++++++++++++++++++++++++++++++++++++++++ src/utils/users.ts | 114 --------------------------------------------- 3 files changed, 133 insertions(+), 114 deletions(-) create mode 100644 src/utils/search.ts (limited to 'src') diff --git a/src/utils/index.ts b/src/utils/index.ts index 82c94100..739e6fb8 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -3,3 +3,4 @@ export * from './moments'; export * from './common'; export * from './users'; export * from './friends'; +export * from './search'; diff --git a/src/utils/search.ts b/src/utils/search.ts new file mode 100644 index 00000000..4293ff25 --- /dev/null +++ b/src/utils/search.ts @@ -0,0 +1,132 @@ +import AsyncStorage from '@react-native-community/async-storage'; + +import {BADGE_DATA} from '../constants/badges'; +import {ProfilePreviewType, CategoryPreviewType} from '../types'; + +/* + * Gets all possible search suggestions. + */ +export const getSearchSuggestions = (): string[] => { + const suggestions: string[] = []; + for (const category of BADGE_DATA) { + for (const interest of category.data) { + suggestions.push(interest.badgeName); + } + } + return suggestions; +}; + +/* + * AsyncStorage key for list of recently-searched users. + */ +const recentlySearchedUsersKey = '@recently_searched_users'; + +/* + * Stores `user` in AsyncStorage as a recently-searched user. + */ +export const addUserToRecentlySearched = async (user: ProfilePreviewType) => { + let users: ProfilePreviewType[]; + // retrieve and update recently-searched categories list + try { + const usersJSON = await AsyncStorage.getItem(recentlySearchedUsersKey); + if (usersJSON) { + users = JSON.parse(usersJSON); + // if category already exists, move it to the end + for (let i = 0; i < users.length; i++) { + // TODO: speed up comparison by adding some id field to category + if (users[i].id === user.id) { + users.splice(i, 1); + break; + } + } + users.push(user); + } else { + users = [user]; + } + // store updated list of recently-searched categories + try { + AsyncStorage.setItem(recentlySearchedUsersKey, JSON.stringify(users)); + } catch (e) { + console.log(e); + } + } catch (e) { + console.log(e); + } +}; + +/* + * Retrieves and returns user's recently-searched categories from AsyncStorage. + */ +export const getRecentlySearchedUsers = async (): Promise< + ProfilePreviewType[] +> => { + try { + const usersJSON = await AsyncStorage.getItem(recentlySearchedUsersKey); + if (usersJSON) return JSON.parse(usersJSON); + } catch (e) { + console.log(e); + } + return []; +}; + +/* + * AsyncStorage key for list of recently-searched categories. + */ +const recentlySearchedCategoriesKey = '@recently_searched_categories'; + +/* + * Stores `category` in AsyncStorage as a recently-searched category. + */ +export const addCategoryToRecentlySearched = async ( + category: CategoryPreviewType, +) => { + let categories: CategoryPreviewType[]; + // retrieve and update recently-searched categories list + try { + const categoriesJSON = await AsyncStorage.getItem( + recentlySearchedCategoriesKey, + ); + if (categoriesJSON) { + categories = JSON.parse(categoriesJSON); + // if category already exists, move it to the end + for (let i = 0; i < categories.length; i++) { + // TODO: speed up comparison by adding some id field to category + if (categories[i].name === category.name) { + categories.splice(i, 1); + break; + } + } + categories.push(category); + } else { + categories = [category]; + } + // store updated list of recently-searched categories + try { + AsyncStorage.setItem( + recentlySearchedCategoriesKey, + JSON.stringify(categories), + ); + } catch (e) { + console.log(e); + } + } catch (e) { + console.log(e); + } +}; + +/* + * Retrieves and returns user's recently-searched categories from AsyncStorage. + */ +export const getRecentlySearchedCategories = async (): Promise< + CategoryPreviewType[] +> => { + try { + const categoriesJSON = await AsyncStorage.getItem( + '@recently_searched_categories', + ); + if (categoriesJSON) return JSON.parse(categoriesJSON); + } catch (e) { + console.log(e); + } + return []; +}; diff --git a/src/utils/users.ts b/src/utils/users.ts index 3e0d9eef..af4f3813 100644 --- a/src/utils/users.ts +++ b/src/utils/users.ts @@ -166,117 +166,3 @@ export const defaultUserProfile = () => { return defaultImage; }; -/* - * AsyncStorage key for list of recently-searched users. - */ -const recentlySearchedUsersKey = '@recently_searched_users'; - -/* - * Stores `user` in AsyncStorage as a recently-searched user. - */ -export const addUserToRecentlySearched = async (user: ProfilePreviewType) => { - let users: ProfilePreviewType[]; - // retrieve and update recently-searched categories list - try { - const usersJSON = await AsyncStorage.getItem(recentlySearchedUsersKey); - if (usersJSON) { - users = JSON.parse(usersJSON); - // if category already exists, move it to the end - for (let i = 0; i < users.length; i++) { - // TODO: speed up comparison by adding some id field to category - if (users[i].id === user.id) { - users.splice(i, 1); - break; - } - } - users.push(user); - } else { - users = [user]; - } - // store updated list of recently-searched categories - try { - AsyncStorage.setItem(recentlySearchedUsersKey, JSON.stringify(users)); - } catch (e) { - console.log(e); - } - } catch (e) { - console.log(e); - } -}; - -/* - * Retrieves and returns user's recently-searched categories from AsyncStorage. - */ -export const getRecentlySearchedUsers = async (): Promise< - ProfilePreviewType[] -> => { - try { - const usersJSON = await AsyncStorage.getItem(recentlySearchedUsersKey); - if (usersJSON) return JSON.parse(usersJSON); - } catch (e) { - console.log(e); - } - return []; -}; - -/* - * AsyncStorage key for list of recently-searched categories. - */ -const recentlySearchedCategoriesKey = '@recently_searched_categories'; - -/* - * Stores `category` in AsyncStorage as a recently-searched category. - */ -export const addCategoryToRecentlySearched = async ( - category: CategoryPreviewType, -) => { - let categories: CategoryPreviewType[]; - // retrieve and update recently-searched categories list - try { - const categoriesJSON = await AsyncStorage.getItem( - recentlySearchedCategoriesKey, - ); - if (categoriesJSON) { - categories = JSON.parse(categoriesJSON); - // if category already exists, move it to the end - for (let i = 0; i < categories.length; i++) { - // TODO: speed up comparison by adding some id field to category - if (categories[i].name === category.name) { - categories.splice(i, 1); - break; - } - } - categories.push(category); - } else { - categories = [category]; - } - // store updated list of recently-searched categories - try { - AsyncStorage.setItem( - recentlySearchedCategoriesKey, - JSON.stringify(categories), - ); - } catch (e) { - console.log(e); - } - } catch (e) { - console.log(e); - } -}; - -/* - * Retrieves and returns user's recently-searched categories from AsyncStorage. - */ -export const getRecentlySearchedCategories = async (): Promise< - CategoryPreviewType[] -> => { - try { - const categoriesJSON = await AsyncStorage.getItem( - '@recently_searched_categories', - ); - if (categoriesJSON) return JSON.parse(categoriesJSON); - } catch (e) { - console.log(e); - } - return []; -}; -- cgit v1.2.3-70-g09d2 From 5eabfa9af6df007bdee61382b4061db8ad5f0683 Mon Sep 17 00:00:00 2001 From: Leon Jiang <35908040+leonyjiang@users.noreply.github.com> Date: Wed, 10 Mar 2021 23:00:12 -0500 Subject: Utilize util to get search suggestions list --- src/components/search/SearchBar.tsx | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/components/search/SearchBar.tsx b/src/components/search/SearchBar.tsx index 61d7582f..1a855f20 100644 --- a/src/components/search/SearchBar.tsx +++ b/src/components/search/SearchBar.tsx @@ -13,7 +13,7 @@ import { import Animated, {interpolate} from 'react-native-reanimated'; import Icon from 'react-native-vector-icons/Feather'; import {normalize} from 'react-native-elements'; -import {SCREEN_HEIGHT} from '../../utils'; +import {SCREEN_HEIGHT, getSearchSuggestions} from '../../utils'; const AnimatedIcon = Animated.createAnimatedComponent(Icon); @@ -39,14 +39,7 @@ const SearchBar: React.FC = ({ }; const DEFAULT_PLACEHOLDER: string = 'Search'; // the list of suggestions to cycle through. TODO: get this from the backend - const SEARCH_SUGGESTIONS: string[] = [ - "Brown '21", - "Brown '22", - "Brown '23", - "Brown '24", - 'Trending on Tagg', - 'New to Tagg', - ]; + const SEARCH_SUGGESTIONS: string[] = getSearchSuggestions(); /* * index & id of current placeholder, used in selecting next placeholder. -1 * indicates DEFAULT_PLACEHOLDER. TODO: make it appear more random by tracking -- cgit v1.2.3-70-g09d2 From e63394198f554c7a302c12d8c540c1d730f65d86 Mon Sep 17 00:00:00 2001 From: Ivan Chen Date: Thu, 11 Mar 2021 18:19:32 -0500 Subject: removed unused store state --- src/store/actions/taggUsers.ts | 4 ++-- src/store/initialStates.ts | 14 -------------- src/store/reducers/taggUsersReducer.ts | 1 - 3 files changed, 2 insertions(+), 17 deletions(-) (limited to 'src') diff --git a/src/store/actions/taggUsers.ts b/src/store/actions/taggUsers.ts index 7b6d4d5e..72ce848b 100644 --- a/src/store/actions/taggUsers.ts +++ b/src/store/actions/taggUsers.ts @@ -11,10 +11,10 @@ export const loadRecentlySearched = (): ThunkAction< > => async (dispatch) => { try { const recentSearches = await loadRecentlySearchedUsers(); - const exploreSections = await getAllExploreSections(); + getAllExploreSections(); dispatch({ type: taggUsersFetched.type, - payload: {recentSearches, explores: exploreSections}, + payload: {recentSearches}, }); } catch (error) { console.log(error); diff --git a/src/store/initialStates.ts b/src/store/initialStates.ts index 1a3db433..b43e4a1d 100644 --- a/src/store/initialStates.ts +++ b/src/store/initialStates.ts @@ -69,22 +69,8 @@ export const NO_SOCIAL_ACCOUNTS: Record = { Twitter: {posts: []}, }; -export const EMPTY_EXPLORE_SECTIONS: Record< - ExploreSectionType, - ProfilePreviewType[] -> = { - 'People You May Know': EMPTY_PROFILE_PREVIEW_LIST, - 'New to Tagg': EMPTY_PROFILE_PREVIEW_LIST, - 'Trending on Tagg': EMPTY_PROFILE_PREVIEW_LIST, - "Brown '21": EMPTY_PROFILE_PREVIEW_LIST, - "Brown '22": EMPTY_PROFILE_PREVIEW_LIST, - "Brown '23": EMPTY_PROFILE_PREVIEW_LIST, - "Brown '24": EMPTY_PROFILE_PREVIEW_LIST, -}; - export const NO_TAGG_USERS = { recentSearches: EMPTY_PROFILE_PREVIEW_LIST, - explores: EMPTY_EXPLORE_SECTIONS, }; export const NO_SOCIALS = { diff --git a/src/store/reducers/taggUsersReducer.ts b/src/store/reducers/taggUsersReducer.ts index 33e2e18d..92973101 100644 --- a/src/store/reducers/taggUsersReducer.ts +++ b/src/store/reducers/taggUsersReducer.ts @@ -7,7 +7,6 @@ const taggUsersSlice = createSlice({ reducers: { taggUsersFetched: (state, action) => { state.recentSearches = action.payload.recentSearches; - state.explores = action.payload.explores; }, }, }); -- cgit v1.2.3-70-g09d2 From b568f553c4ee2f0452f6bb7ab7b03c84d77c15ab Mon Sep 17 00:00:00 2001 From: Ivan Chen Date: Thu, 11 Mar 2021 18:22:24 -0500 Subject: new discover users screen --- src/assets/images/shuffle-1.png | Bin 0 -> 157612 bytes src/assets/images/shuffle-2.png | Bin 0 -> 149495 bytes src/components/common/GradientBorderButton.tsx | 66 ++++++++++++++ src/components/common/index.ts | 1 + src/components/search/SearchCategories.tsx | 82 +++++++++-------- src/screens/search/DiscoverUsers.tsx | 117 ++++++++++++++++++++++--- src/utils/common.ts | 21 +++++ 7 files changed, 233 insertions(+), 54 deletions(-) create mode 100644 src/assets/images/shuffle-1.png create mode 100644 src/assets/images/shuffle-2.png create mode 100644 src/components/common/GradientBorderButton.tsx (limited to 'src') diff --git a/src/assets/images/shuffle-1.png b/src/assets/images/shuffle-1.png new file mode 100644 index 00000000..d28ddc21 Binary files /dev/null and b/src/assets/images/shuffle-1.png differ diff --git a/src/assets/images/shuffle-2.png b/src/assets/images/shuffle-2.png new file mode 100644 index 00000000..a6a701b0 Binary files /dev/null and b/src/assets/images/shuffle-2.png 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 = ({ + text, + darkStyle, + onPress, +}) => { + const labelColor = darkStyle ? 'white' : '#828282'; + const borderWidth = darkStyle ? 2 : 1; + return ( + + + }> + + + + {text} + + + ); +}; +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([]); +interface SearchCategoriesProps { + darkStyle?: boolean; +} + +const SearchCategories: React.FC = ({ + darkStyle = false, +}) => { + const navigation = useNavigation(); + const mtSearchCategory: (key: number) => SearchCategoryType = (key) => ({ + id: key, + name: '...', + category: '...', + }); + const [buttons, setButtons] = useState([ + 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 ( - {buttons && - buttons.map((searchCategory) => ( - - { - navigation.navigate('DiscoverUsers', { - searchCategory, - }); - }}> - {searchCategory.name} - - - ))} + {buttons.map((searchCategory) => ( + { + if (searchCategory.name !== '...') { + navigation.push('DiscoverUsers', { + searchCategory, + }); + } + }} + /> + ))} ); }; @@ -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; @@ -20,14 +31,74 @@ interface DiscoverUsersProps { const DiscoverUsers: React.FC = ({route}) => { const {type: category_type} = route.params; const {id, name} = route.params.searchCategory; - const [users, setUsers] = useState(); + const [categoryName, setCategoryName] = useState(); + const [users, setUsers] = useState([]); + 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: () => ( + { + setShowIcon1(!showIcon1); + setShouldRefresh(true); + }}> + + + ), + }); + + 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}) => ( @@ -37,16 +108,26 @@ const DiscoverUsers: React.FC = ({route}) => { - {name} + {loading && } item.id} renderItem={_renderItem} showsVerticalScrollIndicator={false} + ListFooterComponent={() => ( + <> + Other Groups + setCategoryName(category)} + /> + + )} /> @@ -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; +}; -- cgit v1.2.3-70-g09d2 From 467f437492c431923e131573fd6963fa08cf4263 Mon Sep 17 00:00:00 2001 From: Shravya Ramesh Date: Fri, 12 Mar 2021 11:15:22 -0800 Subject: error --- src/screens/suggestedPeople/SPBody.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/screens/suggestedPeople/SPBody.tsx b/src/screens/suggestedPeople/SPBody.tsx index 6572dc55..bba137c0 100644 --- a/src/screens/suggestedPeople/SPBody.tsx +++ b/src/screens/suggestedPeople/SPBody.tsx @@ -50,7 +50,7 @@ const SPBody: React.FC = ({ let array = []; useEffect(() => { const findBadgeIcons = (badge: UniversityBadge) => { - DATA.forEach((item) => { + DATA?.forEach((item) => { if (item.title === badge.category) { item.data.forEach((object) => { if (object.badgeName === badge.name) { -- cgit v1.2.3-70-g09d2 From 4a05b26c5c32980ac18c832cc4dd74c6c93922a8 Mon Sep 17 00:00:00 2001 From: Ivan Chen Date: Fri, 12 Mar 2021 14:17:55 -0500 Subject: using discover/get_users, updated route params, cleaned up code --- src/components/common/GradientBorderButton.tsx | 10 +++--- src/components/search/SearchCategories.tsx | 25 +++++++++----- src/components/search/SearchResultCell.tsx | 3 -- src/components/search/SearchResultList.tsx | 1 - src/routes/main/MainStackNavigator.tsx | 1 - src/routes/main/MainStackScreen.tsx | 3 +- src/screens/search/DiscoverUsers.tsx | 34 ++++++++++--------- src/screens/search/SearchScreen.tsx | 22 +++++++++--- src/services/ExploreService.ts | 46 ++++++++++++++------------ 9 files changed, 83 insertions(+), 62 deletions(-) (limited to 'src') diff --git a/src/components/common/GradientBorderButton.tsx b/src/components/common/GradientBorderButton.tsx index 0402c44b..00ea7175 100644 --- a/src/components/common/GradientBorderButton.tsx +++ b/src/components/common/GradientBorderButton.tsx @@ -45,20 +45,20 @@ const styles = StyleSheet.create({ marginVertical: 15, }, gradientContainer: { - width: 159, - height: 38, + width: 175, + height: 40, }, label: { fontWeight: '500', - fontSize: normalize(15), + fontSize: normalize(14), }, maskBorder: { borderRadius: 20, }, textContainer: { position: 'absolute', - width: 159, - height: 38, + width: 175, + height: 40, justifyContent: 'center', alignItems: 'center', }, diff --git a/src/components/search/SearchCategories.tsx b/src/components/search/SearchCategories.tsx index f00debb5..a71befe6 100644 --- a/src/components/search/SearchCategories.tsx +++ b/src/components/search/SearchCategories.tsx @@ -2,16 +2,18 @@ import {useNavigation} from '@react-navigation/native'; import React, {useEffect, useState} from 'react'; import {StyleSheet, View} from 'react-native'; import {GradientBorderButton} from '..'; -import {getButtons} from '../../services/ExploreService'; +import {getSuggestedSearchBubbleSuggestions} from '../../services/ExploreService'; import {SearchCategoryType} from '../../types'; import {SCREEN_WIDTH} from '../../utils'; interface SearchCategoriesProps { darkStyle?: boolean; + defaultButtons?: SearchCategoryType[]; } const SearchCategories: React.FC = ({ darkStyle = false, + defaultButtons, }) => { const navigation = useNavigation(); const mtSearchCategory: (key: number) => SearchCategoryType = (key) => ({ @@ -20,18 +22,25 @@ const SearchCategories: React.FC = ({ category: '...', }); const [buttons, setButtons] = useState([ - mtSearchCategory(1), - mtSearchCategory(2), - mtSearchCategory(3), - mtSearchCategory(4), + mtSearchCategory(-1), + mtSearchCategory(-2), + mtSearchCategory(-3), + mtSearchCategory(-4), ]); + useEffect(() => { const loadButtons = async () => { - const localButtons = await getButtons(); + const localButtons = await getSuggestedSearchBubbleSuggestions(); setButtons([]); - setButtons(localButtons); + if (localButtons) { + setButtons(localButtons); + } }; - loadButtons(); + if (!defaultButtons) { + loadButtons(); + } else { + setButtons(defaultButtons); + } }, []); return ( diff --git a/src/components/search/SearchResultCell.tsx b/src/components/search/SearchResultCell.tsx index 5cba6d2f..e0351d96 100644 --- a/src/components/search/SearchResultCell.tsx +++ b/src/components/search/SearchResultCell.tsx @@ -23,13 +23,11 @@ import { } from '../../utils/users'; interface SearchResults { - type: 'badges' | 'categories' | 'users'; profileData: ProfilePreviewType; loggedInUser: UserType; } const SearchResultsCell: React.FC = ({ - type, profileData: { id, name, @@ -114,7 +112,6 @@ const SearchResultsCell: React.FC = ({ const categoryObj: CategoryPreviewType = {name, category}; addCategoryToRecentlySearched(categoryObj); navigation.navigate('DiscoverUsers', { - type, searchCategory: {id, name}, }); }; diff --git a/src/components/search/SearchResultList.tsx b/src/components/search/SearchResultList.tsx index d8cf02d9..704e4192 100644 --- a/src/components/search/SearchResultList.tsx +++ b/src/components/search/SearchResultList.tsx @@ -57,7 +57,6 @@ const SearchResultList: React.FC = ({ renderItem={({section, item}) => { return ( diff --git a/src/routes/main/MainStackNavigator.tsx b/src/routes/main/MainStackNavigator.tsx index 10b8ec3d..8953cfe0 100644 --- a/src/routes/main/MainStackNavigator.tsx +++ b/src/routes/main/MainStackNavigator.tsx @@ -22,7 +22,6 @@ export type MainStackParams = { screenType: ScreenType; }; DiscoverUsers: { - type: 'badges' | 'categories' | 'users'; searchCategory: SearchCategoryType; }; Profile: { diff --git a/src/routes/main/MainStackScreen.tsx b/src/routes/main/MainStackScreen.tsx index 91f41fe4..cb232297 100644 --- a/src/routes/main/MainStackScreen.tsx +++ b/src/routes/main/MainStackScreen.tsx @@ -4,11 +4,9 @@ import {StackNavigationOptions} from '@react-navigation/stack'; import React, {useState} from 'react'; import {StyleSheet, Text} from 'react-native'; import {normalize} from 'react-native-elements'; -import MutualBadgeHolders from '../../screens/suggestedPeople/MutualBadgeHolders'; import BackIcon from '../../assets/icons/back-arrow.svg'; import { AnimatedTutorial, - BadgeSelection, CaptionScreen, CategorySelection, CreateCustomCategory, @@ -26,6 +24,7 @@ import { SuggestedPeopleScreen, SuggestedPeopleUploadPictureScreen, } from '../../screens'; +import MutualBadgeHolders from '../../screens/suggestedPeople/MutualBadgeHolders'; import {ScreenType} from '../../types'; import {AvatarHeaderHeight, SCREEN_WIDTH} from '../../utils'; import {MainStack, MainStackParams} from './MainStackNavigator'; diff --git a/src/screens/search/DiscoverUsers.tsx b/src/screens/search/DiscoverUsers.tsx index a9856909..d67e5448 100644 --- a/src/screens/search/DiscoverUsers.tsx +++ b/src/screens/search/DiscoverUsers.tsx @@ -29,8 +29,7 @@ interface DiscoverUsersProps { } const DiscoverUsers: React.FC = ({route}) => { - const {type: category_type} = route.params; - const {id, name} = route.params.searchCategory; + const {name} = route.params.searchCategory; const [categoryName, setCategoryName] = useState(); const [users, setUsers] = useState([]); const [shouldRefresh, setShouldRefresh] = useState(false); @@ -43,15 +42,15 @@ const DiscoverUsers: React.FC = ({route}) => { thumbnail_url: '', }); const dummyUsers = [ - mtUser(1), - mtUser(2), - mtUser(3), - mtUser(4), - mtUser(5), - mtUser(6), - mtUser(7), - mtUser(8), - mtUser(9), + 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(); @@ -94,7 +93,13 @@ const DiscoverUsers: React.FC = ({route}) => { useEffect(() => { const loadData = async () => { setLoading(true); - setUsers(await getDiscoverUsers(id, category_type)); + if (!categoryName) { + return; + } + const fetched_users = await getDiscoverUsers(categoryName); + if (fetched_users) { + setUsers(fetched_users); + } setLoading(false); }; loadData(); @@ -122,10 +127,7 @@ const DiscoverUsers: React.FC = ({route}) => { ListFooterComponent={() => ( <> Other Groups - setCategoryName(category)} - /> + )} /> diff --git a/src/screens/search/SearchScreen.tsx b/src/screens/search/SearchScreen.tsx index 728510c5..f9a42d86 100644 --- a/src/screens/search/SearchScreen.tsx +++ b/src/screens/search/SearchScreen.tsx @@ -17,7 +17,12 @@ import {SEARCH_ENDPOINT, TAGG_LIGHT_BLUE} from '../../constants'; import {loadSearchResults} from '../../services'; import {resetScreenType} from '../../store/actions'; import {RootState} from '../../store/rootReducer'; -import {ProfilePreviewType, ScreenType, CategoryPreviewType} from '../../types'; +import { + ProfilePreviewType, + ScreenType, + CategoryPreviewType, + SearchCategoryType, +} from '../../types'; import {normalize, SCREEN_HEIGHT, SCREEN_WIDTH} from '../../utils'; /** @@ -37,6 +42,11 @@ const SearchScreen: React.FC = () => { >([]); const [searching, setSearching] = useState(false); const top = Animated.useValue(-SCREEN_HEIGHT); + const defaultButtons: SearchCategoryType[] = [21, 22, 23, 24].map((year) => ({ + id: -1, + name: `Brown '${year}`, + category: 'Brown', + })); const [keyboardVisible, setKeyboardVisible] = React.useState( 'keyboardVisible', ); @@ -57,8 +67,12 @@ const SearchScreen: React.FC = () => { * Main handler for changes in query. */ useEffect(() => { - if (!searching) return; - if (!query.length) loadRecentSearches(); + if (!searching) { + return; + } + if (!query.length) { + loadRecentSearches(); + } if (query.length < 3) { setResults(undefined); return; @@ -181,7 +195,7 @@ const SearchScreen: React.FC = () => { stickyHeaderIndices={[4]} contentContainerStyle={styles.contentContainer} showsVerticalScrollIndicator={false}> - + {results === undefined && recents.length + recentCategories.length !== 0 ? ( diff --git a/src/services/ExploreService.ts b/src/services/ExploreService.ts index 9b0b4f71..07af91ad 100644 --- a/src/services/ExploreService.ts +++ b/src/services/ExploreService.ts @@ -68,13 +68,10 @@ export const getAllExploreSections = async () => { } }; -export const getDiscoverUsers = async (id: number, category_type: string) => { +export const getDiscoverUsers = async (categoryName: string) => { try { const token = await AsyncStorage.getItem('token'); - let url = DISCOVER_ENDPOINT + `${id}/`; - if (category_type === 'badges') { - url += '?type=badge'; - } + const url = `${DISCOVER_ENDPOINT}get_users/?category=${categoryName}`; const response = await fetch(url, { method: 'GET', headers: { @@ -82,31 +79,36 @@ export const getDiscoverUsers = async (id: number, category_type: string) => { }, }); if (response.status !== 200) { - return EMPTY_PROFILE_PREVIEW_LIST; + return undefined; } - const data = await response.json(); - const users: ProfilePreviewType[] = data.users; + const users: ProfilePreviewType[] = await response.json(); return users; } catch (error) { console.log('Error fetching SP user data'); console.log(error); - return []; + return undefined; } }; -export const getButtons = async () => { - const token = await AsyncStorage.getItem('token'); - const response = await fetch(SEARCH_BUTTONS_ENDPOPINT, { - method: 'GET', - headers: { - Authorization: 'Token ' + token, - }, - }); +export const getSuggestedSearchBubbleSuggestions = async () => { + try { + const token = await AsyncStorage.getItem('token'); + const response = await fetch(SEARCH_BUTTONS_ENDPOPINT, { + method: 'GET', + headers: { + Authorization: 'Token ' + token, + }, + }); + + if (response.status !== 200) { + return undefined; + } - if (response.status !== 200) { - return []; + const data: SearchCategoryType[] = await response.json(); + return data; + } catch (error) { + console.log('Error fetching suggested search bubble suggestions'); + console.log(error); + return undefined; } - - const data: SearchCategoryType[] = await response.json(); - return data; }; -- cgit v1.2.3-70-g09d2 From 3c1e9ee07e6cc09cf9ac4d28fb9615e8e36ed14c Mon Sep 17 00:00:00 2001 From: Shravya Ramesh Date: Fri, 12 Mar 2021 11:24:43 -0800 Subject: Defined specific width --- src/components/search/SearchResultCell.tsx | 1 + src/components/search/SearchResultList.tsx | 6 +++++- 2 files changed, 6 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/components/search/SearchResultCell.tsx b/src/components/search/SearchResultCell.tsx index 5cba6d2f..6954ff8c 100644 --- a/src/components/search/SearchResultCell.tsx +++ b/src/components/search/SearchResultCell.tsx @@ -172,6 +172,7 @@ const styles = StyleSheet.create({ flexDirection: 'row', paddingHorizontal: 25, paddingVertical: 15, + width: SCREEN_WIDTH, }, imageContainer: { width: SCREEN_WIDTH * 0.112, diff --git a/src/components/search/SearchResultList.tsx b/src/components/search/SearchResultList.tsx index d8cf02d9..2a4d3746 100644 --- a/src/components/search/SearchResultList.tsx +++ b/src/components/search/SearchResultList.tsx @@ -51,7 +51,7 @@ const SearchResultList: React.FC = ({ {width: SCREEN_WIDTH}, keyboardVisible ? styles.keyboardOpen : {}, ]} - contentContainerStyle={{paddingBottom: SCREEN_HEIGHT * 0.1}} + contentContainerStyle={styles.sectionListContentContainer} sections={results} keyExtractor={(item, index) => item.id + index} renderItem={({section, item}) => { @@ -77,6 +77,10 @@ const styles = StyleSheet.create({ height: SCREEN_HEIGHT, paddingBottom: SCREEN_HEIGHT * 0.1, }, + sectionListContentContainer: { + paddingBottom: SCREEN_HEIGHT * 0.15, + width: SCREEN_WIDTH, + }, sectionHeaderStyle: { width: '100%', height: 0.5, -- cgit v1.2.3-70-g09d2 From 2c9b2cf69d6e2fba44bcecb2636f51c94b8a64dd Mon Sep 17 00:00:00 2001 From: Ivan Chen Date: Fri, 12 Mar 2021 14:57:12 -0500 Subject: fixed layout issue on smaller screens --- src/components/common/GradientBorderButton.tsx | 6 +++--- src/screens/search/DiscoverUsers.tsx | 1 - 2 files changed, 3 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/components/common/GradientBorderButton.tsx b/src/components/common/GradientBorderButton.tsx index 00ea7175..00f46a96 100644 --- a/src/components/common/GradientBorderButton.tsx +++ b/src/components/common/GradientBorderButton.tsx @@ -4,7 +4,7 @@ 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'; +import {normalize, SCREEN_WIDTH} from '../../utils'; interface GradientBorderButtonProps { text: string; @@ -45,7 +45,7 @@ const styles = StyleSheet.create({ marginVertical: 15, }, gradientContainer: { - width: 175, + width: SCREEN_WIDTH / 2 - 40, height: 40, }, label: { @@ -57,7 +57,7 @@ const styles = StyleSheet.create({ }, textContainer: { position: 'absolute', - width: 175, + width: SCREEN_WIDTH / 2 - 40, height: 40, justifyContent: 'center', alignItems: 'center', diff --git a/src/screens/search/DiscoverUsers.tsx b/src/screens/search/DiscoverUsers.tsx index d67e5448..b87bfc37 100644 --- a/src/screens/search/DiscoverUsers.tsx +++ b/src/screens/search/DiscoverUsers.tsx @@ -117,7 +117,6 @@ const DiscoverUsers: React.FC = ({route}) => {