aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBrian Kim <brian@tagg.id>2021-06-01 14:43:30 -0700
committerBrian Kim <brian@tagg.id>2021-06-01 14:43:30 -0700
commit68fcf7c533ba7612c94760b1171c506f64bfc0ae (patch)
treeb7afc5349b493cedf6f019ca9c6ab87dbb465597 /src
parent013dfb29a603fcd51105e0fa28e8b6adc0f49b86 (diff)
Filled out basic front-end, need to integrate with back-end
Diffstat (limited to 'src')
-rw-r--r--src/assets/images/Profile Icon.pngbin0 -> 1504 bytes
-rw-r--r--src/assets/images/pill-icon-1.pngbin0 -> 868 bytes
-rw-r--r--src/assets/images/pill-icon-2.pngbin0 -> 1276 bytes
-rw-r--r--src/assets/images/pill-icon-3.pngbin0 -> 1037 bytes
-rw-r--r--src/assets/images/pill-icon-4.pngbin0 -> 1249 bytes
-rw-r--r--src/assets/images/purple-tip.pngbin0 -> 680 bytes
-rw-r--r--src/constants/constants.ts4
-rw-r--r--src/routes/tabs/NavigationBar.tsx405
-rw-r--r--src/utils/common.ts25
9 files changed, 359 insertions, 75 deletions
diff --git a/src/assets/images/Profile Icon.png b/src/assets/images/Profile Icon.png
new file mode 100644
index 00000000..f8eae388
--- /dev/null
+++ b/src/assets/images/Profile Icon.png
Binary files differ
diff --git a/src/assets/images/pill-icon-1.png b/src/assets/images/pill-icon-1.png
new file mode 100644
index 00000000..06956c6a
--- /dev/null
+++ b/src/assets/images/pill-icon-1.png
Binary files differ
diff --git a/src/assets/images/pill-icon-2.png b/src/assets/images/pill-icon-2.png
new file mode 100644
index 00000000..b2370b80
--- /dev/null
+++ b/src/assets/images/pill-icon-2.png
Binary files differ
diff --git a/src/assets/images/pill-icon-3.png b/src/assets/images/pill-icon-3.png
new file mode 100644
index 00000000..6cdf0b15
--- /dev/null
+++ b/src/assets/images/pill-icon-3.png
Binary files differ
diff --git a/src/assets/images/pill-icon-4.png b/src/assets/images/pill-icon-4.png
new file mode 100644
index 00000000..6e132647
--- /dev/null
+++ b/src/assets/images/pill-icon-4.png
Binary files differ
diff --git a/src/assets/images/purple-tip.png b/src/assets/images/purple-tip.png
new file mode 100644
index 00000000..27f5a89a
--- /dev/null
+++ b/src/assets/images/purple-tip.png
Binary files differ
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, ',');
+};