Authored by 于良

社区首页 review by arthor

'use strict';
import React from 'react';
import {AppRegistry, Platform, StyleSheet, Dimensions} from 'react-native';
import {AppRegistry, Platform, StyleSheet, Dimensions,NativeModules} from 'react-native';
import {
Provider,
... ... @@ -21,6 +21,7 @@ import homeInitialState from './reducers/home/homeInitialState';
import HomeContainer from './containers/HomeContainer';
import NavBar from './components/NavBar';
let VERSION = '0.0.1';
... ... @@ -102,7 +103,7 @@ export default function community(platform) {
<Scene key="root" hideNavBar={true} hideTabBar={true}>
<Scene
key="Home"
title="首页"
title="社区"
hideNavBar={false}
component={HomeContainer}
initial={true}
... ... @@ -111,8 +112,16 @@ export default function community(platform) {
getSceneStyle={(props) => {
return this.navPushStyle(props);
}}
leftTitle={null}
leftButtonImage={require('./images/home/menu_burger.png')}
onLeft={() => {}}
rightTitle={' '}
rightButtonImage={require('./images/home/menu_write.png')}
onRight={() => {}}
/>
</Scene>
</NewRouter>
</Provider>
... ...
'use strict';
import React from 'react';
import ReactNative from 'react-native';
const {
View,
Text,
ScrollView,
Platform,
} = ReactNative;
export default class Home extends React.Component {
static propTypes = {
section1: React.PropTypes.arrayOf(
React.PropTypes.shape({
top: React.PropTypes.string,
bottom: React.PropTypes.string,
small: React.PropTypes.string,
style: View.propTypes.style,
})
),
section2: React.PropTypes.arrayOf(
React.PropTypes.shape({
top: React.PropTypes.string,
bottom: React.PropTypes.string,
small: React.PropTypes.string,
style: View.propTypes.style,
arrowUp: React.PropTypes.bool,
})
),
section3: React.PropTypes.arrayOf(
React.PropTypes.shape({
type: React.PropTypes.string,
thumb: React.PropTypes.number,
title: React.PropTypes.string,
})
),
onPressCategory: React.PropTypes.func,
};
render() {
return (
<View style={{flexDirection: 'row', justifyContent: 'center'}}>
<Text>这是社区首页</Text>
</View>
);
}
}
... ... @@ -38,8 +38,8 @@ import {
BackAndroid,
} from 'react-native';
import {Actions} from 'react-native-router-flux';
import _drawerImage from '../images/menu_burger.png';
import _backButtonImage from '../images/menu_back.png';
import _drawerImage from '../images/home/menu_burger.png';
import _backButtonImage from '../images/home/menu_back.png';
const styles = StyleSheet.create({
title: {
... ...
'use strict';
import React from 'react';
import ReactNative from 'react-native';
import Swiper from 'react-native-swiper';
import ImmutablePropTypes from 'react-immutable-proptypes';
const {
View,
Image,
TouchableOpacity,
StyleSheet,
Dimensions,
} = ReactNative;
export default class Banner extends React.Component {
static propTypes = {
data: ImmutablePropTypes.listOf(
ImmutablePropTypes.contains({
image: React.PropTypes.string.isRequired,
url: React.PropTypes.string.isRequired,
})
),
width: React.PropTypes.number.isRequired,
height: React.PropTypes.number.isRequired,
onPress: React.PropTypes.func,
};
constructor(props) {
super (props);
this.dot = <View
style={{
backgroundColor:'rgba(0,0,0,.2)',
width: 6,
height: 6,
borderRadius: 3,
marginLeft: 3,
marginRight: 3,
marginTop: 3,
marginBottom: 3,
}}
/>;
this.activeDot = <View
style={{
backgroundColor:'white',
width: 6,
height: 6,
borderRadius: 3,
marginLeft: 3,
marginRight: 3,
marginTop: 3,
marginBottom: 3,
}}
/>;
}
render() {
let width = this.props.width;
let height = this.props.height;
let data = this.props.data.toArray();
return (
<Swiper
style={styles.banner}
showsButtons={false}
loop={true}
autoplay={true}
paginationStyle={{bottom: 8}}
dot={this.dot}
activeDot={this.activeDot}
height={height}
>
{data.map((item, i) => {
return (
<TouchableOpacity
key={i}
activeOpacity={1}
onPress={() => {
this.props.onPress && this.props.onPress();
}}
>
<Image source={{uri: item.get('image')}} style={{width, height}}/>
</TouchableOpacity>
);
})}
</Swiper>
);
}
}
let styles = StyleSheet.create({
banner: {
},
});
... ...
'use strict';
import React from 'react';
import ReactNative from 'react-native';
import ImmutablePropTypes from 'react-immutable-proptypes';
import Banner from './Banner';
import Notice from './Notice';
import Section from './Section';
import ListCell from './ListCell';
const {
View,
Text,
Image,
ListView,
TouchableOpacity,
Platform,
StyleSheet,
Dimensions,
} = ReactNative;
let {width, height} = Dimensions.get('window');
let bannerHeight = Math.ceil((363 / 750) * width);
export default class Home extends React.Component {
static propTypes = {
dataBlob: React.PropTypes.shape({
banner: React.PropTypes.shape({
banner: ImmutablePropTypes.listOf(
ImmutablePropTypes.contains({
image: React.PropTypes.string.isRequired,
url: React.PropTypes.string,
}),
),
}),
notice: React.PropTypes.shape({
notice: ImmutablePropTypes.listOf(
ImmutablePropTypes.contains({
title: React.PropTypes.string.isRequired,
url: React.PropTypes.string,
}),
),
}),
section: React.PropTypes.shape({
section: ImmutablePropTypes.listOf(
ImmutablePropTypes.contains({
image: React.PropTypes.string.isRequired,
url: React.PropTypes.string,
})
),
}),
recommendation: React.PropTypes.arrayOf(
ImmutablePropTypes.contains({
avatar: React.PropTypes.string.isRequired,
name: React.PropTypes.string.isRequired,
timeago: React.PropTypes.string.isRequired,
isOwner: React.PropTypes.bool,
isTop: React.PropTypes.bool,
isLike: React.PropTypes.bool,
title: React.PropTypes.string,
desc: React.PropTypes.string,
thumbs: ImmutablePropTypes.listOf(
ImmutablePropTypes.contains({
url: React.PropTypes.string,
})
),
section: React.PropTypes.string,
commentCount: React.PropTypes.number,
likeCount: React.PropTypes.number,
}),
),
}),
onPressPost: React.PropTypes.func,
onPressAvatar: React.PropTypes.func,
onPressSectionTag: React.PropTypes.func,
onPressComment: React.PropTypes.func,
onPressLike: React.PropTypes.func,
};
constructor(props) {
super (props);
this._renderRow = this._renderRow.bind(this);
this._renderSectionHeader = this._renderSectionHeader.bind(this);
this._renderSeparator = this._renderSeparator.bind(this);
this.dataSource = new ListView.DataSource({
rowHasChanged: (r1, r2) => !Immutable.is(r1, r2),
sectionHeaderHasChanged: (s1, s2) => !Immutable.is(s1, s2),
});
}
_renderRow(rowData, sectionID, rowID, highlightRow) {
switch (sectionID) {
case 'banner':
return (
<Banner
data={rowData}
width={width}
height={bannerHeight}
onPress={(url) => {
this.props.onPressBanner && this.props.onPressBanner(url);
}}
/>
);
case 'notice':
return (
<Notice
data={rowData}
width={width}
height={40}
onPress={(url) => {
this.props.onPressNotice && this.props.onPressNotice(url);
}}
/>
);
case 'section':
return (
<Section
data={rowData}
width={width}
height={210}
onPress={(url) => {
this.props._onPressSection && this.props._onPressSection(url);
}}
/>
);
case 'recommendation':
return (
<ListCell
key={sectionID + rowID}
data={rowData}
onPressPost={(url) => {
this.props.onPressPost && this.props.onPressPost(url);
}}
onPressAvatar={(url) => {
this.props.onPressAvatar && this.props.onPressAvatar(url);
}}
onPressSectionTag={(url) => {
this.props.onPressSectionTag && this.props.onPressSectionTag(url);
}}
onPressComment={(url) => {
this.props.onPressComment && this.props.onPressComment(url);
}}
onPressLike={(url) => {
this.props.onPressLike && this.props.onPressLike(url);
}}
/>
);
}
}
_renderSectionHeader(sectionData, sectionID) {
switch (sectionID) {
case 'banner':
case 'notice':
case 'section':
return null;
case 'recommendation':
return (
<View style={styles.sectionHeader}>
<Image style={styles.sectionHeaderImg} source={require('../../images/home/hot.png')}/>
<Text style={styles.sectionHeaderText}>热门推荐</Text>
<View style={styles.sectionHeaderLine}/>
</View>
);
}
}
_renderSeparator(sectionID, rowID, adjacentRowHighlighted) {
return (
<View key={'separator' + sectionID + rowID} style={styles.separator}/>
);
}
render() {
return (
<ListView
dataSource={this.dataSource.cloneWithRowsAndSections(this.props.dataBlob)}
renderRow={this._renderRow}
renderSectionHeader={this._renderSectionHeader}
renderSeparator={this._renderSeparator}
enableEmptySections={true}
/>
);
}
}
let styles = StyleSheet.create({
container: {
flex: 1,
},
sectionHeader: {
flexDirection: 'row',
height: 32,
alignItems: 'center',
backgroundColor: 'white',
},
sectionHeaderImg: {
width: 9,
height: 12,
marginLeft: 17,
},
sectionHeaderText: {
fontSize: 12,
marginLeft: 5,
},
sectionHeaderLine: {
position: 'absolute',
left: 17,
bottom: 0,
width: width,
height: 0.5,
backgroundColor: '#e0e0e0',
},
separator: {
height: 0.5,
backgroundColor: '#e0e0e0',
},
});
... ...
'use strict';
import React from 'react';
import ReactNative from 'react-native';
import ImmutablePropTypes from 'react-immutable-proptypes';
import UserBrief from './UserBrief';
import Thumbs from './Thumbs';
import SectionItem from './SectionItem';
import NumberButton from './NumberButton';
const {
View,
Text,
Image,
TouchableOpacity,
StyleSheet,
Dimensions,
} = ReactNative;
export default class ListCell extends React.Component {
static propTypes = {
data: ImmutablePropTypes.contains({
avatar: React.PropTypes.string.isRequired,
name: React.PropTypes.string.isRequired,
timeago: React.PropTypes.string.isRequired,
isOwner: React.PropTypes.bool,
isTop: React.PropTypes.bool,
isLike: React.PropTypes.bool,
title: React.PropTypes.string,
desc: React.PropTypes.string,
thumbs: ImmutablePropTypes.listOf(
ImmutablePropTypes.contains({
url: React.PropTypes.string,
})
),
section: React.PropTypes.string,
commentCount: React.PropTypes.number,
likeCount: React.PropTypes.number,
}),
onPressPost: React.PropTypes.func,
onPressAvatar: React.PropTypes.func,
onPressSectionTag: React.PropTypes.func,
onPressComment: React.PropTypes.func,
onPressLike: React.PropTypes.func,
};
constructor(props) {
super (props);
}
render() {
let data = this.props.data.toJS();
let {avatar, name, timeago, isOwner, isTop, isLike, title, desc, thumbs, section, commentCount, likeCount} = data;
let likeImage = isLike ? require('../../images/home/like.png') : require('../../images/home/unlike.png')
return (
<TouchableOpacity
style={styles.row}
activeOpacity={0.8}
onPress={() => {
this.props.onPressPost && this.props.onPressPost();
}}
>
<View style={styles.top}>
<UserBrief
avatar={avatar}
name={name}
timeago={timeago}
isOwner={isOwner}
onPressAvatar={() => {
this.props.onPressAvatar && this.props.onPressAvatar();
}}
/>
{isTop ? <Text style={styles.topTag}>置顶</Text> : null}
</View>
<Text style={styles.title} numberOfLines={2}>
{title}
</Text>
<Text style={styles.desc} numberOfLines={2}>
{desc}
</Text>
<Thumbs
style={styles.thumbs}
data={thumbs}
/>
<View style={styles.bottom}>
<SectionItem
name={section}
onPressSection={() => {
this.props.onPressSectionTag && this.props.onPressSectionTag();
}}
/>
<View style={styles.buttonContainer}>
<NumberButton
source={require('../../images/home/mes.png')}
number={commentCount}
onPressButton={() => {
this.props.onPressComment && this.props.onPressComment();
}}
/>
<NumberButton
style={{marginLeft: 20}}
source={likeImage}
number={likeCount}
onPressButton={() => {
this.props.onPressLike && this.props.onPressLike();
}}
/>
</View>
</View>
</TouchableOpacity>
);
}
}
let styles = StyleSheet.create({
row: {
backgroundColor: 'white',
paddingLeft: 17,
paddingRight: 17,
},
top: {
flexDirection: 'row',
height: 60,
},
topTag: {
position: 'absolute',
top: 20,
right: 0,
width: 35,
height: 20,
fontSize: 11,
textAlign: 'center',
color: 'white',
backgroundColor: 'black',
paddingTop: 4.5,
},
title: {
fontSize: 18,
lineHeight: 28,
},
desc: {
fontSize: 14,
lineHeight: 23,
color: '#888888',
},
thumbs: {
marginTop: 15,
marginBottom: 15,
},
bottom: {
flexDirection: 'row',
justifyContent: 'space-between',
marginBottom: 15,
},
buttonContainer: {
flexDirection: 'row',
justifyContent: 'space-between',
},
});
... ...
'use strict';
import React from 'react';
import ReactNative from 'react-native';
import Swiper from 'react-native-swiper';
import ImmutablePropTypes from 'react-immutable-proptypes';
const {
View,
Text,
TouchableOpacity,
StyleSheet,
Dimensions,
} = ReactNative;
export default class Notice extends React.Component {
static propTypes = {
data: ImmutablePropTypes.listOf(
ImmutablePropTypes.contains({
title: React.PropTypes.string.isRequired,
url: React.PropTypes.string.isRequired,
})
),
width: React.PropTypes.number.isRequired,
height: React.PropTypes.number.isRequired,
onPress: React.PropTypes.func,
};
constructor(props) {
super (props);
}
render() {
let width = this.props.width;
let height = this.props.height;
let data = this.props.data.toArray();
return (
<View style={styles.container}>
<Text style={styles.notice}>公告</Text>
<Swiper
style={styles.banner}
horizontal={false}
showsButtons={false}
loop={true}
autoplay={true}
autoplayTimeout={3}
showsPagination={false}
dot={this.dot}
activeDot={this.activeDot}
height={height}
scrollEnabled={false}
>
{data.map((item, i) => {
return (
<TouchableOpacity
key={i}
activeOpacity={1}
onPress={() => {
this.props.onPress && this.props.onPress(item.get('url'));
}}
style={{height: height, justifyContent: 'center', marginRight: 65,}}
>
<Text style={styles.text} numberOfLines={1}>{item.get('title')}</Text>
</TouchableOpacity>
);
})}
</Swiper>
</View>
);
}
}
let styles = StyleSheet.create({
container: {
flexDirection: 'row',
alignItems: 'center',
backgroundColor: 'white',
},
notice: {
marginLeft: 15,
marginRight: 5,
paddingVertical: 5,
paddingHorizontal: 10,
backgroundColor: 'black',
fontSize: 12,
color: 'white',
},
banner: {
},
text: {
fontFamily: 'Helvetica Light',
fontSize: 13,
color: 'black',
},
});
... ...
'use strict';
import React from 'react';
import ReactNative from 'react-native';
const {
View,
Text,
Image,
TouchableOpacity,
StyleSheet,
Dimensions,
} = ReactNative;
export default class NumberButton extends React.Component {
static propTypes = {
source: Image.propTypes.source.isRequired,
number: React.PropTypes.number.isRequired,
onPressButton: React.PropTypes.func,
};
constructor(props) {
super (props);
}
render() {
return (
<TouchableOpacity style={[styles.container, this.props.style]} onPress={() => {
this.props.onPressButton && this.props.onPressButton();
}}>
<Image style={styles.image} source={this.props.source} resizeMode={'contain'}/>
<Text style={styles.number}>{this.props.number}</Text>
</TouchableOpacity>
);
}
}
let styles = StyleSheet.create({
container: {
flexDirection: 'row',
alignItems: 'center',
// alignSelf: 'center',
justifyContent: 'center',
// backgroundColor: '#f2f2f2',
// paddingHorizontal: 10,
},
image: {
width: 18,
height: 18,
},
number: {
fontSize: 14,
marginLeft: 5,
},
});
... ...
'use strict';
import React from 'react';
import ReactNative from 'react-native';
import ImmutablePropTypes from 'react-immutable-proptypes';
const {
View,
Image,
TouchableOpacity,
ListView,
ScrollView,
StyleSheet,
Dimensions,
Animated,
Text,
} = ReactNative;
export default class Section extends React.Component {
static propTypes = {
data: ImmutablePropTypes.listOf(
ImmutablePropTypes.contains({
image: React.PropTypes.string.isRequired,
url: React.PropTypes.string.isRequired,
})
),
width: React.PropTypes.number.isRequired,
height: React.PropTypes.number.isRequired,
onPress: React.PropTypes.func,
};
constructor(props) {
super (props);
this.animatedValue = new Animated.Value(Dimensions.get('window').width / 2);
this._renderRow = this._renderRow.bind(this);
this.state = {
offsetX: 0,
offsetXCenter: 0 + Dimensions.get('window').width / 2,
offsetXCenterAnim: new Animated.Value(Dimensions.get('window').width / 2),
};
}
_renderRow(item, i) {
return (
<TouchableOpacity
style={styles.page}
key={i}
>
<Animated.Image source={{uri: item.get('image')}} style={[styles.image]}/>
</TouchableOpacity>
);
}
render() {
let width = this.props.width;
let height = this.props.height;
let data = this.props.data.toArray();
return (
<View style={styles.container}>
<ScrollView
contentContainerStyle={styles.contentContainer}
horizontal={true}
pagingEnabled={false}
scrollEventThrottle={160}
bounces={false}
onScroll={(event) => {
// console.log(event.nativeEvent);
// this.offsetX = event.nativeEvent.contentOffset.x;
this.setState({
offsetX: event.nativeEvent.contentOffset.x,
offsetXCenter: event.nativeEvent.contentOffset.x + Dimensions.get('window').width / 2,
});
}}
onTouchEnd={(event) => {
// console.log('offsetY:', this.offsetY);
// console.log('touch info:', event.nativeEvent);
}}
>
{data.map((item, i) => {
let pageSize = 190;
let pageCenter = pageSize / 2 + i * pageSize;
let offsetXCenter = this.state.offsetXCenter;
// console.log(offsetXCenter);
// let distance = Math.abs(pageCenter - offsetXCenter);
let distance = offsetXCenter - pageCenter;
i == 1 && console.log(distance);
distance = Math.abs(distance);
distance = distance > 190 ? 190 : distance;
i == 1 && console.log(distance);
// distance = Math.round(distance * 100) / 100;
let m = pageCenter - offsetXCenter;
// m = Math.abs(m);
let a = offsetXCenter + pageCenter;
let scale = this.animatedValue.interpolate({
inputRange: [ -distance, 0, distance],
// inputRange: [-distance*2, -distance, -distance/2, 0, distance/2, distance, distance*2],
outputRange: [1, 0.85, 1],
});
console.log(scale);
return (
<TouchableOpacity
style={styles.page}
key={i}
>
<Animated.Image source={{uri: item.get('image')}} style={[styles.image, {transform: [{ scale }]}]}/>
</TouchableOpacity>
);
})}
</ScrollView>
</View>
);
}
}
let styles = StyleSheet.create({
container: {
// flexDirection: 'row',
// height: 360,
// backgroundColor: 'green'
},
contentContainer: {
flexDirection: 'row',
// width: 220,
backgroundColor: 'gray'
},
page: {
width: 190,
// justifyContent: 'center',
paddingHorizontal: 15,
backgroundColor: 'gray',
},
image: {
width: 160,
height: 150,
marginHorizontal: 15,
},
});
... ...
'use strict';
import React from 'react';
import ReactNative from 'react-native';
const {
View,
Text,
Image,
TouchableOpacity,
StyleSheet,
Dimensions,
} = ReactNative;
export default class SectionItem extends React.Component {
static propTypes = {
name: React.PropTypes.string.isRequired,
onPressSection: React.PropTypes.func,
};
constructor(props) {
super (props);
}
render() {
return (
<TouchableOpacity style={styles.container} onPress={() => {
this.props.onPressSection && this.props.onPressSection();
}}>
<Text style={styles.name}>{this.props.name}</Text>
</TouchableOpacity>
);
}
}
let styles = StyleSheet.create({
container: {
flexDirection: 'row',
// alignItems: 'center',
alignSelf: 'center',
backgroundColor: '#f2f2f2',
},
name: {
fontSize: 14,
margin: 4,
},
});
... ...
'use strict';
import React from 'react';
import ReactNative from 'react-native';
const {
View,
Text,
Image,
TouchableOpacity,
StyleSheet,
Dimensions,
} = ReactNative;
let {width, height} = Dimensions.get('window');
let thumbHeight = Math.ceil((214 / (750 - 34)) * (width - 34));
let marginLeft = Math.ceil(width - 34 - thumbHeight * 3) / 2;
export default class Thumbs extends React.Component {
static propTypes = {
data: React.PropTypes.arrayOf(
React.PropTypes.shape({
url: React.PropTypes.string,
})
),
};
constructor(props) {
super (props);
}
_renderThumbsNumber() {
if (this.props.data.length >= 3) {
return (
<View style={styles.numContainer} >
<View style={[styles.square, styles.square1]}/>
<View style={[styles.square, styles.square2]}/>
<Text style={styles.number}>
{this.props.data.length}
</Text>
</View>
);
} else {
return null;
}
}
render() {
return (
<View style={[styles.container, this.props.style]}>
{this.props.data.slice(0, 3).map((item, i) => {
let margin = i > 0 ? marginLeft: 0;
return <Image key={i} style={[styles.thumb, {marginLeft: margin}]} source={{uri: item.url}}/>
})}
{this._renderThumbsNumber()}
</View>
);
}
}
let styles = StyleSheet.create({
container: {
flexDirection: 'row',
alignItems: 'center',
backgroundColor: 'white',
},
thumb: {
width: thumbHeight,
height: thumbHeight,
},
numContainer: {
backgroundColor: 'black',
opacity: 0.5,
position: 'absolute',
width: 32,
height: 17,
right: 5,
bottom: 5,
flexDirection: 'row',
justifyContent: 'center',
alignItems: 'center',
},
square: {
borderWidth: 0.5,
borderColor: 'white',
width: 10,
height: 8,
},
square1: {
top: -0.5,
},
square2: {
position: 'absolute',
top: 5.5,
left: 6,
},
number: {
color: 'white',
fontFamily: 'Helvetica Light',
fontSize: 12,
marginLeft: 6,
backgroundColor: 'transparent',
},
});
... ...
'use strict';
import React from 'react';
import ReactNative from 'react-native';
import ImmutablePropTypes from 'react-immutable-proptypes';
const {
View,
Text,
Image,
TouchableOpacity,
StyleSheet,
Dimensions,
} = ReactNative;
export default class UserBrief extends React.Component {
static propTypes = {
avatar: React.PropTypes.string.isRequired,
name: React.PropTypes.string.isRequired,
timeago: React.PropTypes.string.isRequired,
isOwner: React.PropTypes.bool,
onPressAvatar: React.PropTypes.func,
};
constructor(props) {
super (props);
}
_renderUserName() {
if (this.props.isOwner) {
return (
<Text style={styles.name} numberOfLines={1}>
{this.props.name + ' | '}
<Text style={styles.owner}>楼主</Text>
</Text>
);
} else {
return (
<Text style={styles.name} numberOfLines={1}>
{this.props.name}
</Text>
);
}
}
render() {
return (
<View style={styles.container}>
<TouchableOpacity onPress={() => {
this.props.onPressAvatar && this.props.onPressAvatar();
}}>
<Image style={styles.avatar} source={{uri: this.props.avatar}} resizeMode={'cover'}/>
</TouchableOpacity>
<View style={styles.text}>
{this._renderUserName()}
<Text style={styles.timeago}>{this.props.timeago}</Text>
</View>
</View>
);
}
}
let styles = StyleSheet.create({
container: {
flexDirection: 'row',
alignItems: 'center',
backgroundColor: 'white',
},
avatar: {
width: 30,
height: 30,
borderRadius: 15,
},
text: {
marginLeft: 5,
},
name: {
fontFamily: 'Helvetica Light',
color: 'black',
fontSize: 13,
width: 130,
},
owner: {
color: '#4a90e2',
},
timeago: {
fontFamily: 'Helvetica Light',
color: '#b0b0b0',
fontSize: 10,
},
});
... ...
... ... @@ -6,20 +6,21 @@ import ReactNative from 'react-native';
import {bindActionCreators} from 'redux';
import {connect} from 'react-redux';
import {Map} from 'immutable';
import Immutable, {Map} from 'immutable';
import Home from '../components/Home';
import Home from '../components/home/Home';
import * as homeActions from '../reducers/home/homeActions';
import {Actions} from 'react-native-router-flux';
const {
StatusBar,
ScrollView,
View,
StyleSheet,
Dimensions,
Platform,
NativeModules
} = ReactNative;
/**
... ... @@ -61,14 +62,202 @@ class HomeContainer extends React.Component {
constructor(props) {
super(props);
this._onPressBanner = this._onPressBanner.bind(this);
this._onPressNotice = this._onPressNotice.bind(this);
this._onPressSection = this._onPressSection.bind(this);
this._onPressPost = this._onPressPost.bind(this);
this._onPressAvatar = this._onPressAvatar.bind(this);
this._onPressSectionTag = this._onPressSectionTag.bind(this);
this._onPressComment = this._onPressComment.bind(this);
this._onPressLike = this._onPressLike.bind(this);
}
componentDidMount() {
let RNNativeConfig = NativeModules.RNNativeConfig;
RNNativeConfig.hideNavBar();
}
_onPressBanner(url) {
console.log('banner');
}
_onPressNotice(url) {
console.log('notice');
}
_onPressSection(url) {
console.log('section');
}
_onPressPost(url) {
console.log('post');
}
_onPressAvatar(url) {
console.log('avatar');
}
_onPressSectionTag(url) {
console.log('section tag');
}
_onPressComment(url) {
console.log('comment');
}
_onPressLike(url) {
console.log('like');
}
render() {
let banner = {
banner: [
{
image: 'https://img10.static.yhbimg.com/yhb-img01/2016/06/28/17/0180ef2077db7ec5117756e47c0b61a7b1.jpg?imageView2/2/w/640/h/240',
url: 'https://www.baidu.com'
},
{
image: 'https://img11.static.yhbimg.com/yhb-img01/2016/06/28/11/01f429fffdff555ed0c141a5ec2b4fd421.jpg?imageView2/2/w/640/h/240',
url: 'https://www.baidu.com'
},
{
image: 'https://img10.static.yhbimg.com/yhb-img01/2016/06/28/12/01dcc29b14bdd04d9051c2e5ce40fe6516.jpg?imageView2/2/w/640/h/240',
url: 'https://www.baidu.com'
},
{
image: 'https://img10.static.yhbimg.com/yhb-img01/2016/06/28/17/0180ef2077db7ec5117756e47c0b61a7b1.jpg?imageView2/2/w/640/h/240',
url: 'https://www.baidu.com'
},
{
image: 'https://img11.static.yhbimg.com/yhb-img01/2016/06/28/11/01f429fffdff555ed0c141a5ec2b4fd421.jpg?imageView2/2/w/640/h/240',
url: 'https://www.baidu.com'
},
{
image: 'https://img10.static.yhbimg.com/yhb-img01/2016/06/28/12/01dcc29b14bdd04d9051c2e5ce40fe6516.jpg?imageView2/2/w/640/h/240',
url: 'https://www.baidu.com'
},
],
};
let notice = {
notice: [
{
title: 'Yoho!Buy特邀摄影师大赛开始报名啦!大赛开始报名啦!',
url: 'https://www.baidu.com'
},
{
title: 'Yoho!Buy特邀摄影师大赛开始报名啦!22222大赛开始报名啦!',
url: 'https://www.baidu.com'
},
{
title: 'Yoho!Buy特邀摄影师大赛开始报名啦!33333大赛开始报名啦!',
url: 'https://www.baidu.com'
},
],
};
let section = {
section: [
{
image: 'https://img10.static.yhbimg.com/yhb-img01/2016/06/28/17/0180ef2077db7ec5117756e47c0b61a7b1.jpg?imageView2/2/w/640/h/240',
url: 'https://www.baidu.com'
},
{
image: 'https://img11.static.yhbimg.com/yhb-img01/2016/06/28/11/01f429fffdff555ed0c141a5ec2b4fd421.jpg?imageView2/2/w/640/h/240',
url: 'https://www.baidu.com'
},
{
image: 'https://img10.static.yhbimg.com/yhb-img01/2016/06/28/12/01dcc29b14bdd04d9051c2e5ce40fe6516.jpg?imageView2/2/w/640/h/240',
url: 'https://www.baidu.com'
},
],
};
let recommendation = [
{
avatar: 'https://img11.static.yhbimg.com/yhb-img01/2016/06/28/11/01f429fffdff555ed0c141a5ec2b4fd421.jpg?imageView2/2/w/640/h/240',
name: '余文乐',
timeago: '2小时前',
isOwner: false,
isTop: true,
isLike: true,
title: 'Yoho!Buy特邀摄影师大赛开始报名啦!',
desc: 'MADNESS作为“六叔”余文乐的个人品牌,经过几个季度的产品表现,相信大家都知道这并不是玩票性质,而是余文乐在做心中的街头品牌。此番MADNESS正式迎来2016春夏的开季,以Los Angeles作为拍摄地点,延续余文乐一直喜欢的简约风格',
thumbs: [
{
url: 'https://img11.static.yhbimg.com/yhb-img01/2016/06/28/11/01f429fffdff555ed0c141a5ec2b4fd421.jpg?imageView2/2/w/640/h/240',
},
{
url: 'https://img11.static.yhbimg.com/yhb-img01/2016/06/28/11/01f429fffdff555ed0c141a5ec2b4fd421.jpg?imageView2/2/w/640/h/240',
},
{
url: 'https://img11.static.yhbimg.com/yhb-img01/2016/06/28/11/01f429fffdff555ed0c141a5ec2b4fd421.jpg?imageView2/2/w/640/h/240',
}
],
section: '永恒的潮流',
commentCount: 123,
likeCount: 45678,
url: 'https://www.baidu.com'
},
{
avatar: 'https://img11.static.yhbimg.com/yhb-img01/2016/06/28/11/01f429fffdff555ed0c141a5ec2b4fd421.jpg?imageView2/2/w/640/h/240',
name: '余文乐',
timeago: '2小时前',
isOwner: true,
isTop: false,
isLike: false,
title: 'Yoho!Buy特邀摄影师大赛开始报名啦!',
desc: 'MADNESS作为“六叔”余文乐的个人品牌,经过几个季度的产品表现,相信大家都知道这并不是玩票性质,而是余文乐在做心中的街头品牌。此番MADNESS正式迎来2016春夏的开季,以Los Angeles作为拍摄地点,延续余文乐一直喜欢的简约风格',
thumbs: [
{
url: 'https://img11.static.yhbimg.com/yhb-img01/2016/06/28/11/01f429fffdff555ed0c141a5ec2b4fd421.jpg?imageView2/2/w/640/h/240',
},
{
url: 'https://img11.static.yhbimg.com/yhb-img01/2016/06/28/11/01f429fffdff555ed0c141a5ec2b4fd421.jpg?imageView2/2/w/640/h/240',
},
{
url: 'https://img11.static.yhbimg.com/yhb-img01/2016/06/28/11/01f429fffdff555ed0c141a5ec2b4fd421.jpg?imageView2/2/w/640/h/240',
}
],
section: '永恒的潮流',
commentCount: 123,
likeCount: 45678,
url: 'https://www.baidu.com'
},
{
avatar: 'https://img11.static.yhbimg.com/yhb-img01/2016/06/28/11/01f429fffdff555ed0c141a5ec2b4fd421.jpg?imageView2/2/w/640/h/240',
name: '余文乐',
timeago: '2小时前',
isOwner: false,
isTop: false,
isLike: true,
title: 'Yoho!Buy特邀摄影师大赛开始报名啦!',
desc: 'MADNESS作为“六叔”余文乐的个人品牌,经过几个季度的产品表现,相信大家都知道这并不是玩票性质,而是余文乐在做心中的街头品牌。此番MADNESS正式迎来2016春夏的开季,以Los Angeles作为拍摄地点,延续余文乐一直喜欢的简约风格',
thumbs: [
{
url: 'https://img11.static.yhbimg.com/yhb-img01/2016/06/28/11/01f429fffdff555ed0c141a5ec2b4fd421.jpg?imageView2/2/w/640/h/240',
},
{
url: 'https://img11.static.yhbimg.com/yhb-img01/2016/06/28/11/01f429fffdff555ed0c141a5ec2b4fd421.jpg?imageView2/2/w/640/h/240',
},
{
url: 'https://img11.static.yhbimg.com/yhb-img01/2016/06/28/11/01f429fffdff555ed0c141a5ec2b4fd421.jpg?imageView2/2/w/640/h/240',
}
],
section: '永恒的潮流',
commentCount: 123,
likeCount: 45678,
url: 'https://www.baidu.com'
},
];
let dataBlob = {
banner: Immutable.fromJS(banner).toObject(),
notice: Immutable.fromJS(notice).toObject(),
section: Immutable.fromJS(section).toObject(),
recommendation: Immutable.fromJS(recommendation).toArray(),
};
return (
<View style={styles.container}>
... ... @@ -76,7 +265,17 @@ class HomeContainer extends React.Component {
hidden={false}
barStyle={'light-content'}
/>
<Home/>
<Home
dataBlob={dataBlob}
onPressBanner={this._onPressBanner}
onPressNotice={this._onPressNotice}
onPressSection={this._onPressSection}
onPressPost={this._onPressPost}
onPressAvatar={this._onPressAvatar}
onPressSectionTag={this._onPressSectionTag}
onPressComment={this._onPressComment}
onPressLike={this._onPressLike}
/>
</View>
);
}
... ... @@ -89,6 +288,7 @@ let styles = StyleSheet.create({
container: {
top: navbarHeight,
height: height - navbarHeight - 49,
flex: 1,
},
});
... ...
... ... @@ -7,7 +7,7 @@
/**
* ## Import immutable record
*/
import {Record} from 'immutable';
import {Record, List, Map} from 'immutable';
/**
* ## InitialState
... ... @@ -17,16 +17,10 @@ import {Record} from 'immutable';
let InitialState = Record({
isFetching: false,
error: null,
shopId: 0,
shopName: '',
overview: new (Record({
rank: 0, //店铺排名
rankHasTrend: false, //店铺排名是否有环比数据
rise: true, //店铺排名是否上升
riseCount: 0, //店铺排名变动数量
goodsCount: 0, //今日有效订单商品件数
goodsAmount: 0, //今日有效订单商品金额
})),
banner: Map(),
notice: List(),
section: List(),
recommendation: List(),
});
export default InitialState;
... ...
... ... @@ -18,8 +18,10 @@
"react-native": "^0.28.0",
"react-native-device-info": "^0.9.3",
"react-native-fabric": "^0.2.2",
"react-native-pan-controller": "0.0.1",
"react-native-router-flux": "^3.30.2",
"react-native-simple-store": "^1.0.1",
"react-native-swiper": "^1.4.5",
"react-redux": "^4.4.5",
"redux": "^3.5.2",
"redux-logger": "^2.6.1",
... ...