diff --git a/README.md b/README.md index ffbbc7c..594c736 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,112 @@ -# Mobius Network mobile wallet +# Mobius Network mobile wallet -## Development +## Development ```sh -yarn start -yarn run ios -yarn run android +yarn start +yarn run ios +yarn run android ``` -## License +## License -The app is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT). +The app is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT). + +## Quiz + +**Question 1:** Are there any problems with the below code? + +``` +import { SIGNUP } from 'consts'; +import { Content, Host, Section, SignUpButton, Version } from './style'; + +// React wasn't imported into this file. The code below won't work. +export default class Signup extends React.Component { +  onSignupPress() { +    // Navigation wasn't imported. An error will happen. +    Navigation.push(this.props.componentId, { +      component: { +        name: SIGNUP +      } +    }); +  }; + +  getFormattedVersion(version) { +    // If the purpose of this function is to return a HTML snippet with the "version" value +    // into it, we need to change the double quotes to back-tick(` `) +    return "${version}”; +  } + +  render() { +    const { versionLabel } = this.props; +    return ( +       +         +          
+            // onSignupPress function wasn't declared using arrow function and also wasn't  +            // bound inside the constructor method available to ES6 classes, which ensures that // the keyword "this" will be bound correctly to the created component. +             +          
+        
+        {() => this.getFormattedVersion(versionLabel)} +      
+    ); +  } +} +``` + +**Question 2:** Is there a difference in the below two statements and if so what? Assume we are using React Native with Redux and Redux-Saga. + +``` +A. store.dispatch(lifecycleActions.loadProfile()); +B. yield effects.put(lifecycleActions.loadProfile()); +``` + +Basically, both statements do the same thing, which is to dispacth an action to the redux store. +In the first statement, an action is dispatched using the _dispacth_ method from redux's store. +In the second statement, a yielded object instructs the redux-saga middleware to dispacth the action.  + +**Question 3:** Explain the differences in the 3 non-constructor functions below. + +``` +class Dashboard { +  constructor(_num) { +    this.num = _num; +  } + +  // The staticFunction can't be used in instances of the Dashboard class. +  // Within the static function, the "this" keyword refers to the Dashboard class. +  static staticFunc() { +    console.log("staticFunc " + this.num); +  } + +  // The syntax of memberFunc1 function allows it to become available +  // in the class prototype method. The "this" keyword will be determined at run time. +  memberFunc1() { +    console.log("memberFunc1 " + this.num); +  } + +  // memberFunc2 doesn't become available in the prototype method. +  // The "this" keyword is bound to its enclosing scope; in this case, +  // the Dashboard class. +  memberFunc2 = () => console.log("memberFunc2 " + this.num); +} +``` + +**Question 4:** Are there any bugs in the below code? +No. +``` +import AsyncStorage from '@react-native-community/async-storage'; +import firebase from 'react-native-firebase'; +import { effects } from 'redux-saga'; +import { authActions } from 'state'; +import { getType } from 'typesafe-actions'; + +function* logout() { + const firebaseAuth = firebase.auth(); + yield effects.call(firebaseAuth.signOut); + yield effects.call(AsyncStorage.removeItem, 'cookie'); +} + +export default effects.takeLatest(getType(authActions.logout), logout); +``` \ No newline at end of file diff --git a/src/components/App/AppNavigator.js b/src/components/App/AppNavigator.js index bb62ea4..85ea256 100644 --- a/src/components/App/AppNavigator.js +++ b/src/components/App/AppNavigator.js @@ -48,7 +48,10 @@ export const StackNavigator = createStackNavigator( header: null, }), }, - Currencies: { + AllCurrencies: { + screen: Currencies, + }, + PopularCurrencies: { screen: Currencies, }, DrawerNavigator, diff --git a/src/components/App/Currencies/Currencies.js b/src/components/App/Currencies/Currencies.js index 76d2674..5194cbb 100644 --- a/src/components/App/Currencies/Currencies.js +++ b/src/components/App/Currencies/Currencies.js @@ -1,6 +1,7 @@ import React, { Component } from 'react'; import PropTypes from 'prop-types'; +import TabSearch from 'components/shared/TabSearch'; import CurrenciesList from './CurrenciesList'; import Header from './Header'; @@ -11,7 +12,7 @@ class Currencies extends Component { addUserCurrency: PropTypes.func, clearSearchQuery: PropTypes.func, navigation: PropTypes.shape({ - pop: PropTypes.func.isRequired, + navigate: PropTypes.func.isRequired, }).isRequired, searchQuery: PropTypes.string, setSearchQuery: PropTypes.func, @@ -31,10 +32,12 @@ class Currencies extends Component { this.handleBack(); }; - handleBack = () => this.props.navigation.pop(); + handleBack = () => this.props.navigation.navigate('Dashboard'); render() { - const { t, setSearchQuery, searchQuery } = this.props; + const { + t, setSearchQuery, searchQuery, navigation, + } = this.props; return (
+ ); } diff --git a/src/components/shared/FloatingPlusButton/FloatingPlusButton.js b/src/components/shared/FloatingPlusButton/FloatingPlusButton.js index 462f1ee..912bd54 100644 --- a/src/components/shared/FloatingPlusButton/FloatingPlusButton.js +++ b/src/components/shared/FloatingPlusButton/FloatingPlusButton.js @@ -10,7 +10,7 @@ class FloatingPlusButton extends Component { }).isRequired, }; - openCurrenciesScreen = () => this.props.navigation.navigate('Currencies'); + openCurrenciesScreen = () => this.props.navigation.navigate('AllCurrencies'); render() { return ( diff --git a/src/components/shared/TabSearch/TabSearch.js b/src/components/shared/TabSearch/TabSearch.js new file mode 100644 index 0000000..4aa9b42 --- /dev/null +++ b/src/components/shared/TabSearch/TabSearch.js @@ -0,0 +1,40 @@ +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; + +import { ActionButton, ButtonRow } from './styles'; + +class TabSearch extends Component { + static propTypes = { + navigation: PropTypes.shape({ + navigate: PropTypes.func.isRequired, + }).isRequired, + t: PropTypes.func.isRequired, + }; + + openAllCurrenciesScreen = () => this.props.navigation.navigate('AllCurrencies'); + + openPopularCurrenciesScreen = () => this.props.navigation.navigate('PopularCurrencies'); + + render() { + const { t } = this.props; + + return ( + + + + + ); + } +} + +export default TabSearch; diff --git a/src/components/shared/TabSearch/TabSearchContainer.js b/src/components/shared/TabSearch/TabSearchContainer.js new file mode 100644 index 0000000..a18592a --- /dev/null +++ b/src/components/shared/TabSearch/TabSearchContainer.js @@ -0,0 +1,5 @@ +import { translate } from 'react-i18next'; + +import TabSearch from './TabSearch'; + +export default translate('translation')(TabSearch); diff --git a/src/components/shared/TabSearch/index.js b/src/components/shared/TabSearch/index.js new file mode 100644 index 0000000..22187eb --- /dev/null +++ b/src/components/shared/TabSearch/index.js @@ -0,0 +1 @@ +export { default } from './TabSearchContainer'; diff --git a/src/components/shared/TabSearch/styles.js b/src/components/shared/TabSearch/styles.js new file mode 100644 index 0000000..d80f6d9 --- /dev/null +++ b/src/components/shared/TabSearch/styles.js @@ -0,0 +1,18 @@ +import styled from 'styled-components'; + +import Button from 'components/shared/Button'; + +export const ButtonRow = styled.View` + align-self: stretch; + flex-direction: row; + justify-content: space-between; +`; + +export const ActionButton = styled(Button).attrs({ + shape: 'square', +})` + flex-grow: 1; + margin-bottom: 0; + margin-top: 0; + text-transform: uppercase; +`;