diff --git a/src/actions/actionTypes.js b/src/actions/actionTypes.js index 5abb9e4..0f82f20 100644 --- a/src/actions/actionTypes.js +++ b/src/actions/actionTypes.js @@ -1,7 +1,7 @@ export const UPDATEVALUE = 'UPDATEVALUE'; export const UPDATEMULT = 'UPDATEMULT'; +export const CLEARALL = 'CLEARALL'; export const MENUOPEN = 'MENUOPEN'; export const MENUCLOSE = 'MENUCLOSE'; export const MAIN = 'MAIN'; export const HELP = 'HELP'; -export const SETREF = 'SETREF'; diff --git a/src/actions/calcActions.js b/src/actions/calcActions.js index 1d77fbe..f8557fa 100644 --- a/src/actions/calcActions.js +++ b/src/actions/calcActions.js @@ -17,3 +17,9 @@ export function updatemult(form, index, mult) { mult, }; } + +export function clearall() { + return { + type: types.CLEARALL, + }; +} diff --git a/src/components/calc.js b/src/components/calc.js index 0b3f22d..ca1c0a4 100644 --- a/src/components/calc.js +++ b/src/components/calc.js @@ -1,20 +1,30 @@ import React, {Component} from 'react'; -import {ScrollView, StyleSheet, Text, TouchableOpacity, View} from 'react-native'; +import {Alert, ScrollView, StyleSheet, TouchableOpacity, View} from 'react-native'; import Resistor from './resistor'; import Section from './section'; +import ClearAll from './clearall'; +import MyText from './mytext' -const styles = StyleSheet.create({ - button: { - width: 100, - height: 30, - padding: 10, - backgroundColor: 'lightgray', - alignItems: 'center', - justifyContent: 'center', - margin: 3 +function getUnit(n) { + if (n >= 1000000) { + return {unit: ' MΩ', mult: 1000000}; + } else if (n >= 1000) { + return {unit: ' kΩ', mult: 1000}; + } else if (n >= 1) { + return {unit: ' Ω', mult: 1}; + } else { + return {unit: ' mΩ', mult: 0.001}; } -}); +} + +const styles = { + table: { + borderBottomColor: 'lightgrey', + borderBottomWidth: 1, + padding: 3, + }, +}; export default class Calc extends Component { constructor(props) { @@ -24,42 +34,165 @@ export default class Calc extends Component { render() { const {state} = this.props; - const allValid = state.have.every((x) => x.valid); - const nonEmpty = state.have.some((x) => x.value); + const targetValid = state.target.valid; + const targetNonEmpty = state.target.value ? true : false; + + const haveAllValid = state.have.every((x) => x.valid); + const haveNonEmpty = state.have.some((x) => x.value); + + const precision = () => { + if (targetValid && targetNonEmpty) { + const pieces = state.target.value.split('.'); + if (pieces[1]) { + if (pieces[1].length > 20) { + return 20; // Max toFixed() allows + } + if (pieces[1].length > 2) { + return pieces[1].length; + } + } + } + return 2; + }; + + const targetRes = state.target.value * state.target.mult; const reciprocalSum = state.have .filter((x) => x.value) - .reduce((a,b) => a + 1.0/(b.value * b.mult), 0.0); + .reduce((a,b) => a + 1.0 / (b.value * b.mult), 0.0); + + const sum = 1.0 / reciprocalSum; + + const percentError = Math.abs((sum - targetRes) / targetRes * 100); + + const nextRes = 1.0 / (1.0 / targetRes - reciprocalSum); + + const printSum = () => { + if (haveAllValid && haveNonEmpty) { + const {unit, mult} = getUnit(sum); + const val = sum / mult; + return val.toFixed(precision()) + unit; + } else { + return '---'; + } + }; + + const printPercentError = () => { + if (targetValid && targetNonEmpty && haveAllValid && haveNonEmpty) { + // Check if the 'overall resistor value' matches the target + const {unit, mult} = getUnit(targetRes); + console.log((targetRes / mult).toFixed(precision()) + unit); + if (printSum() === (targetRes / mult).toFixed(precision()) + unit) { + return (0.0).toFixed(precision()); + } + return percentError.toFixed(precision()); + } else { + return '---'; + } + }; + + const printNextRes= () => { + if (targetValid && targetNonEmpty && haveAllValid && haveNonEmpty) { + // Check if we are done because error is 0 or value's exact + if (nextRes == Infinity || printPercentError() == 0.0) { + return 'Done.'; + } else if (nextRes < 0) { + return 'N/A.'; + } + const {unit, mult} = getUnit(nextRes); + const val = nextRes / mult; + return val.toFixed(precision()) + unit; + } else { + return '---'; + } + }; + + const printInfo = () => { + if (!haveAllValid) { + return 'A parallel resistor is not valid.'; + } else if (!targetNonEmpty) { + return 'No target resistor.'; + } else if (!targetValid) { + return 'Target resistor not valid.'; + } else if (!haveNonEmpty) { + return 'No resistors in parallel.'; + } else if (printNextRes() === 'N/A.') { + return ( + + No solution exists. { + Alert.alert( + 'No Solution Exists', + 'This app recommends resistors to be added in parallel. It\'s impossible to increase resistance (to make it closer to the target) by adding another resistor in parallel.\n\nPlease remove the lowest value resistor if you wish to keep solving.', + [{text: 'OK'}] + ); + }} + > + Why? + + + ); + } else if (printNextRes() === 'Done.') { + return 'Target achieved.'; + } else { + return 'Add the next resistor.'; + } + }; return (
- + Enter the exact resistance target: - + +
+
- - Overall parallel resistor value: - {allValid && nonEmpty ? ' ' + 1/reciprocalSum : ' ???'} - - - Error between this and the target: {0}% - - - Next recommended resistor value: {0} - + + + + Overall parallel resistor value: + + + Error between this and target: + + + Next resistor value needed: + + + + + {printSum()} + + + {printPercentError()} % + + + {printNextRes()} + + + + + {printInfo()} +
- + Enter the resistors you have in parallel: - + +
+
{state.have.map((x,n) => )}
+ + +
); diff --git a/src/components/clearall.js b/src/components/clearall.js new file mode 100644 index 0000000..213a72d --- /dev/null +++ b/src/components/clearall.js @@ -0,0 +1,57 @@ +import React, {Component} from 'react'; +import {bindActionCreators} from 'redux'; +import {connect} from 'react-redux'; +import { + Alert, + StyleSheet, + View, + Text, + TouchableOpacity, +} from 'react-native'; + +import * as calcActions from '../actions/calcActions'; + +const styles = { + clearbutton: { + height: 30, + width: 100, + padding: 10, + backgroundColor: 'lightgray', + alignItems: 'center', + justifyContent: 'center', + margin: 3, + }, +}; + +class ClearAll extends Component { + constructor(props) { + super(props); + } + + render() { + const {actions} = this.props; + + return ( + { + Alert.alert( + 'Clear all resistors?', + '', + [ + {text: 'CANCEL'}, + {text: 'OK', onPress: actions.clearall}, + ] + ) + }} + style={styles.clearbutton} activeOpacity={1} + > + Clear all + + ); + } +} + +export default connect(null, (dispatch) => ({ + actions: bindActionCreators(calcActions, dispatch) +}))(ClearAll); + diff --git a/src/components/help.js b/src/components/help.js index 7c59acf..9759370 100644 --- a/src/components/help.js +++ b/src/components/help.js @@ -1,17 +1,12 @@ 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 ( This is a sample counter app. diff --git a/src/components/mytext.js b/src/components/mytext.js new file mode 100644 index 0000000..33ecdb3 --- /dev/null +++ b/src/components/mytext.js @@ -0,0 +1,25 @@ +import React, {Component} from 'react'; +import {StyleSheet, Text} from 'react-native'; + +const styles = { + mytext: { + color: 'black', + }, +}; + +export default class MyText extends Component { + constructor(props) { + super(props); + } + + render() { + return ( + + {this.props.children} + + ); + } +} + + + diff --git a/src/components/resistor.js b/src/components/resistor.js index 0d2a1dd..4645113 100644 --- a/src/components/resistor.js +++ b/src/components/resistor.js @@ -52,12 +52,10 @@ class Resistor extends Component { updatemult('1'); } - console.log(this); - return ( updatevalue(x)} style={Object.assign({}, styles.resistorinput, { borderColor: data.valid ? 'grey' : 'red', @@ -79,9 +77,8 @@ class Resistor extends Component { { - console.log(this); - Alert.alert( + onPress={() => { + data.value ? Alert.alert( 'Clear resistor value?', data.value + // I created this kludge for fun (so don't hate on me): @@ -93,7 +90,7 @@ class Resistor extends Component { {text: 'CANCEL'}, {text: 'OK', onPress: clear}, ] - ) + ) : null ; }} style={styles.clearbutton} activeOpacity={1} > @@ -119,8 +116,6 @@ function mapStateToProps(state, ownProps) { } } -export default connect(mapStateToProps, - (dispatch) => ({ - actions: bindActionCreators(calcActions, dispatch) - }) -)(Resistor); +export default connect(mapStateToProps, (dispatch) => ({ + actions: bindActionCreators(calcActions, dispatch) +}))(Resistor); diff --git a/src/containers/calcApp.js b/src/containers/calcApp.js index 77336b9..5378b06 100644 --- a/src/containers/calcApp.js +++ b/src/containers/calcApp.js @@ -11,7 +11,6 @@ class CalcApp extends Component { render() { const {state} = this.props; - console.log(this); return ( diff --git a/src/containers/helpApp.js b/src/containers/helpApp.js index ff7dd0b..391a777 100644 --- a/src/containers/helpApp.js +++ b/src/containers/helpApp.js @@ -1,23 +1,16 @@ 'use strict'; import React, {Component} from 'react'; -import {bindActionCreators} from 'redux'; import Help from '../components/help'; -import { connect } from 'react-redux'; -class HelpApp extends Component { +export default class HelpApp extends Component { constructor(props) { super(props); } render() { - const { state, actions } = this.props; return ( - + ); } } - -export default connect(state => ({ - }), (dispatch) => ({ -}))(HelpApp); diff --git a/src/containers/nav.js b/src/containers/nav.js index 2080f03..b0c998c 100644 --- a/src/containers/nav.js +++ b/src/containers/nav.js @@ -18,7 +18,7 @@ class Nav extends Component { const { state, actions } = this.props; const drawerStyles = { - drawer: { shadowColor: '#000000', shadowOpacity: 0.8, shadowRadius: 3}, + drawer: {shadowColor: '#000000', shadowOpacity: 0.8, shadowRadius: 3}, main: {paddingLeft: 3}, } const styles = StyleSheet.create({ @@ -34,8 +34,8 @@ class Nav extends Component { type="overlay" content={} tapToClose={true} - openDrawerOffset={0.3} - captureGestures={false} + openDrawerOffset={(viewport) => viewport.width - 250} + captureGestures={true} panCloseMask={0.3} closedDrawerOffset={-3} styles={drawerStyles} diff --git a/src/reducers/calc.js b/src/reducers/calc.js index 5d13922..94d2c85 100644 --- a/src/reducers/calc.js +++ b/src/reducers/calc.js @@ -91,6 +91,8 @@ export default function calc(state = initialState, action = {}) { ), }; } + case types.CLEARALL: + return initialState; default: return state; }