Authored by 于良

关注和品牌优化 review by 孙凯

... ... @@ -20,7 +20,7 @@ export default class AllBrandListCell extends React.Component {
shouldComponentUpdate(nextProps){
if (Immutable.is(Immutable.fromJS(nextProps.rowData), Immutable.fromJS(this.props.rowData))) {
if (Immutable.is(nextProps.rowData, this.props.rowData)) {
return false;
} else {
return true;
... ... @@ -28,21 +28,21 @@ export default class AllBrandListCell extends React.Component {
}
render() {
let name = this.props.rowData.brand_name;
let is_hot = this.props.rowData.is_hot;
let is_show_new = this.props.rowData.is_show_new;
let shop_id = this.props.rowData.shop_id;
let shop_template_type = this.props.rowData.shop_template_type;
return(
let data = this.props.rowData;
let name = data.get('brand_name');
let is_hot = data.get('is_hot');
let is_show_new = data.get('is_show_new');
let shop_id = data.get('shop_id');
let shop_template_type = data.get('shop_template_type');
let url = `http://m.yohobuy.com?openby:yohobuy={"action":"go.shop","params":{"shop_id":"${shop_id}","shop_template_type":"${shop_template_type}","name":"${name}"}}`;
return (
<TouchableOpacity activeOpacity={0.5} onPress={() => {
this.props.onPressSlideItem && this.props.onPressSlideItem(this.props.rowData);
this.props.onPressSlideItem && this.props.onPressSlideItem(this.props.rowData.toJS());
}}>
<View style={styles.rowTitle}>
<Text style={styles.rowText}>{name}</Text>
{is_show_new=='Y'?<View style={styles.new}><Text style={styles.text}>NEW</Text></View>:null}
{is_hot=='Y'?<View style={styles.hot}><Text style={styles.text}>HOT</Text></View>:null}
{is_show_new=='Y' ? <View style={styles.new}><Text style={styles.text}>NEW</Text></View> : null}
{is_hot=='Y' ? <View style={styles.hot}><Text style={styles.text}>HOT</Text></View> : null}
</View>
</TouchableOpacity>
);
... ...
... ... @@ -39,14 +39,7 @@ export default class Brand extends Component {
this.listView = null;
this.sectionData = Map();
this.sectionDataKey = Map();
}
componentDidMount() {
}
componentWillUnmount() {
this.needScrollSection = 0;
}
componentWillReceiveProps(nextProps) {
... ... @@ -54,11 +47,12 @@ export default class Brand extends Component {
this.listView.scrollTo({x: 0, y: 0, animated: false});
}
}
scrollToSection(index,sectionID){
let item = this.sectionDataKey[sectionID];
if (item) {
if (!item.y) {
needScrollSection = sectionID;
this.needScrollSection = sectionID;
item.count = ScrollCount(sectionID,this.sectionData);
this.props.setInitialListSize && this.props.setInitialListSize(item.count);
this.props.setBrandData && this.props.setBrandData(this.sectionDataKey,this.props.brandChannelFliter);
... ... @@ -73,13 +67,13 @@ export default class Brand extends Component {
if (this.sectionDataKey && this.sectionDataKey[sectionID].y != y) {
this.sectionDataKey[sectionID].y = y;
this.props.setBrandData && this.props.setBrandData(this.sectionDataKey,this.props.brandChannelFliter);
if (needScrollSection == sectionID) {
if (this.needScrollSection == sectionID) {
this.listView.scrollTo({x: 0, y, animated: false});
}
}
}
renderHeader(){
renderHeader() {
return (
<View style={styles.header}>
<TouchableOpacity
... ... @@ -106,16 +100,12 @@ export default class Brand extends Component {
onPressFilter= {this.props.onPressFilter}
brandFliter={this.props.brandFliter}
/>
</View>
);
}
renderSectionHeader(sectionData, sectionID) {
let title = sectionID;
if (sectionID == '0-9') {
title = '0';
}
let title = sectionID == '0-9' ? '0' : sectionID;
return (
<View style={styles.sessionTitle} onLayout={this.onLayout.bind(this, sectionID)}>
<Text style={styles.sessionText}>{title}</Text>
... ... @@ -128,7 +118,7 @@ export default class Brand extends Component {
return (
<AllBrandListCell rowData={rowData} onPressSlideItem={this.props.onPressSlideItem}/>
);
}else {
} else {
return (
<NewHotBannerListCell rowData={rowData} onPressSlideItem={this.props.onPressSlideItem}/>
);
... ... @@ -157,45 +147,49 @@ export default class Brand extends Component {
let data;
if (brandChannelFliter == 1) {
data = brandListForBoy?brandListForBoy.toJS():null;
data = brandListForBoy;
} else if (brandChannelFliter == 2) {
data = brandListForGirl?brandListForGirl.toJS():null;
data = brandListForGirl;
} else if (brandChannelFliter == 3) {
data = brandListForKid?brandListForKid.toJS():null;
data = brandListForKid;
} else if (brandChannelFliter == 4) {
data = brandListForLifeStyle?brandListForLifeStyle.toJS():null;
data = brandListForLifeStyle;
}
let list;
let keys;
let listDataSource;
let contentContainerStyle;
let renderSectionHeader = null;
let showIndexForListView = false;
if (brandFliter == 0) {
list = data?data.all_list:null;
keys = data?data.all_list_key:null;
listDataSource = list?this.dataSource.cloneWithRowsAndSections(list):null;
list = data ? data.get('all_list') : null;
let newList = {};
list && list.map((value, key) => {
newList[key] = value.toArray();
});
listDataSource = newList ? this.dataSource.cloneWithRowsAndSections(newList) : null;
contentContainerStyle = styles.contentContainerOne;
renderSectionHeader = this.renderSectionHeader;
showIndexForListView = true;
this.sectionData = list;
this.sectionDataKey = keys;
this.sectionData = newList;
this.sectionDataKey = data.get('all_list_key').toJS();
} else if (brandFliter == 1) {
list = data?data.new_list:null;
listDataSource = list?this.dataSource.cloneWithRows(list):null;
list = data ? data.get('new_list') : null;
listDataSource = list ? this.dataSource.cloneWithRows(list.toArray()) : null;
contentContainerStyle = styles.contentContainerTwo;
} else if (brandFliter == 2) {
list = data?data.hot_list:null;
listDataSource = list?this.dataSource.cloneWithRows(list):null;
list = data ? data.get('hot_list') : null;
listDataSource = list ? this.dataSource.cloneWithRows(list.toArray()) : null;
contentContainerStyle = styles.contentContainerTwo;
}
if (!list) {
return null;
}
return (
<View style={styles.container}>
<ChannelFliter selectID={brandChannelFliter} onChannelPressFliter={this.props.onChannelPressFliter}/>
... ... @@ -212,7 +206,7 @@ export default class Brand extends Component {
renderHeader={this.renderHeader}
/>
{showIndexForListView?<IndexListView dataSource={Object.keys(list)} onLetterPress={this.scrollToSection}/>: null}
{showIndexForListView ? <IndexListView dataSource={list.keySeq().toArray()} onLetterPress={this.scrollToSection}/> : null}
<LoadingIndicator
isVisible={isFetching}
... ... @@ -230,14 +224,13 @@ export default class Brand extends Component {
}
let {width, height} = Dimensions.get('window');
let needScrollSection = null;
let styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: 'white',
},
contentContainerOne:{
contentContainerOne: {
},
contentContainerTwo: {
... ... @@ -261,6 +254,4 @@ let styles = StyleSheet.create({
width,
backgroundColor: '#e5e5e5',
},
search: {
},
});
... ...
... ... @@ -21,6 +21,14 @@ export default class IndexListView extends React.Component {
this.onTouchMove = this.onTouchMove.bind(this);
}
shouldComponentUpdate(nextProps){
if (Immutable.is(Immutable.fromJS(nextProps.dataSource), Immutable.fromJS(this.props.dataSource))) {
return false;
} else {
return true;
}
}
onTouchMove(e) {
let {dataSource} = this.props;
let Y = e.nativeEvent.pageY - Math.ceil((viewHeight - dataSource.length * (itemHeight+2))/2) - 8;
... ... @@ -30,11 +38,12 @@ export default class IndexListView extends React.Component {
}
render() {
let {dataSource} = this.props;
if (dataSource.length == 0) {
return null;
}
let keyData = [];
keyData.push(<Image key={'search'} style={styles.image} source={require('../../images/search.png')}/>);
... ...
... ... @@ -3,6 +3,7 @@
import React from 'react';
import ReactNative from 'react-native';
import {getSlicedUrl} from '../../utils/Utils';
import Immutable, {Map} from 'immutable';
const {
StyleSheet,
... ... @@ -19,16 +20,25 @@ export default class NewHotBannerListCell extends React.Component {
super(props);
}
shouldComponentUpdate(nextProps){
if (Immutable.is(nextProps.rowData, this.props.rowData)) {
return false;
} else {
return true;
}
}
render() {
let rowData = this.props.rowData;
let newSrc = getSlicedUrl(rowData.brand_ico, width, height, 2);
let name = rowData.brand_name;
let shop_id = rowData.shop_id;
let shop_template_type = rowData.shop_template_type;
let newSrc = getSlicedUrl(rowData.get('brand_ico'), width, height, 2);
let name = rowData.get('brand_name');
let shop_id = rowData.get('shop_id');
let shop_template_type = rowData.get('shop_template_type');
return (
<TouchableOpacity activeOpacity={0.5} onPress={() => {
this.props.onPressSlideItem && this.props.onPressSlideItem(rowData);
this.props.onPressSlideItem && this.props.onPressSlideItem(rowData.toJS());
}}>
<View style={styles.rowContainer}>
<Image
... ... @@ -38,7 +48,7 @@ export default class NewHotBannerListCell extends React.Component {
>
</Image>
<View style={styles.itemTitle}>
<Text style={styles.itemText} numberOfLines={1}>{rowData.brand_name}</Text>
<Text style={styles.itemText} numberOfLines={1}>{rowData.get('brand_name')}</Text>
</View>
</View>
</TouchableOpacity>
... ...
... ... @@ -69,7 +69,7 @@ export default class Brand extends Component {
filtedBrands.map((value, key) => {
data[key] = value.toArray();
});
console.log(data)
return (
<View style={styles.container}>
<ListView
... ...
... ... @@ -25,6 +25,9 @@ export default class Interest extends Component {
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),
... ... @@ -32,13 +35,7 @@ export default class Interest extends Component {
}
componentDidMount() {
if (Platform.OS === 'ios') {
InteractionManager.runAfterInteractions(() => {
this.listView && this.listView.getScrollResponder().startPullToRefresh();
});
}else{
this.props.onRefresh && this.props.onRefresh();
}
this.trigggePullToRefresh();
}
componentWillReceiveProps(nextProps) {
... ... @@ -47,6 +44,16 @@ export default class Interest extends Component {
}
}
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) {
let type = rowData.get('brand_type', '');
... ... @@ -73,6 +80,32 @@ export default class Interest extends Component {
);
}
_onEndReached() {
let {list} = this.props.data;
if (list.size != 0) {
this.props.onEndReached && this.props.onEndReached();
}
}
_renderFooter() {
let {list, ptr, isFetching, endReached} = this.props.data;
let isPullToRefresh = ptr && isFetching;
let isLoadingMore = list.size != 0 && !ptr && isFetching;
if (endReached) {
return <LoadMoreIndicator
isVisible={true}
text={'暂无更多'}
/>;
} else {
return <LoadMoreIndicator
isVisible={isLoadingMore}
animating={isFetching}
/>;
}
}
render() {
let {list, ptr, isFetching, endReached, showLoginTip, cachedList} = this.props.data;
... ... @@ -85,7 +118,7 @@ export default class Interest extends Component {
<View style={styles.container}>
{showLoginTip ? <LoginTip onInterestLogin={this.props.onInterestLogin} /> : null}
{
Platform.OS === 'ios'?<ListView
Platform.OS === 'ios' ? <ListView
ref={(c) => {
this.listView = c;
}}
... ... @@ -98,60 +131,28 @@ export default class Interest extends Component {
onRefreshData={() => {
this.props.onRefresh && this.props.onRefresh();
}}
onEndReached={() => {
if (list.size != 0) {
this.props.onEndReached && this.props.onEndReached();
}
}}
renderFooter={() => {
if (endReached) {
return <LoadMoreIndicator
isVisible={true}
text={'暂无更多'}
/>
} else {
return <LoadMoreIndicator
isVisible={isLoadingMore}
animating={isFetching}
/>
}
}}
/>:<ListView
onEndReached={this._onEndReached}
renderFooter={this._renderFooter}
/> : <ListView
ref={(c) => {
this.listView = c;
}}
refreshControl={
<RefreshControl
refreshing={false}
onRefresh={() => {
this.props.onRefresh && this.props.onRefresh();
}}
colors={['#000000', '#ff0000']}
progressBackgroundColor="#ffffff"
/>
<RefreshControl
refreshing={false}
onRefresh={() => {
this.props.onRefresh && this.props.onRefresh();
}}
colors={['#000000', '#ff0000']}
progressBackgroundColor="#ffffff"
/>
}
contentContainerStyle={styles.contentContainer}
dataSource={this.dataSource.cloneWithRows(dataSource)}
renderRow={this._renderRow}
enableEmptySections={true}
onEndReached={() => {
if (list.size != 0) {
this.props.onEndReached && this.props.onEndReached();
}
}}
renderFooter={() => {
if (endReached) {
return <LoadMoreIndicator
isVisible={true}
text={'暂无更多'}
/>
} else {
return <LoadMoreIndicator
isVisible={isLoadingMore}
animating={isFetching}
/>
}
}}
onEndReached={this._onEndReached}
renderFooter={this._renderFooter}
/>
}
... ...
... ... @@ -58,16 +58,14 @@ class InterestContainer extends Component {
this.subscription = NativeAppEventEmitter.addListener(
'ChannelDidChangeEvent',
(reminder) => {
this.props.actions.resetListPageInfo();
this.props.actions.interestList(true);
this.interest && this.interest.trigggePullToRefresh();
}
);
this.subscription2 = NativeAppEventEmitter.addListener(
'UserDidLoginEvent',
(reminder) => {
this.props.actions.resetListPageInfo();
this.props.actions.interestList(true);
this.interest && this.interest.trigggePullToRefresh();
this.props.actions.showLoginTip(false);
}
);
... ... @@ -75,8 +73,7 @@ class InterestContainer extends Component {
this.subscription3 = NativeAppEventEmitter.addListener(
'UserDidLogoutEvent',
(reminder) => {
this.props.actions.resetListPageInfo();
this.props.actions.interestList(true);
this.interest && this.interest.trigggePullToRefresh();
this.props.actions.showLoginTip(true);
}
);
... ... @@ -84,6 +81,7 @@ class InterestContainer extends Component {
componentDidMount() {
this.props.actions.loadCachedInterestList();
this.props.actions.shouldShowLoginTip();
}
componentWillUnmount() {
... ... @@ -158,6 +156,9 @@ class InterestContainer extends Component {
return (
<View style={styles.container}>
<Interest
ref={(c) => {
this.interest = c;
}}
data={interest}
onInterestLike={this._onInterestLike}
onRefresh={this._onInterestRefresh}
... ...
... ... @@ -57,6 +57,23 @@ export function loadCachedInterestList() {
};
}
export function shouldShowLoginTip() {
return (dispatch, getState) => {
let {app, interest} = getState();
if (interest.cachedList.size > 0) {
return;
}
ReactNative.NativeModules.YH_CommonHelper.uid()
.then(data => {
dispatch(showLoginTip(false));
})
.catch(error => {
dispatch(showLoginTip(true));
});
};
}
export function resetListPageInfo() {
return {
type: RESET_LIST_PAGE_INFO,
... ... @@ -100,7 +117,9 @@ export function interestList(reload=false) {
if (reload) {
// 强制刷新数据
if (interest.ptr && interest.isFetching) {
return;
}
} else {
if (interest.isFetching || interest.endReached || interest.error) {
return;
... ...