diff options
| author | Ivan Chen <ivan@thetaggid.com> | 2020-12-14 19:22:35 -0500 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-12-14 19:22:35 -0500 |
| commit | b5ecbf3e421e9e6f1dbab9f3f851d265ae8470c6 (patch) | |
| tree | 4c1ee927a851649ef03c8a05619e2d78f2cdb1f4 /src/components | |
| parent | 3b7bf256d83e1898642c2aab9072ffbeec8cc032 (diff) | |
[TMA-406&201] User Handle UI for Individual Moments (#129)
* initial work
* made big progress towards flatlist moment view
* UI done, just need to pass in data now
* minor fixes to get things actually running correctly
* vertical scroll working
* initial index working
* moment drawer text color to red
* moved report to drawer
* removed garbage
* added ?
Diffstat (limited to 'src/components')
| -rw-r--r-- | src/components/comments/CommentsCount.tsx | 16 | ||||
| -rw-r--r-- | src/components/common/GenericMoreInfoDrawer.tsx | 2 | ||||
| -rw-r--r-- | src/components/moments/CaptionScreenHeader.tsx | 3 | ||||
| -rw-r--r-- | src/components/moments/IndividualMomentTitleBar.tsx | 45 | ||||
| -rw-r--r-- | src/components/moments/MomentPostContent.tsx | 85 | ||||
| -rw-r--r-- | src/components/moments/MomentPostHeader.tsx | 84 | ||||
| -rw-r--r-- | src/components/moments/index.ts | 5 | ||||
| -rw-r--r-- | src/components/profile/Avatar.tsx | 5 | ||||
| -rw-r--r-- | src/components/profile/MomentMoreInfoDrawer.tsx | 61 |
9 files changed, 283 insertions, 23 deletions
diff --git a/src/components/comments/CommentsCount.tsx b/src/components/comments/CommentsCount.tsx index d210c39a..325e2788 100644 --- a/src/components/comments/CommentsCount.tsx +++ b/src/components/comments/CommentsCount.tsx @@ -1,8 +1,8 @@ +import {useNavigation} from '@react-navigation/native'; import * as React from 'react'; -import {Text} from 'react-native-animatable'; import {StyleSheet, TouchableOpacity} from 'react-native'; +import {Text} from 'react-native-animatable'; import CommentIcon from '../../assets/icons/moment-comment-icon.svg'; -import {useNavigation} from '@react-navigation/native'; import {ScreenType} from '../../types'; /** @@ -11,20 +11,20 @@ import {ScreenType} from '../../types'; */ type CommentsCountProps = { - comments_count: string; - moment_id: string; + commentsCount: string; + momentId: string; screenType: ScreenType; }; const CommentsCount: React.FC<CommentsCountProps> = ({ - comments_count, - moment_id, + commentsCount, + momentId, screenType, }) => { const navigation = useNavigation(); const navigateToCommentsScreen = async () => { navigation.push('MomentCommentsScreen', { - moment_id, + moment_id: momentId, screenType, }); }; @@ -33,7 +33,7 @@ const CommentsCount: React.FC<CommentsCountProps> = ({ <TouchableOpacity onPress={() => navigateToCommentsScreen()}> <CommentIcon style={styles.image} /> <Text style={styles.count}> - {comments_count !== '0' ? comments_count : ''} + {commentsCount !== '0' ? commentsCount : ''} </Text> </TouchableOpacity> </> diff --git a/src/components/common/GenericMoreInfoDrawer.tsx b/src/components/common/GenericMoreInfoDrawer.tsx index 5c58f903..3607ef8f 100644 --- a/src/components/common/GenericMoreInfoDrawer.tsx +++ b/src/components/common/GenericMoreInfoDrawer.tsx @@ -74,7 +74,7 @@ const styles = StyleSheet.create({ panelButtonTitle: { fontSize: 18, fontWeight: 'bold', - color: 'black', + color: 'red', }, icon: { height: 25, diff --git a/src/components/moments/CaptionScreenHeader.tsx b/src/components/moments/CaptionScreenHeader.tsx index 4715b4ef..46dfddfe 100644 --- a/src/components/moments/CaptionScreenHeader.tsx +++ b/src/components/moments/CaptionScreenHeader.tsx @@ -20,7 +20,8 @@ const styles = StyleSheet.create({ container: { flexDirection: 'row', justifyContent: 'center', - height: 30, + alignItems: 'center', + height: '5%', }, headerContainer: { position: 'absolute', diff --git a/src/components/moments/IndividualMomentTitleBar.tsx b/src/components/moments/IndividualMomentTitleBar.tsx new file mode 100644 index 00000000..bd5b307f --- /dev/null +++ b/src/components/moments/IndividualMomentTitleBar.tsx @@ -0,0 +1,45 @@ +import React from 'react'; +import {TouchableOpacity} from 'react-native'; +import {Text, View, StyleSheet, ViewProps} from 'react-native'; +import CloseIcon from '../../assets/ionicons/close-outline.svg'; + +interface IndividualMomentTitleBarProps extends ViewProps { + title: string; + close: () => void; +} +const IndividualMomentTitleBar: React.FC<IndividualMomentTitleBarProps> = ({ + title, + close, + style, +}) => { + return ( + <View style={[styles.container, style]}> + <TouchableOpacity style={styles.closeButton} onPress={close}> + <CloseIcon height={'100%'} width={'100%'} color={'white'} /> + </TouchableOpacity> + <Text style={styles.header}>{title}</Text> + </View> + ); +}; + +const styles = StyleSheet.create({ + container: { + flexDirection: 'row', + alignItems: 'center', + justifyContent: 'center', + height: '5%', + }, + header: { + fontSize: 20, + fontWeight: 'bold', + color: 'white', + }, + closeButton: { + position: 'absolute', + height: '50%', + aspectRatio: 1, + left: '3%', + }, +}); + +export default IndividualMomentTitleBar; diff --git a/src/components/moments/MomentPostContent.tsx b/src/components/moments/MomentPostContent.tsx new file mode 100644 index 00000000..93271fa1 --- /dev/null +++ b/src/components/moments/MomentPostContent.tsx @@ -0,0 +1,85 @@ +import React, {useEffect} from 'react'; +import {Image, StyleSheet, Text, View, ViewProps} from 'react-native'; +import {getMomentCommentsCount} from '../../services'; +import {ScreenType} from '../../types'; +import {getTimePosted, SCREEN_HEIGHT, SCREEN_WIDTH} from '../../utils'; +import {CommentsCount} from '../comments'; + +interface MomentPostContentProps extends ViewProps { + screenType: ScreenType; + momentId: string; + caption: string; + pathHash: string; + dateTime: string; +} +const MomentPostContent: React.FC<MomentPostContentProps> = ({ + screenType, + momentId, + caption, + pathHash, + dateTime, + style, +}) => { + const [elapsedTime, setElapsedTime] = React.useState<string>(); + const [comments_count, setCommentsCount] = React.useState(''); + + useEffect(() => { + setElapsedTime(getTimePosted(dateTime)); + getMomentCommentsCount(momentId, setCommentsCount); + }, [dateTime, momentId]); + return ( + <View style={[styles.container, style]}> + <Image + style={styles.image} + source={{uri: pathHash}} + resizeMode={'cover'} + /> + <View style={styles.footerContainer}> + <CommentsCount + commentsCount={comments_count} + momentId={momentId} + screenType={screenType} + /> + <Text style={styles.text}>{elapsedTime}</Text> + </View> + <Text style={styles.captionText}>{caption}</Text> + </View> + ); +}; + +const styles = StyleSheet.create({ + container: { + height: SCREEN_HEIGHT, + }, + image: { + width: SCREEN_WIDTH, + aspectRatio: 1, + marginBottom: '3%', + }, + footerContainer: { + flexDirection: 'row', + justifyContent: 'space-between', + marginLeft: '7%', + marginRight: '5%', + marginBottom: '2%', + }, + text: { + position: 'relative', + paddingBottom: '1%', + paddingTop: '1%', + marginLeft: '7%', + marginRight: '2%', + color: '#ffffff', + fontWeight: 'bold', + }, + captionText: { + position: 'relative', + paddingBottom: '34%', + paddingTop: '1%', + marginLeft: '5%', + marginRight: '5%', + color: '#ffffff', + fontWeight: 'bold', + }, +}); +export default MomentPostContent; diff --git a/src/components/moments/MomentPostHeader.tsx b/src/components/moments/MomentPostHeader.tsx new file mode 100644 index 00000000..810ccea9 --- /dev/null +++ b/src/components/moments/MomentPostHeader.tsx @@ -0,0 +1,84 @@ +import React, {useState} from 'react'; +import {StyleSheet, Text, View, ViewProps} from 'react-native'; +import {MomentMoreInfoDrawer} from '..'; +import {loadUserMoments} from '../../store/actions'; +import {useDispatch, useSelector} from 'react-redux'; +import {ScreenType} from '../../types'; +import Avatar from '../profile/Avatar'; +import {useNavigation} from '@react-navigation/native'; +import {RootState} from '../../store/rootReducer'; + +interface MomentPostHeaderProps extends ViewProps { + userXId?: string; + screenType: ScreenType; + username: string; + momentId: string; +} + +const MomentPostHeader: React.FC<MomentPostHeaderProps> = ({ + userXId, + screenType, + username, + momentId, + style, +}) => { + const [drawerVisible, setDrawerVisible] = useState(false); + const dispatch = useDispatch(); + const navigation = useNavigation(); + const {userId: loggedInUserId, username: loggedInUserName} = useSelector( + (state: RootState) => state.user.user, + ); + const isOwnProfile = loggedInUserName === username; + + return ( + <View style={[styles.container, style]}> + <View style={styles.header}> + <Avatar + style={styles.avatar} + userXId={userXId} + screenType={screenType} + /> + <Text style={styles.headerText}>{username}</Text> + </View> + <MomentMoreInfoDrawer + isOpen={drawerVisible} + setIsOpen={setDrawerVisible} + momentId={momentId} + isOwnProfile={isOwnProfile} + dismissScreenAndUpdate={() => { + dispatch(loadUserMoments(loggedInUserId)); + navigation.pop(); + }} + /> + </View> + ); +}; + +const styles = StyleSheet.create({ + container: { + flex: 1, + justifyContent: 'space-around', + flexDirection: 'row', + alignItems: 'center', + marginVertical: '2%', + }, + header: { + alignItems: 'center', + flexDirection: 'row', + flex: 1, + }, + avatar: { + flex: 0.2, + aspectRatio: 1, + borderRadius: 999999, + marginLeft: '3%', + }, + headerText: { + fontSize: 15, + fontWeight: 'bold', + color: 'white', + paddingHorizontal: '3%', + flex: 1, + }, +}); +export default MomentPostHeader; diff --git a/src/components/moments/index.ts b/src/components/moments/index.ts index 339e0e19..89fd689c 100644 --- a/src/components/moments/index.ts +++ b/src/components/moments/index.ts @@ -1,2 +1,5 @@ -export {default as CaptionScreenHeader} from '../moments/CaptionScreenHeader'; +export {default as IndividualMomentTitleBar} from './IndividualMomentTitleBar'; +export {default as CaptionScreenHeader} from './CaptionScreenHeader'; +export {default as MomentPostHeader} from './MomentPostHeader'; +export {default as MomentPostContent} from './MomentPostContent'; export {default as Moment} from './Moment'; diff --git a/src/components/profile/Avatar.tsx b/src/components/profile/Avatar.tsx index d3c53043..ba4ec36c 100644 --- a/src/components/profile/Avatar.tsx +++ b/src/components/profile/Avatar.tsx @@ -1,12 +1,13 @@ -import React, {useContext} from 'react'; +import React from 'react'; import {Image, StyleSheet} from 'react-native'; import {useSelector} from 'react-redux'; import {RootState} from '../../store/rootreducer'; import {ScreenType} from '../../types'; const PROFILE_DIM = 100; + interface AvatarProps { - style: object; + style?: object; userXId: string | undefined; screenType: ScreenType; } diff --git a/src/components/profile/MomentMoreInfoDrawer.tsx b/src/components/profile/MomentMoreInfoDrawer.tsx index 18462cbb..91fb3d2b 100644 --- a/src/components/profile/MomentMoreInfoDrawer.tsx +++ b/src/components/profile/MomentMoreInfoDrawer.tsx @@ -1,18 +1,19 @@ import React from 'react'; -import {Alert, TouchableOpacity} from 'react-native'; +import {Alert, StyleSheet, TouchableOpacity, ViewProps} from 'react-native'; import MoreIcon from '../../assets/icons/more_horiz-24px.svg'; -import {deleteMoment} from '../../services'; +import {deleteMoment, sendReport} from '../../services'; import {GenericMoreInfoDrawer} from '../common'; -interface MomentMoreInfoDrawerProps { +interface MomentMoreInfoDrawerProps extends ViewProps { isOpen: boolean; setIsOpen: (visible: boolean) => void; momentId: string; - dismissScreenAndUpdate: Function; + isOwnProfile: boolean; + dismissScreenAndUpdate: () => void; } const MomentMoreInfoDrawer: React.FC<MomentMoreInfoDrawerProps> = (props) => { - const {momentId, setIsOpen, dismissScreenAndUpdate} = props; + const {momentId, setIsOpen, isOwnProfile, dismissScreenAndUpdate} = props; const handleDeleteMoment = async () => { setIsOpen(false); @@ -38,21 +39,61 @@ const MomentMoreInfoDrawer: React.FC<MomentMoreInfoDrawerProps> = (props) => { }); }; + const handleReportMoment = async () => { + setIsOpen(false); + setTimeout(() => { + Alert.alert( + 'Report Issue', + undefined, + [ + { + text: 'Mark as inappropriate', + onPress: () => sendReport(momentId, 'Mark as inappropriate'), + }, + { + text: 'Cancel', + style: 'cancel', + }, + { + text: 'Mark as abusive', + onPress: () => sendReport(momentId, 'Mark as abusive'), + }, + ], + {cancelable: false}, + ); + }, 500); + }; + return ( <> <TouchableOpacity + style={styles.icon} onPress={() => { setIsOpen(true); }}> <MoreIcon height={30} width={30} color={'white'} /> </TouchableOpacity> - <GenericMoreInfoDrawer - {...props} - showIcons={false} - buttons={[['Delete Moment', handleDeleteMoment]]} - /> + {isOwnProfile ? ( + <GenericMoreInfoDrawer + {...props} + showIcons={false} + buttons={[['Delete Moment', handleDeleteMoment]]} + /> + ) : ( + <GenericMoreInfoDrawer + {...props} + showIcons={false} + buttons={[['Report an Issue', handleReportMoment]]} + /> + )} </> ); }; +const styles = StyleSheet.create({ + icon: { + marginRight: '3%', + }, +}); + export default MomentMoreInfoDrawer; |
