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/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/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/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/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/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..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,16 +172,12 @@ class Feed extends Component {
}
componentWillMount() {
- this.props.setTokenHeader(this.props.currentPage);
-
- 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 61a92c04..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
@@ -23,7 +24,9 @@ import {
GOOGLE_CLIENT_SECRET,
TWITTER_CALLBACK,
TWITTER_CONSUMER_KEY,
- TWITTER_CONSUMER_KEY_SECRET
+ TWITTER_CONSUMER_KEY_SECRET,
+ SET_TOKEN,
+ RESET_TOKEN
} from './constants';
/*
@@ -74,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
@@ -93,17 +103,19 @@ 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
+ }))
+ api.setAuthorizationToken(resData.access_token);
}
} catch (error) {
console.log(error, 'error caught');
@@ -225,15 +237,14 @@ 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 ]
- ]);
+ 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');
}
@@ -423,3 +434,9 @@ export function subscribeNewsletter() {
});
};
}
+
+export function resetToken() {
+ return {
+ type: RESET_TOKEN
+ }
+}
diff --git a/app/containers/Main/constants.js b/app/containers/Main/constants.js
index ec256cef..acc34323 100644
--- a/app/containers/Main/constants.js
+++ b/app/containers/Main/constants.js
@@ -15,3 +15,6 @@ 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';
+export const RESET_TOKEN = 'app/containers/Main/RESET_TOKEN';
diff --git a/app/containers/Main/reducer.js b/app/containers/Main/reducer.js
index 8920462b..a630d97e 100644
--- a/app/containers/Main/reducer.js
+++ b/app/containers/Main/reducer.js
@@ -10,7 +10,9 @@ import {
UPDATE_IS_SUBSCRIBED,
UPDATE_IS_NOT_REGISTERED,
UPDATE_IS_LOADING,
- FETCH_PROFILE_DATA
+ FETCH_PROFILE_DATA,
+ SET_TOKEN,
+ RESET_TOKEN
} from './constants';
/*
@@ -24,7 +26,11 @@ const initialState = fromJS({
},
isLoading: false,
isLoggedIn: false,
- isSubscribed: false
+ isSubscribed: false,
+ accessToken: '',
+ refreshToken: '',
+ roleId: null,
+ profileData: null,
});
function mainReducer(state = initialState, action) {
@@ -37,6 +43,17 @@ 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)
+ 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 eefea1a6..e5447779 100644
--- a/app/containers/Main/selectors.js
+++ b/app/containers/Main/selectors.js
@@ -43,3 +43,21 @@ export const getIsLoading = () => createSelector(
selectMainReducer(),
state => state.get('isLoading')
);
+
+/**
+ * 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/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/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
new file mode 100644
index 00000000..ac056afa
--- /dev/null
+++ b/app/containers/Splash/index.js
@@ -0,0 +1,41 @@
+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() {
+ console.log('token', this.props.accessToken);
+ if (this.props.accessToken && this.props.accessToken !== '') {
+ Api.setAuthorizationToken(this.props.accessToken);
+ Actions.mainTabs({ type: 'replace' });
+ } else {
+ Actions.main({ 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..6f75156c 100644
--- a/app/index.js
+++ b/app/index.js
@@ -1,14 +1,16 @@
import React, { Component } from 'react';
import { Router, Scene, Actions } from 'react-native-router-flux';
-import { View, AsyncStorage } 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';
// 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 logger from 'redux-logger';
import reducers from './reducers';
// Style imports
@@ -22,6 +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, setConnectionType } from './modules/net/actions';
import ChangePassword from './containers/ChangePassword';
import OrderList from './containers/OrderList';
import TicketList from './containers/TicketList';
@@ -30,7 +34,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';
@@ -58,16 +62,97 @@ switch (lang) {
}
strings.setLanguage(setlang);
+
/**
* Apply middlewares
*/
-export const createStoreWithMiddleware = applyMiddleware(ReduxThunk)(createStore);
-const store = createStoreWithMiddleware(reducers);
+const store = createStore(
+ reducers,
+ undefined,
+ compose(
+ applyMiddleware(ReduxThunk),
+ autoRehydrate(),
+ )
+);
+
+function handleConnectivity() {
+ const { online, connection } = store.getState().get('network').toJS();
+ console.log({ online, connection });
+ if (!online || [ 'unknown', 'none' ].indexOf(connection) >= 0) {
+ MessageBarManager.showAlert({
+ 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);
+}
+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);
+};
+
+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,
+ profileData: JSON.parse(profileData)
+ }));
+ }
+ callback();
+ }).catch((err) => {
+ // it means no particular data saved on async storage or just new installation
+ callback();
+ });
+ });
+};
export default class App extends Component {
constructor(props) {
super(props);
- this.state = {};
+ this.state = {
+ rehydrated: false
+ };
+ }
+
+ componentWillMount() {
+ persistingStore(() => {
+ this.setState({ rehydrated: true }, () => {
+ MessageBarManager.registerMessageBar(this.messageBar);
+ networkListener();
+ });
+ });
}
onBackPress = () => {
@@ -80,45 +165,52 @@ export default class App extends Component {
render() {
return (
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+ {Platform.OS === 'ios' && }
+
+ {this.state.rehydrated &&
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ }
+
+
+ { this.messageBar = ref; }} />
+
);
}
}
diff --git a/app/modules/net/actions.js b/app/modules/net/actions.js
new file mode 100644
index 00000000..5122b807
--- /dev/null
+++ b/app/modules/net/actions.js
@@ -0,0 +1,17 @@
+import {
+ NETWORK_CHANGE,
+ NETWORK_STATUS_CHANGE,
+} from './constants';
+
+export const setIsOnline = (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
new file mode 100644
index 00000000..f507d3a6
--- /dev/null
+++ b/app/modules/net/constants.js
@@ -0,0 +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
new file mode 100644
index 00000000..c552d045
--- /dev/null
+++ b/app/modules/net/reducer.js
@@ -0,0 +1,24 @@
+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_STATUS_CHANGE:
+ return state.set('online', action.value);
+ case NETWORK_CHANGE:
+ return state.set('connection', 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/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/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/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 e3b623db..a5dae756 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,11 +31,12 @@
"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": "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",
- "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 +48,8 @@
"redux": "^3.7.2",
"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 19c212f2..5bbaf3c7 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"
@@ -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@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"
resolved "https://registry.yarnpkg.com/react-native-oauth/-/react-native-oauth-2.2.0.tgz#8aa7fad344b22cd29f24a4c3385244684dbcbe9e"
@@ -4622,6 +4630,28 @@ redux-logger@^3.0.6:
dependencies:
deep-diff "^0.3.5"
+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:
+ 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"
@@ -5341,6 +5371,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"