Authored by 于良

增加二维码扫描模块 review by 草莓

... ... @@ -2,8 +2,10 @@
import Community from './community/Community';
import Plustar from './plustar/Plustar';
import QRCode from './qrcode/QRCode';
export default function native(platform) {
Community(platform);
Plustar(platform);
QRCode(platform);
}
... ...
'use strict';
import React from 'react';
import ReactNative, {
AppRegistry,
Platform,
StyleSheet,
Dimensions,
TouchableOpacity,
} from 'react-native';
import {
Provider,
connect
} from 'react-redux';
import configureStore from './store/configureStore';
import {Record, List, Map} from 'immutable';
import appInitialState from './reducers/app/appInitialState';
import qrcodeInitialState from './reducers/qrcode/qrcodeInitialState';
import QRCodeContainer from './containers/QRCodeContainer';
import {
setPlatform,
} from './reducers/app/appActions';
function getInitialState() {
const _initState = {
app: (new appInitialState()),
qrcode: (new qrcodeInitialState()),
};
return _initState;
}
export default function native(platform) {
let YH_QRCode = React.createClass({
render() {
const store = configureStore(getInitialState());
store.dispatch(setPlatform(platform));
return (
<Provider store={store}>
<QRCodeContainer />
</Provider>
);
}
});
AppRegistry.registerComponent('YH_QRCode', () => YH_QRCode);
}
let styles = StyleSheet.create({
});
... ...
import React, {Component} from 'react';
import ReactNative from 'react-native';
let { requireNativeComponent } = ReactNative;
// requireNativeComponent automatically resolves this to "YH_BannerViewManager"
module.exports = requireNativeComponent('YH_BannerView', null);
class BannerView extends React.Component {
constructor(props) {
super(props);
this._onSelectBanner = this._onSelectBanner.bind(this);
}
_onSelectBanner(event: Event) {
if (!this.props.onSelectBanner) {
return;
}
this.props.onSelectBanner(event.nativeEvent.url);
}
render() {
return <YH_BannerView {...this.props} onPress={this._onSelectBanner} />;
}
}
BannerView.propTypes = {
autoLooping: React.PropTypes.bool,
items: React.PropTypes.arrayOf(
React.PropTypes.shape({
src: React.PropTypes.string.isRequired,
url: React.PropTypes.string.isRequired,
})
),
onSelectBanner: React.PropTypes.func,
};
let YH_BannerView = requireNativeComponent('YH_BannerView', BannerView);
module.exports = BannerView;
... ...
'use strict'
import React, {Component} from 'react';
import {
View,
Text,
TouchableWithoutFeedback,
StyleSheet,
} from 'react-native';
export default class Button extends Component {
constructor(props) {
super(props);
this.state = {
helighted: false,
}
this._onPress = this._onPress.bind(this);
this._onPressIn = this._onPressIn.bind(this);
this._onPressOut = this._onPressOut.bind(this);
this._helightedTextStyle = this._helightedTextStyle.bind(this);
this._selectedTextStyle = this._selectedTextStyle.bind(this);
}
render() {
return (
<TouchableWithoutFeedback
onPress={()=>{this._onPress()}}
onPressIn={()=>{this._onPressIn()}}
onPressOut={()=>{this._onPressOut()}} >
<View style={this.props.containerStyle || styles.container} >
<Text style={[this._selectedTextStyle(), this._helightedTextStyle()]} >
{this.props.title}
</Text>
</View>
</TouchableWithoutFeedback>
);
}
_helightedTextStyle() {
if(this.state.helighted) {
if(this.props.helightedTitleStyle) {
return this.props.helightedTitleStyle;
}
if(this.props.selected) {
return this.props.normalTitleStyle || styles.titleNormal;
} else {
return this.props.selectedTitleStyle || styles.titleSelected;
}
} else {
return this._selectedTextStyle();
}
}
_selectedTextStyle() {
if(this.props.selected) {
return this.props.selectedTitleStyle || styles.titleSelected;
} else {
return this.props.normalTitleStyle || styles.titleNormal;
}
}
_onPressIn() {
this.setState({
helighted: !this.state.helighted,
});
}
_onPressOut() {
this.setState({
helighted: !this.state.helighted,
});
}
_onPress() {
if(!this.props.onPress) {
return;
}
this.props.onPress();
}
};
Button.propTypes = {
title: React.PropTypes.string,
selected: React.PropTypes.bool,
onPress: React.PropTypes.func,
selectedTitleStyle: React.PropTypes.any,
normalTitleStyle: React.PropTypes.any,
helightedTitleStyle: React.PropTypes.any,
containerStyle: React.PropTypes.any,
};
let styles = StyleSheet.create({
container: {
width: 44,
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
titleHelighted: {
color: 'black',
fontSize: 15,
},
titleNormal: {
color: '#b0b0b0',
fontSize: 15,
},
titleSelected: {
color: 'black',
fontSize: 15,
},
});
... ...
'use strict';
import React, {Component} from 'react';
import ReactNative, {
View,
Text,
StyleSheet,
Dimensions,
} from 'react-native';
import Camera from 'react-native-camera';
export default class QRCode extends Component {
constructor(props) {
super(props);
}
componentDidMount() {
}
render() {
return (
<Camera
onBarCodeRead={this._onBarCodeRead}
style={styles.camera}
>
<View style={styles.rectangleContainer}>
<View style={styles.rectangle}/>
</View>
</Camera>
);
}
}
let styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#f0f0f0',
},
camera: {
height: Dimensions.get('window').height,
alignItems: 'center',
},
rectangleContainer: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
backgroundColor: 'transparent',
},
rectangle: {
height: 250,
width: 250,
borderWidth: 2,
borderColor: '#00FF00',
backgroundColor: 'transparent',
},
});
... ...
import keyMirror from 'key-mirror';
export default keyMirror({
SET_PLATFORM: null,
JUMP_WITH_URL: null,
});
... ...
'use strict'
import React, {Component} from 'react';
import {
StyleSheet,
Dimensions,
Platform,
View,
NativeModules,
InteractionManager,
NativeAppEventEmitter,
} from 'react-native'
import {bindActionCreators} from 'redux';
import {connect} from 'react-redux';
import {Map} from 'immutable';
import * as qrcodeActions from '../reducers/qrcode/qrcodeActions';
import QRCode from '../components/qrcode/QRCode';
const actions = [
qrcodeActions,
];
function mapStateToProps(state) {
return {
...state
};
}
function mapDispatchToProps(dispatch) {
const creators = Map()
.merge(...actions)
.filter(value => typeof value === 'function')
.toObject();
return {
actions: bindActionCreators(creators, dispatch),
dispatch
};
}
class QRCodeContainer extends Component {
constructor(props) {
super(props);
}
componentDidMount() {
}
componentWillUnmount() {
}
render() {
return (
<View style={styles.container}>
<QRCode/>
</View>
);
}
}
let styles = StyleSheet.create({
container: {
flex: 1,
},
});
export default connect(mapStateToProps, mapDispatchToProps)(QRCodeContainer);
... ...
'use strict';
import ReactNative from 'react-native';
const {
SET_PLATFORM,
SET_CHANNEL,
} = require('../../constants/actionTypes').default;
export function setPlatform(platform) {
return {
type: SET_PLATFORM,
payload: platform
};
}
export function setChannel(channel) {
return {
type: SET_CHANNEL,
payload: channel
};
}
... ...
'use strict';
import {Record, List, Map} from 'immutable';
let InitialState = Record({
platform: 'ios', // ios, android
channel: 1, // 1 - boy, 2 - girl, 3 - kid, 4 - lifestyle, 5 - yoho
});
export default InitialState;
... ...
'use strict';
import InitialState from './appInitialState';
const {
SET_PLATFORM,
SET_CHANNEL,
} = require('../../constants/actionTypes').default;
const initialState = new InitialState;
export default function appReducer(state = initialState, action) {
if (!(state instanceof InitialState)) return initialState.merge(state);
switch (action.type) {
case SET_PLATFORM:
return state.set('platform', action.payload);
case SET_CHANNEL:
return state.set('channel', action.payload);
}
return state;
}
... ...
import {combineReducers} from 'redux';
import app from './app/appReducer';
import qrcode from './qrcode/qrcodeReducer';
const rootReducer = combineReducers({
app,
qrcode,
});
export default rootReducer;
... ...
'use strict';
import ReactNative from 'react-native';
import QRCodeService from '../../services/QRCodeService';
const {
JUMP_WITH_URL,
} = require('../../constants/actionTypes').default;
export function jumpWithUrl(url) {
if (!url) {
__DEV__ && console.log('Illegal url');
return;
}
ReactNative.NativeModules.YH_PlustarHelper.jumpWithUrl(url);
return {
type: JUMP_WITH_URL,
payload: url
};
}
... ...
'use strict';
import {Record, List, Map} from 'immutable';
let InitialState = Record({
activeTab: 0,
gender: -1,
0: new (Record({
isFetching: false,
error: null,
head: List(),
foot: List(),
list: List(),
})),
1: new (Record({
isFetching: false,
error: null,
head: List(),
foot: List(),
list: List(),
})),
segment: null,
});
export default InitialState;
... ...
'use strict';
import InitialState from './qrcodeInitialState';
import Immutable, {Map} from 'immutable';
const {
JUMP_WITH_URL,
} = require('../../constants/actionTypes').default;
const initialState = new InitialState;
export default function qrcodeReducer(state=initialState, action) {
switch(action.type) {
}
return state;
}
... ...
'use strict';
import Request from '../../common/services/Request';
export default class QRCodeService {
constructor () {
let baseURL = 'http://service.yoho.cn';
this.api = new Request(baseURL);
}
async fetchList(brand_type, options) {
return await this.api.get({
url: '/guang/api/v3/plustar/getlist',
body: {
brand_type,
...options,
}
})
.then((json) => {
return json;
})
.catch((error) => {
throw(error);
});
}
}
... ...
/**
* # configureStore.js
*
* A Redux boilerplate setup
*
*/
'use strict';
/**
* ## Imports
*
* redux functions
*/
import { createStore, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';
import createLogger from 'redux-logger';
/**
* ## Reducer
* The reducer contains the 4 reducers from
* device, global, auth, profile
*/
import reducer from '../reducers';
const logger = createLogger({
predicate: (getState, action) => process.env.NODE_ENV === `development`
});
/**
* ## creatStoreWithMiddleware
* Like the name...
*/
const createStoreWithMiddleware = applyMiddleware(
thunk,
logger
)(createStore);
/**
* ## configureStore
* @param {Object} the state with for keys:
* device, global, auth, profile
*
*/
export default function configureStore(initialState) {
return createStoreWithMiddleware(reducer, initialState);
};
... ...
... ... @@ -16,6 +16,7 @@
"react": "^15.3.1",
"react-immutable-proptypes": "^2.1.0",
"react-native": "0.32.0",
"react-native-camera": "github:lwansbrough/react-native-camera#1747ec4b0a52472cf2e8ad95f2c3603595e28e13",
"react-native-device-info": "0.9.5",
"react-native-fabric": "0.2.2",
"react-native-progress": "^3.0.1",
... ...