unioil-loyalty-rn-app/app/screens/main/home.js

474 lines
16 KiB
JavaScript

import * as React from 'react';
import { SafeAreaView, View, Text, ScrollView, RefreshControl, Platform, AppState } from 'react-native';
import { BackHandler, ToastAndroid } from 'react-native';
import { connect } from "react-redux";
import { saveUserInfo } from "../../redux/actions/AppUserInfoActions";
import { saveWhatshot, savePromos, saveGuestWhatshot, saveGuestPromos } from "../../redux/actions/AppWhatshotAndPromosActions";
import NetInfo from "../../components/netstatus"
import CustomHeader from '../../components/header.js';
import EmptyHeader from '../../components/header/empty';
import GuestHeader from '../../components/header/guest';
import Theme from '../../components/theme.style.js';
import Elements from '../../components/elements.js';
import REQUEST from '../../components/api/';
import DB from '../../components/storage/';
import RNLocation from 'react-native-location';
import messaging from '@react-native-firebase/messaging';
import { SliderBox } from "react-native-image-slider-box";
import CustomSafeArea from '../../components/safeArea.component';
var PushNotification = require("react-native-push-notification");
class Home extends React.PureComponent {
constructor(props) {
super(props)
this.navigate = (screen, params) => { props.navigation.navigate(screen, params) }
this.displayBanner = false
}
state = {
loading: true,
refresh: false,
connected: false,
infodialog: true,
promogps: [],
showpromogps: false,
promogpsindex: 0,
_carousel: "",
promos: (this.props.whats_hot != undefined && this.props.whats_hot.length > 0) ? this.props.whats_hot : [],
whatsHot: (this.props.promos != undefined && this.props.promos.length > 0) ? this.props.promos : [],
activeSlide: 0,
session: null,
userProfile: {},
notifications: [],
notificationindex: 0,
isGuest: false,
coordinates: undefined,
appState: AppState.currentState
}
componentDidMount() {
AppState.addEventListener('change', this._handleAppStateChange)
this.initLocationConfiguration()
this.init()
}
componentWillUnmount() {
AppState.removeEventListener('change', this._handleAppStateChange)
}
_handleAppStateChange = (nextAppState) => {
if (this.state.appState.match(/inactive|background/) && nextAppState === 'active') {
// this.getPromoDiscountNotifications()
}
this.setState({ appState: nextAppState })
}
initLocationConfiguration = () => {
RNLocation.configure({
// iOS Only
activityType: "other",
allowsBackgroundLocationUpdates: false,
headingFilter: 1, // Degrees
headingOrientation: "portrait",
pausesLocationUpdatesAutomatically: false,
showsBackgroundLocationIndicator: false,
})
RNLocation.requestPermission({
ios: "whenInUse", // or 'always'
android: {
detail: "coarse"
}
}).then(granted => {
if(granted) {
this.locationUpdate()
}
})
}
locationUpdate = () => {
RNLocation.getLatestLocation({ timeout: 20000 }).then(latestLocation => {
if(latestLocation != undefined) {
this.setState({ coordinates: { longitude: latestLocation.longitude, latitude: latestLocation.latitude } })
}
})
}
registerToken = async () => {
NetInfo.netstatus(async isConnected => {
if(isConnected) {
const USERPROFILE = await DB.profile()
const fcmToken = await DB.get('fcmToken')
const isTokenRegister = await DB.get('is_token_register')
if(fcmToken == undefined || fcmToken == null) return
if(isTokenRegister == 'true') return;
REQUEST("fcm_register", "post", {}, {}, {
token: fcmToken,
c_number: USERPROFILE.data.card_number
}, function(res){
console.log(res)
let isRegister = res.newFcmToken.c_number != undefined && res.newFcmToken.token != undefined ? 'true' : 'false'
DB.set('is_token_register', isRegister, onSuccess => {}, onError => {})
}, function(error){
DB.set('is_token_register', 'false', onSuccess => {}, onError => {})
console.log(error)
})
}
})
}
init = () => {
NetInfo.netstatus(async isConnected => {
if(isConnected) {
this.registerToken()
const isGuest = await DB.get('is_guest')
if(isGuest == 'true') {
this.loadIsGuest()
return
}
if(this.state.refresh) {
this.loadMainDetails()
this.setState({ refresh: false })
} else {
if(this.props.userinfo == undefined && this.props.userinfo == null) {
this.loadUserProfile()
} else {
this.setState({ userProfile: this.props.userinfo })
}
if(this.props.whats_hot == undefined && this.props.promos == undefined) {
this.loadMainDetails()
} else {
this.setState({ whatsHot: this.props.whats_hot, promos: this.props.promos, loading: false })
}
}
this.loadNotifications()
} else {
this.setState({ loading: false })
Elements.nointernet2(this.props)
}
})
this.initNotifications()
}
initNotifications = () => {
this.unsubscribe = messaging().onMessage(async remoteMessage => {
setTimeout(async () => {
if(Platform.OS == 'ios'){
let allnotifs = await DB.get("notifications")
let notifs = allnotifs ? JSON.parse(allnotifs) : notifications
this.setState({ notifications: notifs, notificationindex: 0 })
console.log("A new notification has recieved on home page", notifications, allnotifs)
}else{
let allnotifs = await DB.get("notifications")
let notifs = allnotifs ? JSON.parse(allnotifs) : notifications
this.setState({ notifications: notifs, notificationindex: 0 })
console.log("A new notification has recieved on home page", notifications)
}
}, 300);
})
}
loadUserProfile = async () => {
const SESSION = await DB.session()
this.props.saveUserInfo({ token: SESSION.token, card_number: SESSION.user.card_number }).then(res => {
this.setState({ userProfile: res })
DB.updateProfile(res, function(){}, function(error){})
})
}
loadGetCurrentLocationPromo = (SESSION, successCallback, errorCallback) => {
if(this.state.coordinates == undefined) return
const { longitude, latitude } = this.state.coordinates
REQUEST("promo_gps", "post", {
Authorization: SESSION.token
}, {}, {
lcard_uuid: SESSION.user.lcard_uuid,
longitude: longitude,
latitude: latitude
}, function(res){
successCallback(res.data)
}, function(error){
errorCallback(error)
})
}
loadMainDetails = async () => {
const SESSION = await DB.session()
const USERPROFILE = await DB.profile()
try{
this.props.saveWhatshot({ token: SESSION.token, lcard_uuid: `lcard_uuid=${SESSION.user.lcard_uuid}` }).then(res => {
this.setState({ whatsHot: res })
})
.catch(error => {})
this.props.savePromos({ token: SESSION.token, lcard_uuid: `lcard_uuid=${SESSION.user.lcard_uuid}` }).then(res => {
this.setState({ promos: res })
})
.catch(error => {})
this.setState({ session: SESSION, userProfile: USERPROFILE, loading: false })
} catch(error) {
this.setState({ loading: false })
}
}
loadIsGuest = async () => {
this.setState({ isGuest: true, loading: false })
this.props.saveGuestWhatshot().then(res => {
this.setState({ whatsHot: res })
})
.catch(error => {})
this.props.saveGuestPromos().then(res => {
this.setState({ promos: res })
})
.catch(error => {})
this.setState({ userProfile: {} })
}
onBackPress = () => {
let listener = setInterval(() => {
backPressDuration += 1
if(backPressDuration >= 15){
backPressCount = 0
backPressDuration = 0
clearInterval(listener)
}
}, 100)
backPressCount += 1
console.log("Back Press Count", backPressCount, typeof backPressCount)
if(backPressCount == 2){
backPressCount = 0
backPressDuration = 0
BackHandler.exitApp()
return false
}else{
ToastAndroid.show("Press back again to exit.", ToastAndroid.SHORT)
return true
}
}
softLoad = async () => {
NetInfo.netstatus(async isConnected => {
if(isConnected){
this.setState({ loading: true })
if(this.state.isGuest == 'true'){
this.loadIsGuest()
return
}
const SESSION = await DB.session()
this.props.saveUserInfo({ token: SESSION.token, card_number: SESSION.user.card_number }).then(res => {
this.setState({ userProfile: res, loading: false })
DB.updateProfile(res, function(){}, function(error){})
})
.catch(error => {})
}else{
this.setState({ loading: false })
Elements.nointernet2(this.props)
}
})
}
loadNotifications = async () => {
if(!this.displayBanner) {
const SESSION = await DB.session()
this.loadGetCurrentLocationPromo(SESSION, success => {
this.setState({ promogps: success, showpromogps: true, promogpsindex: 0 })
this.displayBanner = true
}, error => {
console.log(error)
this.setState({ showpromogps: false })
this.displayBanner = false
})
}
}
getNotifications = async () => {
let allnotifs = await DB.get("notifications")
let notifs = allnotifs ? JSON.parse(allnotifs) : this.state.notifications
this.setState({ notifications: notifs })
}
getPromoDiscountNotifications = async () => {
const USERPROFILE = await DB.profile()
const fcmToken = await DB.get('fcmToken')
this.setState({ notifications: [], notificationindex: 0 })
REQUEST("account_fcm", "get",
{}, {
noID: true,
value: `${USERPROFILE.data.card_number}/${fcmToken}`
}, {},
async (res) => {
let notifications = JSON.parse(res.notifs)
if(notifications.length > 0) {
let newNotifications = notifications.map((notif,index) => {
notif.visible = true
return notif
})
let jsonNotifs = JSON.stringify(newNotifications)
await DB.set('notifications', jsonNotifs, onSuccess => console.log(onSuccess), onError => console.log(onError))
}
this.setState({ notifications: notifications, notificationindex: 0 })
}, function(error){
console.log(error)
})
}
clearNotificationPromotionBanner = async (notificationID, lastFcmToken) => {
const USERPROFILE = await DB.profile()
REQUEST("account_fcm", "put",
{}, {}, {
notif_id: notificationID,
c_number: USERPROFILE.data.card_number,
token: lastFcmToken
},
function(res){
console.log(res)
}, function(error){
console.log(error)
})
}
renderPromos() {
return this.state.promos.map((promo, index) => {
return (
<Elements.card
key={index}
disabled={0}
title={promo.title || 'Unioil'}
onPress={() => {
this.navigate('PromoDetails', {data: promo, type: "promo", onBackPress: this.softLoad});
}}
image={{uri: promo.image}} />)
})
}
renderPromoGPS() {
if(!this.state.promogps || this.state.promogps.length == 0) return null
return this.state.promogps.map((promo, i) => {
return <Elements.promoGPS
key={i}
visible={this.state.showpromogps}
title={promo.title}
image={{uri: promo.image}}
onDismiss={() => {
this.setState({ promogpsindex: this.state.promogpsindex + 1, showpromogps: false })
// this.getNotifications()
}}
onOpen={() => {
this.setState({ showpromogps: false })
this.navigate('PromoDetails', {data: promo, type: "promogps", onBackPress: this.softLoad});
}}
/>
})
}
updateNotifications = async (index) => {
let nfcopy = this.state.notifications
nfcopy[index].visible = false
this.setState({ notifications: nfcopy, notificationindex: this.state.notificationindex + 1 })
await DB.set("notifications", JSON.stringify(nfcopy), (res) => console.log(res), (e) => console.log(e))
const fcmToken = await DB.get('fcmToken')
this.clearNotificationPromotionBanner(nfcopy[index].id, fcmToken)
}
renderNotifications() {
if(!this.state.notifications || this.state.notifications.length == 0) return null
return this.state.notifications.map((notif, index) => this.state.notificationindex === index &&
<Elements.notification
key={index}
visible={notif.visible}
title={notif.subject}
message={notif.content}
onClose={async () => {
this.updateNotifications(index)
}}
onDismiss={async () => {
this.updateNotifications(index)
}}
/>
)
}
render() {
return (
<View style={{flex: 1, height: '100%'}}>
<CustomSafeArea>
{this.renderNotifications()}
<Elements.loader visible={this.state.loading} />
{this.state.isGuest ? <GuestHeader
navigation={this.props.navigation}
reload={this.loadIsGuest}
/> : null}
{this.state.loading && !this.state.isGuest ? <EmptyHeader
navigation={this.props.navigation}
reload={this.softLoad}
/> : !this.state.isGuest ?
<CustomHeader
title=""
banner={true}
menu={true}
renderIQAir={true}
navigation={this.props.navigation}
reload={this.softLoad}
/> : null }
<ScrollView
showsHorizontalScrollIndicator={false}
showsVerticalScrollIndicator={false}
contentContainerStyle={{
flexGrow: 1,
padding: 15
}}
refreshControl={
<RefreshControl refreshing={this.state.loading} onRefresh={() => {
this.setState({ refresh: true })
this.init()
}} />
}>
{this.state.whatsHot.length > 0 && (<Text style={{color: 'gray', fontFamily: 'Arial', fontWeight: 'bold', marginBottom: 0}}>WHAT'S HOT?</Text>)}
<View style={{width: '100%', height: Theme.screen.h / 3.29, padding: 20, paddingHorizontal: 15, justifyContent: 'center', alignItems: 'center'}}>
<SliderBox
images={this.state.whatsHot}
autoplay={true}
circleLoop={true}
resizeMode={"stretch"}
dotColor={Theme.colors.primary}
inactiveDotColor={Theme.colors.gray}
paginationBoxVerticalPadding={0}
paginationBoxStyle={{bottom: -(Theme.screen.h * .04)}}
parentWidth={Theme.screen.w - 40}
ImageComponentStyle={{borderRadius: 10}}
/>
</View>
{this.state.promos.length > 0 && (<Text style={{color: 'gray', fontFamily: 'Arial', fontWeight: 'bold', marginBottom: 0, marginTop: 10}}>PROMOS</Text>)}
<View style={{flex: 1, flexDirection: 'row', flexWrap: 'wrap', width: '100%', padding: 0, marginTop: 15, marginBottom: 15, justifyContent: 'center'}}>
{this.renderPromos()}
</View>
{this.renderPromoGPS()}
</ScrollView>
</CustomSafeArea>
</View>
)
}
}
const mapStateToProps = (state) => {
return {
userinfo: state.appUserInfoReducer.userinfo,
token: state.appUserInfoReducer.token,
whats_hot: state.appWhatshotAndPromosReducer.whats_hot,
promos: state.appWhatshotAndPromosReducer.promos
}
}
const mapDispatchToProps = {
saveWhatshot,
savePromos,
saveGuestWhatshot,
saveGuestPromos,
saveUserInfo
}
export default connect(mapStateToProps, mapDispatchToProps)(Home)