Authored by 于良

增加home模块 review by 盖剑秋

'use strict';
import React from 'react';
import ReactNative, {
AppRegistry,
Platform,
} 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 homeInitialState from './reducers/home/homeInitialState';
import HomeContainer from './containers/HomeContainer';
import {
setPlatform,
setHost,
setServiceHost,
} from './reducers/app/appActions';
function getInitialState() {
const _initState = {
app: (new appInitialState()),
home: (new homeInitialState()),
};
return _initState;
}
export default function native(platform) {
let YH_Home = React.createClass({
render() {
const store = configureStore(getInitialState());
store.dispatch(setPlatform(platform));
store.dispatch(setHost(this.props.host));
store.dispatch(setServiceHost(this.props.serviceHost));
return (
<Provider store={store}>
<HomeContainer />
</Provider>
);
}
});
AppRegistry.registerComponent('YH_Home', () => YH_Home);
}
... ...
'use strict';
import React, {Component} from 'react';
import ReactNative, {
View,
Text,
Image,
ListView,
StyleSheet,
Dimensions,
TouchableOpacity,
InteractionManager,
Platform,
} from 'react-native';
export default class Home extends Component {
constructor(props) {
super(props);
this._renderRow = this._renderRow.bind(this);
this._onEndReached = this._onEndReached.bind(this);
this._renderFooter = this._renderFooter.bind(this);
this.trigggePullToRefresh = this.trigggePullToRefresh.bind(this);
this.dataSource = new ListView.DataSource({
rowHasChanged: (r1, r2) => !Immutable.is(r1, r2),
});
}
componentDidMount() {
this.trigggePullToRefresh();
}
componentWillReceiveProps(nextProps) {
if (nextProps.data.ptr) {
this.listView && this.listView.scrollTo({x: 0, y: 0, animated: false, });
}
}
trigggePullToRefresh() {
if (Platform.OS === 'ios') {
InteractionManager.runAfterInteractions(() => {
this.listView && this.listView.getScrollResponder().startPullToRefresh();
});
} else {
this.props.onRefresh && this.props.onRefresh();
}
}
_renderRow(rowData: object, sectionID: number, rowID: number) {
return null;
}
_onEndReached() {
}
_renderFooter() {
return null;
}
render() {
let {list, ptr, isFetching, endReached, showLoginTip, cachedList} = this.props.data;
let dataSource = list.size == 0 ? cachedList.toArray() : list.toArray();
let isPullToRefresh = ptr && isFetching;
let isLoadingMore = list.size != 0 && !ptr && isFetching;
return (
<View style={styles.container}>
<ListView
ref={(c) => {
this.listView = c;
}}
contentContainerStyle={styles.contentContainer}
dataSource={this.dataSource.cloneWithRows(dataSource)}
renderRow={this._renderRow}
enableEmptySections={true}
enablePullToRefresh={true}
isOnPullToRefresh={isPullToRefresh}
onRefreshData={() => {
this.props.onRefresh && this.props.onRefresh();
}}
onEndReached={this._onEndReached}
renderFooter={this._renderFooter}
/>
</View>
);
}
}
let {width, height} = Dimensions.get('window');
let styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#f0f0f0',
},
contentContainer: {
},
});
... ...
import keyMirror from 'key-mirror';
export default keyMirror({
SET_PLATFORM: null,
SET_HOST: null,
SET_SERVICE_HOST: null,
SET_CHANNEL: null,
});
... ...
'use strict'
import React, {Component} from 'react';
import ReactNative, {
StyleSheet,
Dimensions,
Platform,
View,
Text,
NativeModules,
InteractionManager,
NativeAppEventEmitter,
} from 'react-native'
import {bindActionCreators} from 'redux';
import {connect} from 'react-redux';
import {Map} from 'immutable';
import * as homeActions from '../reducers/home/homeActions';
import Home from '../components/home/Home';
const actions = [
homeActions,
];
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 HomeContainer extends Component {
constructor(props) {
super(props);
this._onRefresh = this._onRefresh.bind(this);
this._onEndReached = this._onEndReached.bind(this);
this.subscription = NativeAppEventEmitter.addListener(
'ChannelDidChangeEvent',
(reminder) => {
this.home && this.home.trigggePullToRefresh();
}
);
}
componentDidMount() {
}
componentWillUnmount() {
this.subscription && this.subscription.remove();
}
_onRefresh() {
InteractionManager.runAfterInteractions(() => {
});
}
_onEndReached() {
InteractionManager.runAfterInteractions(() => {
});
}
render() {
let {home} = this.props;
return (
<View style={styles.container}>
<Home
ref={(c) => {
this.Home = c;
}}
data={home}
onRefresh={this._onRefresh}
onEndReached={this._onEndReached}
/>
</View>
);
}
}
let styles = StyleSheet.create({
container: {
flex: 1,
},
});
export default connect(mapStateToProps, mapDispatchToProps)(HomeContainer);
... ...
'use strict';
import ReactNative from 'react-native';
const {
SET_PLATFORM,
SET_CHANNEL,
SET_HOST,
SET_SERVICE_HOST,
} = require('../../constants/actionTypes').default;
export function setPlatform(platform) {
return {
type: SET_PLATFORM,
payload: platform
};
}
export function setChannel(channel) {
return {
type: SET_CHANNEL,
payload: channel
};
}
export function setHost(host) {
return {
type: SET_HOST,
payload: host
};
}
export function setServiceHost(host) {
return {
type: SET_SERVICE_HOST,
payload: host
};
}
\ No newline at end of file
... ...
'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
host: 'http://api.yoho.cn',
serviceHost: 'http://service.yoho.cn',
});
export default InitialState;
... ...
'use strict';
import InitialState from './appInitialState';
const {
SET_PLATFORM,
SET_CHANNEL,
SET_HOST,
SET_SERVICE_HOST,
} = 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);
case SET_HOST:
return state.set('host', action.payload);
case SET_SERVICE_HOST:
return state.set('serviceHost', action.payload);
}
return state;
}
... ...
'use strict';
import ReactNative from 'react-native';
import HomeService from '../../services/Home';
import store from 'react-native-simple-store';
const {
SET_CHANNEL,
} = require('../../constants/actionTypes').default;
... ...
'use strict';
import {Record, List, Map} from 'immutable';
let InitialState = Record({
});
export default InitialState;
... ...
'use strict';
import InitialState from './homeInitialState';
import Immutable, {Map} from 'immutable';
const {
SET_CHANNEL,
} = require('../../constants/actionTypes').default;
const initialState = new InitialState;
export default function homeReducer(state=initialState, action) {
switch(action.type) {
}
return state;
}
... ...
import {combineReducers} from 'redux';
import app from './app/appReducer';
import home from './home/homeReducer';
const rootReducer = combineReducers({
app,
home,
});
export default rootReducer;
... ...
'use strict';
import Request from '../../common/services/Request';
export default class HomeService {
constructor (host) {
let baseURL = 'http://api.yoho.cn';
if(host){
baseURL = host;
}
this.api = new Request(baseURL);
}
}
... ...
/**
* # 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);
};
... ...