Skip to content

Instantly share code, notes, and snippets.

@TheBrotherFromASouthernMother
Created November 1, 2023 18:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save TheBrotherFromASouthernMother/f779141162be90bcc5350b94f10ec080 to your computer and use it in GitHub Desktop.
Save TheBrotherFromASouthernMother/f779141162be90bcc5350b94f10ec080 to your computer and use it in GitHub Desktop.
The Green Book Project: Newsfeed
import React, { useState, useEffect } from 'react';
import { View } from 'react-native';
import { withAppContext } from 'components/AppContext';
import AppContextShape from 'test_utilities/contexts';
import { Container, Content } from 'native-base';
import IntroductionBanner from 'Notifications/Newsfeed/components/IntroductionBanner';
import LoadMoreButton from 'Notifications/Newsfeed/components/LoadMoreButton';
import EndOfFeedMessage from 'Notifications/Newsfeed/components/EndOfFeedMessage';
import styles from 'Notifications/Newsfeed/styles';
import useGetReviewNewsfeedItems from 'Notifications/Newsfeed/hooks/useGetReviewNewsfeedItems';
import useHandleLoadMoreReviews from 'Notifications/Newsfeed/hooks/useHandleLoadMoreReviews';
import useHandleItemContentPress from 'Notifications/Newsfeed/hooks/useHandleItemContentPress';
import useHandleIntroductionBannerExit from 'Notifications/Newsfeed/hooks/useHandleIntroductionBannerExit';
import useSetLatestNewsfeedPost from 'Notifications/Newsfeed/hooks/useSetLatestNewsfeedPost';
import useResolveScreenBannerContent from 'Notifications/Newsfeed/hooks/useResolveScreenBannerContent';
import GhostView from 'Notifications/Newsfeed/components/GhostView';
import ErrorView from 'Notifications/Newsfeed/components/ErrorView';
import get from 'lodash/get';
import isEmpty from 'lodash/isEmpty';
import isNil from 'lodash/isNil';
import SurveyBanner from 'Feedback/components/SurveyBanner';
import useHandleSurveyBannerExit from 'Feedback/hooks/useHandleSurveyBannerExit';
import CommunityRoundBannerAnnouncement from 'CommunityRound/NewsfeedBanner';
import useHandleCommunityRoundExitPress from 'CommunityRound/NewsfeedBanner/hooks/useHandleCommunityRoundExitPress';
import RenderIf from 'shared/components/RenderIf';
import useResolveShouldShowVideos from 'Notifications/Newsfeed/hooks/useResolveShouldShowVideos';
import SortedList from 'Notifications/Newsfeed/components/SortedList';
import FakeQuestionInput from 'Notifications/Newsfeed/components/FakeQuestionInput';
import useHandleFakeQuestionInputPress from 'Notifications/Newsfeed/hooks/useHandleFakeQuestionInputPress';
import useResolveShowNewsfeedFakeQuestionInput from 'Notifications/Newsfeed/hooks/useResolveShowNewsfeedFakeQuestionInput';
import useResolveShowNewsfeedQuestions from 'Notifications/Newsfeed/hooks/useResolveShowNewsfeedQuestions'
import { withNavigation } from 'react-navigation';
import { NavigationContextShape } from 'shared/proptypes';
import { REFETCH_NEWSFEED_ITEMS_NAVIGATION_PARAM_NAME } from 'Notifications/constants';
import { QUESTION_PRIORITY_ID_NAVIGATION_PARAM_NAME } from 'QandA/constants';
import Colors from 'constants/Colors';
const Newsfeed = ({
appContext: {
trackEvent,
showMessage,
},
navigation,
}) => {
const [showIntroductionBanner, setShowIntroductionBanner] = useState(false);
const [showSurveyBanner, setShowSurveyBanner] = useState(false);
const [showCommunityRoundBanner, setShowCommunityRoundBanner] = useState(false);
const [hasLoadedInitialReviews, setHasLoadedInitialReviews] = useState(false);
const [paginationNumber, setPaginationNumber] = useState(0);
const [showVideos, setShowVideos] = useState(false);
const [showFakeQuestionInput, setShowFakeQuestionInput] = useState(false);
const [showNewsfeedQuestions, setShowNewsfeedQuestions] = useState(false);
const {
getNewsfeedReviews,
data,
error,
refetch,
fetchMore,
loading,
} = useGetReviewNewsfeedItems();
const reviews = get(data, 'reviewNewfeedList.items', []);
const hasMore = get(data, 'reviewNewfeedList.hasMore', false);
const cursor = get(data, 'reviewNewfeedList.cursor', null);
const videos = get(data, 'video_list.items', [])
const questions = get(data, 'question_list.items', [])
const questionListCursor = get(data, 'question_list.cursor');
const handleIntroductionBannerExit = useHandleIntroductionBannerExit({ setShowIntroductionBanner })
const resolveScreenBannerContent = useResolveScreenBannerContent({
setShowIntroductionBanner,
setShowSurveyBanner,
setShowCommunityRoundBanner,
});
const resolveShowNewsfeedFakeQuestionInput = useResolveShowNewsfeedFakeQuestionInput({ setShowFakeQuestionInput });
const resolveShowNewsfeedQuestions = useResolveShowNewsfeedQuestions({ setShowNewsfeedQuestions });
const handleCommunityRoundExitPress = useHandleCommunityRoundExitPress({ setShowCommunityRoundBanner });
const handleSurveyBannerExit = useHandleSurveyBannerExit({ setShowSurveyBanner })
const handleLoadMoreReviews = useHandleLoadMoreReviews({
fetchMore,
setPaginationNumber,
});
const handleItemContentPress = useHandleItemContentPress();
const setLatestNewsfeedPost = useSetLatestNewsfeedPost({ setClearNotificationBubble: () => {} });
const resolveShouldShowVideos = useResolveShouldShowVideos({ setShowVideos })
const handleFakeQuestionInputPress = useHandleFakeQuestionInputPress();
useEffect(() => {
resolveShouldShowVideos();
}, [
resolveShouldShowVideos,
]);
useEffect(() => {
getNewsfeedReviews();
}, [getNewsfeedReviews]);
useEffect(() => {
if (!isEmpty(reviews)) {
trackEvent('mobile_newsfeed_show');
}
}, [trackEvent, reviews])
useEffect(() => {
if (isEmpty(data) || isNil(data)) return;
setHasLoadedInitialReviews(true);
const latestNewsfeedItemId = get(data, 'reviewNewfeedList.items[0].id');
setLatestNewsfeedPost(latestNewsfeedItemId)
}, [data, setLatestNewsfeedPost]);
useEffect(() => {
resolveShowNewsfeedFakeQuestionInput();
}, [resolveShowNewsfeedFakeQuestionInput])
useEffect(() => {
resolveScreenBannerContent()
}, [resolveScreenBannerContent])
useEffect(() => {
resolveShowNewsfeedQuestions()
}, [resolveShowNewsfeedQuestions]);
useEffect(() => {
if (showNewsfeedQuestions) {
trackEvent('mobile_newsfeed_fake_question_input_view');
}
}, [trackEvent, showNewsfeedQuestions]);
useEffect(() => {
const shouldRefetchItems = navigation.getParam(REFETCH_NEWSFEED_ITEMS_NAVIGATION_PARAM_NAME);
const priorityId = navigation.getParam(QUESTION_PRIORITY_ID_NAVIGATION_PARAM_NAME);
if (shouldRefetchItems) {
refetch({ priorityId });
navigation.setParams({ [REFETCH_NEWSFEED_ITEMS_NAVIGATION_PARAM_NAME]: false });
showMessage({
message: 'Success! Your question has been posted!',
backgroundColor: Colors.brandColor,
color: Colors.white,
duration: 7500,
icon: { icon: 'success', position: 'left' },
});
}
}, [navigation, refetch, showMessage]);
if (loading && !hasLoadedInitialReviews) {
return (
<GhostView
testID="NewsfeedGhostView"
/>
);
}
if (error) {
return (
<ErrorView
testID="NewsfeedErrorView"
refetchButtonTestID="NewsfeedRefetchButton"
refetch={refetch}
/>
)
}
return (
<Container
style={styles.newsFeedContainer}
>
<RenderIf
condition={showIntroductionBanner}
defaultElement={<View style={styles.newsfeedTopPadder} />}
element={
<IntroductionBanner
testID="IntroductionBanner"
exitButtonTestID="IntroductionBannerExitButton"
onExitPress={() => handleIntroductionBannerExit() }
/>
}
/>
<RenderIf
condition={showCommunityRoundBanner}
defaultElement={null}
element={
<CommunityRoundBannerAnnouncement
onExitPress={() => handleCommunityRoundExitPress()}
/>
}
/>
<RenderIf
condition={showSurveyBanner}
defaultElement={null}
element={
<SurveyBanner
onExitPress={() => handleSurveyBannerExit()}
/>
}
/>
<Content
style={styles.newsFeedContent}
contentContainerStyle={styles.newsFeedContentContainer}
>
<RenderIf
condition={showFakeQuestionInput}
defaultElement={null}
element={
<View style={{ marginBottom: 8, marginTop: 12, }}>
<FakeQuestionInput
visible
onFocus={() => handleFakeQuestionInputPress()}
/>
</View>
}
/>
<SortedList
showVideos={showVideos}
reviews={reviews}
videos={videos}
questions={questions}
showQuestions={showNewsfeedQuestions}
handleReviewPress={(review) => handleItemContentPress({ reviewId: review.id, place: review.place })}
/>
<RenderIf
condition={hasMore}
defaultElement={undefined}
element={
<LoadMoreButton
testID="LoadMoreButton"
loading={loading}
onPress={() => handleLoadMoreReviews({
cursor,
questionListCursor,
paginationNumber,
})}
/>
}
/>
<EndOfFeedMessage
showEndOfFeedMessage={!hasMore}
paginationNumber={paginationNumber}
/>
</Content>
</Container>
);
};
Newsfeed.propTypes = {
appContext: AppContextShape.isRequired,
navigation: NavigationContextShape.isRequired,
};
export default withNavigation(withAppContext(Newsfeed));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment