Bug fixes (#261)

* Layout fixes

* RoomsListView's SafeAreaView

* Unhandled promise rejection fix

* Prevent navigation from opening scenes twice

* Create channel fixes
This commit is contained in:
Diego Mello 2018-04-10 10:03:54 -03:00 committed by Guilherme Gazzo
parent 0e8b9fe8d7
commit 6d0e8e50cc
24 changed files with 205 additions and 17456 deletions

View File

@ -1,7 +1,7 @@
import React from 'react';
import { View, StyleSheet, Platform } from 'react-native';
import PropTypes from 'prop-types';
import { SafeAreaView } from 'react-navigation';
import SafeAreaView from 'react-native-safe-area-view';
let platformContainerStyles;
if (Platform.OS === 'ios') {
@ -21,15 +21,16 @@ if (Platform.OS === 'ios') {
};
}
const appBarHeight = Platform.OS === 'ios' ? 44 : 56;
const height = Platform.OS === 'ios' ? 44 : 56;
const backgroundColor = Platform.OS === 'ios' ? '#F7F7F7' : '#FFF';
const styles = StyleSheet.create({
container: {
backgroundColor: Platform.OS === 'ios' ? '#F7F7F7' : '#FFF',
height: appBarHeight,
backgroundColor,
...platformContainerStyles
},
appBar: {
flex: 1
height,
backgroundColor
}
});
@ -40,7 +41,7 @@ export default class Header extends React.PureComponent {
render() {
return (
<SafeAreaView style={styles.container}>
<SafeAreaView forceInset={{ bottom: 'never' }} style={styles.container}>
<View style={styles.appBar}>
{this.props.subview}
</View>

View File

@ -1,11 +1,12 @@
import React from 'react';
import PropTypes from 'prop-types';
import { View, TextInput, SafeAreaView, FlatList, Text, TouchableOpacity } from 'react-native';
import { View, TextInput, FlatList, Text, TouchableOpacity } from 'react-native';
import Icon from 'react-native-vector-icons/MaterialIcons';
import ImagePicker from 'react-native-image-picker';
import { connect } from 'react-redux';
import { emojify } from 'react-emojione';
import { KeyboardAccessoryView } from 'react-native-keyboard-input';
import { isIphoneX } from 'react-native-iphone-x-helper';
import { userTyping, layoutAnimation } from '../../actions/room';
import RocketChat from '../../lib/rocketchat';
@ -479,11 +480,7 @@ export default class MessageBox extends React.PureComponent {
return (
[
this.renderMentions(),
<SafeAreaView
key='messagebox'
style={[styles.textBox, (this.props.editing ? styles.editing : null)]}
>
<View style={styles.textArea}>
<View key='messagebox' style={[styles.textArea, this.props.editing && styles.editing]}>
{this.leftButtons}
<TextInput
ref={component => this.component = component}
@ -501,14 +498,15 @@ export default class MessageBox extends React.PureComponent {
/>
{this.rightButtons}
</View>
</SafeAreaView>
]
);
}
render() {
return (
[
<KeyboardAccessoryView
key='input'
renderContent={() => this.renderContent()}
kbInputRef={this.component}
kbComponent={this.state.showEmojiKeyboard ? 'EmojiKeyboard' : null}
@ -517,7 +515,9 @@ export default class MessageBox extends React.PureComponent {
trackInteractive
// revealKeyboardInteractive
requiresSameParentToManageScrollView
/>
/>,
isIphoneX() ? <View key='iphonex-area' style={styles.iphoneXArea} /> : null
]
);
}
}

View File

@ -11,14 +11,11 @@ export default StyleSheet.create({
borderTopColor: '#D8D8D8',
zIndex: 2
},
safeAreaView: {
flexDirection: 'row',
alignItems: 'center'
},
textArea: {
flexDirection: 'row',
alignItems: 'center',
flexGrow: 0
flexGrow: 0,
backgroundColor: '#fff'
},
textBoxInput: {
textAlignVertical: 'center',
@ -41,29 +38,6 @@ export default StyleSheet.create({
paddingHorizontal: 21,
flex: 0
},
actionRow: {
flexDirection: 'row',
alignItems: 'center',
alignContent: 'center'
},
actionContent: {
borderBottomWidth: 1,
borderBottomColor: '#ECECEC',
borderTopWidth: 1,
borderTopColor: '#ECECEC',
backgroundColor: '#F7F8FA'
},
actionTitle: {
flex: 1,
fontSize: 17,
padding: 14,
textAlign: 'right',
borderBottomWidth: 1,
borderBottomColor: '#ECECEC',
color: '#2F343D'
},
mentionList: {
maxHeight: MENTION_HEIGHT * 4,
borderTopColor: '#ECECEC',
@ -79,12 +53,6 @@ export default StyleSheet.create({
flexDirection: 'row',
alignItems: 'center'
},
emojiContainer: {
height: 200,
borderTopColor: '#ECECEC',
borderTopWidth: 1,
backgroundColor: '#fff'
},
mentionItemCustomEmoji: {
margin: 8,
width: 30,
@ -105,5 +73,13 @@ export default StyleSheet.create({
flex: 1,
borderTopColor: '#ECECEC',
borderTopWidth: 1
},
iphoneXArea: {
height: 50,
backgroundColor: '#fff',
position: 'absolute',
bottom: 0,
left: 0,
right: 0
}
});

View File

@ -67,7 +67,7 @@ export default class Sidebar extends Component {
}
onItemPress = ({ route, focused }) => {
this.props.navigation.navigate('DrawerClose');
this.props.navigation.navigate({ key: 'DrawerClose', routeName: 'DrawerClose' });
if (!focused) {
this.props.navigation.navigate(route.routeName, undefined);
}
@ -75,7 +75,7 @@ export default class Sidebar extends Component {
onPressItem = (item) => {
this.props.selectServer(item.id);
this.props.navigation.navigate('DrawerClose');
this.props.navigation.navigate({ key: 'DrawerClose', routeName: 'DrawerClose' });
}
getState = () => ({

View File

@ -10,7 +10,7 @@ export function setNavigator(nav) {
export function navigate(routeName, params) {
if (config.navigator && routeName) {
const action = NavigationActions.navigate({ routeName, params });
const action = NavigationActions.navigate({ key: routeName, routeName, params });
config.navigator.dispatch(action);
}
}
@ -26,7 +26,7 @@ export function goRoomsList() {
if (config.navigator) {
const action = NavigationActions.reset({
index: 0,
actions: [NavigationActions.navigate({ routeName: 'RoomsList' })]
actions: [NavigationActions.navigate({ key: 'RoomsList', routeName: 'RoomsList' })]
});
config.navigator.dispatch(action);
}
@ -44,8 +44,8 @@ export function goRoom({ rid, name }, counter = 0) {
const action = NavigationActions.reset({
index: 1,
actions: [
NavigationActions.navigate({ routeName: 'RoomsList' }),
NavigationActions.navigate({ routeName: 'Room', params: { room: { rid, name }, rid, name } })
NavigationActions.navigate({ key: 'RoomsList', routeName: 'RoomsList' }),
NavigationActions.navigate({ key: `Room-${ rid }`, routeName: 'Room', params: { room: { rid, name }, rid, name } })
]
});

View File

@ -21,7 +21,7 @@ const PublicRoutes = StackNavigator(
title: 'Servers',
headerRight: (
<TouchableOpacity
onPress={() => navigation.navigate('AddServer')}
onPress={() => navigation.navigate({ key: 'AddServer', routeName: 'AddServer' })}
style={{ width: 50, alignItems: 'center' }}
accessibilityLabel='Add server'
accessibilityTraits='button'

View File

@ -3,12 +3,13 @@ import { select, put, call, take, takeLatest } from 'redux-saga/effects';
import { CREATE_CHANNEL, LOGIN } from '../actions/actionsTypes';
import { createChannelSuccess, createChannelFailure } from '../actions/createChannel';
import RocketChat from '../lib/rocketchat';
import { goRoom } from '../containers/routes/NavigationService';
const create = function* create(data) {
return yield RocketChat.createChannel(data);
};
const get = function* get({ data }) {
const handleRequest = function* handleRequest({ data }) {
try {
yield delay(1000);
const auth = yield select(state => state.login.isAuthenticated);
@ -16,14 +17,15 @@ const get = function* get({ data }) {
yield take(LOGIN.SUCCESS);
}
const result = yield call(create, data);
const { rid, name } = result;
goRoom({ rid, name });
yield put(createChannelSuccess(result));
} catch (err) {
yield put(createChannelFailure(err));
}
};
const getData = function* getData() {
yield takeLatest(CREATE_CHANNEL.REQUEST, get);
const root = function* root() {
yield takeLatest(CREATE_CHANNEL.REQUEST, handleRequest);
};
export default getData;
export default root;

View File

@ -63,7 +63,9 @@ const saveToken = function* saveToken() {
yield AsyncStorage.setItem(RocketChat.TOKEN_KEY, user.token);
yield AsyncStorage.setItem(`${ RocketChat.TOKEN_KEY }-${ server }`, JSON.stringify(user));
const token = yield AsyncStorage.getItem('pushId');
yield token && RocketChat.registerPushToken(user.user.id, token);
if (token) {
RocketChat.registerPushToken(user.user.id, token);
}
Answers.logLogin('Email', true, { server });
};

View File

@ -2,6 +2,7 @@ import React from 'react';
import { connect } from 'react-redux';
import PropTypes from 'prop-types';
import { TextInput, View, Text, Switch, TouchableOpacity, SafeAreaView } from 'react-native';
import Spinner from 'react-native-loading-spinner-overlay';
import LoggedView from './View';
import { createChannelRequest } from '../actions/createChannel';
@ -10,11 +11,11 @@ import KeyboardView from '../presentation/KeyboardView';
@connect(
state => ({
result: state.createChannel,
createChannel: state.createChannel,
users: state.createChannel.users
}),
dispatch => ({
createChannel: data => dispatch(createChannelRequest(data))
create: data => dispatch(createChannelRequest(data))
})
)
export default class CreateChannelView extends LoggedView {
@ -22,34 +23,22 @@ export default class CreateChannelView extends LoggedView {
title: 'Create a New Channel'
});
static propTypes = {
createChannel: PropTypes.func.isRequired,
result: PropTypes.object.isRequired,
create: PropTypes.func.isRequired,
createChannel: PropTypes.object.isRequired,
users: PropTypes.array.isRequired,
navigation: PropTypes.object.isRequired
};
constructor(props) {
super('CreateChannelView', props);
this.default = {
this.state = {
channelName: '',
type: true
};
this.state = this.default;
}
componentDidUpdate() {
if (!this.adding) {
return;
}
if (this.props.result.result && !this.props.result.failure) {
this.props.navigation.navigate('Room', { room: this.props.result.result });
this.adding = false;
}
}
submit() {
this.adding = true;
if (!this.state.channelName.trim() || this.props.result.isFetching) {
if (!this.state.channelName.trim() || this.props.createChannel.isFetching) {
return;
}
const { channelName, type = true } = this.state;
@ -59,19 +48,21 @@ export default class CreateChannelView extends LoggedView {
users = users.map(user => user.name);
// create channel
this.props.createChannel({ name: channelName, users, type });
this.props.create({ name: channelName, users, type });
}
renderChannelNameError() {
if (
!this.props.result.failure ||
this.props.result.error.error !== 'error-duplicate-channel-name'
!this.props.createChannel.failure ||
this.props.createChannel.error.error !== 'error-duplicate-channel-name'
) {
return null;
}
return (
<Text style={[styles.label_white, styles.label_error]}>{this.props.result.error.reason}</Text>
<Text style={[styles.label_white, styles.label_error]}>
{this.props.createChannel.error.reason}
</Text>
);
}
@ -106,7 +97,6 @@ export default class CreateChannelView extends LoggedView {
returnKeyType='done'
autoCapitalize='none'
autoFocus
// onSubmitEditing={() => this.textInput.focus()}
placeholder='Type the channel name here'
/>
{this.renderChannelNameError()}
@ -130,18 +120,16 @@ export default class CreateChannelView extends LoggedView {
</Text>
<TouchableOpacity
onPress={() => this.submit()}
style={[
styles.buttonContainer_white,
this.state.channelName.length === 0 || this.props.result.isFetching
? styles.disabledButton
: styles.enabledButton
]}
style={[styles.buttonContainer_white, styles.enabledButton]}
>
<Text style={styles.button_white}>
{this.props.result.isFetching ? 'LOADING' : 'CREATE'}!
</Text>
<Text style={styles.button_white}>CREATE</Text>
</TouchableOpacity>
</SafeAreaView>
<Spinner
visible={this.props.createChannel.isFetching}
textContent='Loading...'
textStyle={{ color: '#FFF' }}
/>
</KeyboardView>
);
}

View File

@ -102,7 +102,7 @@ export default class ListServerView extends LoggedView {
!this.props.login.token &&
!this.redirected) {
this.redirected = true;
this.props.navigation.navigate('Login');
this.props.navigation.navigate({ key: 'Login', routeName: 'Login' });
} else if (!this.props.connected) {
this.redirected = false;
}

View File

@ -175,19 +175,19 @@ export default class LoginView extends React.Component {
}
register = () => {
this.props.navigation.navigate('Register');
this.props.navigation.navigate({ key: 'Register', routeName: 'Register' });
}
termsService = () => {
this.props.navigation.navigate('TermsService');
this.props.navigation.navigate({ key: 'TermsService', routeName: 'TermsService' });
}
privacyPolicy = () => {
this.props.navigation.navigate('PrivacyPolicy');
this.props.navigation.navigate({ key: 'PrivacyPolicy', routeName: 'PrivacyPolicy' });
}
forgotPassword = () => {
this.props.navigation.navigate('ForgotPassword');
this.props.navigation.navigate({ key: 'ForgotPassword', routeName: 'ForgotPassword' });
}
closeOAuth = () => {

View File

@ -54,7 +54,7 @@ export default class RoomActionsView extends LoggedView {
onPressTouchable = (item) => {
if (item.route) {
return this.props.navigation.navigate(item.route, item.params);
return this.props.navigation.navigate({ key: item.route, routeName: item.route, params: item.params });
}
if (item.event) {
return item.event();

View File

@ -44,7 +44,7 @@ export default class RoomInfoView extends LoggedView {
return {
headerRight: (
<Touch
onPress={() => navigation.navigate('RoomInfoEdit', { rid: navigation.state.params.rid })}
onPress={() => navigation.navigate({ key: 'RoomInfoEdit', routeName: 'RoomInfoEdit', params: { rid: navigation.state.params.rid } })}
underlayColor='#ffffff'
activeOpacity={0.5}
accessibilityLabel='edit'

View File

@ -91,7 +91,7 @@ export default class RoomHeaderView extends React.PureComponent {
style={styles.titleContainer}
accessibilityLabel={accessibilityLabel}
accessibilityTraits='header'
onPress={() => this.props.navigation.navigate('RoomInfo', { rid: this.rid })}
onPress={() => this.props.navigation.navigate({ key: 'RoomInfo', routeName: 'RoomInfo', params: { rid: this.rid } })}
>
{this.isDirect() ?
<View style={[styles.status, { backgroundColor: STATUS_COLORS[this.getUserStatus()] }]} />
@ -135,7 +135,7 @@ export default class RoomHeaderView extends React.PureComponent {
</Touch>
<TouchableOpacity
style={styles.headerButton}
onPress={() => this.props.navigation.navigate('RoomActions', { rid: this.room[0].rid })}
onPress={() => this.props.navigation.navigate({ key: 'RoomActions', routeName: 'RoomActions', params: { rid: this.room[0].rid } })}
accessibilityLabel='Room actions'
accessibilityTraits='button'
>

View File

@ -67,7 +67,7 @@ export class List extends React.Component {
render() {
return (<ListView
enableEmptySections
style={styles.list}
style={[styles.list]}
data={this.data}
onEndReachedThreshold={0.5}
renderFooter={this.props.renderFooter}

View File

@ -73,7 +73,7 @@ export default class RoomView extends LoggedView {
this.state = {
loaded: true,
joined: typeof props.rid === 'undefined',
room: this.rooms[0]
room: {}
};
this.onReactionPress = this.onReactionPress.bind(this);
}
@ -180,7 +180,7 @@ export default class RoomView extends LoggedView {
</View>
);
}
return <MessageBox ref={box => (this.box = box)} onSubmit={this.sendMessage} rid={this.rid} />;
return <MessageBox onSubmit={this.sendMessage} rid={this.rid} />;
};
renderHeader = () => {

View File

@ -77,7 +77,7 @@ export default class RoomsListHeaderView extends React.PureComponent {
}
createChannel() {
this.props.navigation.navigate('SelectUsers');
this.props.navigation.navigate({ key: 'SelectUsers', routeName: 'SelectUsers' });
}
renderLeft() {
@ -89,7 +89,7 @@ export default class RoomsListHeaderView extends React.PureComponent {
<View style={styles.left} accessible accessibilityLabel="Server's list" accessibilityTraits='button'>
<TouchableOpacity
style={styles.headerButton}
onPress={() => this.props.navigation.navigate('DrawerOpen')}
onPress={() => this.props.navigation.navigate({ key: 'DrawerOpen', routeName: 'DrawerOpen' })}
>
<CachedImage
style={styles.serverImage}
@ -159,7 +159,8 @@ export default class RoomsListHeaderView extends React.PureComponent {
size={24}
backgroundColor='transparent'
/>
</TouchableOpacity> : null}
</TouchableOpacity> : null
}
</View>
);
}

View File

@ -3,7 +3,7 @@ import { ListView } from 'realm/react-native';
import React from 'react';
import PropTypes from 'prop-types';
import Icon from 'react-native-vector-icons/Ionicons';
import { Platform, View, TextInput, SafeAreaView, FlatList } from 'react-native';
import { Platform, View, TextInput, FlatList } from 'react-native';
import { connect } from 'react-redux';
import * as actions from '../../actions';
import * as server from '../../actions/connect';
@ -135,7 +135,7 @@ export default class RoomsListView extends React.Component {
_onPressItem = async(item = {}) => {
// if user is using the search we need first to join/create room
if (!item.search) {
return this.props.navigation.navigate({ routeName: 'Room', params: { room: item, ...item } });
return this.props.navigation.navigate({ key: `Room-${ item._id }`, routeName: 'Room', params: { room: item, ...item } });
}
if (item.t === 'd') {
const sub = await RocketChat.createDirectMessageAndWait(item.username);
@ -145,7 +145,7 @@ export default class RoomsListView extends React.Component {
}
_createChannel() {
this.props.navigation.navigate('SelectUsers');
this.props.navigation.navigate({ key: 'SelectUsers', routeName: 'SelectUsers' });
}
_keyExtractor(item) {
@ -210,9 +210,7 @@ export default class RoomsListView extends React.Component {
render = () => (
<View style={styles.container}>
<Banner />
<SafeAreaView style={styles.safeAreaView}>
{this.renderList()}
{Platform.OS === 'android' && this.renderCreateButtons()}
</SafeAreaView>
</View>)
}

View File

@ -39,9 +39,5 @@ export default StyleSheet.create({
padding: 5,
paddingLeft: 10,
color: '#aaa'
},
safeAreaView: {
flex: 1,
backgroundColor: '#fff'
}
});

View File

@ -3,7 +3,7 @@ import { ListView } from 'realm/react-native';
import React from 'react';
import PropTypes from 'prop-types';
import Icon from 'react-native-vector-icons/Ionicons';
import { View, StyleSheet, TextInput, Text, TouchableOpacity, SafeAreaView } from 'react-native';
import { View, StyleSheet, TextInput, Text, TouchableOpacity, SafeAreaView, Platform } from 'react-native';
import { connect } from 'react-redux';
import * as actions from '../actions';
import * as server from '../actions/connect';
@ -57,6 +57,7 @@ const styles = StyleSheet.create({
const ds = new ListView.DataSource({ rowHasChanged: (r1, r2) => r1 !== r2 });
@connect(
state => ({
user: state.login.user,
login: state.login,
Site_Url: state.settings.Site_Url,
users: state.createChannel.users
@ -76,7 +77,37 @@ export default class SelectUsersView extends React.Component {
addUser: PropTypes.func.isRequired,
removeUser: PropTypes.func.isRequired,
resetCreateChannel: PropTypes.func.isRequired,
users: PropTypes.array
users: PropTypes.array,
user: PropTypes.object
};
static navigationOptions = ({ navigation }) => {
const params = navigation.state.params || {};
return {
headerRight: (
params.showCreateiOS && Platform.OS === 'ios' ?
<TouchableOpacity
style={{
backgroundColor: 'transparent',
height: 44,
width: 44,
alignItems: 'center',
justifyContent: 'center'
}}
onPress={() => params.createChannel()}
accessibilityLabel='Create channel'
accessibilityTraits='button'
>
<Icon
name='ios-add'
color='#292E35'
size={24}
backgroundColor='transparent'
/>
</TouchableOpacity> : null
)
};
};
constructor(props) {
@ -91,6 +122,20 @@ export default class SelectUsersView extends React.Component {
this.data.addListener(this.updateState);
}
componentDidMount() {
this.props.navigation.setParams({
createChannel: this._createChannel
});
}
componentWillReceiveProps(nextProps) {
if (nextProps.users.length !== this.props.users.length) {
this.props.navigation.setParams({
showCreateiOS: nextProps.users.length > 0
});
}
}
componentWillUnmount() {
this.data.removeListener(this.updateState);
this.props.resetCreateChannel();
@ -175,7 +220,7 @@ export default class SelectUsersView extends React.Component {
_onPressSelectedItem = item => this.toggleUser(item);
_createChannel = () => {
this.props.navigation.navigate('CreateChannel');
this.props.navigation.navigate({ key: 'CreateChannel', routeName: 'CreateChannel' });
};
renderHeader = () => (
@ -234,6 +279,12 @@ export default class SelectUsersView extends React.Component {
type={item.t}
baseUrl={this.props.Site_Url}
onPress={() => this._onPressItem(item._id, item)}
lastMessage={item.lastMessage}
id={item.rid.replace(this.props.user.id, '').trim()}
_updatedAt={item.roomUpdatedAt}
alert={item.alert}
unread={item.unread}
userMentions={item.userMentions}
/>
);
renderList = () => (
@ -248,7 +299,7 @@ export default class SelectUsersView extends React.Component {
/>
);
renderCreateButton = () => {
if (this.props.users.length === 0) {
if (this.props.users.length === 0 || Platform.OS === 'ios') {
return null;
}
return (

View File

@ -1 +1 @@
./Fabric.framework/run YOUR_API_KEY YOUR_API_SECRET

17280
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -50,6 +50,7 @@
"react-native-fetch-blob": "^0.10.8",
"react-native-image-picker": "^0.26.7",
"react-native-img-cache": "^1.5.2",
"react-native-iphone-x-helper": "^1.0.2",
"react-native-keyboard-aware-scroll-view": "^0.4.4",
"react-native-keyboard-input": "git+https://github.com/RocketChat/react-native-keyboard-input.git",
"react-native-keyboard-tracking-view": "git+https://github.com/RocketChat/react-native-keyboard-tracking-view.git",
@ -60,6 +61,7 @@
"react-native-push-notification": "^3.0.1",
"react-native-responsive-ui": "^1.1.1",
"react-native-safari-view": "^2.1.0",
"react-native-safe-area-view": "^0.7.0",
"react-native-scrollable-tab-view": "^0.8.0",
"react-native-slider": "^0.11.0",
"react-native-splash-screen": "^3.0.6",
@ -69,7 +71,7 @@
"react-native-video": "^2.0.0",
"react-native-video-controls": "^2.1.0",
"react-native-zeroconf": "^0.8.3",
"react-navigation": "^1.3.0",
"react-navigation": "^1.5.9",
"react-redux": "^5.0.6",
"realm": "^2.2.12",
"redux": "^3.7.2",

View File

@ -3987,7 +3987,7 @@ fbjs-scripts@^0.8.1:
semver "^5.1.0"
through2 "^2.0.0"
fbjs@^0.8.12, fbjs@^0.8.9:
fbjs@^0.8.12:
version "0.8.14"
resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-0.8.14.tgz#d1dbe2be254c35a91e09f31f9cd50a40b2a0ed1c"
dependencies:
@ -3999,7 +3999,7 @@ fbjs@^0.8.12, fbjs@^0.8.9:
setimmediate "^1.0.5"
ua-parser-js "^0.7.9"
fbjs@^0.8.14, fbjs@^0.8.16:
fbjs@^0.8.14, fbjs@^0.8.16, fbjs@^0.8.9:
version "0.8.16"
resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-0.8.16.tgz#5e67432f550dc41b572bf55847b8aca64e5337db"
dependencies:
@ -4766,11 +4766,11 @@ iconv-lite@0.4.13:
version "0.4.13"
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.13.tgz#1f88aba4ab0b1508e8312acc39345f36e992e2f2"
iconv-lite@0.4.19, iconv-lite@^0.4.4:
iconv-lite@0.4.19, iconv-lite@^0.4.4, iconv-lite@~0.4.13:
version "0.4.19"
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.19.tgz#f7468f60135f5e5dad3399c0a81be9a1603a082b"
iconv-lite@^0.4.17, iconv-lite@~0.4.13:
iconv-lite@^0.4.17:
version "0.4.18"
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.18.tgz#23d8656b16aae6742ac29732ea8f0336a4789cf2"
@ -6448,7 +6448,14 @@ no-case@^2.2.0:
dependencies:
lower-case "^1.1.1"
node-fetch@^1.0.1, node-fetch@^1.3.3, node-fetch@^1.6.3:
node-fetch@^1.0.1:
version "1.7.3"
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-1.7.3.tgz#980f6f72d85211a5347c6b2bc18c5b84c3eb47ef"
dependencies:
encoding "^0.1.11"
is-stream "^1.0.1"
node-fetch@^1.3.3, node-fetch@^1.6.3:
version "1.7.2"
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-1.7.2.tgz#c54e9aac57e432875233525f3c891c4159ffefd7"
dependencies:
@ -7362,7 +7369,7 @@ promise-inflight@^1.0.1:
dependencies:
asap "~2.0.3"
prop-types@15.6.0, prop-types@^15.6.0:
prop-types@15.6.0:
version "15.6.0"
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.6.0.tgz#ceaf083022fc46b4a35f69e13ef75aed0d639856"
dependencies:
@ -7370,14 +7377,7 @@ prop-types@15.6.0, prop-types@^15.6.0:
loose-envify "^1.3.1"
object-assign "^4.1.1"
prop-types@^15.5.10, prop-types@^15.5.4, prop-types@^15.5.6, prop-types@^15.5.8, prop-types@^15.5.9:
version "15.5.10"
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.5.10.tgz#2797dfc3126182e3a95e3dfbb2e893ddd7456154"
dependencies:
fbjs "^0.8.9"
loose-envify "^1.3.1"
prop-types@^15.6.1:
prop-types@^15.5.10, prop-types@^15.6.0, prop-types@^15.6.1:
version "15.6.1"
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.6.1.tgz#36644453564255ddda391191fb3a125cbdf654ca"
dependencies:
@ -7385,6 +7385,13 @@ prop-types@^15.6.1:
loose-envify "^1.3.1"
object-assign "^4.1.1"
prop-types@^15.5.4, prop-types@^15.5.6, prop-types@^15.5.8, prop-types@^15.5.9:
version "15.5.10"
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.5.10.tgz#2797dfc3126182e3a95e3dfbb2e893ddd7456154"
dependencies:
fbjs "^0.8.9"
loose-envify "^1.3.1"
proxy-addr@~2.0.2:
version "2.0.2"
resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.2.tgz#6571504f47bb988ec8180253f85dd7e14952bdec"
@ -7615,6 +7622,10 @@ react-komposer@^1.8.0:
mobx "^2.3.4"
shallowequal "0.2.x"
react-lifecycles-compat@^1.0.2:
version "1.1.4"
resolved "https://registry.yarnpkg.com/react-lifecycles-compat/-/react-lifecycles-compat-1.1.4.tgz#fc005c72849b7ed364de20a0f64ff58ebdc2009a"
react-mixin@^3.0.3:
version "3.1.0"
resolved "https://registry.yarnpkg.com/react-mixin/-/react-mixin-3.1.0.tgz#0c5dea2ee90d01455dabfbebe44db03a37497e53"
@ -7699,7 +7710,7 @@ react-native-img-cache@^1.5.2:
dependencies:
crypto-js "^3.1.9-1"
react-native-iphone-x-helper@^1.0.1:
react-native-iphone-x-helper@^1.0.1, react-native-iphone-x-helper@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/react-native-iphone-x-helper/-/react-native-iphone-x-helper-1.0.2.tgz#7dbca530930f7c1ce8633cc8fd13ba94102992e1"
@ -7806,9 +7817,9 @@ react-native-svg@^6.0.0:
lodash "^4.16.6"
pegjs "^0.10.0"
react-native-tab-view@^0.0.74:
"react-native-tab-view@github:react-navigation/react-native-tab-view":
version "0.0.74"
resolved "https://registry.yarnpkg.com/react-native-tab-view/-/react-native-tab-view-0.0.74.tgz#62c0c882d9232b461ce181d440d683b4f99d1bd8"
resolved "https://codeload.github.com/react-navigation/react-native-tab-view/tar.gz/36ebd834d78b841fc19778c966465d02fd1213bb"
dependencies:
prop-types "^15.6.0"
@ -7902,17 +7913,18 @@ react-native@0.54:
xmldoc "^0.4.0"
yargs "^9.0.0"
react-navigation@^1.3.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/react-navigation/-/react-navigation-1.4.0.tgz#2e1ec70a5d37af78d4b2cab588caf179b2b16859"
react-navigation@^1.5.9:
version "1.5.9"
resolved "https://registry.yarnpkg.com/react-navigation/-/react-navigation-1.5.9.tgz#2740fd1b0056559c1d15f12958f6b30448a2154d"
dependencies:
clamp "^1.0.1"
hoist-non-react-statics "^2.2.0"
path-to-regexp "^1.7.0"
prop-types "^15.5.10"
react-lifecycles-compat "^1.0.2"
react-native-drawer-layout-polyfill "^1.3.2"
react-native-safe-area-view "^0.7.0"
react-native-tab-view "^0.0.74"
react-native-tab-view "github:react-navigation/react-native-tab-view"
react-proxy@^1.1.7:
version "1.1.8"
@ -9486,8 +9498,8 @@ typical@^2.6.0, typical@^2.6.1:
resolved "https://registry.yarnpkg.com/typical/-/typical-2.6.1.tgz#5c080e5d661cbbe38259d2e70a3c7253e873881d"
ua-parser-js@^0.7.9:
version "0.7.14"
resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.14.tgz#110d53fa4c3f326c121292bbeac904d2e03387ca"
version "0.7.17"
resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.17.tgz#e9ec5f9498b9ec910e7ae3ac626a805c4d09ecac"
uglify-es@^3.1.9, uglify-es@^3.3.4:
version "3.3.10"
@ -9866,8 +9878,8 @@ whatwg-encoding@^1.0.3:
iconv-lite "0.4.19"
whatwg-fetch@>=0.10.0:
version "2.0.3"
resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-2.0.3.tgz#9c84ec2dcf68187ff00bc64e1274b442176e1c84"
version "2.0.4"
resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-2.0.4.tgz#dde6a5df315f9d39991aa17621853d720b85566f"
whatwg-fetch@^1.0.0:
version "1.1.1"