Commit c9163241 authored by Dida Adams Arizona's avatar Dida Adams Arizona

Merge branch 'didam' into 'master'

Start Project

See merge request !1
parents adabf0f2 cf844ea9
Pipeline #221 failed with stages
{
"presets": ["module:metro-react-native-babel-preset"],
"env": {
"production": {
"plugins": ["ignite-ignore-reactotron"]
}
}
}
[android]
target = Google Inc.:Google APIs:23
[maven_repositories]
central = https://repo1.maven.org/maven2
# EditorConfig is awesome: http://EditorConfig.org
# top-most EditorConfig file
root = true
# Unix-style newlines with a newline ending every file
[*]
end_of_line = lf
insert_final_newline = true
indent_style = space
indent_size = 2
charset = utf-8
trim_trailing_whitespace = true
[*.gradle]
indent_size = 4
\ No newline at end of file
# This is an example where you can store your environment variables. Copy this file to .env
# Now your app will have access to the variables added below.
# For more instructions see section "Secrets" in README.md
API_URL=https://myapi.com
GOOGLE_MAPS_API_KEY=abcdefgh
module.exports = {
root: true,
extends: '@react-native-community',
};
[ignore]
; We fork some components by platform
.*/*[.]android.js
; Ignore "BUCK" generated dirs
<PROJECT_ROOT>/\.buckd/
; Ignore polyfills
node_modules/react-native/Libraries/polyfills/.*
; These should not be required directly
; require from fbjs/lib instead: require('fbjs/lib/warning')
node_modules/warning/.*
; Flow doesn't support platforms
.*/Libraries/Utilities/LoadingView.js
[untyped]
.*/node_modules/@react-native-community/cli/.*/.*
[include]
[libs]
node_modules/react-native/Libraries/react-native/react-native-interface.js
node_modules/react-native/flow/
[options]
emoji=true
esproposal.optional_chaining=enable
esproposal.nullish_coalescing=enable
module.file_ext=.js
module.file_ext=.json
module.file_ext=.ios.js
munge_underscores=true
module.name_mapper='^react-native$' -> '<PROJECT_ROOT>/node_modules/react-native/Libraries/react-native/react-native-implementation'
module.name_mapper='^react-native/\(.*\)$' -> '<PROJECT_ROOT>/node_modules/react-native/\1'
module.name_mapper='^[./a-zA-Z0-9$_-]+\.\(bmp\|gif\|jpg\|jpeg\|png\|psd\|svg\|webp\|m4v\|mov\|mp4\|mpeg\|mpg\|webm\|aac\|aiff\|caf\|m4a\|mp3\|wav\|html\|pdf\)$' -> '<PROJECT_ROOT>/node_modules/react-native/Libraries/Image/RelativeImageStub'
suppress_type=$FlowIssue
suppress_type=$FlowFixMe
suppress_type=$FlowFixMeProps
suppress_type=$FlowFixMeState
suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe\\($\\|[^(]\\|(\\(<VERSION>\\)? *\\(site=[a-z,_]*react_native\\(_ios\\)?_\\(oss\\|fb\\)[a-z,_]*\\)?)\\)
suppress_comment=\\(.\\|\n\\)*\\$FlowIssue\\((\\(<VERSION>\\)? *\\(site=[a-z,_]*react_native\\(_ios\\)?_\\(oss\\|fb\\)[a-z,_]*\\)?)\\)?:? #[0-9]+
suppress_comment=\\(.\\|\n\\)*\\$FlowExpectedError
[lints]
sketchy-null-number=warn
sketchy-null-mixed=warn
sketchy-number=warn
untyped-type-import=warn
nonstrict-import=warn
deprecated-type=warn
unsafe-getters-setters=warn
inexact-spread=warn
unnecessary-invariant=warn
signature-verification-failure=warn
deprecated-utility=error
[strict]
deprecated-type
nonstrict-import
sketchy-null
unclear-type
unsafe-getters-setters
untyped-import
untyped-type-import
[version]
^0.105.0
*.pbxproj -text
*.bat text eol=crlf
\ No newline at end of file
# OSX
#
.DS_Store
# Xcode
#
build/
*.pbxuser
!default.pbxuser
*.mode1v3
!default.mode1v3
*.mode2v3
!default.mode2v3
*.perspectivev3
!default.perspectivev3
xcuserdata
*.xccheckout
*.moved-aside
DerivedData
*.hmap
*.ipa
*.xcuserstate
# Android/IntelliJ
#
build/
.idea
.gradle
local.properties
*.iml
# node.js
#
node_modules/
npm-debug.log
yarn-error.log
# BUCK
buck-out/
\.buckd/
*.keystore
!debug.keystore
# fastlane
#
# It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the
# screenshots whenever they are needed.
# For more information about the recommended setup visit:
# https://docs.fastlane.tools/best-practices/source-control/
*/fastlane/report.xml
*/fastlane/Preview.html
*/fastlane/screenshots
# Bundle artifact
*.jsbundle
# CocoaPods
/ios/Pods/
# Misc
#
.env
module.exports = {
bracketSpacing: false,
jsxBracketSameLine: true,
singleQuote: true,
trailingComma: 'all',
};
{}
\ No newline at end of file
import React, { Component } from 'react'
import PropTypes from 'prop-types'
import { View, Text } from 'react-native'
import styles from './Styles/AlertMessageStyles'
export default class AlertMessage extends Component {
static defaultProps = { show: true }
static propTypes = {
title: PropTypes.string,
icon: PropTypes.string,
style: PropTypes.object,
show: PropTypes.bool
}
render () {
let messageComponent = null
if (this.props.show) {
const { title } = this.props
return (
<View
style={[styles.container, this.props.style]}
>
<View style={styles.contentContainer}>
<Text allowFontScaling={false} style={styles.message}>{title && title.toUpperCase()}</Text>
</View>
</View>
)
}
return messageComponent
}
}
import React from 'react'
import { storiesOf } from '@storybook/react-native'
import AlertMessage from './AlertMessage'
storiesOf('AlertMessage')
.add('Default', () => (
<AlertMessage
title='ALERT ALERT'
/>
))
.add('Hidden', () => (
<AlertMessage
title='ALERT ALERT'
show={false}
/>
))
.add('Custom Style', () => (
<AlertMessage
title='ALERT ALERT'
style={{ backgroundColor: 'red' }}
/>
))
import React, { Component } from 'react'
import PropTypes from 'prop-types'
import { Text, TouchableOpacity } from 'react-native'
import styles from './Styles/DrawerButtonStyles'
import ExamplesRegistry from '../Services/ExamplesRegistry'
// Note that this file (App/Components/DrawerButton) needs to be
// imported in your app somewhere, otherwise your component won't be
// compiled and added to the examples dev screen.
// Ignore in coverage report
/* istanbul ignore next */
ExamplesRegistry.addComponentExample('Drawer Button', () =>
<DrawerButton
text='Example left drawer button'
onPress={() => window.alert('Your drawers are showing')}
/>
)
class DrawerButton extends Component {
static propTypes = {
text: PropTypes.string,
onPress: PropTypes.func
}
render () {
return (
<TouchableOpacity onPress={this.props.onPress}>
<Text style={styles.text}>{this.props.text}</Text>
</TouchableOpacity>
)
}
}
export default DrawerButton
import React from 'react'
import { View } from 'react-native'
import { storiesOf } from '@storybook/react-native'
import DrawerButton from './DrawerButton'
storiesOf('DrawerButton')
.add('Default', () => (
<View style={{ backgroundColor: 'black' }}>
<DrawerButton
text='Drawer Button'
onPress={() => { }}
/>
</View>
))
import React, { Component } from 'react'
import PropTypes from 'prop-types'
import { TouchableOpacity, Text } from 'react-native'
import styles from './Styles/FullButtonStyles'
import ExamplesRegistry from '../Services/ExamplesRegistry'
// Note that this file (App/Components/FullButton) needs to be
// imported in your app somewhere, otherwise your component won't be
// compiled and added to the examples dev screen.
// Ignore in coverage report
/* istanbul ignore next */
ExamplesRegistry.addComponentExample('Full Button', () =>
<FullButton
text='Hey there'
onPress={() => window.alert('Full Button Pressed!')}
/>
)
export default class FullButton extends Component {
static propTypes = {
text: PropTypes.string,
onPress: PropTypes.func,
styles: PropTypes.object
}
render () {
return (
<TouchableOpacity style={[styles.button, this.props.styles]} onPress={this.props.onPress}>
<Text style={styles.buttonText}>{this.props.text && this.props.text.toUpperCase()}</Text>
</TouchableOpacity>
)
}
}
import React from 'react'
import { storiesOf } from '@storybook/react-native'
import FullButton from './FullButton'
storiesOf('FullButton')
.add('Default', () => (
<FullButton
text='A simple button'
/>
))
.add('Custom Style', () => (
<FullButton
text='Style Me Up!'
styles={{ backgroundColor: 'blue' }}
/>
))
### Components Folder
All components are stored and organized here
import React, { Component } from 'react'
import PropTypes from 'prop-types'
import { TouchableOpacity, Text } from 'react-native'
import styles from './Styles/RoundedButtonStyles'
import ExamplesRegistry from '../Services/ExamplesRegistry'
// Note that this file (App/Components/RoundedButton) needs to be
// imported in your app somewhere, otherwise your component won't be
// compiled and added to the examples dev screen.
// Ignore in coverage report
/* istanbul ignore next */
ExamplesRegistry.addComponentExample('Rounded Button', () =>
<RoundedButton
text='real buttons have curves'
onPress={() => window.alert('Rounded Button Pressed!')}
/>
)
export default class RoundedButton extends Component {
static propTypes = {
onPress: PropTypes.func,
text: PropTypes.string,
children: PropTypes.string,
navigator: PropTypes.object
}
getText () {
const buttonText = this.props.text || this.props.children || ''
return buttonText.toUpperCase()
}
render () {
return (
<TouchableOpacity style={styles.button} onPress={this.props.onPress}>
<Text style={styles.buttonText}>{this.getText()}</Text>
</TouchableOpacity>
)
}
}
import React from 'react'
import { storiesOf } from '@storybook/react-native'
import RoundedButton from './RoundedButton'
storiesOf('RoundedButton')
.add('Default', () => (
<RoundedButton
text='A simple rounded button'
/>
))
.add('Text as children', () => (
<RoundedButton>
Hello from the children!
</RoundedButton>
))
import './AlertMessage.story'
import './DrawerButton.story'
import './FullButton.story'
import './RoundedButton.story'
import { StyleSheet } from 'react-native'
import { Colors, Metrics, Fonts } from '../../Themes/'
export default StyleSheet.create({
container: {
justifyContent: 'center',
marginVertical: Metrics.section
},
contentContainer: {
alignSelf: 'center',
alignItems: 'center'
},
message: {
marginTop: Metrics.baseMargin,
marginHorizontal: Metrics.baseMargin,
textAlign: 'center',
fontFamily: Fonts.type.base,
fontSize: Fonts.size.regular,
fontWeight: 'bold',
color: Colors.steel
},
icon: {
color: Colors.steel
}
})
import { Metrics, Colors, Fonts } from '../../Themes'
export default {
text: {
...Fonts.style.h5,
color: Colors.snow,
marginVertical: Metrics.baseMargin
}
}
import { StyleSheet } from 'react-native'
import { Fonts, Colors } from '../../Themes/'
export default StyleSheet.create({
button: {
marginVertical: 5,
borderTopColor: Colors.fire,
borderBottomColor: Colors.bloodOrange,
borderTopWidth: 1,
borderBottomWidth: 1,
backgroundColor: Colors.ember
},
buttonText: {
margin: 18,
textAlign: 'center',
color: Colors.snow,
fontSize: Fonts.size.medium,
fontFamily: Fonts.type.bold
}
})
### Styles Folder
Component styles are separated from functionality.
import { StyleSheet } from 'react-native'
import { Fonts, Colors, Metrics } from '../../Themes/'
export default StyleSheet.create({
button: {
height: 45,
borderRadius: 5,
marginHorizontal: Metrics.section,
marginVertical: Metrics.baseMargin,
backgroundColor: Colors.fire,
justifyContent: 'center'
},
buttonText: {
color: Colors.snow,
textAlign: 'center',
fontWeight: 'bold',
fontSize: Fonts.size.medium,
marginVertical: Metrics.baseMargin
}
})
// Simple React Native specific changes
import '../I18n/I18n'
export default {
// font scaling override - RN default is on
allowTextFontScaling: true
}
export default {
showDevScreens: __DEV__,
useFixtures: false,
ezLogin: false,
yellowBox: __DEV__,
reduxLogging: __DEV__,
includeExamples: __DEV__,
useReactotron: __DEV__
}
### Config Folder
All application specific configuration falls in this folder.
`AppConfig.js` - production values.
`DebugConfig.js` - development-wide globals.
`ReactotronConfig.js` - Reactotron client settings.
`ReduxPersist.js` - rehydrate Redux state.
import Config from '../Config/DebugConfig'
import Immutable from 'seamless-immutable'
import Reactotron from 'reactotron-react-native'
import { reactotronRedux as reduxPlugin } from 'reactotron-redux'
import sagaPlugin from 'reactotron-redux-saga'
const reactotron = Reactotron
.configure({ name: 'Ignite App' })
.useReactNative()
.use(reduxPlugin({ onRestore: Immutable }))
.use(sagaPlugin())
if (Config.useReactotron) {
// https://github.com/infinitered/reactotron for more options!
reactotron.connect()
// Let's clear Reactotron on every time we load the app
reactotron.clear()
// Totally hacky, but this allows you to not both importing reactotron-react-native
// on every file. This is just DEV mode, so no big deal.
}
export default reactotron
console.tron = reactotron
import immutablePersistenceTransform from '../Services/ImmutablePersistenceTransform'
import { AsyncStorage } from 'react-native'
// More info here: https://shift.infinite.red/shipping-persistant-reducers-7341691232b1
const REDUX_PERSIST = {
active: true,
reducerVersion: '1.0',
storeConfig: {
key: 'primary',
storage: AsyncStorage,
// Reducer keys that you do NOT want stored to persistence here.
blacklist: ['login', 'search', 'nav'],
// Optionally, just specify the keys you DO want stored to persistence.
// An empty array means 'don't store any reducers' -> infinitered/ignite#409
// whitelist: [],
transforms: [immutablePersistenceTransform]
}
}
export default REDUX_PERSIST
import DebugConfig from './DebugConfig'
import AppConfig from './AppConfig' // eslint-disable-line no-unused-vars
if (__DEV__) {
// If ReactNative's yellow box warnings are too much, it is possible to turn
// it off, but the healthier approach is to fix the warnings. =)
console.disableYellowBox = !DebugConfig.yellowBox
}
import '../Config'
import DebugConfig from '../Config/DebugConfig'
import React, { Component } from 'react'
import { Provider } from 'react-redux'
import RootContainer from './RootContainer'
import createStore from '../Redux'
// create our store
const store = createStore()
/**
* Provides an entry point into our application. Both index.ios.js and index.android.js
* call this component first.
*
* We create our Redux store here, put it into a provider and then bring in our
* RootContainer.
*
* We separate like this to play nice with React Native's hot reloading.
*/
class App extends Component {
render () {
return (
<Provider store={store}>
<RootContainer />
</Provider>
)
}
}
// allow reactotron overlay for fast design in dev mode
export default DebugConfig.useReactotron
? console.tron.overlay(App)
: App
import React, {Component} from 'react';
import {ScrollView, Text, KeyboardAvoidingView, View} from 'react-native';
import {connect} from 'react-redux';
import HomeNavigation from '../Navigation/HomeNavigation';
// Add Actions - replace 'Your' with whatever your reducer is called :)
// import YourActions from '../Redux/YourRedux'
// Styles
import styles from './Styles/HomeBottomTabScreenStyle';
class HomeBottomTabScreen extends Component {
render() {
return (
<View style={styles.mainContainer}>
<HomeNavigation />
</View>
);
}
}
const mapStateToProps = state => {
return {};
};
const mapDispatchToProps = dispatch => {
return {};
};
export default connect(
mapStateToProps,
mapDispatchToProps,
)(HomeBottomTabScreen);
import React, {Component} from 'react';
import {ScrollView, Text, KeyboardAvoidingView, View} from 'react-native';
import {connect} from 'react-redux';
// Add Actions - replace 'Your' with whatever your reducer is called :)
// import YourActions from '../Redux/YourRedux'
// Styles
import styles from './Styles/HomePageScreenStyle';
class HomePageScreen extends Component {
render() {
return (
<ScrollView style={styles.container}>
<KeyboardAvoidingView behavior="position">
<Text>Home Page Screen</Text>
</KeyboardAvoidingView>
</ScrollView>
);
}
}
const mapStateToProps = state => {
return {};
};
const mapDispatchToProps = dispatch => {
return {};
};
export default connect(
mapStateToProps,
mapDispatchToProps,
)(HomePageScreen);
import React, { Component } from 'react'
import { ScrollView, Text, Image, View, BackHandler } from 'react-native'
import DevscreensButton from '../../ignite/DevScreens/DevscreensButton.js'
import { Images } from '../Themes'
// Styles
import styles from './Styles/LaunchScreenStyles'
export default class LaunchScreen extends Component {
componentDidMount() {
setTimeout(() => {
this.props.navigation.navigate('HomeBottomTabScreen')
}, 500);
BackHandler.addEventListener('hardwareBackPress', this.handleBackButtonClick);
}
componentWillUnmount() {
BackHandler.removeEventListener('hardwareBackPress', this.handleBackButtonClick);
}
handleBackButtonClick() {
// this.props.navigation.goBack(null);
alert('anjay')
return true;
}
render () {
return (
<View style={styles.mainContainer}>
<View style={styles.centered}>
<Image source={Images.logo_eCart} style={{resizeMode: 'stretch'}} />
</View>
{/* <Image source={Images.background} style={styles.backgroundImage} resizeMode='stretch' />
<ScrollView style={styles.container}>
<View style={styles.centered}>
<Image source={Images.launch} style={styles.logo} />
</View>
<View style={styles.section} >
<Image source={Images.ready} />
<Text style={styles.sectionText}>
This probably isn't what your app is going to look like. Unless your designer handed you this screen and, in that case, congrats! You're ready to ship. For everyone else, this is where you'll see a live preview of your fully functioning app using Ignite.
</Text>
</View>
<DevscreensButton />
</ScrollView> */}
</View>
)
}
}
import React, { Component } from 'react'
import { ScrollView, Text, KeyboardAvoidingView } from 'react-native'
import { connect } from 'react-redux'
// Add Actions - replace 'Your' with whatever your reducer is called :)
// import YourActions from '../Redux/YourRedux'
// Styles
import styles from './Styles/LoginScreenStyle'
class LoginScreen extends Component {
render () {
return (
<ScrollView style={styles.container}>
<KeyboardAvoidingView behavior='position'>
<Text>LoginScreen</Text>
</KeyboardAvoidingView>
</ScrollView>
)
}
}
const mapStateToProps = (state) => {
return {
}
}
const mapDispatchToProps = (dispatch) => {
return {
}
}
export default connect(mapStateToProps, mapDispatchToProps)(LoginScreen)
import React, { Component } from 'react'
import { ScrollView, Text, KeyboardAvoidingView } from 'react-native'
import { connect } from 'react-redux'
// Add Actions - replace 'Your' with whatever your reducer is called :)
// import YourActions from '../Redux/YourRedux'
// Styles
import styles from './Styles/NotificationScreenStyle'
class NotificationScreen extends Component {
render () {
return (
<ScrollView style={styles.container}>
<KeyboardAvoidingView behavior='position'>
<Text>NotificationScreen</Text>
</KeyboardAvoidingView>
</ScrollView>
)
}
}
const mapStateToProps = (state) => {
return {
}
}
const mapDispatchToProps = (dispatch) => {
return {
}
}
export default connect(mapStateToProps, mapDispatchToProps)(NotificationScreen)
import React, { Component } from 'react'
import { ScrollView, Text, KeyboardAvoidingView } from 'react-native'
import { connect } from 'react-redux'
// Add Actions - replace 'Your' with whatever your reducer is called :)
// import YourActions from '../Redux/YourRedux'
// Styles
import styles from './Styles/ProfileScreenStyle'
class ProfileScreen extends Component {
render () {
return (
<ScrollView style={styles.container}>
<KeyboardAvoidingView behavior='position'>
<Text>ProfileScreen</Text>
</KeyboardAvoidingView>
</ScrollView>
)
}
}
const mapStateToProps = (state) => {
return {
}
}
const mapDispatchToProps = (dispatch) => {
return {
}
}
export default connect(mapStateToProps, mapDispatchToProps)(ProfileScreen)
### Containers Folder
A container is what they call a "Smart Component" in Redux. It is a component
which knows about Redux. They are usually used as "Screens".
Also located in here are 2 special containers: `App.js` and `RootContainer.js`.
`App.js` is first component loaded after `index.ios.js` or `index.android.js`. The purpose of this file is to setup Redux or any other non-visual "global" modules. Having Redux setup here helps with the hot-reloading process in React Native during development as it won't try to reload your sagas and reducers should your colors change (for example).
`RootContainer.js` is the first visual component in the app. It is the ancestor of all other screens and components.
You'll probably find you'll have great mileage in Ignite apps without even touching these 2 files. They, of course, belong to you, so when you're ready to add something non-visual like Firebase or something visual like an overlay, you have spots to place these additions.
import React, { Component } from 'react'
import { ScrollView, Text, KeyboardAvoidingView } from 'react-native'
import { connect } from 'react-redux'
// Add Actions - replace 'Your' with whatever your reducer is called :)
// import YourActions from '../Redux/YourRedux'
// Styles
import styles from './Styles/RegisterScreenStyle'
class RegisterScreen extends Component {
render () {
return (
<ScrollView style={styles.container}>
<KeyboardAvoidingView behavior='position'>
<Text>RegisterScreen</Text>
</KeyboardAvoidingView>
</ScrollView>
)
}
}
const mapStateToProps = (state) => {
return {
}
}
const mapDispatchToProps = (dispatch) => {
return {
}
}
export default connect(mapStateToProps, mapDispatchToProps)(RegisterScreen)
import React, { Component } from 'react'
import { View, StatusBar } from 'react-native'
import ReduxNavigation from '../Navigation/ReduxNavigation'
import { connect } from 'react-redux'
import StartupActions from '../Redux/StartupRedux'
import ReduxPersist from '../Config/ReduxPersist'
// Styles
import styles from './Styles/RootContainerStyles'
class RootContainer extends Component {
componentDidMount () {
// if redux persist is not active fire startup action
if (!ReduxPersist.active) {
this.props.startup()
}
}
render () {
return (
<View style={styles.applicationView}>
<StatusBar barStyle='light-content' />
<ReduxNavigation />
</View>
)
}
}
// wraps dispatch to create nicer functions to call within our component
const mapDispatchToProps = (dispatch) => ({
startup: () => dispatch(StartupActions.startup())
})
export default connect(null, mapDispatchToProps)(RootContainer)
import { StyleSheet } from 'react-native'
import { ApplicationStyles } from '../../Themes/'
export default StyleSheet.create({
...ApplicationStyles.screen
})
import { StyleSheet } from 'react-native'
import { ApplicationStyles } from '../../Themes/'
export default StyleSheet.create({
...ApplicationStyles.screen
})
import { StyleSheet } from 'react-native'
import { Metrics, ApplicationStyles } from '../../Themes/'
export default StyleSheet.create({
...ApplicationStyles.screen,
container: {
paddingBottom: Metrics.baseMargin
},
logo: {
marginTop: Metrics.doubleSection,
height: Metrics.images.logo,
width: Metrics.images.logo,
resizeMode: 'contain'
},
centered: {
alignItems: 'center',
justifyContent: 'center',
height: '100%'
}
})
import { StyleSheet } from 'react-native'
import { ApplicationStyles } from '../../Themes/'
export default StyleSheet.create({
...ApplicationStyles.screen
})
import { StyleSheet } from 'react-native'
import { ApplicationStyles } from '../../Themes/'
export default StyleSheet.create({
...ApplicationStyles.screen
})
import { StyleSheet } from 'react-native'
import { ApplicationStyles } from '../../Themes/'
export default StyleSheet.create({
...ApplicationStyles.screen
})
### Styles Folder
Container styles are separated from functionality.
import { StyleSheet } from 'react-native'
import { ApplicationStyles } from '../../Themes/'
export default StyleSheet.create({
...ApplicationStyles.screen
})
import {StyleSheet} from 'react-native'
import {Fonts, Metrics, Colors} from '../../Themes/'
export default StyleSheet.create({
applicationView: {
flex: 1
},
container: {
flex: 1,
justifyContent: 'center',
backgroundColor: Colors.background
},
welcome: {
fontSize: 20,
textAlign: 'center',
fontFamily: Fonts.type.base,
margin: Metrics.baseMargin
},
myImage: {
width: 200,
height: 200,
alignSelf: 'center'
}
})
import { StyleSheet } from 'react-native'
import { ApplicationStyles } from '../../Themes/'
export default StyleSheet.create({
...ApplicationStyles.screen
})
import React, { Component } from 'react'
import { ScrollView, Text, KeyboardAvoidingView } from 'react-native'
import { connect } from 'react-redux'
// Add Actions - replace 'Your' with whatever your reducer is called :)
// import YourActions from '../Redux/YourRedux'
// Styles
import styles from './Styles/WishlistScreenStyle'
class WishlistScreen extends Component {
render () {
return (
<ScrollView style={styles.container}>
<KeyboardAvoidingView behavior='position'>
<Text>WishlistScreen</Text>
</KeyboardAvoidingView>
</ScrollView>
)
}
}
const mapStateToProps = (state) => {
return {
}
}
const mapDispatchToProps = (dispatch) => {
return {
}
}
export default connect(mapStateToProps, mapDispatchToProps)(WishlistScreen)
### Fixtures folder
All key API responses are housed here.
These API responses can be used for several reasons. _E.G._:
* To bypass logins when building any screen of the application
* To quickly test API parsing in unit tests
* To separate Network from Data concerns while coding
{
"total_count": 7,
"incomplete_results": false,
"items": [
{
"login": "GantMan",
"id": 997157,
"avatar_url": "https://avatars.githubusercontent.com/u/997157?v=3",
"gravatar_id": "",
"url": "https://api.github.com/users/GantMan",
"html_url": "https://github.com/GantMan",
"followers_url": "https://api.github.com/users/GantMan/followers",
"following_url": "https://api.github.com/users/GantMan/following{/other_user}",
"gists_url": "https://api.github.com/users/GantMan/gists{/gist_id}",
"starred_url": "https://api.github.com/users/GantMan/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/GantMan/subscriptions",
"organizations_url": "https://api.github.com/users/GantMan/orgs",
"repos_url": "https://api.github.com/users/GantMan/repos",
"events_url": "https://api.github.com/users/GantMan/events{/privacy}",
"received_events_url": "https://api.github.com/users/GantMan/received_events",
"type": "User",
"site_admin": false,
"score": 122.12115
},
{
"login": "vlad-G",
"id": 13520880,
"avatar_url": "https://avatars.githubusercontent.com/u/13520880?v=3",
"gravatar_id": "",
"url": "https://api.github.com/users/vlad-G",
"html_url": "https://github.com/vlad-G",
"followers_url": "https://api.github.com/users/vlad-G/followers",
"following_url": "https://api.github.com/users/vlad-G/following{/other_user}",
"gists_url": "https://api.github.com/users/vlad-G/gists{/gist_id}",
"starred_url": "https://api.github.com/users/vlad-G/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/vlad-G/subscriptions",
"organizations_url": "https://api.github.com/users/vlad-G/orgs",
"repos_url": "https://api.github.com/users/vlad-G/repos",
"events_url": "https://api.github.com/users/vlad-G/events{/privacy}",
"received_events_url": "https://api.github.com/users/vlad-G/received_events",
"type": "User",
"site_admin": false,
"score": 12.69848
},
{
"login": "gantmani",
"id": 3034094,
"avatar_url": "https://avatars.githubusercontent.com/u/3034094?v=3",
"gravatar_id": "",
"url": "https://api.github.com/users/gantmani",
"html_url": "https://github.com/gantmani",
"followers_url": "https://api.github.com/users/gantmani/followers",
"following_url": "https://api.github.com/users/gantmani/following{/other_user}",
"gists_url": "https://api.github.com/users/gantmani/gists{/gist_id}",
"starred_url": "https://api.github.com/users/gantmani/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/gantmani/subscriptions",
"organizations_url": "https://api.github.com/users/gantmani/orgs",
"repos_url": "https://api.github.com/users/gantmani/repos",
"events_url": "https://api.github.com/users/gantmani/events{/privacy}",
"received_events_url": "https://api.github.com/users/gantmani/received_events",
"type": "User",
"site_admin": false,
"score": 11.641713
},
{
"login": "sgantman",
"id": 5911526,
"avatar_url": "https://avatars.githubusercontent.com/u/5911526?v=3",
"gravatar_id": "",
"url": "https://api.github.com/users/sgantman",
"html_url": "https://github.com/sgantman",
"followers_url": "https://api.github.com/users/sgantman/followers",
"following_url": "https://api.github.com/users/sgantman/following{/other_user}",
"gists_url": "https://api.github.com/users/sgantman/gists{/gist_id}",
"starred_url": "https://api.github.com/users/sgantman/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/sgantman/subscriptions",
"organizations_url": "https://api.github.com/users/sgantman/orgs",
"repos_url": "https://api.github.com/users/sgantman/repos",
"events_url": "https://api.github.com/users/sgantman/events{/privacy}",
"received_events_url": "https://api.github.com/users/sgantman/received_events",
"type": "User",
"site_admin": false,
"score": 7.926345
},
{
"login": "michaelgantman",
"id": 16693070,
"avatar_url": "https://avatars.githubusercontent.com/u/16693070?v=3",
"gravatar_id": "",
"url": "https://api.github.com/users/michaelgantman",
"html_url": "https://github.com/michaelgantman",
"followers_url": "https://api.github.com/users/michaelgantman/followers",
"following_url": "https://api.github.com/users/michaelgantman/following{/other_user}",
"gists_url": "https://api.github.com/users/michaelgantman/gists{/gist_id}",
"starred_url": "https://api.github.com/users/michaelgantman/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/michaelgantman/subscriptions",
"organizations_url": "https://api.github.com/users/michaelgantman/orgs",
"repos_url": "https://api.github.com/users/michaelgantman/repos",
"events_url": "https://api.github.com/users/michaelgantman/events{/privacy}",
"received_events_url": "https://api.github.com/users/michaelgantman/received_events",
"type": "User",
"site_admin": false,
"score": 7.926345
},
{
"login": "gantmanis",
"id": 19141249,
"avatar_url": "https://avatars.githubusercontent.com/u/19141249?v=3",
"gravatar_id": "",
"url": "https://api.github.com/users/gantmanis",
"html_url": "https://github.com/gantmanis",
"followers_url": "https://api.github.com/users/gantmanis/followers",
"following_url": "https://api.github.com/users/gantmanis/following{/other_user}",
"gists_url": "https://api.github.com/users/gantmanis/gists{/gist_id}",
"starred_url": "https://api.github.com/users/gantmanis/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/gantmanis/subscriptions",
"organizations_url": "https://api.github.com/users/gantmanis/orgs",
"repos_url": "https://api.github.com/users/gantmanis/repos",
"events_url": "https://api.github.com/users/gantmanis/events{/privacy}",
"received_events_url": "https://api.github.com/users/gantmanis/received_events",
"type": "User",
"site_admin": false,
"score": 7.8813524
},
{
"login": "Gantman2014",
"id": 7669410,
"avatar_url": "https://avatars.githubusercontent.com/u/7669410?v=3",
"gravatar_id": "",
"url": "https://api.github.com/users/Gantman2014",
"html_url": "https://github.com/Gantman2014",
"followers_url": "https://api.github.com/users/Gantman2014/followers",
"following_url": "https://api.github.com/users/Gantman2014/following{/other_user}",
"gists_url": "https://api.github.com/users/Gantman2014/gists{/gist_id}",
"starred_url": "https://api.github.com/users/Gantman2014/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/Gantman2014/subscriptions",
"organizations_url": "https://api.github.com/users/Gantman2014/orgs",
"repos_url": "https://api.github.com/users/Gantman2014/repos",
"events_url": "https://api.github.com/users/Gantman2014/events{/privacy}",
"received_events_url": "https://api.github.com/users/Gantman2014/received_events",
"type": "User",
"site_admin": false,
"score": 7.8813524
}
]
}
\ No newline at end of file
{
"resources": {
"core": {
"limit": 60,
"remaining": 42,
"reset": 1488126913
},
"search": {
"limit": 10,
"remaining": 9,
"reset": 1488126003
}
},
"rate": {
"limit": 60,
"remaining": 42,
"reset": 1488126913
}
}
\ No newline at end of file
{
"current_user_url": "https://api.github.com/user",
"current_user_authorizations_html_url": "https://github.com/settings/connections/applications{/client_id}",
"authorizations_url": "https://api.github.com/authorizations",
"code_search_url": "https://api.github.com/search/code?q={query}{&page,per_page,sort,order}",
"commit_search_url": "https://api.github.com/search/commits?q={query}{&page,per_page,sort,order}",
"emails_url": "https://api.github.com/user/emails",
"emojis_url": "https://api.github.com/emojis",
"events_url": "https://api.github.com/events",
"feeds_url": "https://api.github.com/feeds",
"followers_url": "https://api.github.com/user/followers",
"following_url": "https://api.github.com/user/following{/target}",
"gists_url": "https://api.github.com/gists{/gist_id}",
"hub_url": "https://api.github.com/hub",
"issue_search_url": "https://api.github.com/search/issues?q={query}{&page,per_page,sort,order}",
"issues_url": "https://api.github.com/issues",
"keys_url": "https://api.github.com/user/keys",
"notifications_url": "https://api.github.com/notifications",
"organization_repositories_url": "https://api.github.com/orgs/{org}/repos{?type,page,per_page,sort}",
"organization_url": "https://api.github.com/orgs/{org}",
"public_gists_url": "https://api.github.com/gists/public",
"rate_limit_url": "https://api.github.com/rate_limit",
"repository_url": "https://api.github.com/repos/{owner}/{repo}",
"repository_search_url": "https://api.github.com/search/repositories?q={query}{&page,per_page,sort,order}",
"current_user_repositories_url": "https://api.github.com/user/repos{?type,page,per_page,sort}",
"starred_url": "https://api.github.com/user/starred{/owner}{/repo}",
"starred_gists_url": "https://api.github.com/gists/starred",
"team_url": "https://api.github.com/teams",
"user_url": "https://api.github.com/users/{user}",
"user_organizations_url": "https://api.github.com/user/orgs",
"user_repositories_url": "https://api.github.com/users/{user}/repos{?type,page,per_page,sort}",
"user_search_url": "https://api.github.com/search/users?q={query}{&page,per_page,sort,order}"
}
\ No newline at end of file
{
"total_count": 1,
"incomplete_results": false,
"items": [
{
"login": "skellock",
"id": 68273,
"avatar_url": "https://avatars.githubusercontent.com/u/68273?v=3",
"gravatar_id": "",
"url": "https://api.github.com/users/skellock",
"html_url": "https://github.com/skellock",
"followers_url": "https://api.github.com/users/skellock/followers",
"following_url": "https://api.github.com/users/skellock/following{/other_user}",
"gists_url": "https://api.github.com/users/skellock/gists{/gist_id}",
"starred_url": "https://api.github.com/users/skellock/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/skellock/subscriptions",
"organizations_url": "https://api.github.com/users/skellock/orgs",
"repos_url": "https://api.github.com/users/skellock/repos",
"events_url": "https://api.github.com/users/skellock/events{/privacy}",
"received_events_url": "https://api.github.com/users/skellock/received_events",
"type": "User",
"site_admin": false,
"score": 107.22611
}
]
}
\ No newline at end of file
// @flow
import I18n from 'react-native-i18n'
// Enable fallbacks if you want `en-US` and `en-GB` to fallback to `en`
I18n.fallbacks = true
// English language is the main language for fall back:
I18n.translations = {
en: require('./languages/english.json')
}
let languageCode = I18n.locale.substr(0, 2)
// All other translations for the app goes to the respective language file:
switch (languageCode) {
case 'af':
I18n.translations.af = require('./languages/af.json')
break
case 'am':
I18n.translations.am = require('./languages/am.json')
break
case 'ar':
I18n.translations.ar = require('./languages/ar.json')
break
case 'bg':
I18n.translations.bg = require('./languages/bg.json')
break
case 'ca':
I18n.translations.ca = require('./languages/ca.json')
break
case 'cs':
I18n.translations.cs = require('./languages/cs.json')
break
case 'da':
I18n.translations.da = require('./languages/da.json')
break
case 'de':
I18n.translations.de = require('./languages/de.json')
break
case 'el':
I18n.translations.el = require('./languages/el.json')
break
case 'es':
I18n.translations.es = require('./languages/es.json')
break
case 'et':
I18n.translations.et = require('./languages/et.json')
break
case 'fi':
let addCode = I18n.locale.substr(0, 3)
if (addCode === 'fil') {
I18n.translations.fil = require('./languages/fil.json')
} else {
I18n.translations.fi = require('./languages/fi.json')
}
break
case 'fr':
I18n.translations.fr = require('./languages/fr.json')
break
case 'he':
I18n.translations.he = require('./languages/he.json')
break
case 'hi':
I18n.translations.hi = require('./languages/hi.json')
break
case 'hr':
I18n.translations.hr = require('./languages/hr.json')
break
case 'hu':
I18n.translations.hu = require('./languages/hu.json')
break
case 'id':
I18n.translations.id = require('./languages/id.json')
break
case 'it':
I18n.translations.it = require('./languages/it.json')
break
case 'ja':
I18n.translations.ja = require('./languages/ja.json')
break
case 'ko':
I18n.translations.ko = require('./languages/ko.json')
break
case 'lt':
I18n.translations.lt = require('./languages/lt.json')
break
case 'lv':
I18n.translations.lv = require('./languages/lv.json')
break
case 'ms':
I18n.translations.ms = require('./languages/ms.json')
break
case 'nb':
I18n.translations.nb = require('./languages/nb.json')
break
case 'nl':
I18n.translations.nl = require('./languages/nl.json')
break
case 'no':
I18n.translations.no = require('./languages/no.json')
break
case 'pl':
I18n.translations.pl = require('./languages/pl.json')
break
case 'pt':
I18n.translations.pt = require('./languages/pt.json')
break
case 'ro':
I18n.translations.ro = require('./languages/ro.json')
break
case 'ru':
I18n.translations.ru = require('./languages/ru.json')
break
case 'sl':
I18n.translations.sl = require('./languages/sl.json')
break
case 'sk':
I18n.translations.sk = require('./languages/sk.json')
break
case 'sr':
I18n.translations.sr = require('./languages/sr.json')
break
case 'sv':
I18n.translations.sv = require('./languages/sv.json')
break
case 'sw':
I18n.translations.sw = require('./languages/sw.json')
break
case 'th':
I18n.translations.th = require('./languages/th.json')
break
case 'tr':
I18n.translations.tr = require('./languages/tr.json')
break
case 'uk':
I18n.translations.uk = require('./languages/uk.json')
break
case 'vi':
I18n.translations.vi = require('./languages/vi.json')
break
case 'zh':
I18n.translations.zh = require('./languages/zh.json')
break
case 'zu':
I18n.translations.zu = require('./languages/zu.json')
break
}
# Idea
Shipping app with localization for all available languages. The main idea here is to minimize the memory required of other languages that is not used by the platform.
For example if the phone is localized in French, then this will only load the French and English translations into memory and ignore the 30+ other languages available.
English translation is set as default fallback in case some translations are not available in the chosen language.
# Installation
Run `ignite add i18n`.
# Usage
TODO: Real usage example.
import I18n from 'App/I18n';
render() {
...
{ I18n.t('welcome') }
...
}
import I18n from 'react-native-i18n'
const missingTranslationRegex = /^\[missing ".*" translation\]$/
// This function is a wrapper to avoid exception wich leads in a crash
const translateOrFallback = (initialMsg, options) => {
// We tried to translate something else than a string
// The native I18n function will simply crash instead of rejecting the attempt with an error message
if (typeof initialMsg !== 'string') {
__DEV__ &&
console.log(
`I18n: you must give a string to translate instead of "${typeof initialMsg}"`
)
return '' // We don't return any message as we don't know what to send
}
let localMsg = I18n.t(initialMsg, options)
// The translation does not exist, the default message is not very sexy
// Instead we return the message we tried to translate
if (missingTranslationRegex.test(localMsg)) {
__DEV__ &&
console.log(
`translation "${initialMsg}" does not exists in translations files`
)
return initialMsg
}
return localMsg
}
export default {
...I18n,
t: translateOrFallback
}
{
"signIn": "Sign In",
"logOut": "Log Out",
"loginLogoutExampleTitle": "Login/Logout Redux + Sagas Example",
"progressiveImageComponent": "Progressive Image Component",
"api": "API",
"locale": "I18n Locale",
"rnVectorIcons": "RN Vector Icons",
"loginWithFacebook": "Login with Facebook",
"rni18n": "RN i18n",
"igniteGenerated": "Ignite Generate Screens",
"forgotPassword": "Forgot Password",
"username": "Username",
"password": "Password",
"cancel": "Cancel",
"welcome": "Welcome",
"login": "Login",
"tempIndicator": "F",
"componentExamples": "Component Examples",
"usageExamples": "Usage Examples",
"apiTesting": "API Testing",
"themeSettings": "Theme Settings",
"deviceDetails": "Device Details",
"noItems": "No Items",
"search": "Search"
}
{
"signIn": "Se connecter",
"logOut": "Se déconnecter",
"loginLogoutExampleTitle": "Connexion / Déconnexion Redux + Sagas Exemple",
"progressiveImageComponent": "Composant Image Progressive",
"api": "Mon Dieu! Une API pour vous!",
"locale": "I18n Paramètres régionaux",
"rnVectorIcons": "RN icônes vectorielles",
"loginWithFacebook": "Se connecter avec Facebook",
"rni18n": "RN i18n",
"igniteGenerated": "Ignite Générer des Écrans",
"forgotPassword": "Mot de passe oublié",
"username": "Nom d'utilisateur",
"password": "Mot de passe",
"cancel": "Annuler",
"welcome": "Bienvenue",
"login": "S'identifier",
"tempIndicator": "C",
"componentExamples": "Exemples de Composants",
"usageExamples": "Exemples d'utilisation",
"apiTesting": "API Testing",
"themeSettings": "Réglage des thèmes",
"deviceDetails": "Détails du périphérique",
"noItems": "Aucun"
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment