aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/components/moments/MomentPost.tsx352
-rw-r--r--src/components/profile/MomentMoreInfoDrawer.tsx7
-rw-r--r--src/screens/profile/IndividualMoment.tsx55
3 files changed, 349 insertions, 65 deletions
diff --git a/src/components/moments/MomentPost.tsx b/src/components/moments/MomentPost.tsx
index 60cb16fa..8a3cfacb 100644
--- a/src/components/moments/MomentPost.tsx
+++ b/src/components/moments/MomentPost.tsx
@@ -1,12 +1,42 @@
-import React, {useEffect, useState} from 'react';
-import {StyleSheet} from 'react-native';
-import {useSelector} from 'react-redux';
-import {MomentPostContent, MomentPostHeader} from '.';
+import {useNavigation} from '@react-navigation/native';
+import React, {useContext, useEffect, useMemo, useRef, useState} from 'react';
+import {
+ Image,
+ KeyboardAvoidingView,
+ Platform,
+ StatusBar,
+ StyleSheet,
+ Text,
+ TouchableOpacity,
+ View,
+} from 'react-native';
+import Animated, {EasingNode} from 'react-native-reanimated';
+import {useDispatch, useSelector, useStore} from 'react-redux';
+import {headerBarOptions} from '../../routes';
+import {MomentContext} from '../../screens/profile/IndividualMoment';
import {deleteMomentTag, loadMomentTags} from '../../services';
+import {loadUserMoments} from '../../store/actions';
import {RootState} from '../../store/rootReducer';
-import {MomentPostType, MomentTagType, ScreenType} from '../../types';
-import {normalize, SCREEN_HEIGHT} from '../../utils';
-
+import {
+ MomentCommentPreviewType,
+ MomentPostType,
+ MomentTagType,
+ ScreenType,
+ UserType,
+} from '../../types';
+import {
+ getLoggedInUserAsProfilePreview,
+ getTimePosted,
+ HeaderHeight,
+ navigateToProfile,
+ normalize,
+ SCREEN_HEIGHT,
+ SCREEN_WIDTH,
+} from '../../utils';
+import {mentionPartTypes, renderTextWithMentions} from '../../utils/comments';
+import {AddComment} from '../comments';
+import CommentsCount from '../comments/CommentsCount';
+import {MomentMoreInfoDrawer, TaggAvatar} from '../profile';
interface MomentPostProps {
moment: MomentPostType;
userXId: string | undefined;
@@ -24,15 +54,13 @@ const MomentPost: React.FC<MomentPostProps> = ({
(state: RootState) => state.user.user,
);
- const {
- user: {username},
- } = useSelector((state: RootState) =>
+ const {user} = useSelector((state: RootState) =>
userXId ? state.userX[screenType][userXId] : state.user,
);
const [tags, setTags] = useState<MomentTagType[]>([]);
const [momentTagId, setMomentTagId] = useState<string>('');
- const isOwnProfile = username === loggedInUsername;
+ const isOwnProfile = user.username === loggedInUsername;
/*
* Load tags on initial render to pass tags data to moment header and content
@@ -71,18 +99,201 @@ const MomentPost: React.FC<MomentPostProps> = ({
}
};
- return (
- <>
- <MomentPostHeader
- style={styles.postHeader}
+ // const [tags, setTags] = useState<MomentTagType[]>(momentTags);
+ const state: RootState = useStore().getState();
+ const navigation = useNavigation();
+ const dispatch = useDispatch();
+ const imageRef = useRef(null);
+ const [visible, setVisible] = useState(false);
+ const [fadeValue, setFadeValue] = useState<Animated.Value<number>>(
+ new Animated.Value(0),
+ );
+ const [commentCount, setCommentCount] = useState<number>(
+ moment.comments_count,
+ );
+ const [commentPreview, setCommentPreview] =
+ useState<MomentCommentPreviewType | null>(moment.comment_preview);
+ const {keyboardVisible, scrollTo} = useContext(MomentContext);
+ const [hideText, setHideText] = useState(false);
+
+ const [isFullScreen, setIsFullScreen] = useState<boolean>(false);
+ const [aspectRatio, setAspectRatio] = useState<number>(1);
+
+ const [drawerVisible, setDrawerVisible] = useState(false);
+
+ useEffect(
+ () =>
+ navigation.setOptions({
+ ...headerBarOptions('white', ''),
+ headerTitle: () => (
+ <View
+ style={{
+ flex: 1,
+ width: SCREEN_WIDTH * 0.6,
+ flexDirection: 'row',
+ justifyContent: 'flex-end',
+ marginVertical: '2%',
+ }}>
+ <View
+ style={{
+ width: '80%',
+ position: 'absolute',
+ left: '10%',
+ right: '10%',
+ height: normalize(70),
+ }}>
+ <Text
+ style={[
+ {
+ textAlign: 'center',
+ color: 'white',
+ fontSize: normalize(18),
+ fontWeight: '700',
+ lineHeight: normalize(21.48),
+ letterSpacing: normalize(1.3),
+ },
+ {
+ fontSize:
+ moment.moment_category.length > 18
+ ? normalize(14)
+ : normalize(16),
+ },
+ ]}>
+ {moment.moment_category}
+ </Text>
+ </View>
+ </View>
+ ),
+ }),
+ [moment.moment_id],
+ );
+
+ useEffect(() => {
+ Image.getSize(
+ moment.moment_url,
+ (w, h) => {
+ const isFS = Math.abs(w / h - 9 / 16) < 0.01;
+ setAspectRatio(w / h);
+ setIsFullScreen(isFS);
+ },
+ (err) => console.log(err),
+ );
+ }, []);
+
+ useEffect(() => {
+ const fade = async () => {
+ Animated.timing(fadeValue, {
+ toValue: 1,
+ duration: 250,
+ easing: EasingNode.linear,
+ }).start();
+ };
+ fade();
+ }, [fadeValue]);
+
+ useEffect(() => {
+ if (!keyboardVisible && hideText) {
+ setHideText(false);
+ }
+ }, [keyboardVisible, hideText]);
+
+ const tagsIcon = useMemo(() => {
+ tags.length > 0 && (
+ <Image
+ source={require('../../assets/icons/tag_indicate.png')}
+ style={styles.tagIcon}
+ />
+ );
+ }, [tags]);
+
+ const MomentUserPreview = () => (
+ <TouchableOpacity
+ onPress={() =>
+ navigateToProfile(state, dispatch, navigation, screenType, user)
+ }
+ style={styles.header}>
+ <TaggAvatar
+ style={styles.avatar}
userXId={userXId}
screenType={screenType}
- username={isOwnProfile ? loggedInUsername : username}
- momentTagId={momentTagId}
- removeTag={removeTag}
- moment={moment}
- tags={tags}
+ editable={false}
+ />
+ <Text style={styles.headerText}>{user.username}</Text>
+ </TouchableOpacity>
+ );
+
+ const TagsIcon = () => {
+ return tags.length === 0 ? (
+ <Image
+ source={require('../../assets/icons/tag_indicate.png')}
+ style={styles.tagIcon}
/>
+ ) : (
+ <React.Fragment />
+ );
+ };
+
+ const [verticalOffset, setVerticalOffset] = useState<number>(0);
+ return (
+ <>
+ <StatusBar barStyle={'light-content'} />
+ <View
+ style={{
+ backgroundColor: 'black',
+ width: SCREEN_WIDTH,
+ height: SCREEN_HEIGHT,
+ flexDirection: 'column',
+ justifyContent: 'center',
+ }}>
+ <Image
+ source={{uri: moment.moment_url}}
+ style={[
+ styles.image,
+ {
+ height: isFullScreen ? SCREEN_HEIGHT : SCREEN_WIDTH / aspectRatio,
+ },
+ ]}
+ resizeMode={'cover'}
+ />
+ <View
+ style={{
+ position: 'absolute',
+ width: SCREEN_WIDTH,
+ height: SCREEN_HEIGHT,
+ flexDirection: 'column',
+ justifyContent: 'space-between',
+ paddingBottom: '24%',
+ }}>
+ <View
+ style={{
+ paddingTop: HeaderHeight,
+ alignSelf: 'flex-end',
+ paddingRight: '8%',
+ }}>
+ <MomentMoreInfoDrawer
+ isOpen={drawerVisible}
+ setIsOpen={setDrawerVisible}
+ isOwnProfile={isOwnProfile}
+ momentTagId={momentTagId}
+ removeTag={removeTag}
+ dismissScreenAndUpdate={() => {
+ dispatch(loadUserMoments(loggedInUserId));
+ navigation.goBack();
+ }}
+ screenType={screenType}
+ moment={moment}
+ tags={tags}
+ />
+ </View>
+ <KeyboardAvoidingView
+ behavior={Platform.OS === 'ios' ? 'padding' : 'height'}
+ keyboardVerticalOffset={-20}>
+ <View
+ style={{
+ flexDirection: 'column',
+ justifyContent: 'flex-end',
+ }}>
+ <TagsIcon />
<View
style={{
position: 'absolute',
@@ -91,6 +302,51 @@ const MomentPost: React.FC<MomentPostProps> = ({
}}>
<CommentsCount moment={moment} screenType={screenType} />
</View>
+ <MomentUserPreview />
+ {!hideText && (
+ <>
+ {moment.caption !== '' &&
+ renderTextWithMentions({
+ value: moment.caption,
+ styles: styles.captionText,
+ partTypes: mentionPartTypes('white'),
+ onPress: (user: UserType) =>
+ navigateToProfile(
+ state,
+ dispatch,
+ navigation,
+ screenType,
+ user,
+ ),
+ })}
+ </>
+ )}
+ <View>
+ <AddComment
+ placeholderText={'Add a comment here!'}
+ momentId={moment.moment_id}
+ callback={(message) => {
+ setCommentPreview({
+ commenter: getLoggedInUserAsProfilePreview(state),
+ comment: message,
+ });
+ setCommentCount(commentCount + 1);
+ }}
+ onFocus={() => {
+ setHideText(true);
+ setVerticalOffset(SCREEN_HEIGHT * 0.05);
+ }}
+ isKeyboardAvoiding={false}
+ theme={'dark'}
+ />
+ <Text style={styles.text}>
+ {getTimePosted(moment.date_created)}
+ </Text>
+ </View>
+ </View>
+ </KeyboardAvoidingView>
+ </View>
+ </View>
</>
);
};
@@ -98,9 +354,63 @@ const MomentPost: React.FC<MomentPostProps> = ({
const styles = StyleSheet.create({
postHeader: {},
postContent: {
- minHeight: SCREEN_HEIGHT * 0.8,
+ // minHeight: SCREEN_HEIGHT * 0.8,
paddingBottom: normalize(20),
},
+ image: {
+ width: SCREEN_WIDTH,
+ marginBottom: '3%',
+ zIndex: 0,
+ position: 'absolute',
+ },
+ text: {
+ marginHorizontal: '5%',
+ color: 'white',
+ fontWeight: '500',
+ textAlign: 'right',
+ marginTop: 5,
+ },
+ captionText: {
+ position: 'relative',
+ marginHorizontal: '5%',
+ color: '#ffffff',
+ fontWeight: '500',
+ fontSize: normalize(13),
+ lineHeight: normalize(15.51),
+ letterSpacing: normalize(0.6),
+ marginBottom: normalize(5),
+ width: SCREEN_WIDTH * 0.79,
+ },
+ tapTag: {
+ position: 'absolute',
+ backgroundColor: 'red',
+ width: 100,
+ height: 100,
+ },
+ tagIcon: {
+ width: normalize(30),
+ height: normalize(30),
+ bottom: normalize(20),
+ left: '5%',
+ },
+ avatar: {
+ width: 48,
+ aspectRatio: 1,
+ borderRadius: 100,
+ marginLeft: '3%',
+ },
+ headerText: {
+ fontSize: 15,
+ fontWeight: 'bold',
+ color: 'white',
+ paddingHorizontal: '3%',
+ flex: 1,
+ },
+ header: {
+ alignItems: 'center',
+ flexDirection: 'row',
+ marginBottom: normalize(15),
+ },
});
export default MomentPost;
diff --git a/src/components/profile/MomentMoreInfoDrawer.tsx b/src/components/profile/MomentMoreInfoDrawer.tsx
index a796ffd8..a8adcfda 100644
--- a/src/components/profile/MomentMoreInfoDrawer.tsx
+++ b/src/components/profile/MomentMoreInfoDrawer.tsx
@@ -169,7 +169,6 @@ const MomentMoreInfoDrawer: React.FC<MomentMoreInfoDrawerProps> = (props) => {
return (
<>
<TouchableOpacity
- style={styles.icon}
onPress={() => {
setIsOpen(true);
}}>
@@ -184,10 +183,4 @@ const MomentMoreInfoDrawer: React.FC<MomentMoreInfoDrawerProps> = (props) => {
);
};
-const styles = StyleSheet.create({
- icon: {
- marginRight: '3%',
- },
-});
-
export default MomentMoreInfoDrawer;
diff --git a/src/screens/profile/IndividualMoment.tsx b/src/screens/profile/IndividualMoment.tsx
index f8113aba..4088895a 100644
--- a/src/screens/profile/IndividualMoment.tsx
+++ b/src/screens/profile/IndividualMoment.tsx
@@ -1,10 +1,9 @@
-import {BlurView} from '@react-native-community/blur';
import {RouteProp} from '@react-navigation/native';
import {StackNavigationProp} from '@react-navigation/stack';
import React, {useEffect, useRef, useState} from 'react';
import {FlatList, Keyboard, StyleSheet} from 'react-native';
import {useSelector} from 'react-redux';
-import {IndividualMomentTitleBar, MomentPost} from '../../components';
+import {MomentPost, TabsGradient} from '../../components';
import {AVATAR_DIM} from '../../constants';
import {MainStackParams} from '../../routes';
import {RootState} from '../../store/rootreducer';
@@ -84,41 +83,23 @@ const IndividualMoment: React.FC<IndividualMomentProps> = ({
keyboardVisible,
scrollTo,
}}>
- <BlurView
- blurType="light"
- blurAmount={30}
- reducedTransparencyFallbackColor="white"
- style={styles.contentContainer}>
- <IndividualMomentTitleBar
- style={styles.header}
- close={() => navigation.goBack()}
- title={moment_category}
- />
- <FlatList
- ref={scrollRef}
- data={momentData}
- contentContainerStyle={styles.listContentContainer}
- renderItem={({item, index}) => (
- <MomentPost
- moment={item}
- userXId={userXId}
- screenType={screenType}
- index={index}
- />
- )}
- keyExtractor={(item, _) => item.moment_id}
- showsVerticalScrollIndicator={false}
- initialScrollIndex={initialIndex}
- onScrollToIndexFailed={() => {
- // TODO: code below does not work, index resets to 0
- // const wait = new Promise((resolve) => setTimeout(resolve, 500));
- // wait.then(() => {
- // console.log('scrolling to ', initialIndex);
- // scrollRef.current?.scrollToIndex({index: initialIndex});
- // });
- }}
- />
- </BlurView>
+ <FlatList
+ ref={scrollRef}
+ data={momentData}
+ renderItem={({item, index}) => (
+ <MomentPost
+ moment={item}
+ userXId={userXId}
+ screenType={screenType}
+ index={index}
+ />
+ )}
+ keyExtractor={(item, _) => item.moment_id}
+ showsVerticalScrollIndicator={false}
+ initialScrollIndex={initialIndex}
+ pagingEnabled
+ />
+ <TabsGradient />
</MomentContext.Provider>
);
};