From 624617158f9f267a296c22743f70a8457525b2a3 Mon Sep 17 00:00:00 2001 From: Mochamad Gufron Date: Mon, 16 Oct 2017 18:27:47 +0700 Subject: [PATCH 1/6] update pods and deps --- ios/Podfile.lock | 46 +++++++++++++++++++++++----------------------- package.json | 3 ++- yarn.lock | 12 ++++++++++-- 3 files changed, 35 insertions(+), 26 deletions(-) diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 0de84b84..d800a0c9 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -1,31 +1,31 @@ PODS: - - Crashlytics (3.8.6): - - Fabric (~> 1.6.3) + - Crashlytics (3.9.0): + - Fabric (~> 1.7.0) - DCTAuth (3.0) - - Fabric (1.6.13) - - Firebase/Core (4.2.0): - - FirebaseAnalytics (= 4.0.3) - - FirebaseCore (= 4.0.7) - - FirebaseAnalytics (4.0.3): + - Fabric (1.7.0) + - Firebase/Core (4.3.0): + - FirebaseAnalytics (= 4.0.4) + - FirebaseCore (= 4.0.8) + - FirebaseAnalytics (4.0.4): - FirebaseCore (~> 4.0) - FirebaseInstanceID (~> 2.0) - GoogleToolboxForMac/NSData+zlib (~> 2.1) - nanopb (~> 0.3) - - FirebaseCore (4.0.7): + - FirebaseCore (4.0.8): - GoogleToolboxForMac/NSData+zlib (~> 2.1) - nanopb (~> 0.3) - - FirebaseInstanceID (2.0.3) - - FirebaseMessaging (2.0.3): + - FirebaseInstanceID (2.0.4) + - FirebaseMessaging (2.0.4): - FirebaseAnalytics (~> 4.0) - FirebaseCore (~> 4.0) - FirebaseInstanceID (~> 2.0) - GoogleToolboxForMac/Logger (~> 2.1) - Protobuf (~> 3.1) - - GoogleToolboxForMac/Defines (2.1.1) - - GoogleToolboxForMac/Logger (2.1.1): - - GoogleToolboxForMac/Defines (= 2.1.1) - - GoogleToolboxForMac/NSData+zlib (2.1.1): - - GoogleToolboxForMac/Defines (= 2.1.1) + - GoogleToolboxForMac/Defines (2.1.3) + - GoogleToolboxForMac/Logger (2.1.3): + - GoogleToolboxForMac/Defines (= 2.1.3) + - GoogleToolboxForMac/NSData+zlib (2.1.3): + - GoogleToolboxForMac/Defines (= 2.1.3) - nanopb (0.3.8): - nanopb/decode (= 0.3.8) - nanopb/encode (= 0.3.8) @@ -50,15 +50,15 @@ CHECKOUT OPTIONS: :git: https://github.com/danielctull/DCTAuth.git SPEC CHECKSUMS: - Crashlytics: 95d05f4e4c19a771250c4bd9ce344d996de32bbf + Crashlytics: 64aad5dd97249dd3ff94b979fea140144590cdd3 DCTAuth: 8add154decd00335d62917828896bba790ce47fd - Fabric: 2fb5676bc811af011a04513451f463dac6803206 - Firebase: 9548cae14d69718add12d75a5b312893f7ef89c7 - FirebaseAnalytics: 76f754d37ca5b04f36856729b6af3ca0152d1069 - FirebaseCore: 9a6cc1e3eaf75905390f9220596ad4fd8f92faee - FirebaseInstanceID: a4fc702b5a026f7322964376047f1a3f1f7cc6ff - FirebaseMessaging: eaf1bfff0193170c04ea3ba3bfe983f68f893118 - GoogleToolboxForMac: 8e329f1b599f2512c6b10676d45736bcc2cbbeb0 + Fabric: e6be012366472553807dada21243c5ab8d904151 + Firebase: 83283761a1ef6dc9846e03d08059f51421afbd65 + FirebaseAnalytics: 722b53c7b32bfc7806b06e0093a2f5180d4f2c5a + FirebaseCore: 69b1a5ac5f857ba6d5fd9d5fe794f4786dd5e579 + FirebaseInstanceID: 70c2b877e9338971b2429ea5a4293df6961aa44e + FirebaseMessaging: 3dd86bfda2acb680b05c97f3f8ac566e9bb87b2a + GoogleToolboxForMac: 2501e2ad72a52eb3dfe7bd9aee7dad11b858bd20 nanopb: 5601e6bca2dbf1ed831b519092ec110f66982ca3 Protobuf: 03eef2ee0b674770735cf79d9c4d3659cf6908e8 diff --git a/package.json b/package.json index e3b623db..82ea247f 100644 --- a/package.json +++ b/package.json @@ -33,8 +33,8 @@ "react-native-oauth": "^2.2.0", "react-native-paypal": "git+https://github.com/refactory-id/react-native-paypal#master", "react-native-photo-grid": "0.0.2", - "react-native-qrcode": "^0.2.6", "react-native-progress": "^3.4.0", + "react-native-qrcode": "^0.2.6", "react-native-router-flux": "^4.0.0-beta.15", "react-native-share": "^1.0.21", "react-native-simple-auth": "^2.1.0", @@ -46,6 +46,7 @@ "redux": "^3.7.2", "redux-immutable": "^4.0.0", "redux-logger": "^3.0.6", + "redux-persist": "^4.10.1", "redux-thunk": "^2.2.0", "reselect": "^3.0.1", "socket.io-client": "^1.4.8" diff --git a/yarn.lock b/yarn.lock index 19c212f2..981684f9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3145,7 +3145,7 @@ json-stable-stringify@^1.0.1: dependencies: jsonify "~0.0.0" -json-stringify-safe@~5.0.1: +json-stringify-safe@^5.0.1, json-stringify-safe@~5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" @@ -3259,7 +3259,7 @@ locate-path@^2.0.0: p-locate "^2.0.0" path-exists "^3.0.0" -lodash-es@^4.2.0, lodash-es@^4.2.1: +lodash-es@^4.17.4, lodash-es@^4.2.0, lodash-es@^4.2.1: version "4.17.4" resolved "https://registry.yarnpkg.com/lodash-es/-/lodash-es-4.17.4.tgz#dcc1d7552e150a0640073ba9cb31d70f032950e7" @@ -4622,6 +4622,14 @@ redux-logger@^3.0.6: dependencies: deep-diff "^0.3.5" +redux-persist@^4.10.1: + version "4.10.1" + resolved "https://registry.yarnpkg.com/redux-persist/-/redux-persist-4.10.1.tgz#4fb2b789942f10f56d51cc7ad068d9d6beb46124" + dependencies: + json-stringify-safe "^5.0.1" + lodash "^4.17.4" + lodash-es "^4.17.4" + redux-thunk@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/redux-thunk/-/redux-thunk-2.2.0.tgz#e615a16e16b47a19a515766133d1e3e99b7852e5" From 4d9ca2ed639488bba1c0572444f833371e78d29a Mon Sep 17 00:00:00 2001 From: Mochamad Gufron Date: Mon, 16 Oct 2017 22:38:04 +0700 Subject: [PATCH 2/6] add splash container --- app/components/Splash/index.js | 8 +------ app/containers/Feed/actions.js | 9 ------- app/containers/Feed/index.js | 1 - app/containers/Main/actions.js | 10 +++++++- app/containers/Main/constants.js | 2 ++ app/containers/Main/reducer.js | 15 ++++++++++-- app/containers/Main/selectors.js | 9 +++++++ app/containers/Splash/index.js | 40 ++++++++++++++++++++++++++++++++ app/index.js | 32 +++++++++++++++++++++---- package.json | 1 + yarn.lock | 24 ++++++++++++++++++- 11 files changed, 126 insertions(+), 25 deletions(-) create mode 100644 app/containers/Splash/index.js diff --git a/app/components/Splash/index.js b/app/components/Splash/index.js index 52244947..23adf14b 100644 --- a/app/components/Splash/index.js +++ b/app/components/Splash/index.js @@ -4,6 +4,7 @@ import { createTransition, Fade } from 'react-native-transition'; import { Actions } from 'react-native-router-flux'; import { getAccessToken } from '../../helpers'; import SplashScreen from './SplashScreen'; +import { createStructuredSelector } from 'reselect'; const Transition = createTransition(Fade); @@ -16,13 +17,6 @@ export default class Splash extends Component { } componentDidMount() { - getAccessToken().then((accessToken) => { - if (accessToken) { - Actions.mainTabs(); - } else { - Actions.main(); - } - }); } render() { diff --git a/app/containers/Feed/actions.js b/app/containers/Feed/actions.js index aa764bb6..73963be3 100644 --- a/app/containers/Feed/actions.js +++ b/app/containers/Feed/actions.js @@ -56,15 +56,6 @@ export function isFetchingMoreFeeds(status) { }; } -export function setTokenHeader(currentpage) { - return (dispatch) => { - getAccessToken().then((accessToken) => { - Api.setAuthorizationToken(accessToken); - dispatch(fetchFeeds(currentpage)); - }); - }; -} - export function fetchFeeds(currentpage) { return (dispatch) => { dispatch(isFetchingFeeds(true)); diff --git a/app/containers/Feed/index.js b/app/containers/Feed/index.js index a401b929..7bf41d8b 100644 --- a/app/containers/Feed/index.js +++ b/app/containers/Feed/index.js @@ -170,7 +170,6 @@ class Feed extends Component { } componentWillMount() { - this.props.setTokenHeader(this.props.currentPage); AsyncStorage.getItem('profile_data').then((profile) => { const data = JSON.parse(profile); diff --git a/app/containers/Main/actions.js b/app/containers/Main/actions.js index 61a92c04..e543db0d 100644 --- a/app/containers/Main/actions.js +++ b/app/containers/Main/actions.js @@ -23,7 +23,8 @@ import { GOOGLE_CLIENT_SECRET, TWITTER_CALLBACK, TWITTER_CONSUMER_KEY, - TWITTER_CONSUMER_KEY_SECRET + TWITTER_CONSUMER_KEY_SECRET, + SET_TOKEN } from './constants'; /* @@ -423,3 +424,10 @@ export function subscribeNewsletter() { }); }; } + +export function setToken(token) { + return { + type: SET_TOKEN, + token + } +} diff --git a/app/containers/Main/constants.js b/app/containers/Main/constants.js index ec256cef..151bfe83 100644 --- a/app/containers/Main/constants.js +++ b/app/containers/Main/constants.js @@ -15,3 +15,5 @@ export const UPDATE_SINGLE_FIELD = 'app/containers/Main/UPDATE_FIELD'; export const UPDATE_IS_LOGGED_IN = 'app/containers/Main/CHECK_IS_LOGGED_IN'; export const UPDATE_IS_SUBSCRIBED = 'app/containers/Main/UPDATE_IS_SUBSCRIBED'; export const UPDATE_IS_LOADING = 'app/containers/Main/UPDATE_IS_LOADING'; + +export const SET_TOKEN = 'app/containers/Main/SET_TOKEN'; diff --git a/app/containers/Main/reducer.js b/app/containers/Main/reducer.js index 8920462b..0604ee84 100644 --- a/app/containers/Main/reducer.js +++ b/app/containers/Main/reducer.js @@ -10,7 +10,8 @@ import { UPDATE_IS_SUBSCRIBED, UPDATE_IS_NOT_REGISTERED, UPDATE_IS_LOADING, - FETCH_PROFILE_DATA + FETCH_PROFILE_DATA, + SET_TOKEN } from './constants'; /* @@ -24,7 +25,11 @@ const initialState = fromJS({ }, isLoading: false, isLoggedIn: false, - isSubscribed: false + isSubscribed: false, + accessToken: '', + refreshToken: '', + roleId: '', + profileData: '', }); function mainReducer(state = initialState, action) { @@ -37,6 +42,12 @@ function mainReducer(state = initialState, action) { return state.setIn([ 'fields', action.field ], action.value); case UPDATE_IS_LOADING: return state.set('isLoading', action.status); + case SET_TOKEN: + const token = action.token; + return state.set('accessToken', token.accessToken) + .set('refreshToken', token.refreshToken) + .set('roleId', token.roleId) + .set('profileData', token.profileData) default: return state; } diff --git a/app/containers/Main/selectors.js b/app/containers/Main/selectors.js index eefea1a6..43b91767 100644 --- a/app/containers/Main/selectors.js +++ b/app/containers/Main/selectors.js @@ -43,3 +43,12 @@ export const getIsLoading = () => createSelector( selectMainReducer(), state => state.get('isLoading') ); + +/** + * Get is loading status + * Returns boolean + */ +export const getAccessToken = () => createSelector( + selectMainReducer(), + state => state.get('accessToken') +); diff --git a/app/containers/Splash/index.js b/app/containers/Splash/index.js new file mode 100644 index 00000000..4e7f4acd --- /dev/null +++ b/app/containers/Splash/index.js @@ -0,0 +1,40 @@ +import React, { Component } from 'react'; + +import { createTransition, Fade } from 'react-native-transition'; +import { Actions } from 'react-native-router-flux'; +import { connect } from 'react-redux'; +import { createStructuredSelector } from 'reselect'; +import { getAccessToken } from '../Main/selectors'; +import SplashScreen from '../../components/Splash/SplashScreen'; +import Api from '../../services/api'; + +const Transition = createTransition(Fade); + +class Splash extends Component { + constructor() { + super(); + this.state = { + isActive: true + }; + } + + componentDidMount() { + if (this.props.accessToken && this.props.accessToken !== '') { + Api.setAuthorizationToken(this.props.accessToken); + Actions.main({ type: 'replace' }); + } else { + Actions.mainTabs({ type: 'replace' }); + } + } + + render() { + return ; + } +} + + +const mapStateToProps = () => createStructuredSelector({ + accessToken: getAccessToken() +}); + +export default connect(mapStateToProps, null)(Splash); diff --git a/app/index.js b/app/index.js index 8220c203..c3bc2318 100644 --- a/app/index.js +++ b/app/index.js @@ -6,7 +6,8 @@ import BusyIndicator from 'react-native-busy-indicator'; // Redux imports import { Provider, connect } from 'react-redux'; -import { createStore, applyMiddleware } from 'redux'; +import { createStore, applyMiddleware, compose } from 'redux'; +import {persistStore, autoRehydrate} from 'redux-persist-immutable'; import ReduxThunk from 'redux-thunk'; import logger from 'redux-logger' import reducers from './reducers'; @@ -22,6 +23,7 @@ import RegisterPhone from './containers/RegisterPhone'; import Schedule from './containers/Schedule'; import ScheduleDetail from './containers/ScheduleDetail'; import Main from './containers/Main'; +import {setToken} from './containers/Main/actions'; import ChangePassword from './containers/ChangePassword'; import OrderList from './containers/OrderList'; import TicketList from './containers/TicketList'; @@ -30,7 +32,7 @@ import MainTabs from './containers/MainTabs'; import SpeakerDetail from './containers/SpeakerDetail'; import NewOrder from './containers/NewOrder'; import AttendeesList from './containers/AttendeesList'; -import Splash from './components/Splash'; +import Splash from './containers/Splash'; import Payment from './containers/Payment'; import PaymentDetail from './containers/PaymentDetail'; import BoothList from './containers/BoothList'; @@ -61,8 +63,30 @@ strings.setLanguage(setlang); /** * Apply middlewares */ -export const createStoreWithMiddleware = applyMiddleware(ReduxThunk)(createStore); -const store = createStoreWithMiddleware(reducers); +const store = createStore( + reducers, + undefined, + compose( + applyMiddleware(ReduxThunk), + autoRehydrate(), + ) +); + +persistStore(store, {storage: AsyncStorage}, () => { + AsyncStorage + .multiGet(['access_token', 'refresh_token', 'role_id', 'profile_data']) + .then(([accessToken, refreshToken, roleId, profileData]) => { + const savedToken = store.getState().getIn(['main', 'accessToken']); + if (!savedToken || savedToken === '') { + store.dispatch(setToken({ + accessToken, + refreshToken, + roleId, + profileData + })) + } + }).catch(err => console.log(err)); +}) export default class App extends Component { constructor(props) { diff --git a/package.json b/package.json index 82ea247f..ba4d1956 100644 --- a/package.json +++ b/package.json @@ -47,6 +47,7 @@ "redux-immutable": "^4.0.0", "redux-logger": "^3.0.6", "redux-persist": "^4.10.1", + "redux-persist-immutable": "^4.3.1", "redux-thunk": "^2.2.0", "reselect": "^3.0.1", "socket.io-client": "^1.4.8" diff --git a/yarn.lock b/yarn.lock index 981684f9..39136684 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4622,7 +4622,21 @@ redux-logger@^3.0.6: dependencies: deep-diff "^0.3.5" -redux-persist@^4.10.1: +redux-persist-immutable@^4.3.1: + version "4.3.1" + resolved "https://registry.yarnpkg.com/redux-persist-immutable/-/redux-persist-immutable-4.3.1.tgz#fcef34a246f1c4ec0ae10ad14a27a614215fd0ee" + dependencies: + redux-persist "^4.0.0" + redux-persist-transform-immutable "^4.1.0" + +redux-persist-transform-immutable@^4.1.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/redux-persist-transform-immutable/-/redux-persist-transform-immutable-4.3.0.tgz#24720c99f0707dd99e920b95f851ae3d1baa6ed8" + dependencies: + transit-immutable-js "^0.7.0" + transit-js "^0.8.846" + +redux-persist@^4.0.0, redux-persist@^4.10.1: version "4.10.1" resolved "https://registry.yarnpkg.com/redux-persist/-/redux-persist-4.10.1.tgz#4fb2b789942f10f56d51cc7ad068d9d6beb46124" dependencies: @@ -5349,6 +5363,14 @@ tr46@~0.0.3: version "0.0.3" resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" +transit-immutable-js@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/transit-immutable-js/-/transit-immutable-js-0.7.0.tgz#993e25089b6311ff402140f556276d6d253005d9" + +transit-js@^0.8.846: + version "0.8.846" + resolved "https://registry.yarnpkg.com/transit-js/-/transit-js-0.8.846.tgz#76e06e8f0e6be27675e3442112f5c9bb75343464" + traverse@0.6.6: version "0.6.6" resolved "https://registry.yarnpkg.com/traverse/-/traverse-0.6.6.tgz#cbdf560fd7b9af632502fed40f918c157ea97137" From 8cef068bedb3a262426533fa20355060a06217f5 Mon Sep 17 00:00:00 2001 From: Mochamad Gufron Date: Mon, 16 Oct 2017 23:28:48 +0700 Subject: [PATCH 3/6] reorder rehydrate --- app/containers/Feed/index.js | 19 ++++++------ app/containers/Main/actions.js | 42 +++++++++++++++------------ app/containers/Main/constants.js | 1 + app/containers/Main/reducer.js | 12 ++++++-- app/containers/Main/selectors.js | 13 +++++++-- app/containers/Settings/actions.js | 2 ++ app/containers/Splash/index.js | 5 ++-- app/index.js | 46 ++++++++++++++++++------------ 8 files changed, 86 insertions(+), 54 deletions(-) diff --git a/app/containers/Feed/index.js b/app/containers/Feed/index.js index 7bf41d8b..579f9569 100644 --- a/app/containers/Feed/index.js +++ b/app/containers/Feed/index.js @@ -50,6 +50,7 @@ import strings from '../../localization'; import HeaderPoint from '../../components/Header'; import * as actions from './actions'; import * as selectors from './selectors'; +import { getProfileData } from '../Main/selectors'; import OrderList from '../OrderList'; import Redeem from '../Redeem'; import { PRIMARYCOLOR } from '../../constants'; @@ -132,7 +133,8 @@ const mapStateToProps = () => imagesData: selectors.getUpdateImage(), textData: selectors.getUpdateText(), currentPage: selectors.getCurrentPage(), - isRemoving: selectors.getIsRemoveFeed() + isRemoving: selectors.getIsRemoveFeed(), + profileData: getProfileData(), }); class Feed extends Component { @@ -170,15 +172,12 @@ class Feed extends Component { } componentWillMount() { - - AsyncStorage.getItem('profile_data').then((profile) => { - const data = JSON.parse(profile); - const firstName = data.first_name; - const lastName = data.last_name; - const url = data.photos[0].url; - const id = data.id; - this.setState({ firstName, lastName, profileUrl: url, userId: id }); - }); + // const data = this.props.profileData; + // const firstName = data.first_name; + // const lastName = data.last_name; + // const url = data.photos[0].url; + // const id = data.id; + // this.setState({ firstName, lastName, profileUrl: url, userId: id }); } setModalVisible = (visible, image) => { diff --git a/app/containers/Main/actions.js b/app/containers/Main/actions.js index e543db0d..291ab2ab 100644 --- a/app/containers/Main/actions.js +++ b/app/containers/Main/actions.js @@ -24,7 +24,8 @@ import { TWITTER_CALLBACK, TWITTER_CONSUMER_KEY, TWITTER_CONSUMER_KEY_SECRET, - SET_TOKEN + SET_TOKEN, + RESET_TOKEN } from './constants'; /* @@ -94,17 +95,18 @@ export function login() { .then(async (response) => { if (response && response.data && response.data.meta.success) { const resData = response.data.data; - const roleId = JSON.stringify(response.data.included.role_id); - const profileData = JSON.stringify(response.data.included); - const boothData = JSON.stringify(response.data.included.booth); + const roleId = response.data.included.role_id; + const profileData = response.data.included; + const boothData = response.data.included.booth; try { if (profileData || boothData) { - await AsyncStorage.multiSet([ - [ 'access_token', resData.access_token ], - [ 'refresh_token', resData.refresh_token ], - [ 'role_id', roleId ], - [ 'profile_data', profileData ] - ]); + dispatch(setToken({ + accessToken: resData.access_token, + refreshToken: resData.refresh_token, + roleId, + profileData, + boothData + })) } } catch (error) { console.log(error, 'error caught'); @@ -226,15 +228,13 @@ export function loginGoogle() { .then(async (response) => { if (response && response.data && response.data.meta.success) { const resData = response.data.data; - const roleId = JSON.stringify(response.data.included.role_id); - const profileData = JSON.stringify(response.data.included); try { - await AsyncStorage.multiSet([ - [ 'access_token', resData.access_token ], - [ 'refresh_token', resData.refresh_token ], - [ 'role_id', roleId ], - [ 'profile_data', profileData ] - ]); + await dispatch(setToken({ + accessToken: resData.access_token, + refreshToken: resData.refresh_token, + roleId: response.data.included.role_id, + profileData: response.data.included, + })) } catch (error) { console.log(error, 'error caught'); } @@ -431,3 +431,9 @@ export function setToken(token) { token } } + +export function resetToken() { + return { + type: RESET_TOKEN + } +} diff --git a/app/containers/Main/constants.js b/app/containers/Main/constants.js index 151bfe83..acc34323 100644 --- a/app/containers/Main/constants.js +++ b/app/containers/Main/constants.js @@ -17,3 +17,4 @@ export const UPDATE_IS_SUBSCRIBED = 'app/containers/Main/UPDATE_IS_SUBSCRIBED'; export const UPDATE_IS_LOADING = 'app/containers/Main/UPDATE_IS_LOADING'; export const SET_TOKEN = 'app/containers/Main/SET_TOKEN'; +export const RESET_TOKEN = 'app/containers/Main/RESET_TOKEN'; diff --git a/app/containers/Main/reducer.js b/app/containers/Main/reducer.js index 0604ee84..a630d97e 100644 --- a/app/containers/Main/reducer.js +++ b/app/containers/Main/reducer.js @@ -11,7 +11,8 @@ import { UPDATE_IS_NOT_REGISTERED, UPDATE_IS_LOADING, FETCH_PROFILE_DATA, - SET_TOKEN + SET_TOKEN, + RESET_TOKEN } from './constants'; /* @@ -28,8 +29,8 @@ const initialState = fromJS({ isSubscribed: false, accessToken: '', refreshToken: '', - roleId: '', - profileData: '', + roleId: null, + profileData: null, }); function mainReducer(state = initialState, action) { @@ -48,6 +49,11 @@ function mainReducer(state = initialState, action) { .set('refreshToken', token.refreshToken) .set('roleId', token.roleId) .set('profileData', token.profileData) + case RESET_TOKEN: + return state.set('accessToken', '') + .set('refreshToken', '') + .set('roleId', null) + .set('profileData', null) default: return state; } diff --git a/app/containers/Main/selectors.js b/app/containers/Main/selectors.js index 43b91767..e5447779 100644 --- a/app/containers/Main/selectors.js +++ b/app/containers/Main/selectors.js @@ -45,10 +45,19 @@ export const getIsLoading = () => createSelector( ); /** - * Get is loading status - * Returns boolean + * Get access token + * @return boolean */ export const getAccessToken = () => createSelector( selectMainReducer(), state => state.get('accessToken') ); + +/** + * Get profile data + * @return boolean + */ +export const getProfileData = () => createSelector( + selectMainReducer(), + state => state.get('profileData') +); diff --git a/app/containers/Settings/actions.js b/app/containers/Settings/actions.js index 56315d06..1e1168f7 100644 --- a/app/containers/Settings/actions.js +++ b/app/containers/Settings/actions.js @@ -12,6 +12,7 @@ import { UPDATE_IS_DISABLED } from './constants'; import { restoreCurrentPage } from '../Feed/actions'; +import { resetToken } from '../Main/actions'; import local from '../../../config/local'; /* @@ -162,6 +163,7 @@ export function logOut() { const keys = [ 'access_token', 'refresh_token', 'role_id', 'profile_data' ]; await AsyncStorage.multiRemove(keys); + dispatch(resetToken()); dispatch(restoreCurrentPage()); dispatch(isLoadingLogout(false)); dispatch(updateIsLogOut(true)); diff --git a/app/containers/Splash/index.js b/app/containers/Splash/index.js index 4e7f4acd..ac056afa 100644 --- a/app/containers/Splash/index.js +++ b/app/containers/Splash/index.js @@ -19,11 +19,12 @@ class Splash extends Component { } componentDidMount() { + console.log('token', this.props.accessToken); if (this.props.accessToken && this.props.accessToken !== '') { Api.setAuthorizationToken(this.props.accessToken); - Actions.main({ type: 'replace' }); - } else { Actions.mainTabs({ type: 'replace' }); + } else { + Actions.main({ type: 'replace' }); } } diff --git a/app/index.js b/app/index.js index c3bc2318..fe05fb77 100644 --- a/app/index.js +++ b/app/index.js @@ -71,27 +71,35 @@ const store = createStore( autoRehydrate(), ) ); - -persistStore(store, {storage: AsyncStorage}, () => { - AsyncStorage - .multiGet(['access_token', 'refresh_token', 'role_id', 'profile_data']) - .then(([accessToken, refreshToken, roleId, profileData]) => { - const savedToken = store.getState().getIn(['main', 'accessToken']); - if (!savedToken || savedToken === '') { - store.dispatch(setToken({ - accessToken, - refreshToken, - roleId, - profileData - })) - } - }).catch(err => console.log(err)); -}) +const persistingStore = (callback = () => {}) => { + persistStore(store, {storage: AsyncStorage}, () => { + AsyncStorage + .multiGet(['access_token', 'refresh_token', 'role_id', 'profile_data']) + .then(([accessToken, refreshToken, roleId, profileData]) => { + const savedToken = store.getState().getIn(['main', 'accessToken']); + if (!savedToken || savedToken === '') { + store.dispatch(setToken({ + accessToken, + refreshToken, + roleId: roleId, + profileData: JSON.parse(profileData) + })) + } + callback(); + }).catch(err => console.log(err)); + }) +}; export default class App extends Component { constructor(props) { super(props); - this.state = {}; + this.state = { + rehydrated: false + }; + } + + componentWillMount() { + persistingStore(() => this.setState({rehydrated: true})); } onBackPress = () => { @@ -105,7 +113,7 @@ export default class App extends Component { render() { return ( - + {this.state.rehydrated && - + } ); From a3e7f6cdcd9fb7ca8e4e4346b78623bd6e244ea9 Mon Sep 17 00:00:00 2001 From: Mochamad Gufron Date: Tue, 17 Oct 2017 00:30:10 +0700 Subject: [PATCH 4/6] add network state change --- android/app/build.gradle | 1 + .../app/android/MainApplication.java | 2 + android/settings.gradle | 2 + app/index.js | 12 +++- app/modules/net/actions.js | 11 +++ app/modules/net/constants.js | 1 + app/modules/net/reducer.js | 20 ++++++ app/modules/net/selectors.js | 8 +++ ios/app.xcodeproj/project.pbxproj | 67 +++++++++++++++++++ package.json | 2 + yarn.lock | 8 +++ 11 files changed, 133 insertions(+), 1 deletion(-) create mode 100644 app/modules/net/actions.js create mode 100644 app/modules/net/constants.js create mode 100644 app/modules/net/reducer.js create mode 100644 app/modules/net/selectors.js diff --git a/android/app/build.gradle b/android/app/build.gradle index 6dd642e9..ccb4a195 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -175,6 +175,7 @@ android { } dependencies { + compile project(':react-native-device-info') compile project(':react-native-paypal') compile project(':react-native-localization') compile project(':react-native-vector-icons') diff --git a/android/app/src/main/java/io/devsummit/app/android/MainApplication.java b/android/app/src/main/java/io/devsummit/app/android/MainApplication.java index 2f3c0e89..17e88e71 100644 --- a/android/app/src/main/java/io/devsummit/app/android/MainApplication.java +++ b/android/app/src/main/java/io/devsummit/app/android/MainApplication.java @@ -3,6 +3,7 @@ import android.app.Application; import com.facebook.react.ReactApplication; +import com.learnium.RNDeviceInfo.RNDeviceInfo; import br.com.vizir.rn.paypal.PayPalPackage; import com.babisoft.ReactNativeLocalization.ReactNativeLocalizationPackage; import com.oblador.vectoricons.VectorIconsPackage; @@ -54,6 +55,7 @@ protected List getPackages() { MainApplication.paypalPackage = new PayPalPackage(PAY_PAL_REQUEST_ID); return Arrays.asList( new MainReactPackage(), + new RNDeviceInfo(), new ReactNativeLocalizationPackage(), MainApplication.getPaypalPackage(), new VectorIconsPackage(), diff --git a/android/settings.gradle b/android/settings.gradle index 891ced56..91285420 100644 --- a/android/settings.gradle +++ b/android/settings.gradle @@ -1,4 +1,6 @@ rootProject.name = 'DevSummit' +include ':react-native-device-info' +project(':react-native-device-info').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-device-info/android') include ':react-native-paypal' project(':react-native-paypal').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-paypal/android') include ':react-native-localization' diff --git a/app/index.js b/app/index.js index fe05fb77..bf610d65 100644 --- a/app/index.js +++ b/app/index.js @@ -1,6 +1,6 @@ import React, { Component } from 'react'; import { Router, Scene, Actions } from 'react-native-router-flux'; -import { View, AsyncStorage } from 'react-native'; +import { View, AsyncStorage, NetInfo } from 'react-native'; import { Container, Content, Spinner } from 'native-base'; import BusyIndicator from 'react-native-busy-indicator'; @@ -24,6 +24,7 @@ import Schedule from './containers/Schedule'; import ScheduleDetail from './containers/ScheduleDetail'; import Main from './containers/Main'; import {setToken} from './containers/Main/actions'; +import {setIsOnline} from './modules/net/actions'; import ChangePassword from './containers/ChangePassword'; import OrderList from './containers/OrderList'; import TicketList from './containers/TicketList'; @@ -60,6 +61,7 @@ switch (lang) { } strings.setLanguage(setlang); + /** * Apply middlewares */ @@ -71,6 +73,14 @@ const store = createStore( autoRehydrate(), ) ); + +function handleConnectivityChange (status) { + console.log('trigger me'); + store.dispatch(setIsOnline(status)) + NetInfo.removeEventListener('connectionChange', handleConnectivityChange); +}; +NetInfo.addEventListener('connectionChange', handleConnectivityChange); + const persistingStore = (callback = () => {}) => { persistStore(store, {storage: AsyncStorage}, () => { AsyncStorage diff --git a/app/modules/net/actions.js b/app/modules/net/actions.js new file mode 100644 index 00000000..5f8d51a6 --- /dev/null +++ b/app/modules/net/actions.js @@ -0,0 +1,11 @@ +import { + NETWORK_CHANGE, +} from './constants'; + +export const setIsOnline = (value) => { + console.log(NETWORK_CHANGE, value); + return { + type: NETWORK_CHANGE, + value + } +} diff --git a/app/modules/net/constants.js b/app/modules/net/constants.js new file mode 100644 index 00000000..026c38fa --- /dev/null +++ b/app/modules/net/constants.js @@ -0,0 +1 @@ +export const NETWORK_CHANGE = 'modules/net/NETWORK_CHANGE'; diff --git a/app/modules/net/reducer.js b/app/modules/net/reducer.js new file mode 100644 index 00000000..25a96b87 --- /dev/null +++ b/app/modules/net/reducer.js @@ -0,0 +1,20 @@ +import { fromJS } from 'immutable'; + +import { + NETWORK_CHANGE, +} from './constants'; + +const initialState = fromJS({ + online: true, +}); + +function netReducer(state = initialState, action) { + switch (action.type) { + case NETWORK_CHANGE: + return state.set('online', action.value); + default: + return state; + } +} + +export default netReducer; diff --git a/app/modules/net/selectors.js b/app/modules/net/selectors.js new file mode 100644 index 00000000..f4f23f31 --- /dev/null +++ b/app/modules/net/selectors.js @@ -0,0 +1,8 @@ +import { createSelector } from 'reselect'; + +const selectNetworkReducer = () => state => state.get('network'); + +export const isOnline = () => createSelector( + selectNetworkReducer(), + state => state.get('online') +); diff --git a/ios/app.xcodeproj/project.pbxproj b/ios/app.xcodeproj/project.pbxproj index 724eff30..b030fc83 100644 --- a/ios/app.xcodeproj/project.pbxproj +++ b/ios/app.xcodeproj/project.pbxproj @@ -58,6 +58,7 @@ 9C98CD9F1F7B681500139C4B /* libjschelpers.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3DAD3EAD1DF850E9000B6D8A /* libjschelpers.a */; }; 9C98CDA01F7B682800139C4B /* libthird-party.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 9CF18CE11F711578009E4D56 /* libthird-party.a */; }; 9C98CDA11F7B682C00139C4B /* libyoga.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3DAD3EA51DF850E9000B6D8A /* libyoga.a */; }; + 9CAD63D51F951D94008E85FB /* libRNDeviceInfo.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 9CAD63D21F95162E008E85FB /* libRNDeviceInfo.a */; }; 9CB86CFB1F7E3A81009143CF /* QBImagePicker.framework in Embed Framework */ = {isa = PBXBuildFile; fileRef = 9CBF94431F7E2CA3001A8393 /* QBImagePicker.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 9CB86CFC1F7E3A81009143CF /* RSKImageCropper.framework in Embed Framework */ = {isa = PBXBuildFile; fileRef = 9CBF94441F7E2CA3001A8393 /* RSKImageCropper.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 9CBF8E481F75678700AFFF12 /* Default-568h@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 9CBF8E471F75678700AFFF12 /* Default-568h@2x.png */; }; @@ -301,6 +302,20 @@ remoteGlobalIDString = 7B5D9D0A1B6AD0EA00CF3A83; remoteInfo = ReactNativeLocalization; }; + 9CAD63D11F95162E008E85FB /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 50EE28D3B0C84A679CC0542E /* RNDeviceInfo.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = DA5891D81BA9A9FC002B4DB2; + remoteInfo = RNDeviceInfo; + }; + 9CAD63D31F95162E008E85FB /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 50EE28D3B0C84A679CC0542E /* RNDeviceInfo.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = E72EC1401F7ABB5A0001BC90; + remoteInfo = "RNDeviceInfo-tvOS"; + }; 9CE392F81F7A16E80021C0F3 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = F6EC7A164CC54E27B1EEDA3A /* RNShare.xcodeproj */; @@ -459,6 +474,7 @@ 365423E507D84F7FA53D5811 /* Roboto.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = Roboto.ttf; path = "../node_modules/native-base/Fonts/Roboto.ttf"; sourceTree = ""; }; 4EC68CDBCC424FECBACF47F1 /* libz.tbd */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libz.tbd; path = usr/lib/libz.tbd; sourceTree = SDKROOT; }; 4F82159FA2EC440195EB210F /* RNVectorIcons.xcodeproj */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "wrapper.pb-project"; name = RNVectorIcons.xcodeproj; path = "../node_modules/react-native-vector-icons/RNVectorIcons.xcodeproj"; sourceTree = ""; }; + 50EE28D3B0C84A679CC0542E /* RNDeviceInfo.xcodeproj */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "wrapper.pb-project"; name = RNDeviceInfo.xcodeproj; path = "../node_modules/react-native-device-info/RNDeviceInfo.xcodeproj"; sourceTree = ""; }; 51799398E8594CCF8CA86A93 /* SimpleLineIcons.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = SimpleLineIcons.ttf; path = "../node_modules/native-base/Fonts/SimpleLineIcons.ttf"; sourceTree = ""; }; 54E45A76BFF891706A35FC1E /* Pods-app.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-app.release.xcconfig"; path = "Pods/Target Support Files/Pods-app/Pods-app.release.xcconfig"; sourceTree = ""; }; 56489A250B984A028B94D923 /* ReactNativeLocalization.xcodeproj */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "wrapper.pb-project"; name = ReactNativeLocalization.xcodeproj; path = "../node_modules/react-native-localization/ReactNativeLocalization.xcodeproj"; sourceTree = ""; }; @@ -499,7 +515,9 @@ C44889F647634BC6838DB34F /* Ionicons.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = Ionicons.ttf; path = "../node_modules/native-base/Fonts/Ionicons.ttf"; sourceTree = ""; }; CCFC7D14F69E4DC5A3A6DDFA /* LRDRCTSimpleToast.xcodeproj */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "wrapper.pb-project"; name = LRDRCTSimpleToast.xcodeproj; path = "../node_modules/react-native-simple-toast/ios/LRDRCTSimpleToast.xcodeproj"; sourceTree = ""; }; CE15BE6BBAAA4B5BAC62171E /* Feather.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = Feather.ttf; path = "../node_modules/react-native-vector-icons/Fonts/Feather.ttf"; sourceTree = ""; }; + CF2CAD6C46F74C319930D4D7 /* libRNDeviceInfo-tvOS.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = "libRNDeviceInfo-tvOS.a"; sourceTree = ""; }; CF57C351BC444B37887A25FE /* Montserrat-Bold.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "Montserrat-Bold.ttf"; path = "../assets/fonts/Montserrat-Bold.ttf"; sourceTree = ""; }; + DB7C12A93D3E4F63892E1BA2 /* libRNDeviceInfo.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libRNDeviceInfo.a; sourceTree = ""; }; DE8D3178DDE04773B6F95F3A /* OFL.txt */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = OFL.txt; path = "../node_modules/native-base/Fonts/OFL.txt"; sourceTree = ""; }; E018BC4CD4814AF487610BC6 /* MaterialIcons.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = MaterialIcons.ttf; path = "../node_modules/react-native-vector-icons/Fonts/MaterialIcons.ttf"; sourceTree = ""; }; E22D7CC99A97DCDD8638412D /* libPods-appTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-appTests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -526,6 +544,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 9CAD63D51F951D94008E85FB /* libRNDeviceInfo.a in Frameworks */, 9CFFFF171F7BF48A00AAF527 /* libimageCropPicker.a in Frameworks */, 9CBF94461F7E2CA9001A8393 /* RSKImageCropper.framework in Frameworks */, 9CFFFF181F7BF48A00AAF527 /* libLRDRCTSimpleToast.a in Frameworks */, @@ -760,6 +779,7 @@ F6EC7A164CC54E27B1EEDA3A /* RNShare.xcodeproj */, 56489A250B984A028B94D923 /* ReactNativeLocalization.xcodeproj */, A34C580BD5764A3D8364D74B /* MFLReactNativePayPal.xcodeproj */, + 50EE28D3B0C84A679CC0542E /* RNDeviceInfo.xcodeproj */, ); name = Libraries; sourceTree = ""; @@ -817,11 +837,22 @@ name = Products; sourceTree = ""; }; + 9CAD63CD1F95162E008E85FB /* Products */ = { + isa = PBXGroup; + children = ( + 9CAD63D21F95162E008E85FB /* libRNDeviceInfo.a */, + 9CAD63D41F95162E008E85FB /* libRNDeviceInfo-tvOS.a */, + ); + name = Products; + sourceTree = ""; + }; 9CE392CD1F7A16E70021C0F3 /* Recovered References */ = { isa = PBXGroup; children = ( 4EC68CDBCC424FECBACF47F1 /* libz.tbd */, 7E4FDE8F0E7E4833A7F9E237 /* libMFLReactNativePayPal.a */, + DB7C12A93D3E4F63892E1BA2 /* libRNDeviceInfo.a */, + CF2CAD6C46F74C319930D4D7 /* libRNDeviceInfo-tvOS.a */, ); name = "Recovered References"; sourceTree = ""; @@ -1168,6 +1199,10 @@ ProductGroup = 9CF18CF21F711578009E4D56 /* Products */; ProjectRef = 7C77BA90E20947609A548199 /* RNAccountKit.xcodeproj */; }, + { + ProductGroup = 9CAD63CD1F95162E008E85FB /* Products */; + ProjectRef = 50EE28D3B0C84A679CC0542E /* RNDeviceInfo.xcodeproj */; + }, { ProductGroup = 9CF18CFC1F711579009E4D56 /* Products */; ProjectRef = BD0BC10FCDDF45309B5A4E07 /* RNDocumentPicker.xcodeproj */; @@ -1392,6 +1427,20 @@ remoteRef = 9C9131BE1F7B285A000D018E /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; + 9CAD63D21F95162E008E85FB /* libRNDeviceInfo.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libRNDeviceInfo.a; + remoteRef = 9CAD63D11F95162E008E85FB /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 9CAD63D41F95162E008E85FB /* libRNDeviceInfo-tvOS.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = "libRNDeviceInfo-tvOS.a"; + remoteRef = 9CAD63D31F95162E008E85FB /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; 9CE392F91F7A16E80021C0F3 /* libRNShare.a */ = { isa = PBXReferenceProxy; fileType = archive.ar; @@ -1869,6 +1918,7 @@ "$(SRCROOT)/../node_modules/react-native-share/ios", "$(SRCROOT)/../node_modules/react-native-localization", "$(SRCROOT)/../node_modules/react-native-paypal/ios/**", + "$(SRCROOT)/../node_modules/react-native-device-info/RNDeviceInfo", ); INFOPLIST_FILE = appTests/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 8.0; @@ -1885,6 +1935,8 @@ "\"$(SRCROOT)/$(TARGET_NAME)\"", "\"$(SRCROOT)/$(TARGET_NAME)\"", "\"$(SRCROOT)/$(TARGET_NAME)\"", + "\"$(SRCROOT)/$(TARGET_NAME)\"", + "\"$(SRCROOT)/$(TARGET_NAME)\"", ); OTHER_LDFLAGS = ( "-ObjC", @@ -1916,6 +1968,7 @@ "$(SRCROOT)/../node_modules/react-native-share/ios", "$(SRCROOT)/../node_modules/react-native-localization", "$(SRCROOT)/../node_modules/react-native-paypal/ios/**", + "$(SRCROOT)/../node_modules/react-native-device-info/RNDeviceInfo", ); INFOPLIST_FILE = appTests/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 8.0; @@ -1932,6 +1985,8 @@ "\"$(SRCROOT)/$(TARGET_NAME)\"", "\"$(SRCROOT)/$(TARGET_NAME)\"", "\"$(SRCROOT)/$(TARGET_NAME)\"", + "\"$(SRCROOT)/$(TARGET_NAME)\"", + "\"$(SRCROOT)/$(TARGET_NAME)\"", ); OTHER_LDFLAGS = ( "-ObjC", @@ -1972,6 +2027,7 @@ "$(SRCROOT)/../node_modules/react-native-fcm/ios", "$(SRCROOT)/../node_modules/react-native-localization", "$(SRCROOT)/../node_modules/react-native-paypal/ios/**", + "$(SRCROOT)/../node_modules/react-native-device-info/RNDeviceInfo", ); INFOPLIST_FILE = app/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; @@ -2026,6 +2082,7 @@ "$(SRCROOT)/../node_modules/react-native-fcm/ios", "$(SRCROOT)/../node_modules/react-native-localization", "$(SRCROOT)/../node_modules/react-native-paypal/ios/**", + "$(SRCROOT)/../node_modules/react-native-device-info/RNDeviceInfo", ); INFOPLIST_FILE = app/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; @@ -2077,6 +2134,7 @@ "$(SRCROOT)/../node_modules/react-native-share/ios", "$(SRCROOT)/../node_modules/react-native-localization", "$(SRCROOT)/../node_modules/react-native-paypal/ios/**", + "$(SRCROOT)/../node_modules/react-native-device-info/RNDeviceInfo", ); INFOPLIST_FILE = "app-tvOS/Info.plist"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; @@ -2092,6 +2150,8 @@ "\"$(SRCROOT)/$(TARGET_NAME)\"", "\"$(SRCROOT)/$(TARGET_NAME)\"", "\"$(SRCROOT)/$(TARGET_NAME)\"", + "\"$(SRCROOT)/$(TARGET_NAME)\"", + "\"$(SRCROOT)/$(TARGET_NAME)\"", ); OTHER_LDFLAGS = ( "-ObjC", @@ -2131,6 +2191,7 @@ "$(SRCROOT)/../node_modules/react-native-share/ios", "$(SRCROOT)/../node_modules/react-native-localization", "$(SRCROOT)/../node_modules/react-native-paypal/ios/**", + "$(SRCROOT)/../node_modules/react-native-device-info/RNDeviceInfo", ); INFOPLIST_FILE = "app-tvOS/Info.plist"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; @@ -2146,6 +2207,8 @@ "\"$(SRCROOT)/$(TARGET_NAME)\"", "\"$(SRCROOT)/$(TARGET_NAME)\"", "\"$(SRCROOT)/$(TARGET_NAME)\"", + "\"$(SRCROOT)/$(TARGET_NAME)\"", + "\"$(SRCROOT)/$(TARGET_NAME)\"", ); OTHER_LDFLAGS = ( "-ObjC", @@ -2185,6 +2248,8 @@ "\"$(SRCROOT)/$(TARGET_NAME)\"", "\"$(SRCROOT)/$(TARGET_NAME)\"", "\"$(SRCROOT)/$(TARGET_NAME)\"", + "\"$(SRCROOT)/$(TARGET_NAME)\"", + "\"$(SRCROOT)/$(TARGET_NAME)\"", ); PRODUCT_BUNDLE_IDENTIFIER = "com.facebook.REACT.app-tvOSTests"; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -2220,6 +2285,8 @@ "\"$(SRCROOT)/$(TARGET_NAME)\"", "\"$(SRCROOT)/$(TARGET_NAME)\"", "\"$(SRCROOT)/$(TARGET_NAME)\"", + "\"$(SRCROOT)/$(TARGET_NAME)\"", + "\"$(SRCROOT)/$(TARGET_NAME)\"", ); PRODUCT_BUNDLE_IDENTIFIER = "com.facebook.REACT.app-tvOSTests"; PRODUCT_NAME = "$(TARGET_NAME)"; diff --git a/package.json b/package.json index ba4d1956..9eff8e4e 100644 --- a/package.json +++ b/package.json @@ -21,6 +21,7 @@ "react-native": "0.46.4", "react-native-busy-indicator": "^1.1.0", "react-native-code-push": "^5.1.0-beta", + "react-native-device-info": "^0.12.0", "react-native-document-picker": "^2.0.0", "react-native-facebook-account-kit": "^0.7.0", "react-native-fcm": "^9.3.0", @@ -30,6 +31,7 @@ "react-native-image-crop-picker": "^0.16.0", "react-native-linear-gradient": "^2.2.0", "react-native-localization": "^0.1.32", + "react-native-message-bar": "^2.0.4", "react-native-oauth": "^2.2.0", "react-native-paypal": "git+https://github.com/refactory-id/react-native-paypal#master", "react-native-photo-grid": "0.0.2", diff --git a/yarn.lock b/yarn.lock index 39136684..d2de2796 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4223,6 +4223,10 @@ react-native-code-push@^5.1.0-beta: plist "1.2.0" xcode "0.9.2" +react-native-device-info@^0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/react-native-device-info/-/react-native-device-info-0.12.0.tgz#f534bf61b3da2ac612d9d715a3ac865bbe6482e6" + react-native-dismiss-keyboard@1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/react-native-dismiss-keyboard/-/react-native-dismiss-keyboard-1.0.0.tgz#32886242b3f2317e121f3aeb9b0a585e2b879b49" @@ -4300,6 +4304,10 @@ react-native-localization@^0.1.32: version "0.1.32" resolved "https://registry.yarnpkg.com/react-native-localization/-/react-native-localization-0.1.32.tgz#623bf3359abdd0f0afff50951dcf06cffda01b2a" +react-native-message-bar@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/react-native-message-bar/-/react-native-message-bar-2.0.4.tgz#ac551ecc8391057a35cd4c48f9b3d412f0a3e9b2" + react-native-oauth@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/react-native-oauth/-/react-native-oauth-2.2.0.tgz#8aa7fad344b22cd29f24a4c3385244684dbcbe9e" From 5d4b891bc431e8c1adb833783520c13f0459af8c Mon Sep 17 00:00:00 2001 From: Mochamad Gufron Date: Wed, 25 Oct 2017 02:04:09 +0700 Subject: [PATCH 5/6] message bar when connection is on/off --- app/containers/Main/actions.js | 19 ++- app/containers/MainTabs/PushNotification.js | 47 +++--- app/index.js | 177 +++++++++++++------- app/modules/net/actions.js | 8 +- app/modules/net/constants.js | 1 + app/modules/net/reducer.js | 6 +- app/reducers.js | 4 +- app/services/api.js | 12 +- app/services/auth.js | 5 + config/development.js | 2 +- package.json | 2 +- yarn.lock | 6 +- 12 files changed, 176 insertions(+), 113 deletions(-) create mode 100644 app/services/auth.js diff --git a/app/containers/Main/actions.js b/app/containers/Main/actions.js index 291ab2ab..d4031473 100644 --- a/app/containers/Main/actions.js +++ b/app/containers/Main/actions.js @@ -5,6 +5,7 @@ import { Actions } from 'react-native-router-flux'; import axios from 'axios'; import { DevSummitAxios } from '../../helpers'; +import api from '../../services/api'; /* * import constants @@ -76,6 +77,13 @@ export function updateisLoading(status) { }; } +export function setToken(token) { + return { + type: SET_TOKEN, + token + } +} + /* * Log user in * save access_token & refresh_token to asyncstorage @@ -107,6 +115,7 @@ export function login() { profileData, boothData })) + api.setAuthorizationToken(resData.access_token); } } catch (error) { console.log(error, 'error caught'); @@ -229,12 +238,13 @@ export function loginGoogle() { if (response && response.data && response.data.meta.success) { const resData = response.data.data; try { - await dispatch(setToken({ + dispatch(setToken({ accessToken: resData.access_token, refreshToken: resData.refresh_token, roleId: response.data.included.role_id, profileData: response.data.included, })) + api.setAuthorizationToken(resData.access_token); } catch (error) { console.log(error, 'error caught'); } @@ -425,13 +435,6 @@ export function subscribeNewsletter() { }; } -export function setToken(token) { - return { - type: SET_TOKEN, - token - } -} - export function resetToken() { return { type: RESET_TOKEN diff --git a/app/containers/MainTabs/PushNotification.js b/app/containers/MainTabs/PushNotification.js index 1f81c223..51b70a0a 100644 --- a/app/containers/MainTabs/PushNotification.js +++ b/app/containers/MainTabs/PushNotification.js @@ -7,6 +7,7 @@ import Toast from 'react-native-simple-toast'; import FCM, { FCMEvent, RemoteNotificationResult, WillPresentNotificationResult, NotificationType } from 'react-native-fcm'; import { getAccessToken, DevSummitAxios } from '../../helpers'; +import auth from '../../services/auth'; // this shall be called regardless of app state: running, background or not running. @@ -53,20 +54,15 @@ FCM.on(FCMEvent.Notification, async (notif) => { }); FCM.on(FCMEvent.RefreshToken, (token) => { - getAccessToken().then((usertoken) => { - const headers = { Authorization: usertoken }; - DevSummitAxios.patch('auth/me/updatefcmtoken', { token }, { headers }) - .then(async (response) => { - if (response.meta && response.meta.success) { - await AsyncStorage.setItem('fcmtoken', token); - } - }) - .catch((err) => { - console.log(err); - }); - }).catch((err) => { - console.log(err); - }); + auth.updateFcmToken(token) + .then(async (response) => { + if (response.meta && response.meta.success) { + await AsyncStorage.setItem('fcmtoken', token); + } + }) + .catch((err) => { + console.log(err); + }); // fcm token may not be available on first load, catch it here }); @@ -88,20 +84,15 @@ export default class PushNotification extends Component { FCM.getFCMToken().then((token) => { this.setState({ fcm_token: token }); // update your fcm token on server. - getAccessToken().then((usertoken) => { - const headers = { Authorization: usertoken }; - DevSummitAxios.patch('auth/me/updatefcmtoken', { token }, { headers }) - .then(async (response) => { - if (response.meta && response.meta.success) { - await AsyncStorage.setItem('fcmtoken', token); - } - }) - .catch((err) => { - console.log(err); - }); - }).catch((err) => { - console.log(err); - }); + auth.updateFcmToken(token) + .then(async (response) => { + if (response.meta && response.meta.success) { + await AsyncStorage.setItem('fcmtoken', token); + } + }) + .catch((err) => { + console.log(err); + }); }); this.notificationListener = FCM.on(FCMEvent.Notification, async (notif) => { // do some component related stuff diff --git a/app/index.js b/app/index.js index bf610d65..b7d98574 100644 --- a/app/index.js +++ b/app/index.js @@ -1,15 +1,16 @@ import React, { Component } from 'react'; import { Router, Scene, Actions } from 'react-native-router-flux'; -import { View, AsyncStorage, NetInfo } from 'react-native'; +import { View, AsyncStorage, NetInfo, StatusBar } from 'react-native'; import { Container, Content, Spinner } from 'native-base'; import BusyIndicator from 'react-native-busy-indicator'; +import { MessageBar as MessageBarAlert, MessageBarManager } from 'react-native-message-bar'; // Redux imports import { Provider, connect } from 'react-redux'; import { createStore, applyMiddleware, compose } from 'redux'; -import {persistStore, autoRehydrate} from 'redux-persist-immutable'; +import { persistStore, autoRehydrate } from 'redux-persist-immutable'; import ReduxThunk from 'redux-thunk'; -import logger from 'redux-logger' +import logger from 'redux-logger'; import reducers from './reducers'; // Style imports @@ -23,8 +24,8 @@ import RegisterPhone from './containers/RegisterPhone'; import Schedule from './containers/Schedule'; import ScheduleDetail from './containers/ScheduleDetail'; import Main from './containers/Main'; -import {setToken} from './containers/Main/actions'; -import {setIsOnline} from './modules/net/actions'; +import { setToken } from './containers/Main/actions'; +import { setIsOnline, setConnectionType } from './modules/net/actions'; import ChangePassword from './containers/ChangePassword'; import OrderList from './containers/OrderList'; import TicketList from './containers/TicketList'; @@ -74,30 +75,68 @@ const store = createStore( ) ); -function handleConnectivityChange (status) { - console.log('trigger me'); - store.dispatch(setIsOnline(status)) +function handleConnectivity() { + const {online, connection} = store.getState().get('network').toJS(); + console.log({online, connection}); + if (!online || ['unknown', 'none'].indexOf(connection) >= 0) { + MessageBarManager.showAlert({ + title: 'Connection problem', + message: 'It seems we\'re having trouble reaching out the server. Please ensure you have a working connection', + alertType: 'error', + shouldHideAfterDelay: false, + shouldHideOnTap: false, + }); + } else { + MessageBarManager.hideAlert(); + } +} +function handleConnectivityChange(status) { + store.dispatch(setConnectionType(status)); + // no connection at all NetInfo.removeEventListener('connectionChange', handleConnectivityChange); +} +function handleConnectivityStatusChange(status) { + store.dispatch(setIsOnline(status)); + // no connection at all + NetInfo.isConnected.removeEventListener('connectionChange', handleConnectivityStatusChange); +} +const networkListener = () => { + setInterval(() => { + NetInfo.addEventListener('connectionChange', handleConnectivityChange); + NetInfo.isConnected.addEventListener('connectionChange', handleConnectivityStatusChange); + setTimeout(() => { + handleConnectivity(); + }, 5 * 100); + }, 5 * 1000); + // give it some delay + setTimeout(() => { + NetInfo.isConnected.fetch().then(handleConnectivityStatusChange); + setTimeout(() => { + handleConnectivity(); + }, 5 * 100); + }, 100); }; -NetInfo.addEventListener('connectionChange', handleConnectivityChange); const persistingStore = (callback = () => {}) => { - persistStore(store, {storage: AsyncStorage}, () => { + persistStore(store, { storage: AsyncStorage }, () => { AsyncStorage - .multiGet(['access_token', 'refresh_token', 'role_id', 'profile_data']) - .then(([accessToken, refreshToken, roleId, profileData]) => { - const savedToken = store.getState().getIn(['main', 'accessToken']); - if (!savedToken || savedToken === '') { - store.dispatch(setToken({ - accessToken, - refreshToken, - roleId: roleId, - profileData: JSON.parse(profileData) - })) - } + .multiGet([ 'access_token', 'refresh_token', 'role_id', 'profile_data' ]) + .then(([ accessToken, refreshToken, roleId, profileData ]) => { + const savedToken = store.getState().getIn([ 'main', 'accessToken' ]); + if (!savedToken || savedToken === '') { + store.dispatch(setToken({ + accessToken, + refreshToken, + roleId, + profileData: JSON.parse(profileData) + })); + } + callback(); + }).catch((err) => { + // it means no particular data saved on async storage or just new installation callback(); - }).catch(err => console.log(err)); - }) + }); + }); }; export default class App extends Component { @@ -109,7 +148,12 @@ export default class App extends Component { } componentWillMount() { - persistingStore(() => this.setState({rehydrated: true})); + persistingStore(() => { + this.setState({ rehydrated: true }, () => { + MessageBarManager.registerMessageBar(this.messageBar); + networkListener(); + }); + }); } onBackPress = () => { @@ -122,45 +166,52 @@ export default class App extends Component { render() { return ( - - {this.state.rehydrated && - - - - - - - - - - - - - - - - - - - - - - - - - - - - } - - + + + + {this.state.rehydrated && + + + + + + + + + + + + + + + + + + + + + + + + + + + + } + + + { this.messageBar = ref; }} /> + ); } } diff --git a/app/modules/net/actions.js b/app/modules/net/actions.js index 5f8d51a6..5122b807 100644 --- a/app/modules/net/actions.js +++ b/app/modules/net/actions.js @@ -1,9 +1,15 @@ import { NETWORK_CHANGE, + NETWORK_STATUS_CHANGE, } from './constants'; export const setIsOnline = (value) => { - console.log(NETWORK_CHANGE, value); + return { + type: NETWORK_STATUS_CHANGE, + value + } +} +export const setConnectionType = (value) => { return { type: NETWORK_CHANGE, value diff --git a/app/modules/net/constants.js b/app/modules/net/constants.js index 026c38fa..f507d3a6 100644 --- a/app/modules/net/constants.js +++ b/app/modules/net/constants.js @@ -1 +1,2 @@ export const NETWORK_CHANGE = 'modules/net/NETWORK_CHANGE'; +export const NETWORK_STATUS_CHANGE = 'modules/net/NETWORK_STATUS_CHANGE'; diff --git a/app/modules/net/reducer.js b/app/modules/net/reducer.js index 25a96b87..c552d045 100644 --- a/app/modules/net/reducer.js +++ b/app/modules/net/reducer.js @@ -2,16 +2,20 @@ import { fromJS } from 'immutable'; import { NETWORK_CHANGE, + NETWORK_STATUS_CHANGE } from './constants'; const initialState = fromJS({ online: true, + connection: 'wifi' }); function netReducer(state = initialState, action) { switch (action.type) { - case NETWORK_CHANGE: + case NETWORK_STATUS_CHANGE: return state.set('online', action.value); + case NETWORK_CHANGE: + return state.set('connection', action.value); default: return state; } diff --git a/app/reducers.js b/app/reducers.js index 1a695e98..0f6ab010 100644 --- a/app/reducers.js +++ b/app/reducers.js @@ -22,6 +22,7 @@ import BoothInfoReducer from './containers/BoothInfo/reducer'; import codeRedeemReducer from './containers/Redeem/reducer'; import Notification from './containers/Notification/reducer'; import FeedReducer from './containers/Feed/reducer'; +import network from './modules/net/reducer'; const rootReducers = combineReducers({ main: MainReducer, @@ -44,7 +45,8 @@ const rootReducers = combineReducers({ boothInfo: BoothInfoReducer, code: codeRedeemReducer, notificationList: Notification, - feed: FeedReducer + feed: FeedReducer, + network }); export default rootReducers; diff --git a/app/services/api.js b/app/services/api.js index 1adf5da8..d18185c9 100644 --- a/app/services/api.js +++ b/app/services/api.js @@ -23,19 +23,19 @@ class Api { return this.id; } put(url, json, qs = {}, config) { - return this.sendRequest('PUT', url, { qs, json, config }); + return this.sendRequest('PUT', url, { qs, json, ...config }); } get(url, config = {}, qs) { - return this.sendRequest('GET', url, { qs, config }); + return this.sendRequest('GET', url, { qs, ...config }); } post(url, json, qs = {}, config = {}) { - return this.sendRequest('POST', url, { qs, json, config }); + return this.sendRequest('POST', url, { qs, json, ...config }); } patch(url, form, qs = {}, config = {}) { - return this.sendRequest('PATCH', url, { qs, form, config }); + return this.sendRequest('PATCH', url, { qs, form, ...config }); } delete(url, qs = {}, config = {}) { - return this.sendRequest('DELETE', url, { qs, config }); + return this.sendRequest('DELETE', url, { qs, ...config }); } setHeader(key, value) { this.config.headers[key] = value; @@ -44,7 +44,7 @@ class Api { this.setHeader('Authorization', `${token}`); } sendRequest(requestMethod, url, data = {}) { - let headers = data.config ? data.config.headers || {} : {}; + let headers = data.config ? data.headers || {} : {}; headers = Object.assign({}, this.client.defaults.headers.common, this.config.headers, headers); return this.client diff --git a/app/services/auth.js b/app/services/auth.js new file mode 100644 index 00000000..b7ea83bf --- /dev/null +++ b/app/services/auth.js @@ -0,0 +1,5 @@ +import Api from './api'; + +export default { + updateFcmToken: token => Api.patch(`auth/me/updatefcmtoken`, null, null, { json: {token}}), +}; diff --git a/config/development.js b/config/development.js index 797488da..c070e0d2 100644 --- a/config/development.js +++ b/config/development.js @@ -18,6 +18,6 @@ export default { PAYPAL_CLIENT_ID: 'Ac-Ikn76GlVB5tFLwMoFYEl9FGumrB7NYdkicE5bd7Q_QfWmnKDyK_ZlZ7mFB-MlENIQR1fTvcj1Ivdv', PAYPAL_CURRENCY: 'USD', - PAYPAL_RATE: Math.pow(10, 4), + PAYPAL_RATE: 10 ** 4, PAYPAL_ENV: Platform.OS === 'android' ? 'sandbox' : 0, }; diff --git a/package.json b/package.json index 9eff8e4e..a5dae756 100644 --- a/package.json +++ b/package.json @@ -31,7 +31,7 @@ "react-native-image-crop-picker": "^0.16.0", "react-native-linear-gradient": "^2.2.0", "react-native-localization": "^0.1.32", - "react-native-message-bar": "^2.0.4", + "react-native-message-bar": "git+https://github.com/refactory-id/react-native-message-bar#master", "react-native-oauth": "^2.2.0", "react-native-paypal": "git+https://github.com/refactory-id/react-native-paypal#master", "react-native-photo-grid": "0.0.2", diff --git a/yarn.lock b/yarn.lock index d2de2796..5bbaf3c7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4304,9 +4304,9 @@ react-native-localization@^0.1.32: version "0.1.32" resolved "https://registry.yarnpkg.com/react-native-localization/-/react-native-localization-0.1.32.tgz#623bf3359abdd0f0afff50951dcf06cffda01b2a" -react-native-message-bar@^2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/react-native-message-bar/-/react-native-message-bar-2.0.4.tgz#ac551ecc8391057a35cd4c48f9b3d412f0a3e9b2" +"react-native-message-bar@git+https://github.com/refactory-id/react-native-message-bar#master": + version "1.6.0" + resolved "git+https://github.com/refactory-id/react-native-message-bar#cea0e2221696fcf2d2ac94c6f76de8c4423cda6f" react-native-oauth@^2.2.0: version "2.2.0" From 8a1660cf2e9e3927709fa11bacb74b20e399f4c4 Mon Sep 17 00:00:00 2001 From: Mochamad Gufron Date: Wed, 25 Oct 2017 02:52:25 +0700 Subject: [PATCH 6/6] update manifest permission --- android/app/src/main/AndroidManifest.xml | 2 ++ .../main/assets/crashlytics-build.properties | 11 ------- .../values/com_crashlytics_export_strings.xml | 10 ------ app/index.js | 31 +++++++++---------- 4 files changed, 17 insertions(+), 37 deletions(-) delete mode 100644 android/app/src/main/assets/crashlytics-build.properties delete mode 100644 android/app/src/main/res/values/com_crashlytics_export_strings.xml diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 72e7684b..b6bb68eb 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -7,6 +7,8 @@ android:launchMode="singleTop"> + + diff --git a/android/app/src/main/assets/crashlytics-build.properties b/android/app/src/main/assets/crashlytics-build.properties deleted file mode 100644 index f4c950f1..00000000 --- a/android/app/src/main/assets/crashlytics-build.properties +++ /dev/null @@ -1,11 +0,0 @@ -#This file is automatically generated by Crashlytics to uniquely -#identify individual builds of your Android application. -# -#Do NOT modify, delete, or commit to source control! -# -#Sun Oct 15 19:54:12 WIB 2017 -version_name=1.0 -package_name=io.devsummit.app.android -build_id=45307a6a-7e0b-4335-9bc4-c6dc9fd23086 -version_code=1 -app_name=DevSummit diff --git a/android/app/src/main/res/values/com_crashlytics_export_strings.xml b/android/app/src/main/res/values/com_crashlytics_export_strings.xml deleted file mode 100644 index a091ae6f..00000000 --- a/android/app/src/main/res/values/com_crashlytics_export_strings.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - -45307a6a-7e0b-4335-9bc4-c6dc9fd23086 - diff --git a/app/index.js b/app/index.js index b7d98574..6f75156c 100644 --- a/app/index.js +++ b/app/index.js @@ -1,6 +1,6 @@ import React, { Component } from 'react'; import { Router, Scene, Actions } from 'react-native-router-flux'; -import { View, AsyncStorage, NetInfo, StatusBar } from 'react-native'; +import { View, AsyncStorage, NetInfo, StatusBar, Platform } from 'react-native'; import { Container, Content, Spinner } from 'native-base'; import BusyIndicator from 'react-native-busy-indicator'; import { MessageBar as MessageBarAlert, MessageBarManager } from 'react-native-message-bar'; @@ -76,26 +76,31 @@ const store = createStore( ); function handleConnectivity() { - const {online, connection} = store.getState().get('network').toJS(); - console.log({online, connection}); - if (!online || ['unknown', 'none'].indexOf(connection) >= 0) { + const { online, connection } = store.getState().get('network').toJS(); + console.log({ online, connection }); + if (!online || [ 'unknown', 'none' ].indexOf(connection) >= 0) { MessageBarManager.showAlert({ - title: 'Connection problem', - message: 'It seems we\'re having trouble reaching out the server. Please ensure you have a working connection', + title: 'Looking for network', + message: 'It seems we can\'t reach out the server at the moment.', alertType: 'error', shouldHideAfterDelay: false, shouldHideOnTap: false, + + titleStyle: { fontSize: 16, fontWeight: 'normal', marginTop: 10, color: 'white' }, + messageStyle: {fontSize: 11, color: 'white'} }); } else { MessageBarManager.hideAlert(); } } function handleConnectivityChange(status) { + console.log('connection', status); store.dispatch(setConnectionType(status)); // no connection at all NetInfo.removeEventListener('connectionChange', handleConnectivityChange); } function handleConnectivityStatusChange(status) { + console.log('status', status); store.dispatch(setIsOnline(status)); // no connection at all NetInfo.isConnected.removeEventListener('connectionChange', handleConnectivityStatusChange); @@ -104,17 +109,11 @@ const networkListener = () => { setInterval(() => { NetInfo.addEventListener('connectionChange', handleConnectivityChange); NetInfo.isConnected.addEventListener('connectionChange', handleConnectivityStatusChange); + NetInfo.isConnectionExpensive().then(status => console.log(status)); setTimeout(() => { handleConnectivity(); }, 5 * 100); }, 5 * 1000); - // give it some delay - setTimeout(() => { - NetInfo.isConnected.fetch().then(handleConnectivityStatusChange); - setTimeout(() => { - handleConnectivity(); - }, 5 * 100); - }, 100); }; const persistingStore = (callback = () => {}) => { @@ -167,11 +166,11 @@ export default class App extends Component { render() { return ( - - + />} + {this.state.rehydrated &&