Created
July 24, 2019 14:49
-
-
Save ldco2016/04003e9ee3144257b60df712464b9c42 to your computer and use it in GitHub Desktop.
ActivityFeed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React, { PureComponent } from "react"; | |
import { | |
FlatList, | |
StyleSheet, | |
AppState, | |
Platform, | |
Dimensions, | |
View, | |
Alert | |
} from "react-native"; | |
import PropTypes from "prop-types"; | |
import OneSignal from "react-native-onesignal"; | |
import { Loading, SwippableCard, BottomAlert } from "common-components"; | |
import EmptyState from "activity-feed/session-user/components/EmptyState"; | |
import EventFeedCard from "events/components/EventFeedCard"; | |
import SurveyBallotFeedCard from "surveys-ballots/components/FeedCard"; | |
import MicroSurvey from "surveys-ballots/components/MicroSurvey"; | |
import ActionAlertFeedCard from "action-alerts/components/ActionAlertFeedCard"; | |
import MissingAddressCard from "action-alerts/components/MissingAddressCard"; | |
import ArticleFeedCard from "articles/components/ArticleFeedCard"; | |
import GetInvolvedFeedCard from "account-settings/components/GetInvolvedFeedCard"; | |
import { connect } from "react-redux"; | |
import { | |
fetchFeed, | |
handleContentSwipe, | |
undoSwipeAction, | |
hideUndoAlert | |
} from "activity-feed/actions"; | |
import { setSelectedEvent } from "events/actions"; | |
import { setSelectedSurvey } from "surveys-ballots/actions"; | |
import { setSelectedAlert, getCampaignDetails } from "action-alerts/actions"; | |
import * as cache from "utils/cache"; | |
import { setSelectedArticle } from "articles/actions"; | |
import { | |
handleUpdateTopics, | |
handleUpdateGetInvoved | |
} from "account-settings/preferencesActions"; | |
import { scale } from "react-native-size-matters"; | |
import { emptyStateStyles } from "theme"; | |
const { height } = Dimensions.get("window"); | |
export class ActivityFeed extends PureComponent { | |
static propTypes = { | |
displayAlert: PropTypes.bool, | |
feed: PropTypes.array, | |
fetchFeed: PropTypes.func, | |
getCampaignDetails: PropTypes.func, | |
handleContentSwipe: PropTypes.func, | |
handleUpdateGetInvoved: PropTypes.func, | |
handleUpdateTopics: PropTypes.func, | |
hideUndoAlert: PropTypes.func, | |
lastSwippedElement: PropTypes.object, | |
loading: PropTypes.bool, | |
navigation: PropTypes.object, | |
setSelectedAlert: PropTypes.func, | |
setSelectedArticle: PropTypes.func, | |
setSelectedEvent: PropTypes.func, | |
setSelectedSurvey: PropTypes.func.isRequired, | |
undoSwipeAction: PropTypes.func, | |
userEmailIsValidForVoterVoice: PropTypes.bool | |
}; | |
constructor(props) { | |
super(props); | |
this.prompted = false; | |
this.state = { | |
refreshing: false, | |
appState: AppState.currentState | |
}; | |
} | |
async componentDidMount() { | |
AppState.addEventListener("change", this._handleAppStateChange); | |
if (!this.props.loading) { | |
const doRefresh = await cache.shouldRefresh("feed"); | |
if (this.props.feed.length === 0 || doRefresh) { | |
this.props.fetchFeed(); | |
} | |
cache.incrementAppViews(); | |
} | |
} | |
componentWillUnmount() { | |
AppState.removeEventListener("change", this._handleAppStateChange); | |
} | |
_handleAppStateChange = async appState => { | |
if ( | |
this.state.appState.match(/inactive|background/) && | |
appState === "active" | |
) { | |
cache.incrementAppViews(); | |
const doRefresh = await cache.shouldRefresh("feed"); | |
if (doRefresh) { | |
this.props.fetchFeed(); | |
} | |
} | |
this.setState({ appState }); | |
}; | |
_keyExtractor = ({ Entity }) => | |
(Entity.Key || Entity.Id || Entity.CampaignId || Entity.Code).toString(); | |
_gotoEvent = event => { | |
cache.setRouteStarter("MainDrawer"); | |
this.props.setSelectedEvent(event); | |
const title = `${event.LegislatureType} Event`; | |
this.props.navigation.navigate("EventDetails", { title }); | |
}; | |
_gotoSurveyBallot = survey => { | |
cache.setRouteStarter("MainDrawer"); | |
this.props.setSelectedSurvey(survey); | |
this.props.navigation.navigate("SurveyDetails"); | |
}; | |
_gotoArticle = article => { | |
cache.setRouteStarter("MainDrawer"); | |
this.props.setSelectedArticle(article); | |
this.props.navigation.navigate("ArticleDetails"); | |
}; | |
_onAlertActionButtonPress = async item => { | |
cache.setRouteStarter("MainDrawer"); | |
await this.props.setSelectedAlert(item.Entity); | |
this.props.getCampaignDetails(); | |
if (this.props.userEmailIsValidForVoterVoice) { | |
this.props.navigation.navigate("Questionnaire"); | |
} else { | |
this.props.navigation.navigate("UnconfirmedEmail"); | |
} | |
}; | |
_onSwipedOut = (swippedItem, index) => { | |
this.props.handleContentSwipe(this.props, { swippedItem, index }); | |
}; | |
_handleGetInvolved = (response, entity) => { | |
if (response !== entity.IsSelected) { | |
const isTopic = entity.Category !== "GetInvolved"; | |
const items = [ | |
{ | |
...entity, | |
IsSelected: response | |
} | |
]; | |
if (isTopic) { | |
this.props.handleUpdateTopics({ topics: items }); | |
} else { | |
this.props.handleUpdateGetInvoved({ involved: items }); | |
} | |
} | |
}; | |
renderItem = ({ item, index }) => { | |
const { Type, Entity } = item; | |
if (Type === "EVENT") { | |
return ( | |
<SwippableCard onSwipedOut={() => this._onSwipedOut(item, index)}> | |
<EventFeedCard | |
style={styles.push} | |
mainActionButtonPress={() => this._gotoEvent(Entity)} | |
event={Entity} | |
/> | |
</SwippableCard> | |
); | |
} | |
if (["SURVEY_SURVEY", "SURVEY_BALLOT"].includes(Type)) { | |
return ( | |
<SwippableCard onSwipedOut={() => this._onSwipedOut(item, index)}> | |
<SurveyBallotFeedCard | |
style={styles.push} | |
survey={Entity} | |
handleViewDetails={() => this._gotoSurveyBallot(Entity)} | |
/> | |
</SwippableCard> | |
); | |
} | |
if (Type === "SURVEY_MICRO") { | |
return ( | |
<SwippableCard onSwipedOut={() => this._onSwipedOut(item, index)}> | |
<MicroSurvey style={styles.push} selectedSurvey={Entity} /> | |
</SwippableCard> | |
); | |
} | |
if (Type === "ALERT") { | |
return ( | |
<SwippableCard onSwipedOut={() => this._onSwipedOut(item, index)}> | |
<ActionAlertFeedCard | |
datePosted={Entity.StartDateUtc} | |
style={styles.push} | |
title={Entity.Headline} | |
content={Entity.Alert} | |
mainActionButtonPress={() => this._onAlertActionButtonPress(item)} | |
secondaryActionButtonPress={() => { | |
this.props.setSelectedAlert(Entity); | |
// eslint-disable-next-line | |
this.props.navigation.navigate("ActionAlertDetails", { | |
content: Entity.Alert, | |
id: Entity.CampaignId, | |
title: Entity.Headline | |
}); | |
}} | |
/> | |
</SwippableCard> | |
); | |
} | |
if (Type === "ARTICLE") { | |
return ( | |
<SwippableCard onSwipedOut={() => this._onSwipedOut(item, index)}> | |
<ArticleFeedCard | |
content={Entity} | |
style={styles.push} | |
mainActionButtonPress={() => this._gotoArticle(Entity)} | |
/> | |
</SwippableCard> | |
); | |
} | |
//prettier-ignore | |
if (Type === 'NOTIFICATION' && Entity.Code === 'INDIVIDUAL_ADDRESS_HOME_MISSING') { | |
return ( | |
<MissingAddressCard | |
style={styles.push} | |
navigate={() => this.props.navigation.navigate('HomeAddress')} | |
/> | |
); | |
} | |
if (["PREFERENCE_TOPIC", "PREFERENCE_INVOLVEMENT"].includes(Type)) { | |
return ( | |
<SwippableCard onSwipedOut={() => this._onSwipedOut(item, index)}> | |
<GetInvolvedFeedCard | |
style={styles.push} | |
title={Entity.DisplayText} | |
onPress={response => this._handleGetInvolved(response, Entity)} | |
/> | |
</SwippableCard> | |
); | |
} | |
return null; | |
}; | |
_onRefresh = async () => { | |
try { | |
this.setState({ refreshing: true }); | |
this.props | |
.fetchFeed() | |
.then(() => { | |
this.setState({ refreshing: false }); | |
}) | |
.catch(() => { | |
this.setState({ refreshing: false }); | |
}); | |
} catch (e) { | |
this.setState({ refreshing: false }); | |
} | |
}; | |
_trackScroll = async event => { | |
try { | |
if (this.prompted) { | |
return; | |
} | |
const y = event.nativeEvent.contentOffset.y; | |
const scrollHeight = height * 0.8; | |
const page = Math.round(Math.floor(y) / scrollHeight); | |
const alert = await cache.shouldPromtpPushNotificationPermissions(); | |
const iOS = Platform.OS === "ios"; | |
if (alert && iOS && page > 1) { | |
this.prompted = true; | |
this._openPromptAlert(); | |
} | |
} catch (e) { | |
return false; | |
} | |
}; | |
_openPromptAlert = () => { | |
Alert.alert( | |
"Push Notifications Access", | |
"Stay engaged with NFIB on the issues and activities you care about by allowing us to notify you using push notifications", | |
[ | |
{ | |
text: "Deny", | |
onPress: () => { | |
cache.pushNotificationsPrompted(); | |
}, | |
style: "cancel" | |
}, | |
{ | |
text: "Allow", | |
onPress: () => { | |
OneSignal.registerForPushNotifications(); | |
cache.pushNotificationsPrompted(); | |
} | |
} | |
], | |
{ cancelable: false } | |
); | |
}; | |
_getAlertTitle = () => { | |
const { lastSwippedElement } = this.props; | |
const { Type } = lastSwippedElement.swippedItem; | |
if (Type.startsWith("PREFERENCE")) { | |
return "Preference Dismissed"; | |
} | |
switch (Type) { | |
case "EVENT": | |
return "Event Dismissed"; | |
case "SURVEY_BALLOT": | |
return "Ballot Dismissed"; | |
case "SURVEY_SURVEY": | |
return "Survey Dismissed"; | |
case "SURVEY_MICRO": | |
return "Micro Survey Dismissed"; | |
case "ARTICLE": | |
return "Article Dismissed"; | |
case "ALERT": | |
return "Action Alert Dismissed"; | |
default: | |
return "Dismissed"; | |
} | |
}; | |
render() { | |
if (this.props.loading && !this.state.refreshing) { | |
return <Loading />; | |
} | |
const contentStyles = | |
this.props.feed.length > 0 ? styles.content : emptyStateStyles.container; | |
return ( | |
<View style={styles.container}> | |
<FlatList | |
contentContainerStyle={contentStyles} | |
showsVerticalScrollIndicator={false} | |
data={this.props.feed} | |
renderItem={this.renderItem} | |
keyExtractor={this._keyExtractor} | |
removeClippedSubviews={false} | |
onRefresh={this._onRefresh} | |
refreshing={this.state.refreshing} | |
ListEmptyComponent={() => ( | |
<EmptyState navigation={this.props.navigation} /> | |
)} | |
scrollEventThrottle={100} | |
onScroll={this._trackScroll} | |
/> | |
{this.props.displayAlert && ( | |
<BottomAlert | |
title={this._getAlertTitle()} | |
onPress={this.props.undoSwipeAction} | |
hideAlert={this.props.hideUndoAlert} | |
/> | |
)} | |
</View> | |
); | |
} | |
} | |
const styles = StyleSheet.create({ | |
container: { | |
flex: 1 | |
}, | |
content: { | |
paddingHorizontal: scale(8), | |
paddingTop: scale(16), | |
paddingBottom: scale(20) | |
}, | |
push: { | |
marginBottom: 16 | |
} | |
}); | |
const mapState2Props = ({ | |
activityFeed, | |
auth: { userEmailIsValidForVoterVoice }, | |
navigation | |
}) => { | |
return { | |
...activityFeed, | |
userEmailIsValidForVoterVoice, | |
loading: activityFeed.loading || navigation.deepLinkLoading | |
}; | |
}; | |
export default connect( | |
mapState2Props, | |
{ | |
fetchFeed, | |
getCampaignDetails, | |
handleUpdateGetInvoved, | |
handleUpdateTopics, | |
setSelectedAlert, | |
setSelectedArticle, | |
setSelectedEvent, | |
setSelectedSurvey, | |
handleContentSwipe, | |
undoSwipeAction, | |
hideUndoAlert | |
} | |
)(ActivityFeed); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment