aboutsummaryrefslogtreecommitdiff
path: root/src/screens/profile/IndividualMoment.tsx
blob: 7d231312abdb8ab7340fa83019969789c355da18 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
import {RouteProp} from '@react-navigation/native';
import {StackNavigationProp} from '@react-navigation/stack';
import React, {useEffect, useRef, useState} from 'react';
import {FlatList, Keyboard, ViewToken} from 'react-native';
import {useSelector} from 'react-redux';
import {MomentPost, TabsGradient} from '../../components';
import {MainStackParams} from '../../routes';
import {RootState} from '../../store/rootreducer';
import {MomentPostType} from '../../types';
import {SCREEN_HEIGHT} from '../../utils';

type MomentContextType = {
  keyboardVisible: boolean;
  currentVisibleMomentId: string | undefined;
};

export const MomentContext = React.createContext({} as MomentContextType);

type IndividualMomentRouteProp = RouteProp<MainStackParams, 'IndividualMoment'>;

type IndividualMomentNavigationProp = StackNavigationProp<
  MainStackParams,
  'IndividualMoment'
>;

interface IndividualMomentProps {
  route: IndividualMomentRouteProp;
  navigation: IndividualMomentNavigationProp;
}

const IndividualMoment: React.FC<IndividualMomentProps> = ({route}) => {
  const {
    userXId,
    screenType,
    moment: {moment_category, moment_id},
  } = route.params;
  const {moments} = useSelector((state: RootState) =>
    userXId ? state.userX[screenType][userXId] : state.moments,
  );
  const scrollRef = useRef<FlatList<MomentPostType>>(null);
  const momentData = moments.filter(
    (m) => m.moment_category === moment_category,
  );
  const initialIndex = momentData.findIndex((m) => m.moment_id === moment_id);
  const [keyboardVisible, setKeyboardVisible] = useState(false);
  const [currentVisibleMomentId, setCurrentVisibleMomentId] = useState<
    string | undefined
  >();
  const [viewableItems, setViewableItems] = useState<ViewToken[]>([]);

  // https://stackoverflow.com/a/57502343
  const viewabilityConfigCallback = useRef(
    (info: {viewableItems: ViewToken[]}) => {
      setViewableItems(info.viewableItems);
    },
  );

  useEffect(() => {
    if (viewableItems.length > 0) {
      const index = viewableItems[0].index;
      if (index !== null && momentData.length > 0) {
        setCurrentVisibleMomentId(momentData[index].moment_id);
      }
    }
  }, [viewableItems]);

  useEffect(() => {
    const showKeyboard = () => setKeyboardVisible(true);
    const hideKeyboard = () => setKeyboardVisible(false);
    Keyboard.addListener('keyboardWillShow', showKeyboard);
    Keyboard.addListener('keyboardWillHide', hideKeyboard);
    return () => {
      Keyboard.removeListener('keyboardWillShow', showKeyboard);
      Keyboard.removeListener('keyboardWillHide', hideKeyboard);
    };
  }, []);

  return (
    <MomentContext.Provider
      value={{
        keyboardVisible,
        currentVisibleMomentId,
      }}>
      <FlatList
        ref={scrollRef}
        data={momentData}
        renderItem={({item}) => (
          <MomentPost
            key={item.moment_id}
            moment={item}
            userXId={userXId}
            screenType={screenType}
          />
        )}
        keyExtractor={(item, _) => item.moment_id}
        showsVerticalScrollIndicator={false}
        initialScrollIndex={initialIndex}
        onViewableItemsChanged={viewabilityConfigCallback.current}
        getItemLayout={(data, index) => ({
          length: SCREEN_HEIGHT,
          offset: SCREEN_HEIGHT * index,
          index,
        })}
        pagingEnabled
      />
      <TabsGradient />
    </MomentContext.Provider>
  );
};

export default IndividualMoment;