diff options
author | Brian Kim <brian@tagg.id> | 2021-06-01 14:43:30 -0700 |
---|---|---|
committer | Brian Kim <brian@tagg.id> | 2021-06-01 14:43:30 -0700 |
commit | 68fcf7c533ba7612c94760b1171c506f64bfc0ae (patch) | |
tree | b7afc5349b493cedf6f019ca9c6ab87dbb465597 /src | |
parent | 013dfb29a603fcd51105e0fa28e8b6adc0f49b86 (diff) |
Filled out basic front-end, need to integrate with back-end
Diffstat (limited to 'src')
-rw-r--r-- | src/assets/images/Profile Icon.png | bin | 0 -> 1504 bytes | |||
-rw-r--r-- | src/assets/images/pill-icon-1.png | bin | 0 -> 868 bytes | |||
-rw-r--r-- | src/assets/images/pill-icon-2.png | bin | 0 -> 1276 bytes | |||
-rw-r--r-- | src/assets/images/pill-icon-3.png | bin | 0 -> 1037 bytes | |||
-rw-r--r-- | src/assets/images/pill-icon-4.png | bin | 0 -> 1249 bytes | |||
-rw-r--r-- | src/assets/images/purple-tip.png | bin | 0 -> 680 bytes | |||
-rw-r--r-- | src/constants/constants.ts | 4 | ||||
-rw-r--r-- | src/routes/tabs/NavigationBar.tsx | 405 | ||||
-rw-r--r-- | src/utils/common.ts | 25 |
9 files changed, 359 insertions, 75 deletions
diff --git a/src/assets/images/Profile Icon.png b/src/assets/images/Profile Icon.png Binary files differnew file mode 100644 index 00000000..f8eae388 --- /dev/null +++ b/src/assets/images/Profile Icon.png diff --git a/src/assets/images/pill-icon-1.png b/src/assets/images/pill-icon-1.png Binary files differnew file mode 100644 index 00000000..06956c6a --- /dev/null +++ b/src/assets/images/pill-icon-1.png diff --git a/src/assets/images/pill-icon-2.png b/src/assets/images/pill-icon-2.png Binary files differnew file mode 100644 index 00000000..b2370b80 --- /dev/null +++ b/src/assets/images/pill-icon-2.png diff --git a/src/assets/images/pill-icon-3.png b/src/assets/images/pill-icon-3.png Binary files differnew file mode 100644 index 00000000..6cdf0b15 --- /dev/null +++ b/src/assets/images/pill-icon-3.png diff --git a/src/assets/images/pill-icon-4.png b/src/assets/images/pill-icon-4.png Binary files differnew file mode 100644 index 00000000..6e132647 --- /dev/null +++ b/src/assets/images/pill-icon-4.png diff --git a/src/assets/images/purple-tip.png b/src/assets/images/purple-tip.png Binary files differnew file mode 100644 index 00000000..27f5a89a --- /dev/null +++ b/src/assets/images/purple-tip.png diff --git a/src/constants/constants.ts b/src/constants/constants.ts index 99d3901b..e6c23554 100644 --- a/src/constants/constants.ts +++ b/src/constants/constants.ts @@ -21,6 +21,9 @@ export const AVATAR_GRADIENT_DIM = 50; export const TAGG_ICON_DIM = 58; export const TAGG_RING_DIM = normalize(60); +// default height of the navigation bar, from react native library, unless on ipad +export const NAV_BAR_HEIGHT = 49; + export const INTEGRATED_SOCIAL_LIST: string[] = [ 'Instagram', 'Facebook', @@ -89,6 +92,7 @@ export const BADGE_GRADIENT_REST = [ 'rgba(78, 54, 41, 1)', 'rgba(236, 32, 39, 1)', ]; +export const NOTIFICATION_ICON_GRADIENT = ['#8F01FF', '#7B02DA']; export const SOCIAL_FONT_COLORS = { INSTAGRAM: INSTAGRAM_FONT_COLOR, diff --git a/src/routes/tabs/NavigationBar.tsx b/src/routes/tabs/NavigationBar.tsx index 000ac614..0e08d834 100644 --- a/src/routes/tabs/NavigationBar.tsx +++ b/src/routes/tabs/NavigationBar.tsx @@ -1,12 +1,26 @@ import {createBottomTabNavigator} from '@react-navigation/bottom-tabs'; -import React, {Fragment, useEffect, useState} from 'react'; +import React, {Fragment, useEffect, useState, useRef} from 'react'; +import {Image, StyleSheet, Text, View} from 'react-native'; +import LinearGradient from 'react-native-linear-gradient'; import {useSelector} from 'react-redux'; import {NavigationIcon} from '../../components'; import {NO_NOTIFICATIONS} from '../../store/initialStates'; import {RootState} from '../../store/rootReducer'; -import {ScreenType} from '../../types'; -import {haveUnreadNotifications} from '../../utils'; +import {ScreenType, NotificationType} from '../../types'; +import { + haveUnreadNotifications, + getUnreadNotifications, + SCREEN_WIDTH, + isIPhoneX, +} from '../../utils'; import MainStackScreen from '../main/MainStackScreen'; +import { + NOTIFICATION_ICON_GRADIENT, + CHIN_HEIGHT, + NAV_BAR_HEIGHT, +} from '../../constants'; +import {normalize} from 'react-native-elements'; +import {numberWithCommas} from '../../utils'; const Tabs = createBottomTabNavigator(); @@ -19,8 +33,47 @@ const NavigationBar: React.FC = () => { (state: RootState) => state, ); - const [unreadNotificationsPresent, setUnreadNotificationsPresent] = - useState<boolean>(false); + const [unread, setUnread] = useState({ + CMT: 4, + FR_REQ: 5, + PR_V: 3, + TAG: 7, + }); + const [showIcon, setShowIcon] = useState<boolean>(true); + const [iconStart, setIconStart] = useState<number[]>([0, -100]); + const [tipStart, setTipStart] = useState<number[]>([0, -100]); + const [complete, setComplete] = useState<boolean>(false); + const [notificationSets, setNotificationSets] = useState({ + CMT: 412314213123, + FR_REQ: 52131, + PR_V: 3, + TAG: 712321, + }); + const [timeCount, setTimeCount] = useState<boolean>(false); + const iconRef = useRef(null); + const tipRef = useRef(null); + const pillTip = require('../../assets/images/purple-tip.png'); + + const navBarPos = 20; + const tipSize = 8; + + const [ + unreadNotificationsPresent, + setUnreadNotificationsPresent, + ] = useState<boolean>(false); + + const countNotifications = ( + notificationsList: NotificationType[], + values: string[], + ) => { + let outputNum = 0; + for (const n of notificationsList) { + if (values.includes(n.notification_type)) { + outputNum++; + } + } + return outputNum; + }; useEffect(() => { const determine = async () => { @@ -28,82 +81,284 @@ const NavigationBar: React.FC = () => { await haveUnreadNotifications(notifications), ); }; + // const establishUnread = async () => { + // setUnread(await getUnreadNotifications(notifications)); + // }; determine(); + // establishUnread(); }, [notifications]); + useEffect(() => { + setTimeout(() => { + console.log('notifications', notifications.length, 'unread', unread); + if (iconRef.current) { + iconRef.current.measure( + ( + _fx: number, + _fy: number, + width: number, + height: number, + _px: number, + _py: number, + ) => { + console.log('HERE 1'); + if (tipRef.current) { + tipRef.current.measure( + ( + __fx: number, + __fy: number, + width2: number, + __height: number, + __px: number, + __py: number, + ) => { + const x = SCREEN_WIDTH / 2 - width / 2; + const y = isIPhoneX() + ? CHIN_HEIGHT + NAV_BAR_HEIGHT + navBarPos + : NAV_BAR_HEIGHT + navBarPos; + setIconStart([x, y]); + setTipStart([width / 2 - width2 / 2, height - 1]); + setTimeout(() => { + setComplete(true); + console.log('HERE 2'); + }, 100); + setTimeCount(true); + }, + ); + } + }, + ); + } else { + console.log('ISSUE', iconRef.current); + } + }, 100); + }, [unread, iconRef, tipRef]); + + useEffect(() => { + if (timeCount) { + setTimeout(() => { + setShowIcon(false); + }, 5000); + } + }, [timeCount]); + + useEffect(() => { + setTimeout(() => { + console.log('complete', complete); + }, 100); + }, [complete]); + + useEffect(() => { + setTimeout(() => { + console.log('iconRef', iconRef); + }, 60000); + }); + return ( - <Tabs.Navigator - screenOptions={({route}) => ({ - tabBarIcon: ({focused}) => { - switch (route.name) { - case 'Home': - return <NavigationIcon tab="Home" disabled={!focused} />; - case 'Search': - return <NavigationIcon tab="Search" disabled={!focused} />; - case 'Upload': - return <NavigationIcon tab="Upload" disabled={!focused} />; - case 'Notifications': - return ( - <NavigationIcon - newIcon={ - newNotificationReceived || unreadNotificationsPresent - } - tab="Notifications" - disabled={!focused} + <> + {unread && Object.keys(unread).length !== 0 && showIcon && ( + <View + style={[ + styles.purpleContainer, + {bottom: iconStart[1], left: iconStart[0]}, + ]} + ref={iconRef}> + <LinearGradient + colors={NOTIFICATION_ICON_GRADIENT} + style={styles.iconPurple}> + {notificationSets.CMT && ( + <> + <Image + source={require('../../assets/images/pill-icon-1.png')} + style={styles.indicationIcon} /> - ); - case 'Chat': - return <NavigationIcon tab="Chat" disabled={!focused} />; - case 'Profile': - return <NavigationIcon tab="Profile" disabled={!focused} />; - case 'SuggestedPeople': - return ( - <NavigationIcon tab="SuggestedPeople" disabled={!focused} /> - ); - default: - return <Fragment />; - } - }, - })} - initialRouteName={isOnboardedUser ? 'Profile' : 'SuggestedPeople'} - tabBarOptions={{ - showLabel: false, - style: { - backgroundColor: 'transparent', - position: 'absolute', - borderTopWidth: 0, - left: 0, - right: 0, - bottom: '1%', - }, - }}> - <Tabs.Screen - name="SuggestedPeople" - component={MainStackScreen} - initialParams={{screenType: ScreenType.SuggestedPeople}} - /> - <Tabs.Screen - name="Search" - component={MainStackScreen} - initialParams={{screenType: ScreenType.Search}} - /> - <Tabs.Screen - name="Notifications" - component={MainStackScreen} - initialParams={{screenType: ScreenType.Notifications}} - /> - <Tabs.Screen - name="Chat" - component={MainStackScreen} - initialParams={{screenType: ScreenType.Chat}} - /> - <Tabs.Screen - name="Profile" - component={MainStackScreen} - initialParams={{screenType: ScreenType.Profile}} - /> - </Tabs.Navigator> + <Text style={styles.text}> + {numberWithCommas(notificationSets.CMT)} + </Text> + </> + )} + {notificationSets.FR_REQ && ( + <> + <Image + source={require('../../assets/images/pill-icon-2.png')} + style={styles.indicationIcon} + /> + <Text style={styles.text}> + {numberWithCommas(notificationSets.FR_REQ)} + </Text> + </> + )} + {notificationSets.PR_V && ( + <> + <Image + source={require('../../assets/images/pill-icon-3.png')} + style={styles.indicationIcon} + /> + <Text style={styles.text}> + {numberWithCommas(notificationSets.PR_V)} + </Text> + </> + )} + {notificationSets.TAG && ( + <> + <Image + source={require('../../assets/images/pill-icon-4.png')} + style={styles.indicationIcon} + /> + <Text style={styles.text}> + {numberWithCommas(notificationSets.TAG)} + </Text> + </> + )} + </LinearGradient> + <Image + style={[styles.tip, {top: tipStart[1], left: tipStart[0]}]} + source={pillTip} + ref={tipRef} + /> + </View> + )} + <Tabs.Navigator + screenOptions={({route}) => ({ + tabBarIcon: ({focused}) => { + switch (route.name) { + case 'Home': + return <NavigationIcon tab="Home" disabled={!focused} />; + case 'Search': + return <NavigationIcon tab="Search" disabled={!focused} />; + case 'Upload': + return <NavigationIcon tab="Upload" disabled={!focused} />; + case 'Notifications': + return ( + <NavigationIcon + newIcon={ + newNotificationReceived || unreadNotificationsPresent + } + tab="Notifications" + disabled={!focused} + /> + ); + case 'Chat': + return <NavigationIcon tab="Chat" disabled={!focused} />; + case 'Profile': + return <NavigationIcon tab="Profile" disabled={!focused} />; + case 'SuggestedPeople': + return ( + <NavigationIcon tab="SuggestedPeople" disabled={!focused} /> + ); + default: + return <Fragment />; + } + }, + })} + initialRouteName={isOnboardedUser ? 'Profile' : 'SuggestedPeople'} + tabBarOptions={{ + showLabel: false, + style: { + backgroundColor: 'transparent', + position: 'absolute', + borderTopWidth: 0, + left: 0, + right: 0, + bottom: '1%', + }, + }}> + <Tabs.Screen + name="SuggestedPeople" + component={MainStackScreen} + initialParams={{screenType: ScreenType.SuggestedPeople}} + listeners={{ + tabPress: (_) => { + setShowIcon(true); + }, + }} + /> + <Tabs.Screen + name="Search" + component={MainStackScreen} + initialParams={{screenType: ScreenType.Search}} + listeners={{ + tabPress: (_) => { + setShowIcon(true); + }, + }} + /> + <Tabs.Screen + name="Notifications" + component={MainStackScreen} + initialParams={{screenType: ScreenType.Notifications}} + listeners={{ + tabPress: (_) => { + setShowIcon(false); + }, + }} + /> + <Tabs.Screen + name="Chat" + component={MainStackScreen} + initialParams={{screenType: ScreenType.Chat}} + listeners={{ + tabPress: (_) => { + setShowIcon(true); + }, + }} + /> + <Tabs.Screen + name="Profile" + component={MainStackScreen} + initialParams={{screenType: ScreenType.Profile}} + listeners={{ + tabPress: (_) => { + setShowIcon(true); + }, + }} + /> + </Tabs.Navigator> + </> ); }; +const styles = StyleSheet.create({ + purpleContainer: { + // borderWidth: 1, + flex: 1, + justifyContent: 'center', + position: 'absolute', + zIndex: 999, + // flexDirection: 'row', + // bottom: 50, + // height: normalize(20), + }, + iconPurple: { + padding: 5, + borderRadius: 15, + flex: 1, + flexDirection: 'row', + // justifyContent: 'center', + // alignContent: 'center', + alignItems: 'center', + }, + text: { + margin: 2, + color: 'white', + fontSize: normalize(10), + justifyContent: 'center', + alignItems: 'center', + }, + tip: { + // borderWidth: 1, + position: 'absolute', + zIndex: 999, + height: 12, + // aspectRatio: 12 / 8, + flex: 1, + resizeMode: 'contain', + }, + indicationIcon: { + height: 15, + width: 15, + margin: 2, + }, +}); + export default NavigationBar; diff --git a/src/utils/common.ts b/src/utils/common.ts index 95e77f64..9d0de64b 100644 --- a/src/utils/common.ts +++ b/src/utils/common.ts @@ -101,6 +101,27 @@ export const haveUnreadNotifications = async ( return false; }; +export const getUnreadNotifications = async ( + notifications: NotificationType[], +): Promise<NotificationType[]> => { + const outputNotifications = []; + for (const n of notifications) { + const notificationDate = moment(n.timestamp); + const prevLastViewed = await AsyncStorage.getItem('notificationLastViewed'); + const lastViewed: moment.Moment | undefined = + prevLastViewed == null ? moment.unix(0) : moment(prevLastViewed); + const dateAge = getDateAge(notificationDate); + if (dateAge === 'unknown') { + continue; + } + const unread = lastViewed ? lastViewed.diff(notificationDate) < 0 : false; + if (unread) { + outputNotifications.push(n); + } + } + return outputNotifications; +}; + // https://stackoverflow.com/a/2450976 export const shuffle = (array: any[]) => { var currentIndex = array.length, @@ -197,3 +218,7 @@ export const validateImageLink = async (url: string | undefined) => { return false; }); }; + +export const numberWithCommas = (digits: number) => { + return digits.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ','); +}; |