1
0
mirror of https://github.com/laurent22/joplin.git synced 2024-12-24 10:27:10 +02:00

RN: Replaced broken Picker by custom dropdown

This commit is contained in:
Laurent Cozic 2017-11-18 23:59:07 +00:00
parent f126e0a944
commit 0c14a42b28
7 changed files with 330 additions and 828 deletions

View File

@ -0,0 +1,129 @@
const React = require('react');
const { TouchableOpacity, TouchableWithoutFeedback , Dimensions, Text, Modal, View } = require('react-native');
const { ItemList } = require('lib/components/ItemList.js');
class Dropdown extends React.Component {
constructor() {
super();
this.headerRef_ = null;
}
componentWillMount() {
this.setState({
headerSize: { x: 0, y: 0, width: 0, height: 0 },
listVisible: false,
});
}
componentDidMount() {
// https://stackoverflow.com/questions/30096038/react-native-getting-the-position-of-an-element
setTimeout(() => {
this.headerRef_.measure((fx, fy, width, height, px, py) => {
this.setState({
headerSize: { x: px, y: py, width: width, height: height }
});
});
}, 100);
}
render() {
const items = this.props.items;
const itemHeight = 60;
const windowHeight = Dimensions.get('window').height - 50;
// Dimensions doesn't return quite the right dimensions so leave an extra gap to make
// sure nothing is off screen.
const listMaxHeight = windowHeight;
const listHeight = Math.min(items.length * itemHeight, listMaxHeight); //Dimensions.get('window').height - this.state.headerSize.y - this.state.headerSize.height - 50;
const maxListTop = windowHeight - listHeight;
const listTop = Math.min(maxListTop, this.state.headerSize.y + this.state.headerSize.height);
const wrapperStyle = {
width: this.state.headerSize.width,
height: listHeight + 2, // +2 for the border (otherwise it makes the scrollbar appear)
marginTop: listTop,
marginLeft: this.state.headerSize.x,
};
const itemListStyle = Object.assign({}, this.props.itemListStyle ? this.props.itemListStyle : {}, {
borderWidth: 1,
borderColor: '#ccc',
});
const itemWrapperStyle = Object.assign({}, this.props.itemWrapperStyle ? this.props.itemWrapperStyle : {}, {
flex:1,
justifyContent: 'center',
height: itemHeight,
paddingLeft: 20,
paddingRight: 10,
});
const headerWrapperStyle = Object.assign({}, this.props.headerWrapperStyle ? this.props.headerWrapperStyle : {}, {
height: 35,
// borderWidth: 1,
// borderColor: '#ccc',
paddingLeft: 20,
paddingRight: 20,
flex: 1,
flexDirection: 'row',
alignItems: 'center',
});
const headerStyle = Object.assign({}, this.props.headerStyle ? this.props.headerStyle : {}, {
flex: 1,
});
const headerArrowStyle = Object.assign({}, this.props.headerStyle ? this.props.headerStyle : {}, {
flex: 0,
});
const itemStyle = Object.assign({}, this.props.itemStyle ? this.props.itemStyle : {}, {
});
let headerLabel = '...';
for (let i = 0; i < items.length; i++) {
const item = items[i];
if (item.value === this.props.selectedValue) headerLabel = item.label;
}
const closeList = () => {
this.setState({ listVisible: false });
}
const itemRenderer= (item) => {
return (
<TouchableOpacity style={itemWrapperStyle} key={item.value} onPress={() => { closeList(); if (this.props.onValueChange) this.props.onValueChange(item.value); }}>
<Text ellipsizeMode="tail" numberOfLines={1} style={itemStyle} key={item.value}>{item.label}</Text>
</TouchableOpacity>
);
}
return (
<View style={{flex: 1, flexDirection: 'column' }}>
<TouchableOpacity style={headerWrapperStyle} ref={(ref) => this.headerRef_ = ref} onPress={() => { this.setState({ listVisible: true }) }}>
<Text ellipsizeMode="tail" numberOfLines={1} style={headerStyle}>{headerLabel}</Text>
<Text style={headerArrowStyle}>{'▼'}</Text>
</TouchableOpacity>
<Modal transparent={true} visible={this.state.listVisible} onRequestClose={() => { closeList(); }} >
<TouchableWithoutFeedback onPressOut={() => { closeList() }}>
<View style={{flex:1}}>
<View style={wrapperStyle}>
<ItemList
style={itemListStyle}
items={this.props.items}
itemHeight={itemHeight}
itemRenderer={(item) => { return itemRenderer(item) }}
/>
</View>
</View>
</TouchableWithoutFeedback>
</Modal>
</View>
);
}
}
module.exports = { Dropdown };

View File

@ -0,0 +1,103 @@
const React = require('react');
const { Text, TouchableHighlight, View, StyleSheet, ScrollView } = require('react-native');
class ItemList extends React.Component {
constructor() {
super();
this.scrollTop_ = 0;
}
itemCount(props = null) {
if (props === null) props = this.props;
return this.props.items ? this.props.items.length : this.props.itemComponents.length;
}
updateStateItemIndexes(props = null, height = null) {
if (props === null) props = this.props;
if (height === null) {
if (!this.state) return;
height = this.state.height;
}
const topItemIndex = Math.max(0, Math.floor(this.scrollTop_ / props.itemHeight));
const visibleItemCount = Math.ceil(height / props.itemHeight);
let bottomItemIndex = topItemIndex + visibleItemCount - 1;
if (bottomItemIndex >= this.itemCount(props)) bottomItemIndex = this.itemCount(props) - 1;
this.setState({
topItemIndex: topItemIndex,
bottomItemIndex: bottomItemIndex,
});
}
componentWillMount() {
this.setState({
topItemIndex: 0,
bottomItemIndex: 0,
height: 0,
itemHeight: this.props.itemHeight ? this.props.itemHeight : 0,
});
this.updateStateItemIndexes();
}
componentWillReceiveProps(newProps) {
if (newProps.itemHeight) {
this.setState({
itemHeight: newProps.itemHeight,
});
}
this.updateStateItemIndexes(newProps);
}
onScroll(event) {
this.scrollTop_ = Math.floor(event.nativeEvent.contentOffset.y);
this.updateStateItemIndexes();
}
onLayout(event) {
this.setState({ height: event.nativeEvent.layout.height });
this.updateStateItemIndexes(null, event.nativeEvent.layout.height);
}
render() {
const style = this.props.style ? this.props.style : {};
const itemHeight = this.state.itemHeight;
//if (!this.props.itemHeight) throw new Error('itemHeight is required');
let itemComps = [];
if (this.props.items) {
const items = this.props.items;
const blankItem = function(key, height) {
return <View key={key} style={{height:height}}></View>
}
itemComps = [blankItem('top', this.state.topItemIndex * this.props.itemHeight)];
for (let i = this.state.topItemIndex; i <= this.state.bottomItemIndex; i++) {
const itemComp = this.props.itemRenderer(items[i]);
itemComps.push(itemComp);
}
itemComps.push(blankItem('bottom', (items.length - this.state.bottomItemIndex - 1) * this.props.itemHeight));
} else {
itemComps = this.props.itemComponents;
}
return (
<ScrollView scrollEventThrottle={500} onLayout={(event) => { this.onLayout(event); }} style={style} onScroll={ (event) => { this.onScroll(event) }}>
{ itemComps }
</ScrollView>
);
}
}
module.exports = { ItemList };

View File

@ -1,6 +1,6 @@
const React = require('react'); const Component = React.Component;
const { connect } = require('react-redux');
const { View, Text, Button, StyleSheet, TouchableOpacity, Picker, Image } = require('react-native');
const { Modal, View, Text, Button, StyleSheet, TouchableOpacity, Image } = require('react-native');
const Icon = require('react-native-vector-icons/Ionicons').default;
const { Log } = require('lib/log.js');
const { BackButtonService } = require('lib/services/back-button.js');
@ -11,6 +11,8 @@ const { FileApi } = require('lib/file-api.js');
const { FileApiDriverOneDrive } = require('lib/file-api-driver-onedrive.js');
const { reg } = require('lib/registry.js');
const { themeStyle } = require('lib/components/global-style.js');
const { ItemList } = require('lib/components/ItemList.js');
const { Dropdown } = require('lib/components/Dropdown.js');
// Rather than applying a padding to the whole bar, it is applied to each
// individual component (button, picker, etc.) so that the touchable areas
@ -40,11 +42,6 @@ class ScreenHeaderComponent extends Component {
shadowColor: '#000000',
elevation: 5,
},
folderPicker: {
flex:1,
color: theme.raisedHighlightedColor,
// Note: cannot set backgroundStyle as that would remove the arrow in the component
},
divider: {
borderBottomWidth: 1,
borderColor: theme.dividerColor,
@ -265,19 +262,29 @@ class ScreenHeaderComponent extends Component {
</MenuOption>);
const createTitleComponent = () => {
const themeId = Setting.value('theme');
const theme = themeStyle(themeId);
const p = this.props.titlePicker;
if (p) {
let items = [];
for (let i = 0; i < p.items.length; i++) {
let item = p.items[i];
items.push(<Picker.Item label={item.label} value={item.value} key={item.value}/>);
}
return (
<View style={{ flex: 1 }}>
<Picker style={this.styles().folderPicker} selectedValue={p.selectedValue} onValueChange={(itemValue, itemIndex) => { if (p.onValueChange) p.onValueChange(itemValue, itemIndex); }}>
{ items }
</Picker>
</View>
<Dropdown
items={p.items}
itemHeight={35}
selectedValue={p.selectedValue}
itemListStyle={{
backgroundColor: theme.backgroundColor,
}}
headerStyle={{
color: theme.raisedColor,
fontSize: theme.fontSize,
}}
itemStyle={{
color: theme.color,
fontSize: theme.fontSize,
}}
onValueChange={(itemValue, itemIndex) => { if (p.onValueChange) p.onValueChange(itemValue, itemIndex); }}
/>
);
} else {
let title = 'title' in this.props && this.props.title !== null ? this.props.title : '';
@ -294,7 +301,7 @@ class ScreenHeaderComponent extends Component {
{ saveButton(this.styles(), () => { if (this.props.onSaveButtonPress) this.props.onSaveButtonPress() }, this.props.saveButtonDisabled === true, this.props.showSaveButton === true) }
{ titleComp }
{ searchButton(this.styles(), () => this.searchButton_press()) }
<Menu onSelect={(value) => this.menu_select(value)} style={this.styles().contextMenu}>
<Menu onSelect={(value) => this.menu_select(value)} style={this.styles().contextMenu}>
<MenuTrigger style={{ paddingTop: PADDING_V, paddingBottom: PADDING_V }}>
<Text style={this.styles().contextMenuTrigger}> &#8942;</Text>
</MenuTrigger>

View File

@ -1,9 +1,10 @@
const React = require('react'); const Component = React.Component;
const { View, Switch, Slider, StyleSheet, Picker, Text, Button } = require('react-native');
const { View, Switch, Slider, StyleSheet, Text, Button, ScrollView } = require('react-native');
const { connect } = require('react-redux');
const { ScreenHeader } = require('lib/components/screen-header.js');
const { _, setLocale } = require('lib/locale.js');
const { BaseScreenComponent } = require('lib/components/base-screen.js');
const { Dropdown } = require('lib/components/Dropdown.js');
const { themeStyle } = require('lib/components/global-style.js');
const { Setting } = require('lib/models/setting.js');
@ -26,7 +27,14 @@ class ConfigScreenComponent extends BaseScreenComponent {
this.styles_ = {};
let styles = {
body: {
flex: 1,
justifyContent: 'flex-start',
flexDirection: 'column',
},
settingContainer: {
flex: 1,
flexDirection: 'row',
borderBottomWidth: 1,
borderBottomColor: theme.dividerColor,
paddingTop: theme.marginTop,
@ -38,13 +46,12 @@ class ConfigScreenComponent extends BaseScreenComponent {
fontWeight: 'bold',
color: theme.color,
fontSize: theme.fontSize,
flex: 1,
},
settingControl: {
color: theme.color,
flex: 1,
},
pickerItem: {
fontSize: theme.fontSize,
}
}
styles.switchSettingText = Object.assign({}, styles.settingText);
@ -63,6 +70,8 @@ class ConfigScreenComponent extends BaseScreenComponent {
}
settingToComponent(key, value) {
const themeId = this.props.theme;
const theme = themeStyle(themeId);
let output = null;
const updateSettingValue = (key, value) => {
@ -72,25 +81,36 @@ class ConfigScreenComponent extends BaseScreenComponent {
const md = Setting.settingMetadata(key);
if (md.isEnum) {
// The Picker component doesn't work properly with int values, so
// convert everything to string (Setting.setValue will convert
// back to the correct type.
value = value.toString();
let items = [];
const settingOptions = md.options();
for (let k in settingOptions) {
if (!settingOptions.hasOwnProperty(k)) continue;
items.push(<Picker.Item label={settingOptions[k]} value={k.toString()} key={k}/>);
items.push({ label: settingOptions[k], value: k.toString() });
}
return (
<View key={key} style={this.styles().settingContainer}>
<Text key="label" style={this.styles().settingText}>{md.label()}</Text>
<Picker key="control" style={this.styles().settingControl} selectedValue={value} onValueChange={(itemValue, itemIndex) => updateSettingValue(key, itemValue)} >
{ items }
</Picker>
<Dropdown
key="control"
style={this.styles().settingControl}
items={items}
selectedValue={value}
itemListStyle={{
backgroundColor: theme.backgroundColor,
}}
headerStyle={{
color: theme.color,
fontSize: theme.fontSize,
}}
itemStyle={{
color: theme.color,
fontSize: theme.fontSize,
}}
onValueChange={(itemValue, itemIndex) => { updateSettingValue(key, itemValue); }}
/>
</View>
);
} else if (md.type == Setting.TYPE_BOOL) {
@ -128,12 +148,14 @@ class ConfigScreenComponent extends BaseScreenComponent {
settingComps.push(comp);
}
//style={this.styles().body}
return (
<View style={this.rootStyle(this.props.theme).root}>
<ScreenHeader title={_('Configuration')}/>
<View style={this.styles().body}>
<ScrollView >
{ settingComps }
</View>
</ScrollView>
</View>
);
}

View File

@ -1,5 +1,5 @@
const React = require('react'); const Component = React.Component;
const { View, Button, Picker } = require('react-native');
const { View, Button } = require('react-native');
const { connect } = require('react-redux');
const { reg } = require('lib/registry.js');
const { Log } = require('lib/log.js');

View File

@ -2087,795 +2087,6 @@
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
},
"fsevents": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.1.3.tgz",
"integrity": "sha512-WIr7iDkdmdbxu/Gh6eKEZJL6KPE74/5MEsf2whTOFNxbIoIixogroLdKYqB6FDav4Wavh/lZdzzd3b2KxIXC5Q==",
"optional": true,
"requires": {
"nan": "2.8.0",
"node-pre-gyp": "0.6.39"
},
"dependencies": {
"abbrev": {
"version": "1.1.0",
"bundled": true,
"optional": true
},
"ajv": {
"version": "4.11.8",
"bundled": true,
"optional": true,
"requires": {
"co": "4.6.0",
"json-stable-stringify": "1.0.1"
}
},
"ansi-regex": {
"version": "2.1.1",
"bundled": true
},
"aproba": {
"version": "1.1.1",
"bundled": true,
"optional": true
},
"are-we-there-yet": {
"version": "1.1.4",
"bundled": true,
"optional": true,
"requires": {
"delegates": "1.0.0",
"readable-stream": "2.2.9"
}
},
"asn1": {
"version": "0.2.3",
"bundled": true,
"optional": true
},
"assert-plus": {
"version": "0.2.0",
"bundled": true,
"optional": true
},
"asynckit": {
"version": "0.4.0",
"bundled": true,
"optional": true
},
"aws-sign2": {
"version": "0.6.0",
"bundled": true,
"optional": true
},
"aws4": {
"version": "1.6.0",
"bundled": true,
"optional": true
},
"balanced-match": {
"version": "0.4.2",
"bundled": true
},
"bcrypt-pbkdf": {
"version": "1.0.1",
"bundled": true,
"optional": true,
"requires": {
"tweetnacl": "0.14.5"
}
},
"block-stream": {
"version": "0.0.9",
"bundled": true,
"requires": {
"inherits": "2.0.3"
}
},
"boom": {
"version": "2.10.1",
"bundled": true,
"requires": {
"hoek": "2.16.3"
}
},
"brace-expansion": {
"version": "1.1.7",
"bundled": true,
"requires": {
"balanced-match": "0.4.2",
"concat-map": "0.0.1"
}
},
"buffer-shims": {
"version": "1.0.0",
"bundled": true
},
"caseless": {
"version": "0.12.0",
"bundled": true,
"optional": true
},
"co": {
"version": "4.6.0",
"bundled": true,
"optional": true
},
"code-point-at": {
"version": "1.1.0",
"bundled": true
},
"combined-stream": {
"version": "1.0.5",
"bundled": true,
"requires": {
"delayed-stream": "1.0.0"
}
},
"concat-map": {
"version": "0.0.1",
"bundled": true
},
"console-control-strings": {
"version": "1.1.0",
"bundled": true
},
"core-util-is": {
"version": "1.0.2",
"bundled": true
},
"cryptiles": {
"version": "2.0.5",
"bundled": true,
"requires": {
"boom": "2.10.1"
}
},
"dashdash": {
"version": "1.14.1",
"bundled": true,
"optional": true,
"requires": {
"assert-plus": "1.0.0"
},
"dependencies": {
"assert-plus": {
"version": "1.0.0",
"bundled": true,
"optional": true
}
}
},
"debug": {
"version": "2.6.8",
"bundled": true,
"optional": true,
"requires": {
"ms": "2.0.0"
}
},
"deep-extend": {
"version": "0.4.2",
"bundled": true,
"optional": true
},
"delayed-stream": {
"version": "1.0.0",
"bundled": true
},
"delegates": {
"version": "1.0.0",
"bundled": true,
"optional": true
},
"detect-libc": {
"version": "1.0.2",
"bundled": true,
"optional": true
},
"ecc-jsbn": {
"version": "0.1.1",
"bundled": true,
"optional": true,
"requires": {
"jsbn": "0.1.1"
}
},
"extend": {
"version": "3.0.1",
"bundled": true,
"optional": true
},
"extsprintf": {
"version": "1.0.2",
"bundled": true
},
"forever-agent": {
"version": "0.6.1",
"bundled": true,
"optional": true
},
"form-data": {
"version": "2.1.4",
"bundled": true,
"optional": true,
"requires": {
"asynckit": "0.4.0",
"combined-stream": "1.0.5",
"mime-types": "2.1.15"
}
},
"fs.realpath": {
"version": "1.0.0",
"bundled": true
},
"fstream": {
"version": "1.0.11",
"bundled": true,
"requires": {
"graceful-fs": "4.1.11",
"inherits": "2.0.3",
"mkdirp": "0.5.1",
"rimraf": "2.6.1"
}
},
"fstream-ignore": {
"version": "1.0.5",
"bundled": true,
"optional": true,
"requires": {
"fstream": "1.0.11",
"inherits": "2.0.3",
"minimatch": "3.0.4"
}
},
"gauge": {
"version": "2.7.4",
"bundled": true,
"optional": true,
"requires": {
"aproba": "1.1.1",
"console-control-strings": "1.1.0",
"has-unicode": "2.0.1",
"object-assign": "4.1.1",
"signal-exit": "3.0.2",
"string-width": "1.0.2",
"strip-ansi": "3.0.1",
"wide-align": "1.1.2"
}
},
"getpass": {
"version": "0.1.7",
"bundled": true,
"optional": true,
"requires": {
"assert-plus": "1.0.0"
},
"dependencies": {
"assert-plus": {
"version": "1.0.0",
"bundled": true,
"optional": true
}
}
},
"glob": {
"version": "7.1.2",
"bundled": true,
"requires": {
"fs.realpath": "1.0.0",
"inflight": "1.0.6",
"inherits": "2.0.3",
"minimatch": "3.0.4",
"once": "1.4.0",
"path-is-absolute": "1.0.1"
}
},
"graceful-fs": {
"version": "4.1.11",
"bundled": true
},
"har-schema": {
"version": "1.0.5",
"bundled": true,
"optional": true
},
"har-validator": {
"version": "4.2.1",
"bundled": true,
"optional": true,
"requires": {
"ajv": "4.11.8",
"har-schema": "1.0.5"
}
},
"has-unicode": {
"version": "2.0.1",
"bundled": true,
"optional": true
},
"hawk": {
"version": "3.1.3",
"bundled": true,
"requires": {
"boom": "2.10.1",
"cryptiles": "2.0.5",
"hoek": "2.16.3",
"sntp": "1.0.9"
}
},
"hoek": {
"version": "2.16.3",
"bundled": true
},
"http-signature": {
"version": "1.1.1",
"bundled": true,
"optional": true,
"requires": {
"assert-plus": "0.2.0",
"jsprim": "1.4.0",
"sshpk": "1.13.0"
}
},
"inflight": {
"version": "1.0.6",
"bundled": true,
"requires": {
"once": "1.4.0",
"wrappy": "1.0.2"
}
},
"inherits": {
"version": "2.0.3",
"bundled": true
},
"ini": {
"version": "1.3.4",
"bundled": true,
"optional": true
},
"is-fullwidth-code-point": {
"version": "1.0.0",
"bundled": true,
"requires": {
"number-is-nan": "1.0.1"
}
},
"is-typedarray": {
"version": "1.0.0",
"bundled": true,
"optional": true
},
"isarray": {
"version": "1.0.0",
"bundled": true
},
"isstream": {
"version": "0.1.2",
"bundled": true,
"optional": true
},
"jodid25519": {
"version": "1.0.2",
"bundled": true,
"optional": true,
"requires": {
"jsbn": "0.1.1"
}
},
"jsbn": {
"version": "0.1.1",
"bundled": true,
"optional": true
},
"json-schema": {
"version": "0.2.3",
"bundled": true,
"optional": true
},
"json-stable-stringify": {
"version": "1.0.1",
"bundled": true,
"optional": true,
"requires": {
"jsonify": "0.0.0"
}
},
"json-stringify-safe": {
"version": "5.0.1",
"bundled": true,
"optional": true
},
"jsonify": {
"version": "0.0.0",
"bundled": true,
"optional": true
},
"jsprim": {
"version": "1.4.0",
"bundled": true,
"optional": true,
"requires": {
"assert-plus": "1.0.0",
"extsprintf": "1.0.2",
"json-schema": "0.2.3",
"verror": "1.3.6"
},
"dependencies": {
"assert-plus": {
"version": "1.0.0",
"bundled": true,
"optional": true
}
}
},
"mime-db": {
"version": "1.27.0",
"bundled": true
},
"mime-types": {
"version": "2.1.15",
"bundled": true,
"requires": {
"mime-db": "1.27.0"
}
},
"minimatch": {
"version": "3.0.4",
"bundled": true,
"requires": {
"brace-expansion": "1.1.7"
}
},
"minimist": {
"version": "0.0.8",
"bundled": true
},
"mkdirp": {
"version": "0.5.1",
"bundled": true,
"requires": {
"minimist": "0.0.8"
}
},
"ms": {
"version": "2.0.0",
"bundled": true,
"optional": true
},
"node-pre-gyp": {
"version": "0.6.39",
"bundled": true,
"optional": true,
"requires": {
"detect-libc": "1.0.2",
"hawk": "3.1.3",
"mkdirp": "0.5.1",
"nopt": "4.0.1",
"npmlog": "4.1.0",
"rc": "1.2.1",
"request": "2.81.0",
"rimraf": "2.6.1",
"semver": "5.3.0",
"tar": "2.2.1",
"tar-pack": "3.4.0"
}
},
"nopt": {
"version": "4.0.1",
"bundled": true,
"optional": true,
"requires": {
"abbrev": "1.1.0",
"osenv": "0.1.4"
}
},
"npmlog": {
"version": "4.1.0",
"bundled": true,
"optional": true,
"requires": {
"are-we-there-yet": "1.1.4",
"console-control-strings": "1.1.0",
"gauge": "2.7.4",
"set-blocking": "2.0.0"
}
},
"number-is-nan": {
"version": "1.0.1",
"bundled": true
},
"oauth-sign": {
"version": "0.8.2",
"bundled": true,
"optional": true
},
"object-assign": {
"version": "4.1.1",
"bundled": true,
"optional": true
},
"once": {
"version": "1.4.0",
"bundled": true,
"requires": {
"wrappy": "1.0.2"
}
},
"os-homedir": {
"version": "1.0.2",
"bundled": true,
"optional": true
},
"os-tmpdir": {
"version": "1.0.2",
"bundled": true,
"optional": true
},
"osenv": {
"version": "0.1.4",
"bundled": true,
"optional": true,
"requires": {
"os-homedir": "1.0.2",
"os-tmpdir": "1.0.2"
}
},
"path-is-absolute": {
"version": "1.0.1",
"bundled": true
},
"performance-now": {
"version": "0.2.0",
"bundled": true,
"optional": true
},
"process-nextick-args": {
"version": "1.0.7",
"bundled": true
},
"punycode": {
"version": "1.4.1",
"bundled": true,
"optional": true
},
"qs": {
"version": "6.4.0",
"bundled": true,
"optional": true
},
"rc": {
"version": "1.2.1",
"bundled": true,
"optional": true,
"requires": {
"deep-extend": "0.4.2",
"ini": "1.3.4",
"minimist": "1.2.0",
"strip-json-comments": "2.0.1"
},
"dependencies": {
"minimist": {
"version": "1.2.0",
"bundled": true,
"optional": true
}
}
},
"readable-stream": {
"version": "2.2.9",
"bundled": true,
"requires": {
"buffer-shims": "1.0.0",
"core-util-is": "1.0.2",
"inherits": "2.0.3",
"isarray": "1.0.0",
"process-nextick-args": "1.0.7",
"string_decoder": "1.0.1",
"util-deprecate": "1.0.2"
}
},
"request": {
"version": "2.81.0",
"bundled": true,
"optional": true,
"requires": {
"aws-sign2": "0.6.0",
"aws4": "1.6.0",
"caseless": "0.12.0",
"combined-stream": "1.0.5",
"extend": "3.0.1",
"forever-agent": "0.6.1",
"form-data": "2.1.4",
"har-validator": "4.2.1",
"hawk": "3.1.3",
"http-signature": "1.1.1",
"is-typedarray": "1.0.0",
"isstream": "0.1.2",
"json-stringify-safe": "5.0.1",
"mime-types": "2.1.15",
"oauth-sign": "0.8.2",
"performance-now": "0.2.0",
"qs": "6.4.0",
"safe-buffer": "5.0.1",
"stringstream": "0.0.5",
"tough-cookie": "2.3.2",
"tunnel-agent": "0.6.0",
"uuid": "3.0.1"
}
},
"rimraf": {
"version": "2.6.1",
"bundled": true,
"requires": {
"glob": "7.1.2"
}
},
"safe-buffer": {
"version": "5.0.1",
"bundled": true
},
"semver": {
"version": "5.3.0",
"bundled": true,
"optional": true
},
"set-blocking": {
"version": "2.0.0",
"bundled": true,
"optional": true
},
"signal-exit": {
"version": "3.0.2",
"bundled": true,
"optional": true
},
"sntp": {
"version": "1.0.9",
"bundled": true,
"requires": {
"hoek": "2.16.3"
}
},
"sshpk": {
"version": "1.13.0",
"bundled": true,
"optional": true,
"requires": {
"asn1": "0.2.3",
"assert-plus": "1.0.0",
"bcrypt-pbkdf": "1.0.1",
"dashdash": "1.14.1",
"ecc-jsbn": "0.1.1",
"getpass": "0.1.7",
"jodid25519": "1.0.2",
"jsbn": "0.1.1",
"tweetnacl": "0.14.5"
},
"dependencies": {
"assert-plus": {
"version": "1.0.0",
"bundled": true,
"optional": true
}
}
},
"string-width": {
"version": "1.0.2",
"bundled": true,
"requires": {
"code-point-at": "1.1.0",
"is-fullwidth-code-point": "1.0.0",
"strip-ansi": "3.0.1"
}
},
"string_decoder": {
"version": "1.0.1",
"bundled": true,
"requires": {
"safe-buffer": "5.0.1"
}
},
"stringstream": {
"version": "0.0.5",
"bundled": true,
"optional": true
},
"strip-ansi": {
"version": "3.0.1",
"bundled": true,
"requires": {
"ansi-regex": "2.1.1"
}
},
"strip-json-comments": {
"version": "2.0.1",
"bundled": true,
"optional": true
},
"tar": {
"version": "2.2.1",
"bundled": true,
"requires": {
"block-stream": "0.0.9",
"fstream": "1.0.11",
"inherits": "2.0.3"
}
},
"tar-pack": {
"version": "3.4.0",
"bundled": true,
"optional": true,
"requires": {
"debug": "2.6.8",
"fstream": "1.0.11",
"fstream-ignore": "1.0.5",
"once": "1.4.0",
"readable-stream": "2.2.9",
"rimraf": "2.6.1",
"tar": "2.2.1",
"uid-number": "0.0.6"
}
},
"tough-cookie": {
"version": "2.3.2",
"bundled": true,
"optional": true,
"requires": {
"punycode": "1.4.1"
}
},
"tunnel-agent": {
"version": "0.6.0",
"bundled": true,
"optional": true,
"requires": {
"safe-buffer": "5.0.1"
}
},
"tweetnacl": {
"version": "0.14.5",
"bundled": true,
"optional": true
},
"uid-number": {
"version": "0.0.6",
"bundled": true,
"optional": true
},
"util-deprecate": {
"version": "1.0.2",
"bundled": true
},
"uuid": {
"version": "3.0.1",
"bundled": true,
"optional": true
},
"verror": {
"version": "1.3.6",
"bundled": true,
"optional": true,
"requires": {
"extsprintf": "1.0.2"
}
},
"wide-align": {
"version": "1.1.2",
"bundled": true,
"optional": true,
"requires": {
"string-width": "1.0.2"
}
},
"wrappy": {
"version": "1.0.2",
"bundled": true
}
}
},
"gauge": {
"version": "1.2.7",
"resolved": "https://registry.npmjs.org/gauge/-/gauge-1.2.7.tgz",
@ -4759,12 +3970,6 @@
"resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz",
"integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s="
},
"nan": {
"version": "2.8.0",
"resolved": "https://registry.npmjs.org/nan/-/nan-2.8.0.tgz",
"integrity": "sha1-7XFfP+neArV6XmJS2QqWZ14fCFo=",
"optional": true
},
"natural-compare": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
@ -5445,6 +4650,42 @@
"resolved": "https://registry.npmjs.org/react-native-image-resizer/-/react-native-image-resizer-1.0.0.tgz",
"integrity": "sha1-1H4UlDw3k44of71jnk23zrf9iRc="
},
"react-native-material-buttons": {
"version": "0.5.0",
"resolved": "https://registry.npmjs.org/react-native-material-buttons/-/react-native-material-buttons-0.5.0.tgz",
"integrity": "sha1-qys+P8P1AMpxP1Hp11l4r/YCFSo=",
"requires": {
"prop-types": "15.6.0",
"react-native-material-ripple": "0.7.5"
}
},
"react-native-material-dropdown": {
"version": "0.5.2",
"resolved": "https://registry.npmjs.org/react-native-material-dropdown/-/react-native-material-dropdown-0.5.2.tgz",
"integrity": "sha1-tdcNb+JiiCapOwhbaDheyONIvC8=",
"requires": {
"prop-types": "15.6.0",
"react-native-material-buttons": "0.5.0",
"react-native-material-ripple": "0.7.5",
"react-native-material-textfield": "0.10.2"
}
},
"react-native-material-ripple": {
"version": "0.7.5",
"resolved": "https://registry.npmjs.org/react-native-material-ripple/-/react-native-material-ripple-0.7.5.tgz",
"integrity": "sha1-4q9REGgFMvFK6jw6Q4JHvi/+9lk=",
"requires": {
"prop-types": "15.6.0"
}
},
"react-native-material-textfield": {
"version": "0.10.2",
"resolved": "https://registry.npmjs.org/react-native-material-textfield/-/react-native-material-textfield-0.10.2.tgz",
"integrity": "sha1-MOxDCyomGraUFBGZ+7quRlQX9Do=",
"requires": {
"prop-types": "15.6.0"
}
},
"react-native-popup-dialog": {
"version": "0.9.38",
"resolved": "https://registry.npmjs.org/react-native-popup-dialog/-/react-native-popup-dialog-0.9.38.tgz",
@ -5981,7 +5222,6 @@
"anymatch": "1.3.2",
"exec-sh": "0.2.1",
"fb-watchman": "2.0.0",
"fsevents": "1.1.3",
"minimatch": "3.0.4",
"minimist": "1.2.0",
"walker": "1.0.7",

View File

@ -25,6 +25,7 @@
"react-native-fetch-blob": "^0.10.6",
"react-native-fs": "^2.8.1",
"react-native-image-resizer": "^1.0.0",
"react-native-material-dropdown": "^0.5.2",
"react-native-popup-dialog": "^0.9.35",
"react-native-popup-menu": "^0.8.3",
"react-native-side-menu": "^1.1.3",