⬆️ Major bumps! Move to RN 0.59

- ⬆️ Bump all dependencies
- ⬆️ react-native 0.59.x using the the `react-native eject` method
- ⬆️ react 16.8.x
- ⬆️ react-navigation 3.x
- ⬆️ tipsi-stripe 7.x
- 📝 Add section on linking native dependencies to README
- 🔥 Remove bitrise android build support
- 🐛 Add a 10 second timeout to all API requests and stop persisting HTTP request state fixing requests hangs
This commit is contained in:
Nikolai R Kristiansen committed 2019-05-04 23:32:45 +02:00
1 parent 3c7564d7bb
commit 8bbbf06fac
16 files changed
+1700 -1104

No files matched your search

+6 -2
View File
@@ -12,12 +12,16 @@
## Development
# Improve compile times
touch ~/.gradle/gradle.properties && echo -e "org.gradle.daemon=true\norg.gradle.jvmargs=-Xmx2048M" >> ~/.gradle/gradle.properties
# Run android emulator (first avd)
yarn emulator
# Make sure you have hw.keyboard=yes in your avd config.ini (in $HOME/.android/avd/.../) for reloading when pressing R twice to work.
### Linking native dependencies
We use a Podfile to install the stripe ios library, but not for anything else.
Before running any `react-native link` commands, rename `ios/Podfile` to something else before running, then rename the file back when you are done.
This is to let the react-native CLI know we use the Dusken xcode project and not cocoapods for managing all other dependencies.
This avoids alot of issues resulting from poor cocoapods support by react native.
## Prepare release build
# Fastlane
bundle update
+3 -1
View File
@@ -3,8 +3,10 @@ import { AppRegistry } from "react-native";
import { Sentry } from 'react-native-sentry';
import Config from 'react-native-config';
import {name as appName} from './app.json';
if(Config.SENTRY_DSN) {
Sentry.config(Config.SENTRY_DSN).install();
}
AppRegistry.registerComponent('Dusken', () => App);
AppRegistry.registerComponent(appName, () => App);
+35 -41
View File
@@ -1,5 +1,5 @@
{
"name": "Dusken",
"name": "dusken",
"version": "0.0.1",
"private": true,
"scripts": {
@@ -12,49 +12,43 @@
"start": "node node_modules/react-native/local-cli/cli.js start",
"test": "jest"
},
"jest": {
"preset": "react-native",
"setupFiles": [
"<rootDir>/jest/setup.js"
],
"transformIgnorePatterns": [
"node_modules/(?!(jest-)?react-native|react-clone-referenced-element|react-navigation|native-base|@shoutem|tipsi-stripe)"
]
},
"dependencies": {
"apollo-cache-inmemory": "^1.1.0",
"apollo-client": "^2.0.2",
"apollo-link-http": "^1.1.0",
"email-validator": "^1.1.1",
"graphql": "^0.11.7",
"graphql-tag": "^2.5.0",
"moment": "^2.19.4",
"native-base": "^2.3.5",
"prop-types": "^15.5.10",
"react": "16.0.0",
"react-apollo": "^2.0.0",
"react-native": "0.51.0",
"react-native-confetti": "^0.0.6",
"react-native-config": "^0.11.2",
"react-native-htmlview": "^0.12.1",
"react-native-sentry": "^0.32.0",
"react-native-vector-icons": "~4.4.2",
"react-navigation": "^1.0.0-beta.21",
"react-redux": "^5.0.6",
"redux": "^3.7.2",
"redux-logger": "^3.0.6",
"redux-persist": "^4.10.2",
"redux-thunk": "^2.2.0",
"tipsi-stripe": "^4.5.1"
"@react-native-community/async-storage": "^1.3.4",
"apollo-cache-inmemory": "^1.5.1",
"apollo-client": "^2.5.1",
"apollo-link-http": "^1.5.14",
"email-validator": "^2.0.4",
"graphql": "^14.2.1",
"graphql-tag": "^2.10.1",
"moment": "^2.24.0",
"native-base": "^2.12.1",
"prop-types": "^15.7.2",
"react": "16.8.3",
"react-apollo": "^2.5.5",
"react-native": "0.59.5",
"react-native-confetti": "^0.1.0",
"react-native-config": "^0.11.7",
"react-native-gesture-handler": "^1.2.1",
"react-native-htmlview": "^0.14.0",
"react-native-screens": "^1.0.0-alpha.22",
"react-native-sentry": "^0.42.0",
"react-native-vector-icons": "^6.4.2",
"react-navigation": "^3.9.1",
"react-navigation-hooks": "^1.0.0-alpha.2",
"react-redux": "^7.0.3",
"redux": "^4.0.1",
"redux-persist": "^5.10.0",
"redux-thunk": "^2.3.0",
"tipsi-stripe": "^7.5.0"
},
"devDependencies": {
"babel-jest": "21.2.0",
"jest": "21.2.1",
"@babel/core": "^7.4.4",
"@babel/runtime": "^7.4.4",
"babel-jest": "^24.7.1",
"jest": "^24.7.1",
"jest-fetch-mock": "^1.6.5",
"react-dom": "^16.0.0",
"react-test-renderer": "16.2.0"
},
"resolutions": {
"@sentry/cli": "1.27.0"
"metro-react-native-babel-preset": "^0.54.0",
"react-dom": "16.8.3",
"react-test-renderer": "16.8.3"
}
}
+7 -18
View File
@@ -1,10 +1,6 @@
import React, {Component} from 'react';
import {Provider} from 'react-redux';
import {applyMiddleware, createStore} from 'redux';
import logger from 'redux-logger';
import thunk from 'redux-thunk';
import {autoRehydrate, persistStore} from 'redux-persist'
import {AsyncStorage} from 'react-native'
import {PersistGate} from 'redux-persist/es/integration/react'
import Config from 'react-native-config';
import {ApolloClient} from 'apollo-client';
import {HttpLink} from 'apollo-link-http';
@@ -12,15 +8,9 @@ import {InMemoryCache} from 'apollo-cache-inmemory';
import {ApolloProvider} from "react-apollo";
import Dusken from "./Dusken";
import duskenApp from "./reducers";
import {store, persistor} from './reduxStore';
let store = createStore(
duskenApp,
applyMiddleware(...[logger, thunk]),
autoRehydrate()
);
const apolloClient = new ApolloClient({
link: new HttpLink({uri: `${Config.DUSKEN_API_URL}/api/graphql/`}),
cache: new InMemoryCache()
@@ -30,13 +20,12 @@ export default class App extends Component {
render() {
return (
<Provider store={store}>
<ApolloProvider client={apolloClient}>
<Dusken />
</ApolloProvider>
<PersistGate loading={null} persistor={persistor}>
<ApolloProvider client={apolloClient}>
<Dusken />
</ApolloProvider>
</PersistGate>
</Provider>
)
}
}
// begin periodically persisting the store
persistStore(store, {storage: AsyncStorage});
+5 -4
View File
@@ -6,13 +6,14 @@ import {
userDataFailure, userDataRequest, userDataSuccess,
membershipChargeFailure, membershipChargeRequest, membershipChargeSuccess,
} from "./actions";
import { fetchWithTimeout } from "./utils";
export function requestLogin(username, password) {
return (dispatch) => {
// We are now logging in
dispatch(loginRequest());
return fetch(`${Config.DUSKEN_API_URL}/auth/obtain-token/`, {
return fetchWithTimeout(`${Config.DUSKEN_API_URL}/auth/obtain-token/`, {
method: 'POST',
headers: {
'Accept': 'application/json',
@@ -47,7 +48,7 @@ export function requestUserData(auth_token) {
// We are now fetching user data
dispatch(userDataRequest());
return fetch(`${Config.DUSKEN_API_URL}/api/me/`, {
return fetchWithTimeout(`${Config.DUSKEN_API_URL}/api/me/`, {
method: 'GET',
headers: {
'Accept': 'application/json',
@@ -77,7 +78,7 @@ export function requestRegisterUser(firstName, lastName, email, phoneNumber, pas
return (dispatch) => {
dispatch(registerUserRequest());
return fetch(`${Config.DUSKEN_API_URL}/api/user/register/`, {
return fetchWithTimeout(`${Config.DUSKEN_API_URL}/api/user/register/`, {
method: 'POST',
headers: {
'Accept': 'application/json',
@@ -113,7 +114,7 @@ export function requestMembershipCharge(auth_token, stripe_token, membership_typ
return (dispatch) => {
dispatch(membershipChargeRequest());
return fetch(`${Config.DUSKEN_API_URL}/api/membership/charge/`, {
return fetchWithTimeout(`${Config.DUSKEN_API_URL}/api/membership/charge/`, {
method: 'POST',
headers: {
'Accept': 'application/json',
+3 -2
View File
@@ -1,4 +1,5 @@
import {StyleSheet, View, SectionList, Platform} from "react-native";
import {StyleSheet, View, Platform} from "react-native";
import {SectionList} from 'react-navigation';
import {Card, ListItem, CardItem, Body, Text as Text, Left, Right, Icon, Button, Content, Spinner} from 'native-base';
import React, { Component } from 'react';
import moment from "moment";
@@ -118,4 +119,4 @@ const styles = StyleSheet.create({
listHeader: {
paddingTop: 8,
}
});
});
+1 -1
View File
@@ -9,7 +9,7 @@ import Proof from "./Proof";
import {requestMembershipCharge} from "../../api";
stripe.init({
stripe.setOptions({
publishableKey: Config.STRIPE_PUBLISHABLE_KEY || '',
});
+1 -1
View File
@@ -261,4 +261,4 @@ const styles = StyleSheet.create({
paddingTop: 2,
paddingBottom: 12,
}
});
});
@@ -1,5 +1,6 @@
import React, {Component} from 'react';
import {connect} from "react-redux";
import UserRegister from "./UserRegister";
import {requestRegisterUser} from "../../api";
@@ -45,4 +46,4 @@ function storeToProps(store) {
export default connect(
storeToProps,
{requestRegisterUser}
)(UserRegisterContainer);
)(UserRegisterContainer);
+23 -12
View File
@@ -1,5 +1,5 @@
import {Platform, StyleSheet} from 'react-native';
import {TabNavigator, StackNavigator} from "react-navigation";
import {createBottomTabNavigator, createStackNavigator, createAppContainer, getActiveChildNavigationOptions} from "react-navigation";
import AboutScreen from "./screens/AboutScreen";
import EventDetailScreen from "./screens/EventDetailScreen";
@@ -9,9 +9,9 @@ import MembershipScreen from "./screens/MembershipScreen";
import UserRegisterScreen from "./screens/UserRegisterScreen";
const tabBarRoutes = {
EventList: { screen: EventListScreen },
Membership: { screen: MembershipScreen },
About: { screen: AboutScreen },
EventList: EventListScreen,
Membership: MembershipScreen,
About: AboutScreen,
};
const tabBarOptions = {
@@ -41,16 +41,27 @@ const tabBarOptions = {
}
}),
},
}
},
navigationOptions: ({ navigation, screenProps }) => ({
// get header title from active child screen
...getActiveChildNavigationOptions(navigation, screenProps),
headerStyle: {
backgroundColor: '#f58220',
},
headerTitleStyle: {
color: 'white',
},
headerTintColor: 'white',
})
};
const tabNav = TabNavigator(tabBarRoutes, tabBarOptions);
const tabNav = createBottomTabNavigator(tabBarRoutes, tabBarOptions);
const DuskenNavigation = StackNavigator({
Root: { screen: tabNav },
Login: { screen: LoginScreen },
UserRegister: { screen: UserRegisterScreen },
EventDetail: { screen: EventDetailScreen },
const DuskenNavigation = createStackNavigator({
Root: tabNav,
Login: LoginScreen,
UserRegister: UserRegisterScreen,
EventDetail: EventDetailScreen,
});
export default DuskenNavigation;
export default createAppContainer(DuskenNavigation);
+26
View File
@@ -0,0 +1,26 @@
import { applyMiddleware, createStore } from 'redux';
import { persistStore, persistReducer } from 'redux-persist';
import AsyncStorage from '@react-native-community/async-storage';
import thunk from "redux-thunk";
import rootReducer from './reducers'
const persistConfig = {
key: 'root',
storage: AsyncStorage,
blacklist: [
'isLoggingIn',
'isFetchingUserData',
'isRegisteringUser',
'isChargingMembership'
]
};
const persistedReducer = persistReducer(persistConfig, rootReducer);
export let store = createStore(
persistedReducer,
applyMiddleware(...[thunk])
);
export let persistor = persistStore(store);
+1 -8
View File
@@ -8,13 +8,6 @@ import getTheme from '../../native-base-theme/components';
export default class AboutScreen extends Component {
static navigationOptions = {
title: 'Om oss',
headerStyle: {
backgroundColor: '#f58220',
},
headerTitleStyle: {
color: 'white',
},
headerTintColor: 'white',
tabBarIcon: ({ tintColor }) => (
<Icon name="info" size={16} color={tintColor} style={{marginTop: 5}} />
),
@@ -26,4 +19,4 @@ export default class AboutScreen extends Component {
<AboutContainer />
</StyleProvider>);
}
}
}
+1 -8
View File
@@ -7,13 +7,6 @@ import getTheme from '../../native-base-theme/components';
export default class EventsScreen extends Component {
static navigationOptions = {
title: 'Program',
headerStyle: {
backgroundColor: '#f58220',
},
headerTitleStyle: {
color: 'white',
},
headerTintColor: 'white',
tabBarIcon: ({ tintColor }) => (
<Icon name="event" size={16} color={tintColor} style={{marginTop: 5}}/>
),
@@ -31,4 +24,4 @@ export default class EventsScreen extends Component {
</StyleProvider>
);
}
}
}
+1 -8
View File
@@ -7,13 +7,6 @@ import getTheme from '../../native-base-theme/components';
export default class MembershipScreen extends Component {
static navigationOptions = {
title: 'Medlemskap',
headerStyle: {
backgroundColor: '#f58220',
},
headerTitleStyle: {
color: 'white',
},
headerTintColor: 'white',
tabBarIcon: ({ tintColor }) => (
<Icon name="user" size={16} color={tintColor} style={{marginTop: 5}} />
),
@@ -41,4 +34,4 @@ export default class MembershipScreen extends Component {
</StyleProvider>
)
}
}
}
+11
View File
@@ -1,3 +1,14 @@
export function snakeToCamelCase(val) {
return val.replace(/_([a-z])/g, function (g) { return g[1].toUpperCase(); });
}
export function fetchWithTimeout(url, options, timeout=10000) {
/** Wraps fetch to allow it to time out */
// FIXME: show timeout message in UI
return Promise.race([
fetch(url, options),
new Promise((_, reject) =>
setTimeout(() => reject(new Error('Fetch request timed out')), timeout)
)
]);
}
+1574 -997
View File
File diff suppressed because it is too large. Load diff