From 013dfb29a603fcd51105e0fa28e8b6adc0f49b86 Mon Sep 17 00:00:00 2001 From: Brian Kim Date: Thu, 27 May 2021 15:06:14 -0400 Subject: Bug fix duplicate variables --- src/components/moments/MomentPostContent.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/components/moments/MomentPostContent.tsx b/src/components/moments/MomentPostContent.tsx index f485396f..c00433e7 100644 --- a/src/components/moments/MomentPostContent.tsx +++ b/src/components/moments/MomentPostContent.tsx @@ -38,12 +38,12 @@ const MomentPostContent: React.FC = ({ const [elapsedTime, setElapsedTime] = useState(''); const [comments_count, setCommentsCount] = useState(''); const [tags, setTags] = useState(momentTags); - const [visible, setVisible] = useState(false); + // const [visible, setVisible] = useState(false); const state: RootState = useStore().getState(); const navigation = useNavigation(); const dispatch = useDispatch(); const imageRef = useRef(null); - const [fadeValue, setFadeValue] = useState(new Animated.Value(0)); + // const [fadeValue, setFadeValue] = useState(new Animated.Value(0)); const [visible, setVisible] = useState(false); const [fadeValue, setFadeValue] = useState>( -- cgit v1.2.3-70-g09d2 From 68fcf7c533ba7612c94760b1171c506f64bfc0ae Mon Sep 17 00:00:00 2001 From: Brian Kim Date: Tue, 1 Jun 2021 14:43:30 -0700 Subject: Filled out basic front-end, need to integrate with back-end --- ios/Podfile.lock | 4 +- src/assets/images/Profile Icon.png | Bin 0 -> 1504 bytes src/assets/images/pill-icon-1.png | Bin 0 -> 868 bytes src/assets/images/pill-icon-2.png | Bin 0 -> 1276 bytes src/assets/images/pill-icon-3.png | Bin 0 -> 1037 bytes src/assets/images/pill-icon-4.png | Bin 0 -> 1249 bytes src/assets/images/purple-tip.png | Bin 0 -> 680 bytes src/constants/constants.ts | 4 + src/routes/tabs/NavigationBar.tsx | 405 ++++++++++++++++++++++++++++++------- src/utils/common.ts | 25 +++ 10 files changed, 361 insertions(+), 77 deletions(-) create mode 100644 src/assets/images/Profile Icon.png create mode 100644 src/assets/images/pill-icon-1.png create mode 100644 src/assets/images/pill-icon-2.png create mode 100644 src/assets/images/pill-icon-3.png create mode 100644 src/assets/images/pill-icon-4.png create mode 100644 src/assets/images/purple-tip.png (limited to 'src') diff --git a/ios/Podfile.lock b/ios/Podfile.lock index ae1e7ceb..cbd13f20 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -335,7 +335,7 @@ PODS: - React-Core - react-native-date-picker (3.3.0): - React-Core - - react-native-document-picker (5.0.3): + - react-native-document-picker (5.0.4): - React-Core - react-native-image-resizer (1.4.4): - React-Core @@ -740,7 +740,7 @@ SPEC CHECKSUMS: react-native-cameraroll: 88f4e62d9ecd0e1f253abe4f685474f2ea14bfa2 react-native-contacts: 931baebf460125c5a7bbce1c4521a96c69795123 react-native-date-picker: 76fc79be2f3cad8ff1b2850fc5601e5f8107979d - react-native-document-picker: 2e6ecd112c48215e36431734d902f35201ffab0a + react-native-document-picker: 1a7518132d4a06b67f459be9bb1464a567d2b3b4 react-native-image-resizer: 13ac4af788f88af36d0353a1324401ebabd04fe4 react-native-netinfo: e849fc21ca2f4128a5726c801a82fc6f4a6db50d react-native-safe-area-context: f0906bf8bc9835ac9a9d3f97e8bde2a997d8da79 diff --git a/src/assets/images/Profile Icon.png b/src/assets/images/Profile Icon.png new file mode 100644 index 00000000..f8eae388 Binary files /dev/null and b/src/assets/images/Profile Icon.png 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 Binary files /dev/null and b/src/assets/images/pill-icon-1.png 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 Binary files /dev/null and b/src/assets/images/pill-icon-2.png 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 Binary files /dev/null and b/src/assets/images/pill-icon-3.png 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 Binary files /dev/null and b/src/assets/images/pill-icon-4.png differ diff --git a/src/assets/images/purple-tip.png b/src/assets/images/purple-tip.png new file mode 100644 index 00000000..27f5a89a Binary files /dev/null and b/src/assets/images/purple-tip.png 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(false); + const [unread, setUnread] = useState({ + CMT: 4, + FR_REQ: 5, + PR_V: 3, + TAG: 7, + }); + const [showIcon, setShowIcon] = useState(true); + const [iconStart, setIconStart] = useState([0, -100]); + const [tipStart, setTipStart] = useState([0, -100]); + const [complete, setComplete] = useState(false); + const [notificationSets, setNotificationSets] = useState({ + CMT: 412314213123, + FR_REQ: 52131, + PR_V: 3, + TAG: 712321, + }); + const [timeCount, setTimeCount] = useState(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(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 ( - ({ - tabBarIcon: ({focused}) => { - switch (route.name) { - case 'Home': - return ; - case 'Search': - return ; - case 'Upload': - return ; - case 'Notifications': - return ( - + {unread && Object.keys(unread).length !== 0 && showIcon && ( + + + {notificationSets.CMT && ( + <> + - ); - case 'Chat': - return ; - case 'Profile': - return ; - case 'SuggestedPeople': - return ( - - ); - default: - return ; - } - }, - })} - initialRouteName={isOnboardedUser ? 'Profile' : 'SuggestedPeople'} - tabBarOptions={{ - showLabel: false, - style: { - backgroundColor: 'transparent', - position: 'absolute', - borderTopWidth: 0, - left: 0, - right: 0, - bottom: '1%', - }, - }}> - - - - - - + + {numberWithCommas(notificationSets.CMT)} + + + )} + {notificationSets.FR_REQ && ( + <> + + + {numberWithCommas(notificationSets.FR_REQ)} + + + )} + {notificationSets.PR_V && ( + <> + + + {numberWithCommas(notificationSets.PR_V)} + + + )} + {notificationSets.TAG && ( + <> + + + {numberWithCommas(notificationSets.TAG)} + + + )} + + + + )} + ({ + tabBarIcon: ({focused}) => { + switch (route.name) { + case 'Home': + return ; + case 'Search': + return ; + case 'Upload': + return ; + case 'Notifications': + return ( + + ); + case 'Chat': + return ; + case 'Profile': + return ; + case 'SuggestedPeople': + return ( + + ); + default: + return ; + } + }, + })} + initialRouteName={isOnboardedUser ? 'Profile' : 'SuggestedPeople'} + tabBarOptions={{ + showLabel: false, + style: { + backgroundColor: 'transparent', + position: 'absolute', + borderTopWidth: 0, + left: 0, + right: 0, + bottom: '1%', + }, + }}> + { + setShowIcon(true); + }, + }} + /> + { + setShowIcon(true); + }, + }} + /> + { + setShowIcon(false); + }, + }} + /> + { + setShowIcon(true); + }, + }} + /> + { + setShowIcon(true); + }, + }} + /> + + ); }; +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 => { + 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, ','); +}; -- cgit v1.2.3-70-g09d2 From 43a420ec518f122b684bb9d2f4dd4043bf65d2d2 Mon Sep 17 00:00:00 2001 From: Brian Kim Date: Wed, 2 Jun 2021 11:58:59 -0700 Subject: Some cosmetic changes --- src/assets/images/Group 479.jpg | Bin 0 -> 753 bytes src/assets/images/Group 479.svg | 5 ++ src/routes/tabs/NavigationBar.tsx | 185 +++++++++++++++++--------------------- 3 files changed, 87 insertions(+), 103 deletions(-) create mode 100644 src/assets/images/Group 479.jpg create mode 100644 src/assets/images/Group 479.svg (limited to 'src') diff --git a/src/assets/images/Group 479.jpg b/src/assets/images/Group 479.jpg new file mode 100644 index 00000000..74abad92 Binary files /dev/null and b/src/assets/images/Group 479.jpg differ diff --git a/src/assets/images/Group 479.svg b/src/assets/images/Group 479.svg new file mode 100644 index 00000000..4e1eee01 --- /dev/null +++ b/src/assets/images/Group 479.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/src/routes/tabs/NavigationBar.tsx b/src/routes/tabs/NavigationBar.tsx index 0e08d834..1693d057 100644 --- a/src/routes/tabs/NavigationBar.tsx +++ b/src/routes/tabs/NavigationBar.tsx @@ -6,13 +6,8 @@ import {useSelector} from 'react-redux'; import {NavigationIcon} from '../../components'; import {NO_NOTIFICATIONS} from '../../store/initialStates'; import {RootState} from '../../store/rootReducer'; -import {ScreenType, NotificationType} from '../../types'; -import { - haveUnreadNotifications, - getUnreadNotifications, - SCREEN_WIDTH, - isIPhoneX, -} from '../../utils'; +import {ScreenType} from '../../types'; +import {haveUnreadNotifications, SCREEN_WIDTH, isIPhoneX} from '../../utils'; import MainStackScreen from '../main/MainStackScreen'; import { NOTIFICATION_ICON_GRADIENT, @@ -21,6 +16,7 @@ import { } from '../../constants'; import {normalize} from 'react-native-elements'; import {numberWithCommas} from '../../utils'; +import PillIcon4 from '../../assets/images/Group 479.svg'; const Tabs = createBottomTabNavigator(); @@ -32,13 +28,6 @@ const NavigationBar: React.FC = () => { const {notifications: {notifications} = NO_NOTIFICATIONS} = useSelector( (state: RootState) => state, ); - - const [unread, setUnread] = useState({ - CMT: 4, - FR_REQ: 5, - PR_V: 3, - TAG: 7, - }); const [showIcon, setShowIcon] = useState(true); const [iconStart, setIconStart] = useState([0, -100]); const [tipStart, setTipStart] = useState([0, -100]); @@ -50,31 +39,18 @@ const NavigationBar: React.FC = () => { TAG: 712321, }); const [timeCount, setTimeCount] = useState(false); + const [timeOut, setTimeOut] = useState(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(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 () => { setUnreadNotificationsPresent( @@ -90,7 +66,12 @@ const NavigationBar: React.FC = () => { useEffect(() => { setTimeout(() => { - console.log('notifications', notifications.length, 'unread', unread); + console.log( + 'notifications', + notifications.length, + 'unread', + notificationSets, + ); if (iconRef.current) { iconRef.current.measure( ( @@ -132,12 +113,12 @@ const NavigationBar: React.FC = () => { console.log('ISSUE', iconRef.current); } }, 100); - }, [unread, iconRef, tipRef]); + }, [notificationSets, iconRef, tipRef]); useEffect(() => { if (timeCount) { setTimeout(() => { - setShowIcon(false); + setTimeOut(true); }, 5000); } }, [timeCount]); @@ -156,68 +137,68 @@ const NavigationBar: React.FC = () => { return ( <> - {unread && Object.keys(unread).length !== 0 && showIcon && ( - - - {notificationSets.CMT && ( - <> - - - {numberWithCommas(notificationSets.CMT)} - - - )} - {notificationSets.FR_REQ && ( - <> - - - {numberWithCommas(notificationSets.FR_REQ)} - - - )} - {notificationSets.PR_V && ( - <> - - - {numberWithCommas(notificationSets.PR_V)} - - - )} - {notificationSets.TAG && ( - <> - - - {numberWithCommas(notificationSets.TAG)} - - - )} - - - - )} + {notificationSets && + Object.keys(notificationSets).length !== 0 && + showIcon && + !timeOut && ( + + + {notificationSets.CMT && ( + <> + + + {numberWithCommas(notificationSets.CMT)} + + + )} + {notificationSets.FR_REQ && ( + <> + + + {numberWithCommas(notificationSets.FR_REQ)} + + + )} + {notificationSets.PR_V && ( + <> + + + {numberWithCommas(notificationSets.PR_V)} + + + )} + {notificationSets.TAG && ( + <> + + + {numberWithCommas(notificationSets.TAG)} + + + )} + + + + )} ({ tabBarIcon: ({focused}) => { @@ -320,22 +301,16 @@ const NavigationBar: React.FC = () => { 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: { @@ -344,21 +319,25 @@ const styles = StyleSheet.create({ fontSize: normalize(10), justifyContent: 'center', alignItems: 'center', + marginRight: 10, }, tip: { - // borderWidth: 1, position: 'absolute', zIndex: 999, height: 12, - // aspectRatio: 12 / 8, flex: 1, resizeMode: 'contain', }, indicationIcon: { - height: 15, - width: 15, + height: 14, + width: 14, margin: 2, }, + svgIndicationIcon: { + height: 14, + width: 14, + margin: 3, + }, }); export default NavigationBar; -- cgit v1.2.3-70-g09d2 From f26079e3fcae59f0a97fe31fc29a9f4a43811cbb Mon Sep 17 00:00:00 2001 From: Brian Kim Date: Wed, 2 Jun 2021 16:18:25 -0700 Subject: Removed excess function --- src/utils/common.ts | 21 --------------------- 1 file changed, 21 deletions(-) (limited to 'src') diff --git a/src/utils/common.ts b/src/utils/common.ts index 9d0de64b..049dae90 100644 --- a/src/utils/common.ts +++ b/src/utils/common.ts @@ -101,27 +101,6 @@ export const haveUnreadNotifications = async ( return false; }; -export const getUnreadNotifications = async ( - notifications: NotificationType[], -): Promise => { - 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, -- cgit v1.2.3-70-g09d2 From 19630f8bc3b4b53244007e08436c5be67a4d7ef1 Mon Sep 17 00:00:00 2001 From: Brian Kim Date: Mon, 7 Jun 2021 15:58:08 +0900 Subject: Basic integration with API --- src/constants/api.ts | 1 + src/routes/tabs/NavigationBar.tsx | 31 ++++++------ src/services/NotificationService.ts | 99 +++++++++++++++++++++++++++---------- 3 files changed, 91 insertions(+), 40 deletions(-) (limited to 'src') diff --git a/src/constants/api.ts b/src/constants/api.ts index f02ee407..8d2e1a1e 100644 --- a/src/constants/api.ts +++ b/src/constants/api.ts @@ -45,6 +45,7 @@ export const BLOCK_USER_ENDPOINT: string = API_URL + 'block/'; export const PASSWORD_RESET_ENDPOINT: string = API_URL + 'password-reset/'; export const MOMENT_CATEGORY_ENDPOINT: string = API_URL + 'moment-category/'; export const NOTIFICATIONS_ENDPOINT: string = API_URL + 'notifications/'; +export const NOTIFICATIONS_COUNT_ENDPOINT: string = API_URL + 'notifications/unread_count/' export const DISCOVER_ENDPOINT: string = API_URL + 'discover/'; export const SEARCH_BUTTONS_ENDPOPINT: string = DISCOVER_ENDPOINT + 'search_buttons/'; diff --git a/src/routes/tabs/NavigationBar.tsx b/src/routes/tabs/NavigationBar.tsx index 1693d057..3359fc0d 100644 --- a/src/routes/tabs/NavigationBar.tsx +++ b/src/routes/tabs/NavigationBar.tsx @@ -6,6 +6,7 @@ import {useSelector} from 'react-redux'; import {NavigationIcon} from '../../components'; import {NO_NOTIFICATIONS} from '../../store/initialStates'; import {RootState} from '../../store/rootReducer'; +import {getNotificationsUnreadCount} from '../../services'; import {ScreenType} from '../../types'; import {haveUnreadNotifications, SCREEN_WIDTH, isIPhoneX} from '../../utils'; import MainStackScreen from '../main/MainStackScreen'; @@ -32,12 +33,7 @@ const NavigationBar: React.FC = () => { const [iconStart, setIconStart] = useState([0, -100]); const [tipStart, setTipStart] = useState([0, -100]); const [complete, setComplete] = useState(false); - const [notificationSets, setNotificationSets] = useState({ - CMT: 412314213123, - FR_REQ: 52131, - PR_V: 3, - TAG: 712321, - }); + const [notificationSets, setNotificationSets] = useState({}); const [timeCount, setTimeCount] = useState(false); const [timeOut, setTimeOut] = useState(false); const iconRef = useRef(null); @@ -130,10 +126,17 @@ const NavigationBar: React.FC = () => { }, [complete]); useEffect(() => { - setTimeout(() => { - console.log('iconRef', iconRef); - }, 60000); - }); + // setTimeout(() => { + // console.log('iconRef', iconRef); + // }, 60000); + + const getCount = async () => { + const data = await getNotificationsUnreadCount(); + setNotificationSets(data); + }; + + getCount(); + }, []); return ( <> @@ -172,22 +175,22 @@ const NavigationBar: React.FC = () => { )} - {notificationSets.PR_V && ( + {notificationSets.P_VIEW && ( <> - {numberWithCommas(notificationSets.PR_V)} + {numberWithCommas(notificationSets.P_VIEW)} )} - {notificationSets.TAG && ( + {notificationSets.MOM_TAG && ( <> - {numberWithCommas(notificationSets.TAG)} + {numberWithCommas(notificationSets.MOM_TAG)} )} diff --git a/src/services/NotificationService.ts b/src/services/NotificationService.ts index c5c843f5..92f1cdd1 100644 --- a/src/services/NotificationService.ts +++ b/src/services/NotificationService.ts @@ -1,31 +1,78 @@ import AsyncStorage from '@react-native-community/async-storage'; -import {NOTIFICATIONS_ENDPOINT} from '../constants'; +import { + NOTIFICATIONS_ENDPOINT, + NOTIFICATIONS_COUNT_ENDPOINT, +} from '../constants'; import {NotificationType} from '../types'; -export const getNotificationsData: () => Promise = - async () => { - try { - const token = await AsyncStorage.getItem('token'); - const response = await fetch(NOTIFICATIONS_ENDPOINT, { - method: 'GET', - headers: { - Authorization: 'Token ' + token, - }, - }); - if (response.status === 200) { - const data: any[] = await response.json(); - let typedData: NotificationType[] = []; - for (const o of data) { - typedData.push({ - ...o.notification, - unread: false, - }); - } - return typedData; +export const getNotificationsData: () => Promise< + NotificationType[] +> = async () => { + try { + const token = await AsyncStorage.getItem('token'); + const response = await fetch(NOTIFICATIONS_ENDPOINT, { + method: 'GET', + headers: { + Authorization: 'Token ' + token, + }, + }); + if (response.status === 200) { + const data: any[] = await response.json(); + let typedData: NotificationType[] = []; + for (const o of data) { + typedData.push({ + ...o.notification, + unread: false, + }); } - return []; - } catch (error) { - console.log('Unable to fetch notifications'); - return []; + return typedData; } - }; + return []; + } catch (error) { + console.log('Unable to fetch notifications'); + return []; + } +}; + +export const getNotificationsUnreadCount: () => Promise<{ + CMT?: number; + FRD_REQ?: number; + P_VIEW?: number; + MOM_TAG?: number; +}> = async () => { + try { + const token = await AsyncStorage.getItem('token'); + const response = await fetch(NOTIFICATIONS_COUNT_ENDPOINT, { + method: 'GET', + headers: { + Authorization: 'Token ' + token, + }, + }); + if (response.status === 200) { + const data: any = await response.json(); + const typedData: { + CMT?: number; + FRD_REQ?: number; + P_VIEW?: number; + MOM_TAG?: number; + } = {}; + if (data.CMT && data.CMT > 0) { + typedData.CMT = data.CMT; + } + if (data.FRD_REQ && data.FRD_REQ > 0) { + typedData.FRD_REQ = data.FRD_REQ; + } + if (data.P_VIEW && data.P_VIEW > 0) { + typedData.P_VIEW = data.P_VIEW; + } + if (data.MOM_TAG && data.MOM_TAG > 0) { + typedData.MOM_TAG = data.MOM_TAG; + } + return typedData; + } + return []; + } catch (error) { + console.log('Unable to fetch notifications'); + return []; + } +}; -- cgit v1.2.3-70-g09d2 From 2ab67a10be5305ed54464688c4147a493bfed8f6 Mon Sep 17 00:00:00 2001 From: Brian Kim Date: Tue, 8 Jun 2021 08:14:37 +0900 Subject: Clean up --- src/routes/tabs/NavigationBar.tsx | 34 +++++----------------------------- 1 file changed, 5 insertions(+), 29 deletions(-) (limited to 'src') diff --git a/src/routes/tabs/NavigationBar.tsx b/src/routes/tabs/NavigationBar.tsx index 3359fc0d..4b291023 100644 --- a/src/routes/tabs/NavigationBar.tsx +++ b/src/routes/tabs/NavigationBar.tsx @@ -32,7 +32,6 @@ const NavigationBar: React.FC = () => { const [showIcon, setShowIcon] = useState(true); const [iconStart, setIconStart] = useState([0, -100]); const [tipStart, setTipStart] = useState([0, -100]); - const [complete, setComplete] = useState(false); const [notificationSets, setNotificationSets] = useState({}); const [timeCount, setTimeCount] = useState(false); const [timeOut, setTimeOut] = useState(false); @@ -53,21 +52,11 @@ 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', - notificationSets, - ); if (iconRef.current) { iconRef.current.measure( ( @@ -78,7 +67,6 @@ const NavigationBar: React.FC = () => { _px: number, _py: number, ) => { - console.log('HERE 1'); if (tipRef.current) { tipRef.current.measure( ( @@ -95,10 +83,6 @@ const NavigationBar: React.FC = () => { : NAV_BAR_HEIGHT + navBarPos; setIconStart([x, y]); setTipStart([width / 2 - width2 / 2, height - 1]); - setTimeout(() => { - setComplete(true); - console.log('HERE 2'); - }, 100); setTimeCount(true); }, ); @@ -106,7 +90,6 @@ const NavigationBar: React.FC = () => { }, ); } else { - console.log('ISSUE', iconRef.current); } }, 100); }, [notificationSets, iconRef, tipRef]); @@ -120,19 +103,12 @@ const NavigationBar: React.FC = () => { }, [timeCount]); useEffect(() => { - setTimeout(() => { - console.log('complete', complete); - }, 100); - }, [complete]); - - useEffect(() => { - // setTimeout(() => { - // console.log('iconRef', iconRef); - // }, 60000); - const getCount = async () => { - const data = await getNotificationsUnreadCount(); - setNotificationSets(data); + // const data = await getNotificationsUnreadCount(); + const data = {}; + setTimeout(() => { + setNotificationSets(data); + }, 100); }; getCount(); -- cgit v1.2.3-70-g09d2 From 9c48eeee298eacf781f25907c231f503edb4c5a4 Mon Sep 17 00:00:00 2001 From: Brian Kim Date: Tue, 8 Jun 2021 18:17:21 +0900 Subject: Integrate with backend --- src/constants/api.ts | 3 +- src/routes/tabs/NavigationBar.tsx | 34 ++++++++++-------- src/services/NotificationService.ts | 72 +++++++++++++++++++++++-------------- 3 files changed, 67 insertions(+), 42 deletions(-) (limited to 'src') diff --git a/src/constants/api.ts b/src/constants/api.ts index 8d2e1a1e..b55489d9 100644 --- a/src/constants/api.ts +++ b/src/constants/api.ts @@ -45,7 +45,8 @@ export const BLOCK_USER_ENDPOINT: string = API_URL + 'block/'; export const PASSWORD_RESET_ENDPOINT: string = API_URL + 'password-reset/'; export const MOMENT_CATEGORY_ENDPOINT: string = API_URL + 'moment-category/'; export const NOTIFICATIONS_ENDPOINT: string = API_URL + 'notifications/'; -export const NOTIFICATIONS_COUNT_ENDPOINT: string = API_URL + 'notifications/unread_count/' +export const NOTIFICATIONS_COUNT_ENDPOINT: string = API_URL + 'notifications/unread_count/'; +export const NOTIFICATIONS_DATE: string = API_URL + 'notifications/seen/'; export const DISCOVER_ENDPOINT: string = API_URL + 'discover/'; export const SEARCH_BUTTONS_ENDPOPINT: string = DISCOVER_ENDPOINT + 'search_buttons/'; diff --git a/src/routes/tabs/NavigationBar.tsx b/src/routes/tabs/NavigationBar.tsx index 4b291023..77131098 100644 --- a/src/routes/tabs/NavigationBar.tsx +++ b/src/routes/tabs/NavigationBar.tsx @@ -6,7 +6,10 @@ import {useSelector} from 'react-redux'; import {NavigationIcon} from '../../components'; import {NO_NOTIFICATIONS} from '../../store/initialStates'; import {RootState} from '../../store/rootReducer'; -import {getNotificationsUnreadCount} from '../../services'; +import { + getNotificationsUnreadCount, + setNotificationsReadDate, +} from '../../services'; import {ScreenType} from '../../types'; import {haveUnreadNotifications, SCREEN_WIDTH, isIPhoneX} from '../../utils'; import MainStackScreen from '../main/MainStackScreen'; @@ -41,10 +44,8 @@ const NavigationBar: React.FC = () => { const navBarPos = 20; - const [ - unreadNotificationsPresent, - setUnreadNotificationsPresent, - ] = useState(false); + const [unreadNotificationsPresent, setUnreadNotificationsPresent] = + useState(false); useEffect(() => { const determine = async () => { @@ -56,6 +57,7 @@ const NavigationBar: React.FC = () => { }, [notifications]); useEffect(() => { + console.log('notifications', notificationSets); setTimeout(() => { if (iconRef.current) { iconRef.current.measure( @@ -94,18 +96,18 @@ const NavigationBar: React.FC = () => { }, 100); }, [notificationSets, iconRef, tipRef]); - useEffect(() => { - if (timeCount) { - setTimeout(() => { - setTimeOut(true); - }, 5000); - } - }, [timeCount]); + // useEffect(() => { + // if (timeCount) { + // setTimeout(() => { + // setTimeOut(true); + // }, 5000); + // } + // }, [timeCount]); useEffect(() => { const getCount = async () => { - // const data = await getNotificationsUnreadCount(); - const data = {}; + const data = await getNotificationsUnreadCount(); + // const data = {}; setTimeout(() => { setNotificationSets(data); }, 100); @@ -250,6 +252,7 @@ const NavigationBar: React.FC = () => { listeners={{ tabPress: (_) => { setShowIcon(false); + setNotificationsReadDate(); }, }} /> @@ -298,7 +301,7 @@ const styles = StyleSheet.create({ fontSize: normalize(10), justifyContent: 'center', alignItems: 'center', - marginRight: 10, + marginRight: 5, }, tip: { position: 'absolute', @@ -311,6 +314,7 @@ const styles = StyleSheet.create({ height: 14, width: 14, margin: 2, + marginLeft: 5, }, svgIndicationIcon: { height: 14, diff --git a/src/services/NotificationService.ts b/src/services/NotificationService.ts index 92f1cdd1..3c0245a5 100644 --- a/src/services/NotificationService.ts +++ b/src/services/NotificationService.ts @@ -2,37 +2,37 @@ import AsyncStorage from '@react-native-community/async-storage'; import { NOTIFICATIONS_ENDPOINT, NOTIFICATIONS_COUNT_ENDPOINT, + NOTIFICATIONS_DATE, } from '../constants'; import {NotificationType} from '../types'; -export const getNotificationsData: () => Promise< - NotificationType[] -> = async () => { - try { - const token = await AsyncStorage.getItem('token'); - const response = await fetch(NOTIFICATIONS_ENDPOINT, { - method: 'GET', - headers: { - Authorization: 'Token ' + token, - }, - }); - if (response.status === 200) { - const data: any[] = await response.json(); - let typedData: NotificationType[] = []; - for (const o of data) { - typedData.push({ - ...o.notification, - unread: false, - }); +export const getNotificationsData: () => Promise = + async () => { + try { + const token = await AsyncStorage.getItem('token'); + const response = await fetch(NOTIFICATIONS_ENDPOINT, { + method: 'GET', + headers: { + Authorization: 'Token ' + token, + }, + }); + if (response.status === 200) { + const data: any[] = await response.json(); + let typedData: NotificationType[] = []; + for (const o of data) { + typedData.push({ + ...o.notification, + unread: false, + }); + } + return typedData; } - return typedData; + return []; + } catch (error) { + console.log('Unable to fetch notifications'); + return []; } - return []; - } catch (error) { - console.log('Unable to fetch notifications'); - return []; - } -}; + }; export const getNotificationsUnreadCount: () => Promise<{ CMT?: number; @@ -76,3 +76,23 @@ export const getNotificationsUnreadCount: () => Promise<{ return []; } }; + +export const setNotificationsReadDate: () => Promise = async () => { + try { + const token = await AsyncStorage.getItem('token'); + const response = await fetch(NOTIFICATIONS_DATE, { + method: 'POST', + headers: { + Authorization: 'Token ' + token, + }, + }); + if (response.status === 204) { + return true; + } else { + return false; + } + } catch (error) { + console.log('Unable to fetch notifications'); + return false; + } +}; -- cgit v1.2.3-70-g09d2 From 4636694489159c5f9edf0238460bde08e2219f80 Mon Sep 17 00:00:00 2001 From: Brian Kim Date: Tue, 8 Jun 2021 18:18:14 +0900 Subject: Remove some excess comments --- src/routes/tabs/NavigationBar.tsx | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/routes/tabs/NavigationBar.tsx b/src/routes/tabs/NavigationBar.tsx index 77131098..fa129a23 100644 --- a/src/routes/tabs/NavigationBar.tsx +++ b/src/routes/tabs/NavigationBar.tsx @@ -96,13 +96,13 @@ const NavigationBar: React.FC = () => { }, 100); }, [notificationSets, iconRef, tipRef]); - // useEffect(() => { - // if (timeCount) { - // setTimeout(() => { - // setTimeOut(true); - // }, 5000); - // } - // }, [timeCount]); + useEffect(() => { + if (timeCount) { + setTimeout(() => { + setTimeOut(true); + }, 5000); + } + }, [timeCount]); useEffect(() => { const getCount = async () => { -- cgit v1.2.3-70-g09d2 From 2f66fec878e9bba15ac7f2397820bb48d3f167bb Mon Sep 17 00:00:00 2001 From: Brian Kim Date: Tue, 8 Jun 2021 18:21:26 +0900 Subject: Add documentation --- src/routes/tabs/NavigationBar.tsx | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/routes/tabs/NavigationBar.tsx b/src/routes/tabs/NavigationBar.tsx index fa129a23..e962c8da 100644 --- a/src/routes/tabs/NavigationBar.tsx +++ b/src/routes/tabs/NavigationBar.tsx @@ -47,6 +47,8 @@ const NavigationBar: React.FC = () => { const [unreadNotificationsPresent, setUnreadNotificationsPresent] = useState(false); + // Prior to pill inclusion, determines if notification bell + // should have purple dot useEffect(() => { const determine = async () => { setUnreadNotificationsPresent( @@ -56,8 +58,9 @@ const NavigationBar: React.FC = () => { determine(); }, [notifications]); + // If there are notifications, determines the size of the pill + // and sets points for correct placement useEffect(() => { - console.log('notifications', notificationSets); setTimeout(() => { if (iconRef.current) { iconRef.current.measure( @@ -96,6 +99,7 @@ const NavigationBar: React.FC = () => { }, 100); }, [notificationSets, iconRef, tipRef]); + // Used so that pill disappears after 5 seconds useEffect(() => { if (timeCount) { setTimeout(() => { @@ -104,10 +108,10 @@ const NavigationBar: React.FC = () => { } }, [timeCount]); + // Gets data from backend to check for unreads useEffect(() => { const getCount = async () => { const data = await getNotificationsUnreadCount(); - // const data = {}; setTimeout(() => { setNotificationSets(data); }, 100); @@ -229,6 +233,8 @@ const NavigationBar: React.FC = () => { name="SuggestedPeople" component={MainStackScreen} initialParams={{screenType: ScreenType.SuggestedPeople}} + // Added these to as a way to close pill when on + // notification page listeners={{ tabPress: (_) => { setShowIcon(true); @@ -252,6 +258,7 @@ const NavigationBar: React.FC = () => { listeners={{ tabPress: (_) => { setShowIcon(false); + // Updates backend's date of reading notifications setNotificationsReadDate(); }, }} -- cgit v1.2.3-70-g09d2 From fb9aaaa3ff24497ee1a06c6c85c2bbbc835335e0 Mon Sep 17 00:00:00 2001 From: brian-tagg <83606050+brian-tagg@users.noreply.github.com> Date: Wed, 9 Jun 2021 00:47:27 +0900 Subject: Update src/services/NotificationService.ts Co-authored-by: Ivan Chen --- src/services/NotificationService.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/services/NotificationService.ts b/src/services/NotificationService.ts index 3c0245a5..2ffc85b2 100644 --- a/src/services/NotificationService.ts +++ b/src/services/NotificationService.ts @@ -56,7 +56,7 @@ export const getNotificationsUnreadCount: () => Promise<{ P_VIEW?: number; MOM_TAG?: number; } = {}; - if (data.CMT && data.CMT > 0) { + if (data.CMT) { typedData.CMT = data.CMT; } if (data.FRD_REQ && data.FRD_REQ > 0) { -- cgit v1.2.3-70-g09d2 From 7316bc3b11d84224ae91a12ec07c97915b0d6c60 Mon Sep 17 00:00:00 2001 From: Shravya Ramesh Date: Tue, 8 Jun 2021 11:19:31 -0700 Subject: Add edit option to bottom drawer, Style --- src/components/common/GenericMoreInfoDrawer.tsx | 14 +++++------ src/components/profile/MomentMoreInfoDrawer.tsx | 32 +++++++++++++++++++----- src/components/profile/ProfileMoreInfoDrawer.tsx | 5 ++-- 3 files changed, 35 insertions(+), 16 deletions(-) (limited to 'src') diff --git a/src/components/common/GenericMoreInfoDrawer.tsx b/src/components/common/GenericMoreInfoDrawer.tsx index 0928ed44..cfc45131 100644 --- a/src/components/common/GenericMoreInfoDrawer.tsx +++ b/src/components/common/GenericMoreInfoDrawer.tsx @@ -3,15 +3,16 @@ import { GestureResponderEvent, StyleSheet, Text, + TextStyle, TouchableOpacity, View, ViewProps, ViewStyle, } from 'react-native'; import {useSafeAreaInsets} from 'react-native-safe-area-context'; -import BottomDrawer from './BottomDrawer'; import {TAGG_LIGHT_BLUE} from '../../constants'; import {normalize, SCREEN_HEIGHT, SCREEN_WIDTH} from '../../utils'; +import BottomDrawer from './BottomDrawer'; // conforms the JSX onPress attribute type type OnPressHandler = (event: GestureResponderEvent) => void; @@ -20,13 +21,12 @@ interface GenericMoreInfoDrawerProps extends ViewProps { isOpen: boolean; setIsOpen: (visible: boolean) => void; showIcons: boolean; - textColor: string; // An array of title, onPressHandler, and icon component - buttons: [string, OnPressHandler, JSX.Element?][]; + buttons: [string, OnPressHandler, JSX.Element?, TextStyle?][]; } const GenericMoreInfoDrawer: React.FC = (props) => { - const {buttons, showIcons, textColor} = props; + const {buttons, showIcons} = props; // each button is 80px high, cancel button is always there const initialSnapPosition = (buttons.length + 1) * 80 + useSafeAreaInsets().bottom; @@ -44,13 +44,11 @@ const GenericMoreInfoDrawer: React.FC = (props) => { showHeader={false} initialSnapPosition={initialSnapPosition}> - {buttons.map(([title, action, icon], index) => ( + {buttons.map(([title, action, icon, textStyle], index) => ( {showIcons && {icon}} - - {title} - + {title} diff --git a/src/components/profile/MomentMoreInfoDrawer.tsx b/src/components/profile/MomentMoreInfoDrawer.tsx index 1265497e..a5411935 100644 --- a/src/components/profile/MomentMoreInfoDrawer.tsx +++ b/src/components/profile/MomentMoreInfoDrawer.tsx @@ -1,20 +1,24 @@ +import {useNavigation} from '@react-navigation/native'; import React, {useEffect, useState} from 'react'; import { Alert, GestureResponderEvent, StyleSheet, + TextStyle, TouchableOpacity, ViewProps, } from 'react-native'; import MoreIcon from '../../assets/icons/more_horiz-24px.svg'; import {ERROR_DELETE_MOMENT, MOMENT_DELETED_MSG} from '../../constants/strings'; import {deleteMoment, sendReport} from '../../services'; +import {ScreenType} from '../../types/types'; import {GenericMoreInfoDrawer} from '../common'; enum MomentDrawerOptions { DeleteMoment = 'Delete Moment', ReportIssue = 'Report an Issue', RemoveTag = 'Remove yourself from moment', + EditMoment = 'Edit Moment', } interface MomentMoreInfoDrawerProps extends ViewProps { isOpen: boolean; @@ -105,12 +109,27 @@ const MomentMoreInfoDrawer: React.FC = (props) => { }; const [drawerButtons, setDrawerButtons] = useState< - [string, (event: GestureResponderEvent) => void, JSX.Element?][] - >([ + [string, (event: GestureResponderEvent) => void, JSX.Element?, TextStyle?][] + >( isOwnProfile - ? [MomentDrawerOptions.DeleteMoment, handleDeleteMoment] - : [MomentDrawerOptions.ReportIssue, handleReportMoment], - ]); + ? [ + [ + MomentDrawerOptions.DeleteMoment, + handleDeleteMoment, + undefined, + {color: 'red'}, + ], + [MomentDrawerOptions.EditMoment, handleEditMoment], + ] + : [ + [ + MomentDrawerOptions.ReportIssue, + handleReportMoment, + undefined, + {color: 'red'}, + ], + ], + ); /* * Update bottom drawer options to contain/not contain 'remove tag' option @@ -129,6 +148,8 @@ const MomentMoreInfoDrawer: React.FC = (props) => { localDrawerButtons.push([ MomentDrawerOptions.RemoveTag, handleRemoveTag, + undefined, + {color: 'red'}, ]); setDrawerButtons(localDrawerButtons); } else if (momentTagId === '' && present !== -1) { @@ -153,7 +174,6 @@ const MomentMoreInfoDrawer: React.FC = (props) => { diff --git a/src/components/profile/ProfileMoreInfoDrawer.tsx b/src/components/profile/ProfileMoreInfoDrawer.tsx index ecc45211..656f81bb 100644 --- a/src/components/profile/ProfileMoreInfoDrawer.tsx +++ b/src/components/profile/ProfileMoreInfoDrawer.tsx @@ -55,12 +55,12 @@ const ProfileMoreInfoDrawer: React.FC = (props) => { @@ -68,7 +68,6 @@ const ProfileMoreInfoDrawer: React.FC = (props) => { = (props) => { source={require('../../assets/images/settings/settings.png')} style={styles.image} />, + {color: 'black'}, ], [ 'Edit Profile', @@ -85,6 +85,7 @@ const ProfileMoreInfoDrawer: React.FC = (props) => { source={require('../../assets/images/settings/edit-profile.png')} style={styles.image} />, + {color: 'black'}, ], ]} /> -- cgit v1.2.3-70-g09d2 From f52f6eaa57250a3eb5cf50dab393c5ec29f4d688 Mon Sep 17 00:00:00 2001 From: Ivan Chen Date: Mon, 7 Jun 2021 15:57:32 -0400 Subject: Resolve warning --- src/components/moments/MomentPostContent.tsx | 4 ++-- src/components/suggestedPeople/legacy/BadgesDropdown.tsx | 6 +++--- src/screens/onboarding/BasicInfoOnboarding.tsx | 6 +++--- 3 files changed, 8 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/components/moments/MomentPostContent.tsx b/src/components/moments/MomentPostContent.tsx index 4a1f3894..23eeae42 100644 --- a/src/components/moments/MomentPostContent.tsx +++ b/src/components/moments/MomentPostContent.tsx @@ -2,7 +2,7 @@ import {useNavigation} from '@react-navigation/native'; import React, {useEffect, useRef, useState} from 'react'; import {Image, StyleSheet, Text, View, ViewProps} from 'react-native'; import {TouchableWithoutFeedback} from 'react-native-gesture-handler'; -import Animated, {Easing} from 'react-native-reanimated'; +import Animated, {EasingNode} from 'react-native-reanimated'; import {useDispatch, useStore} from 'react-redux'; import {getCommentsCount} from '../../services'; import {RootState} from '../../store/rootReducer'; @@ -66,7 +66,7 @@ const MomentPostContent: React.FC = ({ Animated.timing(fadeValue, { toValue: 1, duration: 250, - easing: Easing.linear, + easing: EasingNode.linear, }).start(); }; fade(); diff --git a/src/components/suggestedPeople/legacy/BadgesDropdown.tsx b/src/components/suggestedPeople/legacy/BadgesDropdown.tsx index 2c177e69..307205b8 100644 --- a/src/components/suggestedPeople/legacy/BadgesDropdown.tsx +++ b/src/components/suggestedPeople/legacy/BadgesDropdown.tsx @@ -1,7 +1,7 @@ import React, {useEffect, useState} from 'react'; import {StyleSheet} from 'react-native'; import {TouchableOpacity} from 'react-native-gesture-handler'; -import Animated, {Easing} from 'react-native-reanimated'; +import Animated, {EasingNode} from 'react-native-reanimated'; import {BadgeIcon, UniversityIcon} from '../..'; import {UniversityBadgeDisplayType, UniversityType} from '../../../types'; import {normalize} from '../../../utils'; @@ -41,7 +41,7 @@ const BadgesDropdown: React.FC = ({ Animated.timing(top[i], { toValue: i * 40 + 50, duration: 150, - easing: Easing.linear, + easing: EasingNode.linear, }).start(); } } @@ -54,7 +54,7 @@ const BadgesDropdown: React.FC = ({ Animated.timing(top[i], { toValue: 0, duration: 150, - easing: Easing.linear, + easing: EasingNode.linear, }).start(); } } diff --git a/src/screens/onboarding/BasicInfoOnboarding.tsx b/src/screens/onboarding/BasicInfoOnboarding.tsx index e5e6f59b..d5998ac1 100644 --- a/src/screens/onboarding/BasicInfoOnboarding.tsx +++ b/src/screens/onboarding/BasicInfoOnboarding.tsx @@ -13,7 +13,7 @@ import { TouchableOpacity, } from 'react-native'; import {normalize} from 'react-native-elements'; -import Animated, {Easing, useValue} from 'react-native-reanimated'; +import Animated, {EasingNode, useValue} from 'react-native-reanimated'; import { ArrowButton, Background, @@ -99,7 +99,7 @@ const BasicInfoOnboarding: React.FC = ({route}) => { Animated.timing(fadeButtonValue, { toValue: target, duration: 100, - easing: Easing.linear, + easing: EasingNode.linear, }).start(); }; @@ -108,7 +108,7 @@ const BasicInfoOnboarding: React.FC = ({route}) => { Animated.timing(fadeValue, { toValue: 1, duration: 1000, - easing: Easing.linear, + easing: EasingNode.linear, }).start(); }; fade(); -- cgit v1.2.3-70-g09d2 From d71a4d178715d34570d949e0cd0c1c58186715fc Mon Sep 17 00:00:00 2001 From: Ivan Chen Date: Mon, 7 Jun 2021 16:07:56 -0400 Subject: Adjust header height --- .../moments/IndividualMomentTitleBar.tsx | 1 - src/screens/profile/IndividualMoment.tsx | 26 ++++++++-------------- 2 files changed, 9 insertions(+), 18 deletions(-) (limited to 'src') diff --git a/src/components/moments/IndividualMomentTitleBar.tsx b/src/components/moments/IndividualMomentTitleBar.tsx index 79453ade..2bebafa7 100644 --- a/src/components/moments/IndividualMomentTitleBar.tsx +++ b/src/components/moments/IndividualMomentTitleBar.tsx @@ -30,7 +30,6 @@ const styles = StyleSheet.create({ flexDirection: 'row', alignItems: 'center', justifyContent: 'flex-start', - height: '5%', }, headerContainer: { width: '80%', diff --git a/src/screens/profile/IndividualMoment.tsx b/src/screens/profile/IndividualMoment.tsx index 4ad4515d..f8015720 100644 --- a/src/screens/profile/IndividualMoment.tsx +++ b/src/screens/profile/IndividualMoment.tsx @@ -8,7 +8,12 @@ import {IndividualMomentTitleBar, MomentPost} from '../../components'; import {MainStackParams} from '../../routes'; import {RootState} from '../../store/rootreducer'; import {MomentType} from '../../types'; -import {SCREEN_HEIGHT, SCREEN_WIDTH, StatusBarHeight} from '../../utils'; +import { + normalize, + SCREEN_HEIGHT, + SCREEN_WIDTH, + StatusBarHeight, +} from '../../utils'; /** * Individual moment view opened when user clicks on a moment tile @@ -23,8 +28,6 @@ interface IndividualMomentProps { navigation: IndividualMomentNavigationProp; } -const ITEM_HEIGHT = SCREEN_HEIGHT * 0.9; - const IndividualMoment: React.FC = ({ route, navigation, @@ -50,7 +53,7 @@ const IndividualMoment: React.FC = ({ navigation.pop()} - {...{title: moment_category}} + title={moment_category} /> = ({ renderItem={({item}: {item: MomentType}) => ( )} - keyExtractor={(item, index) => index.toString()} + keyExtractor={(_, index) => index.toString()} showsVerticalScrollIndicator={false} - snapToAlignment={'start'} - snapToInterval={ITEM_HEIGHT} - decelerationRate={'fast'} initialScrollIndex={initialIndex} - getItemLayout={(data, index) => ({ - length: ITEM_HEIGHT, - offset: ITEM_HEIGHT * index, - index, - })} - pagingEnabled /> @@ -87,11 +81,9 @@ const styles = StyleSheet.create({ flex: 9, }, header: { - flex: 1, + height: normalize(70), }, postContainer: { - height: ITEM_HEIGHT, - width: SCREEN_WIDTH, flex: 1, }, postHeader: { -- cgit v1.2.3-70-g09d2 From 960b1516bc06c1fa16ba47a4aab62c94c3b10beb Mon Sep 17 00:00:00 2001 From: Ivan Chen Date: Mon, 7 Jun 2021 16:11:09 -0400 Subject: Cleanup code --- src/screens/profile/IndividualMoment.tsx | 42 +++++++++----------------------- 1 file changed, 11 insertions(+), 31 deletions(-) (limited to 'src') diff --git a/src/screens/profile/IndividualMoment.tsx b/src/screens/profile/IndividualMoment.tsx index f8015720..95428c39 100644 --- a/src/screens/profile/IndividualMoment.tsx +++ b/src/screens/profile/IndividualMoment.tsx @@ -2,18 +2,13 @@ import {BlurView} from '@react-native-community/blur'; import {RouteProp} from '@react-navigation/native'; import {StackNavigationProp} from '@react-navigation/stack'; import React from 'react'; -import {FlatList, StyleSheet, View} from 'react-native'; +import {FlatList, StyleSheet} from 'react-native'; import {useSelector} from 'react-redux'; import {IndividualMomentTitleBar, MomentPost} from '../../components'; import {MainStackParams} from '../../routes'; import {RootState} from '../../store/rootreducer'; import {MomentType} from '../../types'; -import { - normalize, - SCREEN_HEIGHT, - SCREEN_WIDTH, - StatusBarHeight, -} from '../../utils'; +import {normalize, StatusBarHeight} from '../../utils'; /** * Individual moment view opened when user clicks on a moment tile @@ -55,41 +50,26 @@ const IndividualMoment: React.FC = ({ close={() => navigation.pop()} title={moment_category} /> - - ( - - )} - keyExtractor={(_, index) => index.toString()} - showsVerticalScrollIndicator={false} - initialScrollIndex={initialIndex} - /> - + ( + + )} + keyExtractor={(_, index) => index.toString()} + showsVerticalScrollIndicator={false} + initialScrollIndex={initialIndex} + /> ); }; const styles = StyleSheet.create({ contentContainer: { - width: SCREEN_WIDTH, - height: SCREEN_HEIGHT, paddingTop: StatusBarHeight, flex: 1, - paddingBottom: 0, - }, - content: { - flex: 9, }, header: { height: normalize(70), }, - postContainer: { - flex: 1, - }, - postHeader: { - flex: 1, - }, - postContent: {flex: 9}, }); export default IndividualMoment; -- cgit v1.2.3-70-g09d2 From 040ff3d591ea3874dab85325dc437494fb47e287 Mon Sep 17 00:00:00 2001 From: Ivan Chen Date: Mon, 7 Jun 2021 16:18:25 -0400 Subject: Cleanup styles --- src/components/moments/MomentPost.tsx | 29 +++++++--------------------- src/components/moments/MomentPostContent.tsx | 9 +++++++-- 2 files changed, 14 insertions(+), 24 deletions(-) (limited to 'src') diff --git a/src/components/moments/MomentPost.tsx b/src/components/moments/MomentPost.tsx index 7149a5b4..926ae931 100644 --- a/src/components/moments/MomentPost.tsx +++ b/src/components/moments/MomentPost.tsx @@ -71,7 +71,7 @@ const MomentPost: React.FC = ({item, userXId, screenType}) => { }; return ( - + <> = ({item, userXId, screenType}) => { screenType={screenType} momentTags={tags} /> - + ); }; const styles = StyleSheet.create({ - contentContainer: { - width: SCREEN_WIDTH, - height: SCREEN_HEIGHT, - paddingTop: StatusBarHeight, - flex: 1, - paddingBottom: 0, - }, - content: { - flex: 9, - }, - header: { - flex: 1, - }, - postContainer: { - height: ITEM_HEIGHT, - width: SCREEN_WIDTH, - flex: 1, - }, postHeader: { - flex: 1, + // borderWidth: 1, + }, + postContent: { + // borderWidth: 1, + marginBottom: 10, }, - postContent: {flex: 9}, }); export default MomentPost; diff --git a/src/components/moments/MomentPostContent.tsx b/src/components/moments/MomentPostContent.tsx index 23eeae42..2f0f36f7 100644 --- a/src/components/moments/MomentPostContent.tsx +++ b/src/components/moments/MomentPostContent.tsx @@ -88,13 +88,18 @@ const MomentPostContent: React.FC = ({ {tags.length > 0 && ( )} {visible && ( - + null} + imageRef={imageRef} + /> )} -- cgit v1.2.3-70-g09d2 From 47cde91048371301a17e072b8ec02861be563860 Mon Sep 17 00:00:00 2001 From: Ivan Chen Date: Mon, 7 Jun 2021 16:21:54 -0400 Subject: Cleanup styles --- src/components/moments/MomentPost.tsx | 7 ++----- src/components/moments/MomentPostContent.tsx | 5 +---- 2 files changed, 3 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/components/moments/MomentPost.tsx b/src/components/moments/MomentPost.tsx index 926ae931..b97b8034 100644 --- a/src/components/moments/MomentPost.tsx +++ b/src/components/moments/MomentPost.tsx @@ -95,12 +95,9 @@ const MomentPost: React.FC = ({item, userXId, screenType}) => { }; const styles = StyleSheet.create({ - postHeader: { - // borderWidth: 1, - }, + postHeader: {}, postContent: { - // borderWidth: 1, - marginBottom: 10, + minHeight: SCREEN_HEIGHT * 0.8, }, }); diff --git a/src/components/moments/MomentPostContent.tsx b/src/components/moments/MomentPostContent.tsx index 2f0f36f7..de31ad55 100644 --- a/src/components/moments/MomentPostContent.tsx +++ b/src/components/moments/MomentPostContent.tsx @@ -122,9 +122,7 @@ const MomentPostContent: React.FC = ({ }; const styles = StyleSheet.create({ - container: { - height: SCREEN_HEIGHT, - }, + container: {}, image: { width: SCREEN_WIDTH, aspectRatio: 1, @@ -148,7 +146,6 @@ const styles = StyleSheet.create({ }, captionText: { position: 'relative', - paddingBottom: '34%', paddingTop: '1%', marginLeft: '5%', marginRight: '5%', -- cgit v1.2.3-70-g09d2 From 96a80c53fcc0b5815b56f0ed0b48d152a6c6e2a4 Mon Sep 17 00:00:00 2001 From: Ivan Chen Date: Tue, 8 Jun 2021 11:33:13 -0400 Subject: Cleanup linter warnings --- src/components/moments/MomentPost.tsx | 6 ++---- src/components/moments/MomentPostContent.tsx | 1 - src/routes/main/MainStackScreen.tsx | 1 - 3 files changed, 2 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/components/moments/MomentPost.tsx b/src/components/moments/MomentPost.tsx index b97b8034..1f363052 100644 --- a/src/components/moments/MomentPost.tsx +++ b/src/components/moments/MomentPost.tsx @@ -1,11 +1,11 @@ import React, {useEffect, useState} from 'react'; -import {StyleSheet, View} from 'react-native'; +import {StyleSheet} from 'react-native'; import {useSelector} from 'react-redux'; import {MomentPostContent, MomentPostHeader} from '.'; import {deleteMomentTag, loadMomentTags} from '../../services'; import {RootState} from '../../store/rootReducer'; import {MomentTagType, MomentType, ScreenType} from '../../types'; -import {SCREEN_HEIGHT, SCREEN_WIDTH, StatusBarHeight} from '../../utils'; +import {SCREEN_HEIGHT} from '../../utils'; interface MomentPostProps { item: MomentType; @@ -13,8 +13,6 @@ interface MomentPostProps { screenType: ScreenType; } -const ITEM_HEIGHT = SCREEN_HEIGHT * 0.9; - const MomentPost: React.FC = ({item, userXId, screenType}) => { const {userId: loggedInUserId, username: loggedInUsername} = useSelector( (state: RootState) => state.user.user, diff --git a/src/components/moments/MomentPostContent.tsx b/src/components/moments/MomentPostContent.tsx index de31ad55..dcad9aca 100644 --- a/src/components/moments/MomentPostContent.tsx +++ b/src/components/moments/MomentPostContent.tsx @@ -11,7 +11,6 @@ import { getTimePosted, navigateToProfile, normalize, - SCREEN_HEIGHT, SCREEN_WIDTH, } from '../../utils'; import {mentionPartTypes, renderTextWithMentions} from '../../utils/comments'; diff --git a/src/routes/main/MainStackScreen.tsx b/src/routes/main/MainStackScreen.tsx index f6a012d6..3be2ff28 100644 --- a/src/routes/main/MainStackScreen.tsx +++ b/src/routes/main/MainStackScreen.tsx @@ -245,7 +245,6 @@ const MainStackScreen: React.FC = ({route}) => { Date: Tue, 8 Jun 2021 14:20:57 -0400 Subject: Create MomentPostType --- src/components/moments/MomentPost.tsx | 22 +++++++++++++--------- src/screens/profile/IndividualMoment.tsx | 6 +++--- src/services/MomentService.ts | 21 ++++++--------------- src/store/initialStates.ts | 11 +++++++---- src/types/types.ts | 10 +++++++++- 5 files changed, 38 insertions(+), 32 deletions(-) (limited to 'src') diff --git a/src/components/moments/MomentPost.tsx b/src/components/moments/MomentPost.tsx index 1f363052..4f8bb63f 100644 --- a/src/components/moments/MomentPost.tsx +++ b/src/components/moments/MomentPost.tsx @@ -4,16 +4,20 @@ import {useSelector} from 'react-redux'; import {MomentPostContent, MomentPostHeader} from '.'; import {deleteMomentTag, loadMomentTags} from '../../services'; import {RootState} from '../../store/rootReducer'; -import {MomentTagType, MomentType, ScreenType} from '../../types'; +import {MomentPostType, MomentTagType, ScreenType} from '../../types'; import {SCREEN_HEIGHT} from '../../utils'; interface MomentPostProps { - item: MomentType; + moment: MomentPostType; userXId: string | undefined; screenType: ScreenType; } -const MomentPost: React.FC = ({item, userXId, screenType}) => { +const MomentPost: React.FC = ({ + moment, + userXId, + screenType, +}) => { const {userId: loggedInUserId, username: loggedInUsername} = useSelector( (state: RootState) => state.user.user, ); @@ -29,7 +33,7 @@ const MomentPost: React.FC = ({item, userXId, screenType}) => { const isOwnProfile = username === loggedInUsername; const loadTags = async () => { - const response = await loadMomentTags(item.moment_id); + const response = await loadMomentTags(moment.moment_id); setTags(response ? response : []); }; @@ -74,17 +78,17 @@ const MomentPost: React.FC = ({item, userXId, screenType}) => { userXId={userXId} screenType={screenType} username={isOwnProfile ? loggedInUsername : username} - momentId={item.moment_id} + momentId={moment.moment_id} style={styles.postHeader} momentTagId={momentTagId} removeTag={removeTag} /> diff --git a/src/screens/profile/IndividualMoment.tsx b/src/screens/profile/IndividualMoment.tsx index 95428c39..ba6a731c 100644 --- a/src/screens/profile/IndividualMoment.tsx +++ b/src/screens/profile/IndividualMoment.tsx @@ -7,7 +7,7 @@ import {useSelector} from 'react-redux'; import {IndividualMomentTitleBar, MomentPost} from '../../components'; import {MainStackParams} from '../../routes'; import {RootState} from '../../store/rootreducer'; -import {MomentType} from '../../types'; +import {MomentPostType, MomentType} from '../../types'; import {normalize, StatusBarHeight} from '../../utils'; /** @@ -52,8 +52,8 @@ const IndividualMoment: React.FC = ({ /> ( - + renderItem={({item}: {item: MomentPostType}) => ( + )} keyExtractor={(_, index) => index.toString()} showsVerticalScrollIndicator={false} diff --git a/src/services/MomentService.ts b/src/services/MomentService.ts index af602dc7..e227bc9e 100644 --- a/src/services/MomentService.ts +++ b/src/services/MomentService.ts @@ -6,7 +6,7 @@ import { MOMENT_TAGS_ENDPOINT, MOMENT_THUMBNAIL_ENDPOINT, } from '../constants'; -import {MomentTagType, MomentType} from '../types'; +import {MomentPostType, MomentTagType, MomentType} from '../types'; import {checkImageUploadStatus} from '../utils'; export const postMoment = async ( @@ -54,11 +54,7 @@ export const postMoment = async ( return undefined; }; -export const loadMoments: ( - userId: string, - token: string, -) => Promise = async (userId, token) => { - let moments: MomentType[] = []; +export const loadMoments = async (userId: string, token: string) => { try { const response = await fetch(MOMENTS_ENDPOINT + '?user_id=' + userId, { method: 'GET', @@ -66,19 +62,14 @@ export const loadMoments: ( Authorization: 'Token ' + token, }, }); - const status = response.status; - if (status === 200) { - const data = await response.json(); - moments = data; - } else { - console.log('Could not load moments!'); - return []; + if (response.status === 200) { + const typedData: MomentPostType[] = await response.json(); + return typedData; } } catch (err) { console.log(err); - return []; } - return moments; + return []; }; export const deleteMoment = async (momentId: string) => { diff --git a/src/store/initialStates.ts b/src/store/initialStates.ts index e2902a2d..92a1e456 100644 --- a/src/store/initialStates.ts +++ b/src/store/initialStates.ts @@ -1,14 +1,17 @@ -import {CommentThreadType, UniversityType} from './../types/types'; import { - MomentType, NotificationType, - ProfilePreviewType, ProfileInfoType, + ProfilePreviewType, ScreenType, SocialAccountType, UserType, UserXType, } from '../types'; +import { + CommentThreadType, + MomentPostType, + UniversityType, +} from './../types/types'; export const NO_PROFILE: ProfileInfoType = { biography: '', @@ -29,7 +32,7 @@ export const NO_PROFILE: ProfileInfoType = { is_private: true, }; -export const EMPTY_MOMENTS_LIST = []; +export const EMPTY_MOMENTS_LIST = []; export const EMPTY_NOTIFICATIONS_LIST = []; diff --git a/src/types/types.ts b/src/types/types.ts index e54c2201..1e50eba8 100644 --- a/src/types/types.ts +++ b/src/types/types.ts @@ -119,6 +119,14 @@ export interface MomentType { thumbnail_url: string; } +export interface MomentPostType extends MomentType { + comments_count: number; + comment_preview: { + user: ProfilePreviewType; + comment: string; + }; +} + export interface MomentTagType { id: string; user: ProfilePreviewType; @@ -172,7 +180,7 @@ export enum ScreenType { */ export interface UserXType { friends: ProfilePreviewType[]; - moments: MomentType[]; + moments: MomentPostType[]; socialAccounts: Record; momentCategories: string[]; user: UserType; -- cgit v1.2.3-70-g09d2 From be1df6bb00e89c92da9a33d0375cfecb441d3a23 Mon Sep 17 00:00:00 2001 From: Ivan Chen Date: Tue, 8 Jun 2021 14:53:28 -0400 Subject: Cleanup code, Add comment count --- src/components/moments/MomentPost.tsx | 5 +---- src/components/moments/MomentPostContent.tsx | 31 ++++++++-------------------- src/components/moments/MomentPostHeader.tsx | 3 ++- 3 files changed, 12 insertions(+), 27 deletions(-) (limited to 'src') diff --git a/src/components/moments/MomentPost.tsx b/src/components/moments/MomentPost.tsx index 4f8bb63f..ffdbed81 100644 --- a/src/components/moments/MomentPost.tsx +++ b/src/components/moments/MomentPost.tsx @@ -85,10 +85,7 @@ const MomentPost: React.FC = ({ /> diff --git a/src/components/moments/MomentPostContent.tsx b/src/components/moments/MomentPostContent.tsx index dcad9aca..c59a9c39 100644 --- a/src/components/moments/MomentPostContent.tsx +++ b/src/components/moments/MomentPostContent.tsx @@ -4,9 +4,8 @@ import {Image, StyleSheet, Text, View, ViewProps} from 'react-native'; import {TouchableWithoutFeedback} from 'react-native-gesture-handler'; import Animated, {EasingNode} from 'react-native-reanimated'; import {useDispatch, useStore} from 'react-redux'; -import {getCommentsCount} from '../../services'; import {RootState} from '../../store/rootReducer'; -import {MomentTagType, ScreenType, UserType} from '../../types'; +import {MomentPostType, MomentTagType, ScreenType, UserType} from '../../types'; import { getTimePosted, navigateToProfile, @@ -19,18 +18,12 @@ import {MomentTags} from '../common'; interface MomentPostContentProps extends ViewProps { screenType: ScreenType; - momentId: string; - caption: string; - pathHash: string; - dateTime: string; + moment: MomentPostType; momentTags: MomentTagType[]; } const MomentPostContent: React.FC = ({ screenType, - momentId, - caption, - pathHash, - dateTime, + moment, style, momentTags, }) => { @@ -38,7 +31,6 @@ const MomentPostContent: React.FC = ({ const navigation = useNavigation(); const dispatch = useDispatch(); const [elapsedTime, setElapsedTime] = useState(''); - const [comments_count, setCommentsCount] = useState(''); const [tags, setTags] = useState(momentTags); const imageRef = useRef(null); const [visible, setVisible] = useState(false); @@ -52,13 +44,8 @@ const MomentPostContent: React.FC = ({ }, [momentTags]); useEffect(() => { - const fetchCommentsCount = async () => { - const count = await getCommentsCount(momentId, false); - setCommentsCount(count); - }; - setElapsedTime(getTimePosted(dateTime)); - fetchCommentsCount(); - }, [dateTime, momentId]); + setElapsedTime(getTimePosted(moment.date_created)); + }, [moment.date_created]); useEffect(() => { const fade = async () => { @@ -81,7 +68,7 @@ const MomentPostContent: React.FC = ({ {tags.length > 0 && ( @@ -103,14 +90,14 @@ const MomentPostContent: React.FC = ({ )} {elapsedTime} {renderTextWithMentions({ - value: caption, + value: moment.caption, styles: styles.captionText, partTypes: mentionPartTypes('white'), onPress: (user: UserType) => diff --git a/src/components/moments/MomentPostHeader.tsx b/src/components/moments/MomentPostHeader.tsx index dc6a3cd9..64581e06 100644 --- a/src/components/moments/MomentPostHeader.tsx +++ b/src/components/moments/MomentPostHeader.tsx @@ -62,6 +62,7 @@ const MomentPostHeader: React.FC = ({ style={styles.avatar} userXId={userXId} screenType={screenType} + editable={false} /> {username} @@ -74,7 +75,7 @@ const MomentPostHeader: React.FC = ({ removeTag={removeTag} dismissScreenAndUpdate={() => { dispatch(loadUserMoments(loggedInUserId)); - navigation.pop(); + navigation.goBack(); }} /> -- cgit v1.2.3-70-g09d2 From 7de499af625b28074e86854b997e66257ffab8c8 Mon Sep 17 00:00:00 2001 From: Ivan Chen Date: Tue, 8 Jun 2021 16:18:30 -0400 Subject: Adjust styling --- src/components/comments/AddComment.tsx | 34 ++++++++++++++++++++-------- src/components/moments/MomentPostContent.tsx | 30 ++++++++++++++++-------- src/screens/profile/IndividualMoment.tsx | 4 ++-- src/services/MomentService.ts | 2 +- src/types/types.ts | 2 +- 5 files changed, 48 insertions(+), 24 deletions(-) (limited to 'src') diff --git a/src/components/comments/AddComment.tsx b/src/components/comments/AddComment.tsx index b229d010..24ff830a 100644 --- a/src/components/comments/AddComment.tsx +++ b/src/components/comments/AddComment.tsx @@ -24,10 +24,15 @@ import {MentionInputControlled} from './MentionInputControlled'; export interface AddCommentProps { momentId: string; placeholderText: string; + theme?: 'dark' | 'white'; } -const AddComment: React.FC = ({momentId, placeholderText}) => { - const {setShouldUpdateAllComments, commentTapped} = +const AddComment: React.FC = ({ + momentId, + placeholderText, + theme = 'white', +}) => { + const {setShouldUpdateAllComments = () => null, commentTapped} = useContext(CommentContext); const [inReplyToMention, setInReplyToMention] = useState(''); const [comment, setComment] = useState(''); @@ -106,13 +111,14 @@ const AddComment: React.FC = ({momentId, placeholderText}) => { keyboardVerticalOffset={SCREEN_HEIGHT * 0.1}> { @@ -124,11 +130,15 @@ const AddComment: React.FC = ({momentId, placeholderText}) => { inputRef={ref} partTypes={mentionPartTypes('blue')} /> - - - - - + {(theme === 'white' || (theme === 'dark' && keyboardVisible)) && ( + + + + + + )} @@ -136,7 +146,11 @@ const AddComment: React.FC = ({momentId, placeholderText}) => { }; const styles = StyleSheet.create({ - container: { + containerDark: { + alignItems: 'center', + width: SCREEN_WIDTH, + }, + containerWhite: { backgroundColor: '#f7f7f7', alignItems: 'center', width: SCREEN_WIDTH, diff --git a/src/components/moments/MomentPostContent.tsx b/src/components/moments/MomentPostContent.tsx index c59a9c39..e76a8ceb 100644 --- a/src/components/moments/MomentPostContent.tsx +++ b/src/components/moments/MomentPostContent.tsx @@ -4,6 +4,7 @@ import {Image, StyleSheet, Text, View, ViewProps} from 'react-native'; import {TouchableWithoutFeedback} from 'react-native-gesture-handler'; import Animated, {EasingNode} from 'react-native-reanimated'; import {useDispatch, useStore} from 'react-redux'; +import {ADD_COMMENT_TEXT} from '../../constants/strings'; import {RootState} from '../../store/rootReducer'; import {MomentPostType, MomentTagType, ScreenType, UserType} from '../../types'; import { @@ -13,7 +14,7 @@ import { SCREEN_WIDTH, } from '../../utils'; import {mentionPartTypes, renderTextWithMentions} from '../../utils/comments'; -import {CommentsCount} from '../comments'; +import {AddComment, CommentsCount} from '../comments'; import {MomentTags} from '../common'; interface MomentPostContentProps extends ViewProps { @@ -38,7 +39,6 @@ const MomentPostContent: React.FC = ({ const [fadeValue, setFadeValue] = useState>( new Animated.Value(0), ); - useEffect(() => { setTags(momentTags); }, [momentTags]); @@ -96,19 +96,27 @@ const MomentPostContent: React.FC = ({ /> {elapsedTime} - {renderTextWithMentions({ - value: moment.caption, - styles: styles.captionText, - partTypes: mentionPartTypes('white'), - onPress: (user: UserType) => - navigateToProfile(state, dispatch, navigation, screenType, user), - })} + {moment.caption !== '' && + renderTextWithMentions({ + value: moment.caption, + styles: styles.captionText, + partTypes: mentionPartTypes('white'), + onPress: (user: UserType) => + navigateToProfile(state, dispatch, navigation, screenType, user), + })} + ); }; const styles = StyleSheet.create({ - container: {}, + container: { + borderWidth: 1, + }, image: { width: SCREEN_WIDTH, aspectRatio: 1, @@ -117,6 +125,7 @@ const styles = StyleSheet.create({ footerContainer: { flexDirection: 'row', justifyContent: 'space-between', + borderWidth: 1, marginLeft: '7%', marginRight: '5%', marginBottom: '2%', @@ -140,6 +149,7 @@ const styles = StyleSheet.create({ fontSize: normalize(13), lineHeight: normalize(15.51), letterSpacing: normalize(0.6), + borderWidth: 1, }, tapTag: { position: 'absolute', diff --git a/src/screens/profile/IndividualMoment.tsx b/src/screens/profile/IndividualMoment.tsx index ba6a731c..5ac8aeab 100644 --- a/src/screens/profile/IndividualMoment.tsx +++ b/src/screens/profile/IndividualMoment.tsx @@ -7,7 +7,7 @@ import {useSelector} from 'react-redux'; import {IndividualMomentTitleBar, MomentPost} from '../../components'; import {MainStackParams} from '../../routes'; import {RootState} from '../../store/rootreducer'; -import {MomentPostType, MomentType} from '../../types'; +import {MomentPostType} from '../../types'; import {normalize, StatusBarHeight} from '../../utils'; /** @@ -47,7 +47,7 @@ const IndividualMoment: React.FC = ({ style={styles.contentContainer}> navigation.pop()} + close={() => navigation.goBack()} title={moment_category} /> Date: Tue, 8 Jun 2021 16:52:05 -0400 Subject: Move things around, Add logic to disable button --- src/components/comments/AddComment.tsx | 10 +++++++++- src/components/moments/MomentPostContent.tsx | 16 ++++++++-------- 2 files changed, 17 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/components/comments/AddComment.tsx b/src/components/comments/AddComment.tsx index 24ff830a..12fd7e4d 100644 --- a/src/components/comments/AddComment.tsx +++ b/src/components/comments/AddComment.tsx @@ -133,7 +133,12 @@ const AddComment: React.FC = ({ {(theme === 'white' || (theme === 'dark' && keyboardVisible)) && ( @@ -190,6 +195,9 @@ const styles = StyleSheet.create({ marginVertical: '2%', alignSelf: 'flex-end', }, + greyButton: { + backgroundColor: 'grey', + }, whiteBackround: { backgroundColor: '#fff', }, diff --git a/src/components/moments/MomentPostContent.tsx b/src/components/moments/MomentPostContent.tsx index e76a8ceb..582cba25 100644 --- a/src/components/moments/MomentPostContent.tsx +++ b/src/components/moments/MomentPostContent.tsx @@ -88,14 +88,6 @@ const MomentPostContent: React.FC = ({ /> )} - - - {elapsedTime} - {moment.caption !== '' && renderTextWithMentions({ value: moment.caption, @@ -104,6 +96,14 @@ const MomentPostContent: React.FC = ({ onPress: (user: UserType) => navigateToProfile(state, dispatch, navigation, screenType, user), })} + + + {elapsedTime} + Date: Tue, 8 Jun 2021 15:30:35 -0400 Subject: add empty website to submission --- src/screens/profile/EditProfile.tsx | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/screens/profile/EditProfile.tsx b/src/screens/profile/EditProfile.tsx index 26802e45..765bbf01 100644 --- a/src/screens/profile/EditProfile.tsx +++ b/src/screens/profile/EditProfile.tsx @@ -305,14 +305,13 @@ const EditProfile: React.FC = ({route, navigation}) => { type: 'image/jpg', }); } - if (form.website) { - if (form.isValidWebsite) { - request.append('website', form.website); - } else { - setForm({...form, attemptedSubmit: false}); - setTimeout(() => setForm({...form, attemptedSubmit: true})); - invalidFields = true; - } + + if (form.isValidWebsite) { + request.append('website', form.website); + } else { + setForm({...form, attemptedSubmit: false}); + setTimeout(() => setForm({...form, attemptedSubmit: true})); + invalidFields = true; } if (form.bio) { -- cgit v1.2.3-70-g09d2 From 17d41145a0791d2687c7f4abd934b83c008e6f12 Mon Sep 17 00:00:00 2001 From: hsalhab Date: Tue, 8 Jun 2021 17:08:26 -0400 Subject: fix regex, forward slash needs escape --- src/constants/regex.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/constants/regex.ts b/src/constants/regex.ts index 61523203..f934185d 100644 --- a/src/constants/regex.ts +++ b/src/constants/regex.ts @@ -36,7 +36,7 @@ export const nameRegex: RegExp = /^[A-Za-z'\-,. ]{2,20}$/; * - match alphanumerics, and special characters used in URLs */ export const websiteRegex: RegExp = - /^$|^(https?:\/\/)?(www\.)?[-a-zA-Z0-9@:%._+~#=]{1,50}\.[a-zA-Z0-9()]{2,6}\b([-a-zA-Z0-9()@:%_+.~#?&/=]{0,35})$/; + /^$|^(https?:\/\/)?(www\.)?[-a-zA-Z0-9@:%._+~#=]{1,50}\.[a-zA-Z0-9()]{2,6}\b([-a-zA-Z0-9()@:%_+.~#?&\/=]{0,35})$/; /** * The website regex has the following constraints -- cgit v1.2.3-70-g09d2 From 6070fae504921259a24af78952af36d3c9643022 Mon Sep 17 00:00:00 2001 From: Ivan Chen Date: Tue, 8 Jun 2021 17:17:11 -0400 Subject: Remove CommentCount, Add new comments component --- src/components/comments/CommentsCount.tsx | 58 ------------------------- src/components/comments/index.ts | 1 - src/components/moments/MomentPostContent.tsx | 63 +++++++++++++++------------- src/screens/profile/IndividualMoment.tsx | 2 +- 4 files changed, 36 insertions(+), 88 deletions(-) delete mode 100644 src/components/comments/CommentsCount.tsx (limited to 'src') diff --git a/src/components/comments/CommentsCount.tsx b/src/components/comments/CommentsCount.tsx deleted file mode 100644 index f4f8197d..00000000 --- a/src/components/comments/CommentsCount.tsx +++ /dev/null @@ -1,58 +0,0 @@ -import {useNavigation} from '@react-navigation/native'; -import * as React from 'react'; -import {StyleSheet, TouchableOpacity} from 'react-native'; -import {Text} from 'react-native-animatable'; -import CommentIcon from '../../assets/icons/moment-comment-icon.svg'; -import {ScreenType} from '../../types'; - -/** - * Provides a view for the comment icon and the comment count. - * When the user clicks on this view, a new screen opens to display all the comments. - */ - -type CommentsCountProps = { - commentsCount: string; - momentId: string; - screenType: ScreenType; -}; - -const CommentsCount: React.FC = ({ - commentsCount, - momentId, - screenType, -}) => { - const navigation = useNavigation(); - const navigateToCommentsScreen = async () => { - navigation.push('MomentCommentsScreen', { - moment_id: momentId, - screenType, - }); - }; - return ( - <> - - - - {commentsCount !== '0' ? commentsCount : ''} - - - - ); -}; - -const styles = StyleSheet.create({ - image: { - position: 'relative', - width: 21, - height: 21, - }, - count: { - position: 'relative', - fontWeight: 'bold', - color: 'white', - paddingTop: '3%', - textAlign: 'center', - }, -}); - -export default CommentsCount; diff --git a/src/components/comments/index.ts b/src/components/comments/index.ts index 6293f799..ebd93844 100644 --- a/src/components/comments/index.ts +++ b/src/components/comments/index.ts @@ -1,3 +1,2 @@ -export {default as CommentsCount} from '../comments/CommentsCount'; export {default as CommentTile} from './CommentTile'; export {default as AddComment} from './AddComment'; diff --git a/src/components/moments/MomentPostContent.tsx b/src/components/moments/MomentPostContent.tsx index 582cba25..34503bf4 100644 --- a/src/components/moments/MomentPostContent.tsx +++ b/src/components/moments/MomentPostContent.tsx @@ -1,10 +1,12 @@ import {useNavigation} from '@react-navigation/native'; import React, {useEffect, useRef, useState} from 'react'; import {Image, StyleSheet, Text, View, ViewProps} from 'react-native'; -import {TouchableWithoutFeedback} from 'react-native-gesture-handler'; +import { + TouchableOpacity, + TouchableWithoutFeedback, +} from 'react-native-gesture-handler'; import Animated, {EasingNode} from 'react-native-reanimated'; import {useDispatch, useStore} from 'react-redux'; -import {ADD_COMMENT_TEXT} from '../../constants/strings'; import {RootState} from '../../store/rootReducer'; import {MomentPostType, MomentTagType, ScreenType, UserType} from '../../types'; import { @@ -14,7 +16,7 @@ import { SCREEN_WIDTH, } from '../../utils'; import {mentionPartTypes, renderTextWithMentions} from '../../utils/comments'; -import {AddComment, CommentsCount} from '../comments'; +import {AddComment} from '../comments'; import {MomentTags} from '../common'; interface MomentPostContentProps extends ViewProps { @@ -31,22 +33,21 @@ const MomentPostContent: React.FC = ({ const state: RootState = useStore().getState(); const navigation = useNavigation(); const dispatch = useDispatch(); - const [elapsedTime, setElapsedTime] = useState(''); const [tags, setTags] = useState(momentTags); const imageRef = useRef(null); const [visible, setVisible] = useState(false); - const [fadeValue, setFadeValue] = useState>( new Animated.Value(0), ); + const commentCountText = + moment.comments_count === 0 + ? 'No Comments' + : moment.comments_count + ' comments'; + useEffect(() => { setTags(momentTags); }, [momentTags]); - useEffect(() => { - setElapsedTime(getTimePosted(moment.date_created)); - }, [moment.date_created]); - useEffect(() => { const fade = async () => { Animated.timing(fadeValue, { @@ -96,19 +97,22 @@ const MomentPostContent: React.FC = ({ onPress: (user: UserType) => navigateToProfile(state, dispatch, navigation, screenType, user), })} - - - {elapsedTime} - + + navigation.push('MomentCommentsScreen', { + moment_id: moment.moment_id, + screenType, + }) + }> + {commentCountText} + + {getTimePosted(moment.date_created)} ); }; @@ -122,22 +126,24 @@ const styles = StyleSheet.create({ aspectRatio: 1, marginBottom: '3%', }, - footerContainer: { + commentsPreviewContainer: { flexDirection: 'row', justifyContent: 'space-between', - borderWidth: 1, - marginLeft: '7%', - marginRight: '5%', + marginHorizontal: '5%', marginBottom: '2%', + borderWidth: 1, + }, + commentCount: { + fontWeight: '700', + color: 'white', + fontSize: normalize(12), }, text: { - position: 'relative', - paddingBottom: '1%', - paddingTop: '1%', - marginLeft: '7%', - marginRight: '2%', - color: '#ffffff', - fontWeight: 'bold', + marginHorizontal: '5%', + color: 'white', + fontWeight: '500', + textAlign: 'right', + marginTop: 5, }, captionText: { position: 'relative', @@ -150,6 +156,7 @@ const styles = StyleSheet.create({ lineHeight: normalize(15.51), letterSpacing: normalize(0.6), borderWidth: 1, + marginBottom: normalize(18), }, tapTag: { position: 'absolute', diff --git a/src/screens/profile/IndividualMoment.tsx b/src/screens/profile/IndividualMoment.tsx index 5ac8aeab..447ba2a9 100644 --- a/src/screens/profile/IndividualMoment.tsx +++ b/src/screens/profile/IndividualMoment.tsx @@ -55,7 +55,7 @@ const IndividualMoment: React.FC = ({ renderItem={({item}: {item: MomentPostType}) => ( )} - keyExtractor={(_, index) => index.toString()} + keyExtractor={(item, _) => item.moment_id} showsVerticalScrollIndicator={false} initialScrollIndex={initialIndex} /> -- cgit v1.2.3-70-g09d2 From c6832a84caf1f23c2115a3b8061e120f9fab623d Mon Sep 17 00:00:00 2001 From: Ivan Chen Date: Tue, 8 Jun 2021 17:40:10 -0400 Subject: Update date format --- src/utils/moments.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/utils/moments.ts b/src/utils/moments.ts index 90d69519..9e8cc332 100644 --- a/src/utils/moments.ts +++ b/src/utils/moments.ts @@ -19,21 +19,21 @@ export const getTimePosted = (date_time: string) => { // 1 minute to less than 1 hour else if (difference >= 60 && difference < 60 * 60) { difference = now.diff(datePosted, 'minutes'); - time = difference + (difference === 1 ? ' minute' : ' minutes'); + time = difference + 'm ago'; } // 1 hour to less than 1 day else if (difference >= 60 * 60 && difference < 24 * 60 * 60) { difference = now.diff(datePosted, 'hours'); - time = difference + (difference === 1 ? ' hour' : ' hours'); + time = difference + 'h ago'; } // Any number of days else if (difference >= 24 * 60 * 60 && difference < 24 * 60 * 60 * 3) { difference = now.diff(datePosted, 'days'); - time = difference + (difference === 1 ? ' day' : ' days'); + time = difference + 'd ago'; } // More than 3 days else if (difference >= 24 * 60 * 60 * 3) { - time = datePosted.format('MMMM D, YYYY'); + time = datePosted.format('M-D-YYYY'); } return time; }; -- cgit v1.2.3-70-g09d2 From 18770a692d03fb68267b51ef05cd4b58917b0e62 Mon Sep 17 00:00:00 2001 From: Ivan Chen Date: Tue, 8 Jun 2021 17:43:04 -0400 Subject: Create MomentCommentPrevew component --- src/components/moments/MomentCommentPreview.tsx | 52 +++++++++++++++++++++++++ src/components/moments/MomentPost.tsx | 3 +- src/components/moments/MomentPostContent.tsx | 33 ++-------------- 3 files changed, 57 insertions(+), 31 deletions(-) create mode 100644 src/components/moments/MomentCommentPreview.tsx (limited to 'src') diff --git a/src/components/moments/MomentCommentPreview.tsx b/src/components/moments/MomentCommentPreview.tsx new file mode 100644 index 00000000..45bbbfad --- /dev/null +++ b/src/components/moments/MomentCommentPreview.tsx @@ -0,0 +1,52 @@ +import {useNavigation} from '@react-navigation/native'; +import React from 'react'; +import {StyleSheet, Text} from 'react-native'; +import {TouchableOpacity} from 'react-native-gesture-handler'; +import {MomentPostType, ScreenType} from '../../types'; +import {normalize} from '../../utils'; + +interface MomentCommentPreviewProps { + moment: MomentPostType; + screenType: ScreenType; +} + +const MomentCommentPreview: React.FC = ({ + moment, + screenType, +}) => { + const navigation = useNavigation(); + const commentCountText = + moment.comments_count === 0 + ? 'No Comments' + : moment.comments_count + ' comments'; + + return ( + + navigation.push('MomentCommentsScreen', { + moment_id: moment.moment_id, + screenType, + }) + }> + {commentCountText} + TODO: Add comment preview here + + ); +}; + +const styles = StyleSheet.create({ + commentsPreviewContainer: { + flexDirection: 'column', + marginHorizontal: '5%', + marginBottom: '2%', + borderWidth: 1, + }, + commentCount: { + fontWeight: '700', + color: 'white', + fontSize: normalize(12), + }, +}); + +export default MomentCommentPreview; diff --git a/src/components/moments/MomentPost.tsx b/src/components/moments/MomentPost.tsx index ffdbed81..02dbffa3 100644 --- a/src/components/moments/MomentPost.tsx +++ b/src/components/moments/MomentPost.tsx @@ -5,7 +5,7 @@ import {MomentPostContent, MomentPostHeader} from '.'; import {deleteMomentTag, loadMomentTags} from '../../services'; import {RootState} from '../../store/rootReducer'; import {MomentPostType, MomentTagType, ScreenType} from '../../types'; -import {SCREEN_HEIGHT} from '../../utils'; +import {normalize, SCREEN_HEIGHT} from '../../utils'; interface MomentPostProps { moment: MomentPostType; @@ -97,6 +97,7 @@ const styles = StyleSheet.create({ postHeader: {}, postContent: { minHeight: SCREEN_HEIGHT * 0.8, + paddingBottom: normalize(20), }, }); diff --git a/src/components/moments/MomentPostContent.tsx b/src/components/moments/MomentPostContent.tsx index 34503bf4..01863660 100644 --- a/src/components/moments/MomentPostContent.tsx +++ b/src/components/moments/MomentPostContent.tsx @@ -1,10 +1,7 @@ import {useNavigation} from '@react-navigation/native'; import React, {useEffect, useRef, useState} from 'react'; import {Image, StyleSheet, Text, View, ViewProps} from 'react-native'; -import { - TouchableOpacity, - TouchableWithoutFeedback, -} from 'react-native-gesture-handler'; +import {TouchableWithoutFeedback} from 'react-native-gesture-handler'; import Animated, {EasingNode} from 'react-native-reanimated'; import {useDispatch, useStore} from 'react-redux'; import {RootState} from '../../store/rootReducer'; @@ -18,6 +15,7 @@ import { import {mentionPartTypes, renderTextWithMentions} from '../../utils/comments'; import {AddComment} from '../comments'; import {MomentTags} from '../common'; +import MomentCommentPreview from './MomentCommentPreview'; interface MomentPostContentProps extends ViewProps { screenType: ScreenType; @@ -39,10 +37,6 @@ const MomentPostContent: React.FC = ({ const [fadeValue, setFadeValue] = useState>( new Animated.Value(0), ); - const commentCountText = - moment.comments_count === 0 - ? 'No Comments' - : moment.comments_count + ' comments'; useEffect(() => { setTags(momentTags); @@ -97,16 +91,7 @@ const MomentPostContent: React.FC = ({ onPress: (user: UserType) => navigateToProfile(state, dispatch, navigation, screenType, user), })} - - navigation.push('MomentCommentsScreen', { - moment_id: moment.moment_id, - screenType, - }) - }> - {commentCountText} - + Date: Tue, 8 Jun 2021 18:19:19 -0400 Subject: Added comment preview, WIP on mention part types --- src/components/moments/MomentCommentPreview.tsx | 66 ++++++++++++++++++++++--- src/components/moments/MomentPostContent.tsx | 6 +-- src/utils/comments.tsx | 41 ++++++++++----- 3 files changed, 88 insertions(+), 25 deletions(-) (limited to 'src') diff --git a/src/components/moments/MomentCommentPreview.tsx b/src/components/moments/MomentCommentPreview.tsx index 45bbbfad..03f30dda 100644 --- a/src/components/moments/MomentCommentPreview.tsx +++ b/src/components/moments/MomentCommentPreview.tsx @@ -1,9 +1,11 @@ import {useNavigation} from '@react-navigation/native'; import React from 'react'; -import {StyleSheet, Text} from 'react-native'; +import {Image, StyleSheet, Text, View} from 'react-native'; import {TouchableOpacity} from 'react-native-gesture-handler'; -import {MomentPostType, ScreenType} from '../../types'; -import {normalize} from '../../utils'; +import {useDispatch, useStore} from 'react-redux'; +import {MomentPostType, ScreenType, UserType} from '../../types'; +import {navigateToProfile, normalize} from '../../utils'; +import {mentionPartTypes, renderTextWithMentions} from '../../utils/comments'; interface MomentCommentPreviewProps { moment: MomentPostType; @@ -15,11 +17,18 @@ const MomentCommentPreview: React.FC = ({ screenType, }) => { const navigation = useNavigation(); + const state = useStore().getState(); const commentCountText = moment.comments_count === 0 ? 'No Comments' : moment.comments_count + ' comments'; + /** + * TODO: + * - figure out why mention PartTypes have type warnings + * - fix padding for all types (double check on iPhone 8) + */ + return ( = ({ screenType, }) }> - {commentCountText} - TODO: Add comment preview here + {commentCountText} + {moment.comment_preview !== null && ( + + + + + {moment.comment_preview.commenter.username} + + {renderTextWithMentions({ + value: moment.comment_preview.comment, + styles: styles.normalFont, + partTypes: mentionPartTypes('commentPreview'), + onPress: (user: UserType) => + navigateToProfile( + state, + useDispatch, + navigation, + screenType, + user, + ), + })} + + + )} ); }; const styles = StyleSheet.create({ commentsPreviewContainer: { + height: normalize(50), flexDirection: 'column', + justifyContent: 'space-around', marginHorizontal: '5%', marginBottom: '2%', - borderWidth: 1, }, - commentCount: { + whiteBold: { fontWeight: '700', color: 'white', - fontSize: normalize(12), + fontSize: normalize(13), + }, + previewContainer: { + flexDirection: 'row', + width: '95%', + }, + avatar: { + height: normalize(16), + width: normalize(16), + borderRadius: 99, + }, + normalFont: { + // top: -5, + fontWeight: 'normal', }, }); diff --git a/src/components/moments/MomentPostContent.tsx b/src/components/moments/MomentPostContent.tsx index 01863660..5fd683a4 100644 --- a/src/components/moments/MomentPostContent.tsx +++ b/src/components/moments/MomentPostContent.tsx @@ -120,16 +120,14 @@ const styles = StyleSheet.create({ }, captionText: { position: 'relative', - paddingTop: '1%', - marginLeft: '5%', - marginRight: '5%', + marginHorizontal: '5%', color: '#ffffff', fontWeight: '500', fontSize: normalize(13), lineHeight: normalize(15.51), letterSpacing: normalize(0.6), - borderWidth: 1, marginBottom: normalize(18), + borderWidth: 1, }, tapTag: { position: 'absolute', diff --git a/src/utils/comments.tsx b/src/utils/comments.tsx index 5c17cefe..e700da88 100644 --- a/src/utils/comments.tsx +++ b/src/utils/comments.tsx @@ -79,26 +79,41 @@ export const renderTextWithMentions: React.FC = ({ ); }; -export const mentionPartTypes: (style: 'blue' | 'white') => PartType[] = ( - style, +const textStyle: (theme: 'blue' | 'white' | 'commentPreview') => PartType = ( + theme, ) => { + switch (theme) { + case 'blue': + return { + color: TAGG_LIGHT_BLUE, + top: normalize(3), + }; + case 'commentPreview': + return { + color: 'white', + fontWeight: '800', + top: normalize(3), + }; + case 'white': + default: + return { + color: 'white', + fontWeight: '800', + top: normalize(7.5), + }; + } +}; + +export const mentionPartTypes: ( + theme: 'blue' | 'white' | 'commentPreview', +) => PartType[] = (theme) => { return [ { trigger: '@', renderSuggestions: (props) => , allowedSpacesCount: 0, isInsertSpaceAfterMention: true, - textStyle: - style === 'blue' - ? { - color: TAGG_LIGHT_BLUE, - top: normalize(3), - } - : { - color: 'white', - fontWeight: '800', - top: normalize(7.5), - }, + textStyle: textStyle(theme), }, ]; }; -- cgit v1.2.3-70-g09d2 From 2ddd29120980ebced560dac09bbe270dc4aee0d1 Mon Sep 17 00:00:00 2001 From: Brian Kim Date: Wed, 9 Jun 2021 09:24:00 +0900 Subject: Create separate pill component --- src/components/notifications/NotificationPill.tsx | 202 ++++++++++++++++++++ src/components/notifications/index.ts | 1 + src/routes/tabs/NavigationBar.tsx | 221 +--------------------- src/utils/common.ts | 1 + 4 files changed, 211 insertions(+), 214 deletions(-) create mode 100644 src/components/notifications/NotificationPill.tsx (limited to 'src') diff --git a/src/components/notifications/NotificationPill.tsx b/src/components/notifications/NotificationPill.tsx new file mode 100644 index 00000000..7017d2e7 --- /dev/null +++ b/src/components/notifications/NotificationPill.tsx @@ -0,0 +1,202 @@ +import React, {useEffect, useState, useRef} from 'react'; +import {Image, StyleSheet, Text, View} from 'react-native'; +import LinearGradient from 'react-native-linear-gradient'; +import {SCREEN_WIDTH, isIPhoneX, numberWithCommas} from '../../utils'; +import { + NOTIFICATION_ICON_GRADIENT, + CHIN_HEIGHT, + NAV_BAR_HEIGHT, +} from '../../constants'; +import {getNotificationsUnreadCount} from '../../services'; +import {normalize} from 'react-native-elements'; +import PillIcon4 from '../../assets/images/Group 479.svg'; + +interface NotificationPillProps { + showIcon: boolean; +} + +export const NotificationPill: React.FC = ({ + showIcon, +}) => { + const [iconStart, setIconStart] = useState([0, -100]); + const [tipStart, setTipStart] = useState([0, -100]); + const [notificationSets, setNotificationSets] = useState({}); + const [timeCount, setTimeCount] = useState(false); + const [timeOut, setTimeOut] = useState(false); + const iconRef = useRef(null); + const tipRef = useRef(null); + const pillTip = require('../../assets/images/purple-tip.png'); + + const navBarPos = 20; + + // If there are notifications, determines the size of the pill + // and sets points for correct placement + useEffect(() => { + setTimeout(() => { + if (iconRef.current) { + iconRef.current.measure( + ( + _fx: number, + _fy: number, + width: number, + height: number, + _px: number, + _py: number, + ) => { + 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]); + setTimeCount(true); + }, + ); + } + }, + ); + } else { + } + }, 100); + }, [notificationSets, iconRef, tipRef]); + + // Used so that pill disappears after 5 seconds + useEffect(() => { + if (timeCount) { + setTimeout(() => { + setTimeOut(true); + }, 5000); + } + }, [timeCount]); + + // Gets data from backend to check for unreads + useEffect(() => { + const getCount = async () => { + const data = await getNotificationsUnreadCount(); + setTimeout(() => { + setNotificationSets(data); + }, 100); + }; + + getCount(); + }, []); + + return ( + <> + {notificationSets && + Object.keys(notificationSets).length !== 0 && + showIcon && + !timeOut && ( + + + {notificationSets.CMT && ( + <> + + + {numberWithCommas(notificationSets.CMT)} + + + )} + {notificationSets.FR_REQ && ( + <> + + + {numberWithCommas(notificationSets.FR_REQ)} + + + )} + {notificationSets.P_VIEW && ( + <> + + + {numberWithCommas(notificationSets.P_VIEW)} + + + )} + {notificationSets.MOM_TAG && ( + <> + + + {numberWithCommas(notificationSets.MOM_TAG)} + + + )} + + + + )} + + ); +}; + +const styles = StyleSheet.create({ + purpleContainer: { + flex: 1, + justifyContent: 'center', + position: 'absolute', + zIndex: 999, + }, + iconPurple: { + padding: 5, + borderRadius: 15, + flex: 1, + flexDirection: 'row', + alignItems: 'center', + }, + text: { + margin: 2, + color: 'white', + fontSize: normalize(10), + justifyContent: 'center', + alignItems: 'center', + marginRight: 5, + }, + tip: { + position: 'absolute', + zIndex: 999, + height: 12, + flex: 1, + resizeMode: 'contain', + }, + indicationIcon: { + height: 14, + width: 14, + margin: 2, + marginLeft: 5, + }, + svgIndicationIcon: { + height: 14, + width: 14, + margin: 3, + }, +}); diff --git a/src/components/notifications/index.ts b/src/components/notifications/index.ts index 733b56f1..077c26a4 100644 --- a/src/components/notifications/index.ts +++ b/src/components/notifications/index.ts @@ -1,2 +1,3 @@ export {default as Notification} from './Notification'; export {InviteFriendsPrompt} from './NotificationPrompts'; +export {NotificationPill} from './NotificationPill'; diff --git a/src/routes/tabs/NavigationBar.tsx b/src/routes/tabs/NavigationBar.tsx index e962c8da..c3a42739 100644 --- a/src/routes/tabs/NavigationBar.tsx +++ b/src/routes/tabs/NavigationBar.tsx @@ -1,26 +1,14 @@ import {createBottomTabNavigator} from '@react-navigation/bottom-tabs'; -import React, {Fragment, useEffect, useState, useRef} from 'react'; -import {Image, StyleSheet, Text, View} from 'react-native'; -import LinearGradient from 'react-native-linear-gradient'; +import React, {Fragment, useEffect, useState} from 'react'; import {useSelector} from 'react-redux'; import {NavigationIcon} from '../../components'; import {NO_NOTIFICATIONS} from '../../store/initialStates'; import {RootState} from '../../store/rootReducer'; -import { - getNotificationsUnreadCount, - setNotificationsReadDate, -} from '../../services'; +import {setNotificationsReadDate} from '../../services'; import {ScreenType} from '../../types'; -import {haveUnreadNotifications, SCREEN_WIDTH, isIPhoneX} from '../../utils'; +import {haveUnreadNotifications} 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'; -import PillIcon4 from '../../assets/images/Group 479.svg'; +import {NotificationPill} from '../../components/notifications'; const Tabs = createBottomTabNavigator(); @@ -32,17 +20,8 @@ const NavigationBar: React.FC = () => { const {notifications: {notifications} = NO_NOTIFICATIONS} = useSelector( (state: RootState) => state, ); + // Triggered if user clicks on Notifications page to close the pill const [showIcon, setShowIcon] = useState(true); - const [iconStart, setIconStart] = useState([0, -100]); - const [tipStart, setTipStart] = useState([0, -100]); - const [notificationSets, setNotificationSets] = useState({}); - const [timeCount, setTimeCount] = useState(false); - const [timeOut, setTimeOut] = useState(false); - const iconRef = useRef(null); - const tipRef = useRef(null); - const pillTip = require('../../assets/images/purple-tip.png'); - - const navBarPos = 20; const [unreadNotificationsPresent, setUnreadNotificationsPresent] = useState(false); @@ -58,132 +37,9 @@ const NavigationBar: React.FC = () => { determine(); }, [notifications]); - // If there are notifications, determines the size of the pill - // and sets points for correct placement - useEffect(() => { - setTimeout(() => { - if (iconRef.current) { - iconRef.current.measure( - ( - _fx: number, - _fy: number, - width: number, - height: number, - _px: number, - _py: number, - ) => { - 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]); - setTimeCount(true); - }, - ); - } - }, - ); - } else { - } - }, 100); - }, [notificationSets, iconRef, tipRef]); - - // Used so that pill disappears after 5 seconds - useEffect(() => { - if (timeCount) { - setTimeout(() => { - setTimeOut(true); - }, 5000); - } - }, [timeCount]); - - // Gets data from backend to check for unreads - useEffect(() => { - const getCount = async () => { - const data = await getNotificationsUnreadCount(); - setTimeout(() => { - setNotificationSets(data); - }, 100); - }; - - getCount(); - }, []); - return ( <> - {notificationSets && - Object.keys(notificationSets).length !== 0 && - showIcon && - !timeOut && ( - - - {notificationSets.CMT && ( - <> - - - {numberWithCommas(notificationSets.CMT)} - - - )} - {notificationSets.FR_REQ && ( - <> - - - {numberWithCommas(notificationSets.FR_REQ)} - - - )} - {notificationSets.P_VIEW && ( - <> - - - {numberWithCommas(notificationSets.P_VIEW)} - - - )} - {notificationSets.MOM_TAG && ( - <> - - - {numberWithCommas(notificationSets.MOM_TAG)} - - - )} - - - - )} + ({ tabBarIcon: ({focused}) => { @@ -233,23 +89,11 @@ const NavigationBar: React.FC = () => { name="SuggestedPeople" component={MainStackScreen} initialParams={{screenType: ScreenType.SuggestedPeople}} - // Added these to as a way to close pill when on - // notification page - listeners={{ - tabPress: (_) => { - setShowIcon(true); - }, - }} /> { - setShowIcon(true); - }, - }} /> { initialParams={{screenType: ScreenType.Notifications}} listeners={{ tabPress: (_) => { + // Closes the pill once this screen has been opened setShowIcon(false); // Updates backend's date of reading notifications setNotificationsReadDate(); @@ -267,67 +112,15 @@ const NavigationBar: React.FC = () => { name="Chat" component={MainStackScreen} initialParams={{screenType: ScreenType.Chat}} - listeners={{ - tabPress: (_) => { - setShowIcon(true); - }, - }} /> { - setShowIcon(true); - }, - }} /> ); }; -const styles = StyleSheet.create({ - purpleContainer: { - flex: 1, - justifyContent: 'center', - position: 'absolute', - zIndex: 999, - }, - iconPurple: { - padding: 5, - borderRadius: 15, - flex: 1, - flexDirection: 'row', - alignItems: 'center', - }, - text: { - margin: 2, - color: 'white', - fontSize: normalize(10), - justifyContent: 'center', - alignItems: 'center', - marginRight: 5, - }, - tip: { - position: 'absolute', - zIndex: 999, - height: 12, - flex: 1, - resizeMode: 'contain', - }, - indicationIcon: { - height: 14, - width: 14, - margin: 2, - marginLeft: 5, - }, - svgIndicationIcon: { - height: 14, - width: 14, - margin: 3, - }, -}); - export default NavigationBar; diff --git a/src/utils/common.ts b/src/utils/common.ts index 049dae90..cb0bd62d 100644 --- a/src/utils/common.ts +++ b/src/utils/common.ts @@ -198,6 +198,7 @@ export const validateImageLink = async (url: string | undefined) => { }); }; +// Documentation: https://stackoverflow.com/questions/2901102/how-to-print-a-number-with-commas-as-thousands-separators-in-javascript export const numberWithCommas = (digits: number) => { return digits.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ','); }; -- cgit v1.2.3-70-g09d2 From 9d7e900a89f343f7752457956f8e1d205774b910 Mon Sep 17 00:00:00 2001 From: Brian Kim Date: Wed, 9 Jun 2021 09:28:38 +0900 Subject: Clean up MomentPostContent --- src/components/moments/MomentPostContent.tsx | 2 -- 1 file changed, 2 deletions(-) (limited to 'src') diff --git a/src/components/moments/MomentPostContent.tsx b/src/components/moments/MomentPostContent.tsx index c00433e7..ecbfb3a2 100644 --- a/src/components/moments/MomentPostContent.tsx +++ b/src/components/moments/MomentPostContent.tsx @@ -38,12 +38,10 @@ const MomentPostContent: React.FC = ({ const [elapsedTime, setElapsedTime] = useState(''); const [comments_count, setCommentsCount] = useState(''); const [tags, setTags] = useState(momentTags); - // const [visible, setVisible] = useState(false); const state: RootState = useStore().getState(); const navigation = useNavigation(); const dispatch = useDispatch(); const imageRef = useRef(null); - // const [fadeValue, setFadeValue] = useState(new Animated.Value(0)); const [visible, setVisible] = useState(false); const [fadeValue, setFadeValue] = useState>( -- cgit v1.2.3-70-g09d2 From 3f42ed623adf591543bb8b738077e9172781ed09 Mon Sep 17 00:00:00 2001 From: Ivan Chen Date: Wed, 9 Jun 2021 16:36:01 -0400 Subject: Fix malformed code issue --- src/utils/common.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/utils/common.ts b/src/utils/common.ts index 645f229a..1956e811 100644 --- a/src/utils/common.ts +++ b/src/utils/common.ts @@ -237,4 +237,4 @@ export const badgesToDisplayBadges = ( // Documentation: https://stackoverflow.com/questions/2901102/how-to-print-a-number-with-commas-as-thousands-separators-in-javascript export const numberWithCommas = (digits: number) => { return digits.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ','); - \ No newline at end of file +}; -- cgit v1.2.3-70-g09d2 From 587d08dc8f0508b6efa76cc7d57f21ac2a5fd9fb Mon Sep 17 00:00:00 2001 From: Husam Salhab <47015061+hsalhab@users.noreply.github.com> Date: Wed, 9 Jun 2021 16:43:02 -0400 Subject: [TMA-909] Fix Contact Search (#460) * shows proper results and handles null lists * remove unnecessary existing users code * fix height and remove console log * lint --- src/screens/profile/EditProfile.tsx | 2 +- src/screens/profile/InviteFriendsScreen.tsx | 56 ++++++++++++++--------------- 2 files changed, 29 insertions(+), 29 deletions(-) (limited to 'src') diff --git a/src/screens/profile/EditProfile.tsx b/src/screens/profile/EditProfile.tsx index 765bbf01..20a62b19 100644 --- a/src/screens/profile/EditProfile.tsx +++ b/src/screens/profile/EditProfile.tsx @@ -305,7 +305,7 @@ const EditProfile: React.FC = ({route, navigation}) => { type: 'image/jpg', }); } - + if (form.isValidWebsite) { request.append('website', form.website); } else { diff --git a/src/screens/profile/InviteFriendsScreen.tsx b/src/screens/profile/InviteFriendsScreen.tsx index 89f2e62f..9ee6fb1c 100644 --- a/src/screens/profile/InviteFriendsScreen.tsx +++ b/src/screens/profile/InviteFriendsScreen.tsx @@ -21,7 +21,6 @@ import { getRemainingInviteCount, usersFromContactsService, } from '../../services/UserFriendsService'; -import {ProfilePreviewType} from '../../types'; import { extractContacts, HeaderHeight, @@ -45,11 +44,10 @@ export type SearchResultType = { const InviteFriendsScreen: React.FC = () => { const navigation = useNavigation(); - const [usersFromContacts, setUsersFromContacts] = useState< - ProfilePreviewType[] + const [nonUsersFromContacts, setNonUsersFromContacts] = useState< + InviteContactType[] >([]); - const [nonUsersFromContacts, setNonUsersFromContacts] = useState<[]>([]); - const [pendingUsers] = useState<[]>([]); + const [pendingUsers, setPendingUsers] = useState([]); const [results, setResults] = useState({ nonUsersFromContacts: nonUsersFromContacts, pendingUsers: pendingUsers, @@ -80,8 +78,8 @@ const InviteFriendsScreen: React.FC = () => { const permission = await checkPermission(); if (permission === 'authorized') { let response = await usersFromContactsService(retrievedContacts); - await setUsersFromContacts(response.existing_tagg_users); await setNonUsersFromContacts(response.invite_from_contacts); + await setPendingUsers(response.pending_users); setResults({ nonUsersFromContacts: response.invite_from_contacts, pendingUsers: response.pending_users, @@ -100,30 +98,32 @@ const InviteFriendsScreen: React.FC = () => { useEffect(() => { const search = async () => { if (query.length > 0) { - const searchResultsUsers = usersFromContacts.filter( - (item: ProfilePreviewType) => - (item.first_name + ' ' + item.last_name) - .toLowerCase() - .startsWith(query) || - item.username.toLowerCase().startsWith(query) || - item.last_name.toLowerCase().startsWith(query), - ); - const searchResultsNonUsers = nonUsersFromContacts.filter( - (item: InviteContactType) => - (item.firstName + ' ' + item.lastName) - .toLowerCase() - .startsWith(query) || - item.lastName.toLowerCase().startsWith(query), - ); - const sanitizedResult = { - usersFromContacts: searchResultsUsers, + const searchResultsPendingUsers = pendingUsers + ? pendingUsers.filter( + (item: InviteContactType) => + (item.firstName + ' ' + item.lastName) + .toLowerCase() + .startsWith(query) || + item.lastName.toLowerCase().startsWith(query), + ) + : []; + const searchResultsNonUsers = nonUsersFromContacts + ? nonUsersFromContacts.filter( + (item: InviteContactType) => + (item.firstName + ' ' + item.lastName) + .toLowerCase() + .startsWith(query) || + item.lastName.toLowerCase().startsWith(query), + ) + : []; + setResults({ nonUsersFromContacts: searchResultsNonUsers, - }; - setResults(sanitizedResult); + pendingUsers: searchResultsPendingUsers, + }); } else { setResults({ - nonUsersFromContacts: nonUsersFromContacts, - pendingUsers: pendingUsers, + nonUsersFromContacts: nonUsersFromContacts || [], + pendingUsers: pendingUsers || [], }); } }; @@ -203,7 +203,7 @@ const InviteFriendsScreen: React.FC = () => { styles.subheader, { height: - 72 * + 75 * (results.pendingUsers ? results.pendingUsers.length : 1), }, ]}> -- cgit v1.2.3-70-g09d2 From 93796732be3f5070c0a124d29533396f79736c83 Mon Sep 17 00:00:00 2001 From: Ivan Chen Date: Wed, 9 Jun 2021 17:37:40 -0400 Subject: Cleanup code --- src/components/notifications/NotificationPill.tsx | 15 +++++++++++---- src/services/NotificationService.ts | 10 ++-------- src/types/types.ts | 4 +++- 3 files changed, 16 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/components/notifications/NotificationPill.tsx b/src/components/notifications/NotificationPill.tsx index 7017d2e7..01622a6f 100644 --- a/src/components/notifications/NotificationPill.tsx +++ b/src/components/notifications/NotificationPill.tsx @@ -20,7 +20,12 @@ export const NotificationPill: React.FC = ({ }) => { const [iconStart, setIconStart] = useState([0, -100]); const [tipStart, setTipStart] = useState([0, -100]); - const [notificationSets, setNotificationSets] = useState({}); + const [notificationSets, setNotificationSets] = useState<{ + CMT?: number; + FRD_REQ?: number; + P_VIEW?: number; + MOM_TAG?: number; + }>({}); const [timeCount, setTimeCount] = useState(false); const [timeOut, setTimeOut] = useState(false); const iconRef = useRef(null); @@ -84,7 +89,9 @@ export const NotificationPill: React.FC = ({ const getCount = async () => { const data = await getNotificationsUnreadCount(); setTimeout(() => { - setNotificationSets(data); + if (data) { + setNotificationSets(data); + } }, 100); }; @@ -117,14 +124,14 @@ export const NotificationPill: React.FC = ({ )} - {notificationSets.FR_REQ && ( + {notificationSets.FRD_REQ && ( <> - {numberWithCommas(notificationSets.FR_REQ)} + {numberWithCommas(notificationSets.FRD_REQ)} )} diff --git a/src/services/NotificationService.ts b/src/services/NotificationService.ts index 2ffc85b2..ccaa9135 100644 --- a/src/services/NotificationService.ts +++ b/src/services/NotificationService.ts @@ -34,12 +34,7 @@ export const getNotificationsData: () => Promise = } }; -export const getNotificationsUnreadCount: () => Promise<{ - CMT?: number; - FRD_REQ?: number; - P_VIEW?: number; - MOM_TAG?: number; -}> = async () => { +export const getNotificationsUnreadCount = async () => { try { const token = await AsyncStorage.getItem('token'); const response = await fetch(NOTIFICATIONS_COUNT_ENDPOINT, { @@ -70,11 +65,10 @@ export const getNotificationsUnreadCount: () => Promise<{ } return typedData; } - return []; } catch (error) { console.log('Unable to fetch notifications'); - return []; } + return undefined; }; export const setNotificationsReadDate: () => Promise = async () => { diff --git a/src/types/types.ts b/src/types/types.ts index e54c2201..fd75ab50 100644 --- a/src/types/types.ts +++ b/src/types/types.ts @@ -254,7 +254,9 @@ export type TypeOfNotification = // notification_object is MomentType | 'MOM_TAG' // notification_object is undefined - | 'SYSTEM_MSG'; + | 'SYSTEM_MSG' + // notification_object is undefined + | 'P_VIEW'; export type UniversityBadge = { id: number; -- cgit v1.2.3-70-g09d2 From 189e0cb9f298ff956fc722fdcd4dcd9acd982985 Mon Sep 17 00:00:00 2001 From: Shravya Ramesh Date: Wed, 9 Jun 2021 16:03:30 -0700 Subject: Pass moment instead of sub fields --- src/components/moments/MomentPost.tsx | 8 +++----- src/components/moments/MomentPostContent.tsx | 24 +++++++++--------------- src/components/moments/MomentPostHeader.tsx | 12 ++++++++---- 3 files changed, 20 insertions(+), 24 deletions(-) (limited to 'src') diff --git a/src/components/moments/MomentPost.tsx b/src/components/moments/MomentPost.tsx index 7149a5b4..e744fcd9 100644 --- a/src/components/moments/MomentPost.tsx +++ b/src/components/moments/MomentPost.tsx @@ -76,18 +76,16 @@ const MomentPost: React.FC = ({item, userXId, screenType}) => { userXId={userXId} screenType={screenType} username={isOwnProfile ? loggedInUsername : username} - momentId={item.moment_id} style={styles.postHeader} momentTagId={momentTagId} removeTag={removeTag} + moment={item} + tags={tags} /> diff --git a/src/components/moments/MomentPostContent.tsx b/src/components/moments/MomentPostContent.tsx index 4a1f3894..153833d7 100644 --- a/src/components/moments/MomentPostContent.tsx +++ b/src/components/moments/MomentPostContent.tsx @@ -6,7 +6,7 @@ import Animated, {Easing} from 'react-native-reanimated'; import {useDispatch, useStore} from 'react-redux'; import {getCommentsCount} from '../../services'; import {RootState} from '../../store/rootReducer'; -import {MomentTagType, ScreenType, UserType} from '../../types'; +import {MomentTagType, MomentType, ScreenType, UserType} from '../../types'; import { getTimePosted, navigateToProfile, @@ -20,19 +20,13 @@ import {MomentTags} from '../common'; interface MomentPostContentProps extends ViewProps { screenType: ScreenType; - momentId: string; - caption: string; - pathHash: string; - dateTime: string; + moment: MomentType; momentTags: MomentTagType[]; } const MomentPostContent: React.FC = ({ screenType, - momentId, - caption, - pathHash, - dateTime, style, + moment, momentTags, }) => { const state: RootState = useStore().getState(); @@ -54,12 +48,12 @@ const MomentPostContent: React.FC = ({ useEffect(() => { const fetchCommentsCount = async () => { - const count = await getCommentsCount(momentId, false); + const count = await getCommentsCount(moment.moment_id, false); setCommentsCount(count); }; - setElapsedTime(getTimePosted(dateTime)); + setElapsedTime(getTimePosted(moment.date_created)); fetchCommentsCount(); - }, [dateTime, momentId]); + }, [moment.date_created, moment.moment_id]); useEffect(() => { const fade = async () => { @@ -82,7 +76,7 @@ const MomentPostContent: React.FC = ({ {tags.length > 0 && ( @@ -100,13 +94,13 @@ const MomentPostContent: React.FC = ({ {elapsedTime} {renderTextWithMentions({ - value: caption, + value: moment.caption, styles: styles.captionText, partTypes: mentionPartTypes('white'), onPress: (user: UserType) => diff --git a/src/components/moments/MomentPostHeader.tsx b/src/components/moments/MomentPostHeader.tsx index dc6a3cd9..cde7639c 100644 --- a/src/components/moments/MomentPostHeader.tsx +++ b/src/components/moments/MomentPostHeader.tsx @@ -10,7 +10,7 @@ import { import {useDispatch, useSelector, useStore} from 'react-redux'; import {loadUserMoments} from '../../store/actions'; import {RootState} from '../../store/rootReducer'; -import {ScreenType} from '../../types'; +import {MomentTagType, MomentType, ScreenType} from '../../types'; import {fetchUserX, userXInStore} from '../../utils'; import {MomentMoreInfoDrawer} from '../profile'; import TaggAvatar from '../profile/TaggAvatar'; @@ -19,19 +19,21 @@ interface MomentPostHeaderProps extends ViewProps { userXId?: string; screenType: ScreenType; username: string; - momentId: string; momentTagId: string; removeTag: () => Promise; + moment: MomentType; + tags: MomentTagType[]; } const MomentPostHeader: React.FC = ({ userXId, screenType, username, - momentId, style, momentTagId, removeTag, + moment, + tags, }) => { const [drawerVisible, setDrawerVisible] = useState(false); const dispatch = useDispatch(); @@ -68,7 +70,6 @@ const MomentPostHeader: React.FC = ({ = ({ dispatch(loadUserMoments(loggedInUserId)); navigation.pop(); }} + screenType={screenType} + moment={moment} + tags={tags} /> ); -- cgit v1.2.3-70-g09d2 From 2286d1b013b73534537a3265876361527856fd1a Mon Sep 17 00:00:00 2001 From: Shravya Ramesh Date: Wed, 9 Jun 2021 16:08:49 -0700 Subject: Add edit moment functionality to caption screen --- src/screens/moments/TagFriendsScreen.tsx | 4 +- src/screens/profile/CaptionScreen.tsx | 90 +++++++++++++++++++++----------- src/services/MomentService.ts | 32 ++++++++++++ 3 files changed, 94 insertions(+), 32 deletions(-) (limited to 'src') diff --git a/src/screens/moments/TagFriendsScreen.tsx b/src/screens/moments/TagFriendsScreen.tsx index c8bca9f4..570c3776 100644 --- a/src/screens/moments/TagFriendsScreen.tsx +++ b/src/screens/moments/TagFriendsScreen.tsx @@ -30,7 +30,7 @@ interface TagFriendsScreenProps { route: TagFriendsScreenRouteProps; } const TagFriendsScreen: React.FC = ({route}) => { - const {image, selectedTags} = route.params; + const {imagePath, selectedTags} = route.params; const navigation = useNavigation(); const imageRef = useRef(null); const [tags, setTags] = useState([]); @@ -85,7 +85,7 @@ const TagFriendsScreen: React.FC = ({route}) => { diff --git a/src/screens/profile/CaptionScreen.tsx b/src/screens/profile/CaptionScreen.tsx index 8bffd82b..949b61fd 100644 --- a/src/screens/profile/CaptionScreen.tsx +++ b/src/screens/profile/CaptionScreen.tsx @@ -23,7 +23,7 @@ import TaggLoadingIndicator from '../../components/common/TaggLoadingIndicator'; import {TAGG_LIGHT_BLUE_2} from '../../constants'; import {ERROR_UPLOAD, SUCCESS_PIC_UPLOAD} from '../../constants/strings'; import {MainStackParams} from '../../routes'; -import {postMoment, postMomentTags} from '../../services'; +import {patchMoment, postMoment, postMomentTags} from '../../services'; import { loadUserMoments, updateProfileCompletionStage, @@ -47,14 +47,16 @@ interface CaptionScreenProps { } const CaptionScreen: React.FC = ({route, navigation}) => { - const {title, image, screenType, selectedTags} = route.params; + const {title, image, screenType, selectedTags, moment} = route.params; const { user: {userId}, } = useSelector((state: RootState) => state.user); const dispatch = useDispatch(); - const [caption, setCaption] = useState(''); + const [caption, setCaption] = useState(moment ? moment.caption : ''); const [loading, setLoading] = useState(false); - const [tags, setTags] = useState([]); + const [tags, setTags] = useState( + selectedTags ? selectedTags : [], + ); const [taggedList, setTaggedList] = useState(''); useEffect(() => { @@ -84,22 +86,32 @@ const CaptionScreen: React.FC = ({route, navigation}) => { }); }; + const handleFailed = () => { + setLoading(false); + setTimeout(() => { + Alert.alert(moment ? 'Error editing moment' : ERROR_UPLOAD); + }, 500); + }; + const handleSuccess = () => { + setLoading(false); + navigateToProfile(); + setTimeout(() => { + Alert.alert(moment ? 'Successfully edited moment!' : SUCCESS_PIC_UPLOAD); + }, 500); + }; + + const formattedTags = () => { + return tags.map((tag) => ({ + x: Math.floor(tag.x), + y: Math.floor(tag.y), + z: Math.floor(tag.z), + user_id: tag.user.id, + })); + }; + const handleShare = async () => { - const handleFailed = () => { - setLoading(false); - setTimeout(() => { - Alert.alert(ERROR_UPLOAD); - }, 500); - }; - const handleSuccess = () => { - setLoading(false); - navigateToProfile(); - setTimeout(() => { - Alert.alert(SUCCESS_PIC_UPLOAD); - }, 500); - }; setLoading(true); - if (!image.filename) { + if (!image?.filename || !title) { return; } const momentResponse = await postMoment( @@ -115,12 +127,7 @@ const CaptionScreen: React.FC = ({route, navigation}) => { } const momentTagResponse = await postMomentTags( momentResponse.moment_id, - tags.map((tag) => ({ - x: Math.floor(tag.x), - y: Math.floor(tag.y), - z: Math.floor(tag.z), - user_id: tag.user.id, - })), + formattedTags(), ); if (!momentTagResponse) { handleFailed(); @@ -133,6 +140,23 @@ const CaptionScreen: React.FC = ({route, navigation}) => { handleSuccess(); }; + const handleDone = async () => { + setLoading(true); + if (moment?.moment_id) { + const success = await patchMoment( + moment.moment_id, + caption, + formattedTags(), + ); + if (success) { + dispatch(loadUserMoments(userId)); + handleSuccess(); + } else { + handleFailed(); + } + } + }; + return ( {loading ? : } @@ -148,17 +172,20 @@ const CaptionScreen: React.FC = ({route, navigation}) => { onPress={() => navigateToProfile()} />