Commit everything done until beginning version control
Removed the boilerplate's counter, started a drawer menu, added a toolbar to access the menu, created the calculator form and state.
This commit is contained in:
parent
ff17b2a0d3
commit
7f6fc32d74
|
@ -66,6 +66,7 @@ import com.android.build.OutputFile
|
||||||
*/
|
*/
|
||||||
|
|
||||||
apply from: "../../node_modules/react-native/react.gradle"
|
apply from: "../../node_modules/react-native/react.gradle"
|
||||||
|
apply from: "../../node_modules/react-native-vector-icons/fonts.gradle"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set this to true to create two separate APKs instead of one:
|
* Set this to true to create two separate APKs instead of one:
|
||||||
|
@ -129,6 +130,8 @@ dependencies {
|
||||||
compile fileTree(dir: "libs", include: ["*.jar"])
|
compile fileTree(dir: "libs", include: ["*.jar"])
|
||||||
compile "com.android.support:appcompat-v7:23.0.1"
|
compile "com.android.support:appcompat-v7:23.0.1"
|
||||||
compile "com.facebook.react:react-native:+" // From node_modules
|
compile "com.facebook.react:react-native:+" // From node_modules
|
||||||
|
compile project(':react-native-vector-icons')
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Run this once to be able to run the application with BUCK
|
// Run this once to be able to run the application with BUCK
|
||||||
|
|
|
@ -8,6 +8,7 @@ import com.facebook.react.ReactInstanceManager;
|
||||||
import com.facebook.react.ReactNativeHost;
|
import com.facebook.react.ReactNativeHost;
|
||||||
import com.facebook.react.ReactPackage;
|
import com.facebook.react.ReactPackage;
|
||||||
import com.facebook.react.shell.MainReactPackage;
|
import com.facebook.react.shell.MainReactPackage;
|
||||||
|
import com.oblador.vectoricons.VectorIconsPackage;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -24,6 +25,7 @@ public class MainApplication extends Application implements ReactApplication {
|
||||||
protected List<ReactPackage> getPackages() {
|
protected List<ReactPackage> getPackages() {
|
||||||
return Arrays.<ReactPackage>asList(
|
return Arrays.<ReactPackage>asList(
|
||||||
new MainReactPackage()
|
new MainReactPackage()
|
||||||
|
, new VectorIconsPackage()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-2.10-all.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-2.2-all.zip
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
rootProject.name = 'Counter'
|
rootProject.name = 'Counter'
|
||||||
|
|
||||||
include ':app'
|
include ':app'
|
||||||
|
|
||||||
|
include ':react-native-vector-icons'
|
||||||
|
project(':react-native-vector-icons').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-vector-icons/android')
|
||||||
|
|
|
@ -1,2 +0,0 @@
|
||||||
export const INCREMENT = 'INCREMENT';
|
|
||||||
export const DECREMENT = 'DECREMENT';
|
|
|
@ -1,13 +0,0 @@
|
||||||
import * as types from './actionTypes';
|
|
||||||
|
|
||||||
export function increment() {
|
|
||||||
return {
|
|
||||||
type: types.INCREMENT
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export function decrement() {
|
|
||||||
return {
|
|
||||||
type: types.DECREMENT
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -1,36 +0,0 @@
|
||||||
import React, {Component} from 'react';
|
|
||||||
import {StyleSheet, View, Text, TouchableOpacity} from 'react-native';
|
|
||||||
|
|
||||||
const styles = StyleSheet.create({
|
|
||||||
button: {
|
|
||||||
width: 100,
|
|
||||||
height: 30,
|
|
||||||
padding: 10,
|
|
||||||
backgroundColor: 'lightgray',
|
|
||||||
alignItems: 'center',
|
|
||||||
justifyContent: 'center',
|
|
||||||
margin: 3
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
export default class Counter extends Component {
|
|
||||||
constructor(props) {
|
|
||||||
super(props);
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
|
||||||
const { counter, increment, decrement } = this.props;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<View style={{flex: 1, alignItems: 'center', justifyContent: 'center' }}>
|
|
||||||
<Text>{counter}</Text>
|
|
||||||
<TouchableOpacity onPress={increment} style={styles.button}>
|
|
||||||
<Text>up</Text>
|
|
||||||
</TouchableOpacity>
|
|
||||||
<TouchableOpacity onPress={decrement} style={styles.button}>
|
|
||||||
<Text>down</Text>
|
|
||||||
</TouchableOpacity>
|
|
||||||
</View>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,22 +0,0 @@
|
||||||
import * as types from '../actions/actionTypes';
|
|
||||||
|
|
||||||
const initialState = {
|
|
||||||
count: 0
|
|
||||||
};
|
|
||||||
|
|
||||||
export default function counter(state = initialState, action = {}) {
|
|
||||||
switch (action.type) {
|
|
||||||
case types.INCREMENT:
|
|
||||||
return {
|
|
||||||
...state,
|
|
||||||
count: state.count + 1
|
|
||||||
};
|
|
||||||
case types.DECREMENT:
|
|
||||||
return {
|
|
||||||
...state,
|
|
||||||
count: state.count - 1
|
|
||||||
};
|
|
||||||
default:
|
|
||||||
return state;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,5 +0,0 @@
|
||||||
import counter from './counter';
|
|
||||||
|
|
||||||
export {
|
|
||||||
counter
|
|
||||||
};
|
|
|
@ -1,6 +1,6 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import React, { AppRegistry } from 'react-native';
|
import React, { AppRegistry } from 'react-native';
|
||||||
import App from './app/containers/app';
|
import App from './src/containers/app';
|
||||||
|
|
||||||
AppRegistry.registerComponent('Counter', () => App);
|
AppRegistry.registerComponent('Counter', () => App);
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import React, { AppRegistry } from 'react-native';
|
import React, { AppRegistry } from 'react-native';
|
||||||
import App from './app/containers/app';
|
import App from './src/containers/app';
|
||||||
|
|
||||||
AppRegistry.registerComponent('Counter', () => App);
|
AppRegistry.registerComponent('Counter', () => App);
|
||||||
|
|
|
@ -11,6 +11,8 @@
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"react": "15.3.2",
|
"react": "15.3.2",
|
||||||
"react-native": "0.34.0",
|
"react-native": "0.34.0",
|
||||||
|
"react-native-drawer": "^2.3.0",
|
||||||
|
"react-native-vector-icons": "^4.0.0",
|
||||||
"react-redux": "4.4.5",
|
"react-redux": "4.4.5",
|
||||||
"redux": "3.5.2",
|
"redux": "3.5.2",
|
||||||
"redux-actions": "0.11.0",
|
"redux-actions": "0.11.0",
|
||||||
|
|
7
src/actions/actionTypes.js
Normal file
7
src/actions/actionTypes.js
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
export const UPDATEVALUE = 'UPDATEVALUE';
|
||||||
|
export const UPDATEMULT = 'UPDATEMULT';
|
||||||
|
export const MENUOPEN = 'MENUOPEN';
|
||||||
|
export const MENUCLOSE = 'MENUCLOSE';
|
||||||
|
export const MAIN = 'MAIN';
|
||||||
|
export const HELP = 'HELP';
|
||||||
|
export const SETREF = 'SETREF';
|
19
src/actions/calcActions.js
Normal file
19
src/actions/calcActions.js
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
import * as types from './actionTypes';
|
||||||
|
|
||||||
|
export function updatevalue(form, index, value) {
|
||||||
|
return {
|
||||||
|
type: types.UPDATEVALUE,
|
||||||
|
form,
|
||||||
|
index,
|
||||||
|
value,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function updatemult(form, index, mult) {
|
||||||
|
return {
|
||||||
|
type: types.UPDATEMULT,
|
||||||
|
form,
|
||||||
|
index,
|
||||||
|
mult,
|
||||||
|
};
|
||||||
|
}
|
25
src/actions/menuActions.js
Normal file
25
src/actions/menuActions.js
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
import * as types from './actionTypes';
|
||||||
|
|
||||||
|
export function menuopen() {
|
||||||
|
return {
|
||||||
|
type: types.MENUOPEN
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function menuclose() {
|
||||||
|
return {
|
||||||
|
type: types.MENUCLOSE
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function main() {
|
||||||
|
return {
|
||||||
|
type: types.MAIN
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function help() {
|
||||||
|
return {
|
||||||
|
type: types.HELP
|
||||||
|
};
|
||||||
|
}
|
67
src/components/calc.js
Normal file
67
src/components/calc.js
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
import React, {Component} from 'react';
|
||||||
|
import {ScrollView, StyleSheet, Text, TouchableOpacity, View} from 'react-native';
|
||||||
|
|
||||||
|
import Resistor from './resistor';
|
||||||
|
import Section from './section';
|
||||||
|
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
button: {
|
||||||
|
width: 100,
|
||||||
|
height: 30,
|
||||||
|
padding: 10,
|
||||||
|
backgroundColor: 'lightgray',
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center',
|
||||||
|
margin: 3
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
export default class Calc extends Component {
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const {state} = this.props;
|
||||||
|
|
||||||
|
const allValid = state.have.every((x) => x.valid);
|
||||||
|
const nonEmpty = state.have.some((x) => x.value);
|
||||||
|
|
||||||
|
const reciprocalSum = state.have
|
||||||
|
.filter((x) => x.value)
|
||||||
|
.reduce((a,b) => a + 1.0/(b.value * b.mult), 0.0);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ScrollView>
|
||||||
|
<View style={{padding: 20}}>
|
||||||
|
<Section>
|
||||||
|
<Text>
|
||||||
|
Enter the exact resistance target:
|
||||||
|
</Text>
|
||||||
|
<Resistor form="target" />
|
||||||
|
</Section>
|
||||||
|
<Section>
|
||||||
|
<Text>
|
||||||
|
Overall parallel resistor value:
|
||||||
|
{allValid && nonEmpty ? ' ' + 1/reciprocalSum : ' ???'}
|
||||||
|
</Text>
|
||||||
|
<Text>
|
||||||
|
Error between this and the target: {0}%
|
||||||
|
</Text>
|
||||||
|
<Text>
|
||||||
|
Next recommended resistor value: {0}
|
||||||
|
</Text>
|
||||||
|
</Section>
|
||||||
|
<Section>
|
||||||
|
<Text>
|
||||||
|
Enter the resistors you have in parallel:
|
||||||
|
</Text>
|
||||||
|
{state.have.map((x,n) =>
|
||||||
|
<Resistor form="have" index={n} key={n} />
|
||||||
|
)}
|
||||||
|
</Section>
|
||||||
|
</View>
|
||||||
|
</ScrollView>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
24
src/components/help.js
Normal file
24
src/components/help.js
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
import React, {Component} from 'react';
|
||||||
|
import {StyleSheet, View, Text, TouchableOpacity} from 'react-native';
|
||||||
|
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
});
|
||||||
|
|
||||||
|
export default class Help extends Component {
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
//const { counter } = this.props;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<View style={{flex: 1, alignItems: 'center', justifyContent: 'center' }}>
|
||||||
|
<Text>This is a sample counter app.</Text>
|
||||||
|
<Text>Press Increase to add 1 to the value.</Text>
|
||||||
|
<Text>Press Decrease to subtract 1 from the value.</Text>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
29
src/components/menu.js
Normal file
29
src/components/menu.js
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
import React, {Component} from 'react';
|
||||||
|
import {StyleSheet, View, Text, TouchableOpacity} from 'react-native';
|
||||||
|
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
main: {
|
||||||
|
backgroundColor: '#ffffff',
|
||||||
|
flex: 1,
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export default class Menu extends Component {
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const { main, help } = this.props;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<View style={styles.main}>
|
||||||
|
<Text onPress={main}>Calculator</Text>
|
||||||
|
<Text onPress={help}>Help</Text>
|
||||||
|
<Text>Link 4</Text>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
124
src/components/resistor.js
Normal file
124
src/components/resistor.js
Normal file
|
@ -0,0 +1,124 @@
|
||||||
|
import React, {Component} from 'react';
|
||||||
|
import {bindActionCreators} from 'redux';
|
||||||
|
import {connect} from 'react-redux';
|
||||||
|
import {
|
||||||
|
Alert,
|
||||||
|
Picker,
|
||||||
|
StyleSheet,
|
||||||
|
View,
|
||||||
|
Text,
|
||||||
|
TextInput,
|
||||||
|
TouchableOpacity,
|
||||||
|
} from 'react-native';
|
||||||
|
|
||||||
|
import * as calcActions from '../actions/calcActions';
|
||||||
|
|
||||||
|
const styles = {
|
||||||
|
resistorinput: {
|
||||||
|
flex: 1,
|
||||||
|
height: 40,
|
||||||
|
maxWidth: 80,
|
||||||
|
borderWidth: 1,
|
||||||
|
textAlign: 'right',
|
||||||
|
},
|
||||||
|
clearbutton: {
|
||||||
|
height: 30,
|
||||||
|
padding: 10,
|
||||||
|
backgroundColor: 'lightgray',
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center',
|
||||||
|
margin: 3,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
class Resistor extends Component {
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const {data, actions} = this.props;
|
||||||
|
|
||||||
|
// Curry the update functions to make them simpler
|
||||||
|
const updatevalue = (x) => actions.updatevalue(
|
||||||
|
this.props.form, this.props.index, x
|
||||||
|
);
|
||||||
|
const updatemult = (x) => actions.updatemult(
|
||||||
|
this.props.form, this.props.index, x
|
||||||
|
);
|
||||||
|
|
||||||
|
const clear = () => {
|
||||||
|
updatevalue('');
|
||||||
|
updatemult('1');
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(this);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<View style={{flex: 1, flexDirection: 'row', justifyContent: 'center', margin: 3}}>
|
||||||
|
<TextInput
|
||||||
|
value={data.value}
|
||||||
|
onChangeText={(x) => updatevalue(x)}
|
||||||
|
style={Object.assign({}, styles.resistorinput, {
|
||||||
|
borderColor: data.valid ? 'grey' : 'red',
|
||||||
|
})}
|
||||||
|
underlineColorAndroid={'transparent'}
|
||||||
|
autoCorrect={false}
|
||||||
|
keyboardType={'numeric'}
|
||||||
|
/>
|
||||||
|
<Picker
|
||||||
|
ref={(x) => this._picker = x}
|
||||||
|
selectedValue={data.mult}
|
||||||
|
onValueChange={(x) => updatemult(x)}
|
||||||
|
style={{height: 40, width: 100}}
|
||||||
|
mode={'dropdown'}
|
||||||
|
>
|
||||||
|
<Picker.Item label=" MΩ" value="1000000" />
|
||||||
|
<Picker.Item label=" kΩ" value="1000" />
|
||||||
|
<Picker.Item label=" Ω" value="1" />
|
||||||
|
<Picker.Item label=" mΩ" value="0.001" />
|
||||||
|
</Picker>
|
||||||
|
<TouchableOpacity onPress={() => {
|
||||||
|
console.log(this);
|
||||||
|
Alert.alert(
|
||||||
|
'Clear resistor value?',
|
||||||
|
data.value +
|
||||||
|
// I created this kludge for fun (so don't hate on me):
|
||||||
|
this._picker.props.children
|
||||||
|
.map((x) => x.props)
|
||||||
|
.filter((x) => x.value == data.mult)[0]
|
||||||
|
.label,
|
||||||
|
[
|
||||||
|
{text: 'CANCEL'},
|
||||||
|
{text: 'OK', onPress: clear},
|
||||||
|
]
|
||||||
|
)
|
||||||
|
}} style={styles.clearbutton} activeOpacity={1}
|
||||||
|
>
|
||||||
|
<Text>Clear</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Redux stuff
|
||||||
|
function mapStateToProps(state, ownProps) {
|
||||||
|
if (ownProps.form == "target") {
|
||||||
|
return {
|
||||||
|
data: state.calc.target,
|
||||||
|
};
|
||||||
|
} else if (ownProps.form == "have") {
|
||||||
|
return {
|
||||||
|
data: state.calc.have[ownProps.index],
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default connect(mapStateToProps,
|
||||||
|
(dispatch) => ({
|
||||||
|
actions: bindActionCreators(calcActions, dispatch)
|
||||||
|
})
|
||||||
|
)(Resistor);
|
18
src/components/section.js
Normal file
18
src/components/section.js
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
import React, {Component} from 'react';
|
||||||
|
import {View} from 'react-native';
|
||||||
|
|
||||||
|
export default class Section extends Component {
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<View style={{marginBottom: 15}}>
|
||||||
|
{this.props.children}
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,13 @@
|
||||||
import React, {Component} from 'react';
|
import React, {Component} from 'react';
|
||||||
|
import { StyleSheet } from 'react-native';
|
||||||
|
import Ionicons from 'react-native-vector-icons/Ionicons';
|
||||||
import { createStore, applyMiddleware, combineReducers } from 'redux';
|
import { createStore, applyMiddleware, combineReducers } from 'redux';
|
||||||
import { Provider } from 'react-redux';
|
import { Provider } from 'react-redux';
|
||||||
import thunk from 'redux-thunk';
|
import thunk from 'redux-thunk';
|
||||||
|
import Drawer from 'react-native-drawer';
|
||||||
|
|
||||||
import * as reducers from '../reducers';
|
import * as reducers from '../reducers';
|
||||||
import CounterApp from './counterApp';
|
import Nav from './nav';
|
||||||
|
|
||||||
const createStoreWithMiddleware = applyMiddleware(thunk)(createStore);
|
const createStoreWithMiddleware = applyMiddleware(thunk)(createStore);
|
||||||
const reducer = combineReducers(reducers);
|
const reducer = combineReducers(reducers);
|
||||||
|
@ -14,7 +17,7 @@ export default class App extends Component {
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<Provider store={store}>
|
<Provider store={store}>
|
||||||
<CounterApp />
|
<Nav />
|
||||||
</Provider>
|
</Provider>
|
||||||
);
|
);
|
||||||
}
|
}
|
24
src/containers/calcApp.js
Normal file
24
src/containers/calcApp.js
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
import React, {Component} from 'react';
|
||||||
|
import Calc from '../components/calc';
|
||||||
|
import {connect} from 'react-redux';
|
||||||
|
|
||||||
|
class CalcApp extends Component {
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const {state} = this.props;
|
||||||
|
console.log(this);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Calc state={state}/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default connect(state => ({
|
||||||
|
state: state.calc
|
||||||
|
}))(CalcApp);
|
|
@ -2,14 +2,10 @@
|
||||||
|
|
||||||
import React, {Component} from 'react';
|
import React, {Component} from 'react';
|
||||||
import {bindActionCreators} from 'redux';
|
import {bindActionCreators} from 'redux';
|
||||||
import Counter from '../components/counter';
|
import Help from '../components/help';
|
||||||
import * as counterActions from '../actions/counterActions';
|
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
|
|
||||||
// @connect(state => ({
|
class HelpApp extends Component {
|
||||||
// state: state.counter
|
|
||||||
// }))
|
|
||||||
class CounterApp extends Component {
|
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
}
|
}
|
||||||
|
@ -17,17 +13,15 @@ class CounterApp extends Component {
|
||||||
render() {
|
render() {
|
||||||
const { state, actions } = this.props;
|
const { state, actions } = this.props;
|
||||||
return (
|
return (
|
||||||
<Counter
|
<Help
|
||||||
counter={state.count}
|
|
||||||
{...actions} />
|
{...actions} />
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default connect(state => ({
|
export default connect(state => ({
|
||||||
state: state.counter
|
|
||||||
}),
|
}),
|
||||||
(dispatch) => ({
|
(dispatch) => ({
|
||||||
actions: bindActionCreators(counterActions, dispatch)
|
|
||||||
})
|
})
|
||||||
)(CounterApp);
|
)(HelpApp);
|
||||||
|
|
30
src/containers/menuApp.js
Normal file
30
src/containers/menuApp.js
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
import React, {Component} from 'react';
|
||||||
|
import {bindActionCreators} from 'redux';
|
||||||
|
import Menu from '../components/menu';
|
||||||
|
import * as menuActions from '../actions/menuActions';
|
||||||
|
import { connect } from 'react-redux';
|
||||||
|
|
||||||
|
class MenuApp extends Component {
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const { state, actions } = this.props;
|
||||||
|
return (
|
||||||
|
<Menu {...actions} />
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default connect(state => ({
|
||||||
|
state: state
|
||||||
|
}),
|
||||||
|
(dispatch) => ({
|
||||||
|
actions: bindActionCreators(menuActions, dispatch)
|
||||||
|
})
|
||||||
|
)(MenuApp);
|
||||||
|
|
||||||
|
|
70
src/containers/nav.js
Normal file
70
src/containers/nav.js
Normal file
|
@ -0,0 +1,70 @@
|
||||||
|
'use strict';
|
||||||
|
import React, {Component} from 'react';
|
||||||
|
import {View, StyleSheet} from 'react-native';
|
||||||
|
import {bindActionCreators} from 'redux';
|
||||||
|
import {connect} from 'react-redux';
|
||||||
|
import Ionicons from 'react-native-vector-icons/Ionicons';
|
||||||
|
import Drawer from 'react-native-drawer';
|
||||||
|
|
||||||
|
import * as menuActions from '../actions/menuActions';
|
||||||
|
import MenuApp from '../containers/menuApp';
|
||||||
|
|
||||||
|
class Nav extends Component {
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const { state, actions } = this.props;
|
||||||
|
|
||||||
|
const drawerStyles = {
|
||||||
|
drawer: { shadowColor: '#000000', shadowOpacity: 0.8, shadowRadius: 3},
|
||||||
|
main: {paddingLeft: 3},
|
||||||
|
}
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
toolbar: {
|
||||||
|
backgroundColor: '#e9eaed',
|
||||||
|
height: 56,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Drawer
|
||||||
|
open={state.isOpen}
|
||||||
|
type="overlay"
|
||||||
|
content={<MenuApp />}
|
||||||
|
tapToClose={true}
|
||||||
|
openDrawerOffset={0.3}
|
||||||
|
captureGestures={false}
|
||||||
|
panCloseMask={0.3}
|
||||||
|
closedDrawerOffset={-3}
|
||||||
|
styles={drawerStyles}
|
||||||
|
tweenHandler={(ratio) => ({
|
||||||
|
main: { opacity: 1, },
|
||||||
|
mainOverlay: { opacity: ratio/2, backgroundColor: 'black', },
|
||||||
|
})}
|
||||||
|
>
|
||||||
|
<Ionicons.ToolbarAndroid
|
||||||
|
navIconName={"md-menu"}
|
||||||
|
onIconClicked={actions.menuopen}
|
||||||
|
style={styles.toolbar}
|
||||||
|
subtitle={state.subtitle}
|
||||||
|
title="Exact Resistor Calculator"
|
||||||
|
/>
|
||||||
|
<View style={{flex: 1}}>
|
||||||
|
{state.page}
|
||||||
|
</View>
|
||||||
|
</Drawer>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default connect(state => ({
|
||||||
|
state: state.menu
|
||||||
|
}),
|
||||||
|
(dispatch) => ({
|
||||||
|
actions: bindActionCreators(menuActions, dispatch)
|
||||||
|
})
|
||||||
|
)(Nav);
|
||||||
|
|
||||||
|
|
97
src/reducers/calc.js
Normal file
97
src/reducers/calc.js
Normal file
|
@ -0,0 +1,97 @@
|
||||||
|
import * as types from '../actions/actionTypes';
|
||||||
|
|
||||||
|
const initialState = {
|
||||||
|
target: {
|
||||||
|
value: '',
|
||||||
|
mult: '1',
|
||||||
|
valid: true,
|
||||||
|
},
|
||||||
|
have: [
|
||||||
|
{
|
||||||
|
value: '',
|
||||||
|
mult: '1',
|
||||||
|
valid: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: '',
|
||||||
|
mult: '1',
|
||||||
|
valid: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: '',
|
||||||
|
mult: '1',
|
||||||
|
valid: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
function isPosReal(n) {
|
||||||
|
return n == '' || // Allowed to be blank
|
||||||
|
!isNaN(parseFloat(n)) && // Has to be real
|
||||||
|
isFinite(n) // Can't be infinite
|
||||||
|
&& parseFloat(n) > 0; // Must be positive, non-zero
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function calc(state = initialState, action = {}) {
|
||||||
|
const {type, value, form, index, mult} = action;
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case types.UPDATEVALUE:
|
||||||
|
const valid = isPosReal(value);
|
||||||
|
|
||||||
|
if (form == "target") {
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
target: {
|
||||||
|
...state.target,
|
||||||
|
value: value,
|
||||||
|
valid: valid,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} else if (form == "have") {
|
||||||
|
const newState = {
|
||||||
|
...state,
|
||||||
|
have: state.have.map((x,n) =>
|
||||||
|
n == index ? {
|
||||||
|
...x,
|
||||||
|
value: value,
|
||||||
|
valid: valid,
|
||||||
|
} : x
|
||||||
|
),
|
||||||
|
};
|
||||||
|
|
||||||
|
// If all values are full, add another resistor
|
||||||
|
if (newState.have.every((x) => x.value)) {
|
||||||
|
newState.have.push({
|
||||||
|
value: '',
|
||||||
|
mult: '1',
|
||||||
|
valid: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return newState;
|
||||||
|
}
|
||||||
|
case types.UPDATEMULT:
|
||||||
|
if (form == "target") {
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
target: {
|
||||||
|
...state.target,
|
||||||
|
mult: mult,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} else if (form == "have") {
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
have: state.have.map((x,n) =>
|
||||||
|
n == index ? {
|
||||||
|
...x,
|
||||||
|
mult: mult,
|
||||||
|
} : x
|
||||||
|
),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
}
|
7
src/reducers/index.js
Normal file
7
src/reducers/index.js
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
import calc from './calc';
|
||||||
|
import menu from './menu';
|
||||||
|
|
||||||
|
export {
|
||||||
|
calc,
|
||||||
|
menu,
|
||||||
|
};
|
43
src/reducers/menu.js
Normal file
43
src/reducers/menu.js
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
import React, {Component} from 'react';
|
||||||
|
import * as types from '../actions/actionTypes';
|
||||||
|
|
||||||
|
import CalcApp from '../containers/calcApp';
|
||||||
|
import HelpApp from '../containers/helpApp';
|
||||||
|
|
||||||
|
const initialState = {
|
||||||
|
isOpen: false,
|
||||||
|
refdrawer: null,
|
||||||
|
page: <CalcApp />,
|
||||||
|
subtitle: 'Calculator Page',
|
||||||
|
};
|
||||||
|
|
||||||
|
export default function menu(state = initialState, action = {}) {
|
||||||
|
switch (action.type) {
|
||||||
|
case types.MENUOPEN:
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
isOpen: true,
|
||||||
|
};
|
||||||
|
case types.MENUCLOSE:
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
isOpen: false,
|
||||||
|
};
|
||||||
|
case types.MAIN:
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
isOpen: false,
|
||||||
|
page: <CalcApp />,
|
||||||
|
subtitle: 'Calculator Page',
|
||||||
|
};
|
||||||
|
case types.HELP:
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
isOpen: false,
|
||||||
|
page: <HelpApp />,
|
||||||
|
subtitle: 'Help',
|
||||||
|
};
|
||||||
|
default:
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user