Authored by 张丽霞

红人店铺改版为sectionList,review by Redding

'use strict'
import React, {Component} from 'react';
import {
StyleSheet,
Dimensions,
Platform,
View,
Text,
Image,
SectionList,
TouchableOpacity,
} from 'react-native';
import Immutable,{Map,Record} from 'immutable';
import Header from './Header';
import RedBrandStoreFilter from './RedBrandStoreFilter';
import Title from './Title';
import Video from './Video';
import SingleImage from './SingleImage';
import DoubleImage from './DoubleImage';
import TripleImage from './TripleImage';
import RedBrandSwiper from './RedBrandSwiper';
import ProductCategoryList from './ProductCategoryList';
import LoadingIndicator from '../../../common/components/LoadingIndicator';
import LoadMoreIndicator from '../../../common/components/LoadMoreIndicator';
import RedBrandTwoProductCell from './RedBrandTwoProductCell';
import BrandProductFilter from './BrandProductFilter';
import CouponCell from '../../../brandStore/components/brandStore/brandStoreSubView/Cells/CouponCell';
import Prompt from '../../../coupon/components/coupon/Prompt';
import FourImages from './FourImages';
import GoodsGroupList from './GoodsGroupList';
const VIEWABILITY_CONFIG = {
minimumViewTime: 3000,
viewAreaCoveragePercentThreshold: 100,
waitForInteraction: true,
};
export default class RedBrand extends Component {
constructor(props) {
super(props);
this.renderSectionHeader = this.renderSectionHeader.bind(this);
this.renderItem = this.renderItem.bind(this);
this._onPressProductFilter = this._onPressProductFilter.bind(this);
this._onPressFilter = this._onPressFilter.bind(this);
this._onPressLaunchProfile = this._onPressLaunchProfile.bind(this);
this.getItemLayout = this.getItemLayout.bind(this);
this._calculateSectionRealHeight = this._calculateSectionRealHeight.bind(this);
this.containerHeight = 0;
this.sectionData = [];
}
_onPressLaunchProfile(value){
this.refs.redBrandList && this.refs.redBrandList.scrollToLocation({itemIndex: 0,sectionIndex: 0, viewPosition: 0, animated: false});
this.props.onPressLaunchProfile && this.props.onPressLaunchProfile(value);
}
_onPressProductFilter(value){
let {fliter} = this.props;
let sectionIndex = 1;
if (fliter != 0) {
let height = Math.ceil((234/750)*width) + 84; //header
this.refs.redBrandList && this.refs.redBrandList.scrollToLocation({itemIndex: 0,sectionIndex: 1, viewPosition: height, animated: false});
} else {
let filterIndex = 0;
this.sectionData.map((item, index) => {
if (item.key == 'ShopBanner') {
filterIndex++;
}else if(item.key == 'brandReource') {
let sectionDataSource = item.data;
if (sectionDataSource.length != 0) {
sectionDataSource.map((shopsdecoratorItem, index) => {
if (shopsdecoratorItem.get('module_type') == 'coupon') {
if (shopsdecoratorItem.list > 0) {
filterIndex++;
}
}else if (shopsdecoratorItem.get('module_type') == 'CarouselImage') {
filterIndex++;
}else if (shopsdecoratorItem.get('module_type') == 'Title') {
filterIndex++;
}else if (shopsdecoratorItem.get('module_type') == 'SingleImage') {
filterIndex++;
}else if (shopsdecoratorItem.get('module_type') == 'DoubleImage') {
filterIndex++;
}else if (shopsdecoratorItem.get('module_type') == 'Video') {
filterIndex++;
}else if (shopsdecoratorItem.get('module_type') == 'TripleImage') {
filterIndex++;
}else if (shopsdecoratorItem.get('module_type') == 'FourImage') {
filterIndex++;
}else if (shopsdecoratorItem.get('module_type') == 'AppRecommendProduct') {
filterIndex++;
}
});
}
}
});
this.refs.redBrandList && this.refs.redBrandList.scrollToIndex({animated: false,index: filterIndex, viewPosition: 0});
}
this.props.onPressProductFilter && this.props.onPressProductFilter(value);
}
_onPressFilter(value){
let height = Math.ceil((234/750)*width) + 44; //header
this.refs.redBrandList && this.refs.redBrandList.scrollToLocation({itemIndex: 0,sectionIndex: 1, viewPosition: height, animated: false});
this.props.onPressProductFilter && this.props.onPressStoreFilter(value);
}
_calculateSectionRealHeight(dataSource, layoutIndex) {
let {
productList,
launchProfile,
productListForNew,
shopsdecorator,
} = this.props;
let result ={
length: 0,
offset: 0,
}
let realContainerHeight = 0;
let countNumb = 0;
dataSource.map((item, index) => {
if (item.key == 'ShopBanner') {
if (!shopsdecorator || shopsdecorator.template_type != '1') {
result.length = Math.ceil((234/750)*width); //header
if (countNumb == layoutIndex) {
return result;
}
realContainerHeight += Math.ceil((234/750)*width); //header
}
}else if(item.key == 'brandReource') {
realContainerHeight += 44; //height of RedBrandStoreFilter
countNumb++;
let sectionDataSource = item.data;
if (sectionDataSource.length == 0) {
result.offset = realContainerHeight;
result.length = 0;
return result;
}
sectionDataSource.map((shopsdecoratorItem, index) => {
result.offset = realContainerHeight;
if (shopsdecoratorItem.get('module_type') == 'coupon') {
if (shopsdecoratorItem.list > 0) {
countNumb++;
result.length = 90;
realContainerHeight += 90; //height for coupon
}
}else if (shopsdecoratorItem.get('module_type') == 'CarouselImage') {
let swiperHeight = Math.ceil((234 / 750) * width);
let properties = shopsdecoratorItem.get('module_data').get('properties').toJS();
let isModuleMargin = properties.isModuleMargin;
let backgroundHeight =isModuleMargin=='1'?(swiperHeight+10):swiperHeight;
countNumb++;
result.length = backgroundHeight;
realContainerHeight += backgroundHeight; //height for RedBrandSwiper
}else if (shopsdecoratorItem.get('module_type') == 'Title') {
let properties = shopsdecoratorItem.get('module_data').get('properties').toJS();
let isModuleMargin = properties.isModuleMargin;
let heightDiff = isModuleMargin=='1'?40+10:40;
countNumb++;
result.length = heightDiff;
realContainerHeight += heightDiff; //height for title
}else if (shopsdecoratorItem.get('module_type') == 'SingleImage') {
let properties = shopsdecoratorItem.get('module_data').get('properties').toJS();
let imageW = properties.width;
let imageH = properties.height;
imageW = imageW ? imageW : width;
imageH = imageH ? imageH : 400
let isModuleMargin = properties.isModuleMargin;
let imageHeight = (imageH*width)/(imageW==0?1:imageW);//根据返回信息计算出高度
let backgroundHeight =isModuleMargin=='1'?(imageHeight+10):imageHeight;
countNumb++;
result.length = backgroundHeight;
realContainerHeight += backgroundHeight;
}else if (shopsdecoratorItem.get('module_type') == 'DoubleImage') {
let properties = shopsdecoratorItem.get('module_data').get('properties').toJS();
let isModuleMargin = properties.isModuleMargin;
let backgroundHeight =isModuleMargin=='1'?(width/2+10):width/2;
countNumb++;
result.length = backgroundHeight;
realContainerHeight += backgroundHeight;
}else if (shopsdecoratorItem.get('module_type') == 'Video') {
let properties = shopsdecoratorItem.get('module_data').get('properties').toJS();
let isModuleMargin = properties.isModuleMargin;
let backgroundHeight = Math.ceil(((363+190)/750)*width);
let heigthW = isModuleMargin=='1'?backgroundHeight+10:backgroundHeight;
countNumb++;
result.length = backgroundHeight;
realContainerHeight += backgroundHeight;
}else if (shopsdecoratorItem.get('module_type') == 'TripleImage') {
let properties = shopsdecoratorItem.get('module_data').get('properties').toJS();
let isModuleMargin = properties.isModuleMargin;
let displayType = properties.displayType;
let nullHeigth = 10;
let heightDiff = 0;
switch (displayType) {
case '1':{
let containerHeigth = Math.ceil((333/750)*width);
heightDiff = isModuleMargin=='1'?containerHeigth+nullHeigth:containerHeigth;
}
break;
case '2':{
let containerHeigth = Math.ceil(width/3);
heightDiff = isModuleMargin=='1'?containerHeigth+nullHeigth:containerHeigth;
}
break;
case '3':
case '4':{
let containerHeigth = Math.ceil((468/750)*width);
heightDiff = isModuleMargin=='1'?containerHeigth+nullHeigth:containerHeigth;
}
break;
default:
return null;
}
countNumb++;
result.length = heightDiff;
realContainerHeight += heightDiff;
}else if (shopsdecoratorItem.get('module_type') == 'FourImage') {
let list = shopsdecoratorItem.get('module_data').get('data').toArray();
let properties = shopsdecoratorItem.get('module_data').get('properties').toJS();
let isModuleMargin = properties.isModuleMargin;
if (!list || list.length == 0) {
return null;
}
let itemWidth = (width - 4)/4;
let rowHeightArray = [];
for (var i = 0; i < Math.ceil(list.length / 4); i++) {
rowHeightArray.push(itemWidth);
}
list.map((item, i) => {
if (item.get('text') && item.get('text') != '') {
rowHeightArray[Math.floor(i/list.length)] = itemWidth + 20;
}
});
let backgroundWidth = width;
let backgroundHeight = 0;
for (var i = 0; i < rowHeightArray.length; i++) {
backgroundHeight += rowHeightArray[i];
}
if (isModuleMargin == '1') {
backgroundHeight += 10;
}
countNumb++;
result.length = backgroundHeight;
realContainerHeight += backgroundHeight;
}else if (shopsdecoratorItem.get('module_type') == 'AppRecommendProduct') {
let properties = shopsdecoratorItem.get('module_data').get('properties').toJS();
let isModuleMargin = properties.isModuleMargin;
let list = shopsdecoratorItem.get('list');
if (list && list.size > 0) {
let backgroundWidth = width;
let rowWidth = Math.ceil(137.5 * width / 320);
let rowMarginHorizontal = (width - rowWidth * 2) / 3;
const DEVICE_WIDTH_RATIO = width / 320;
let rowHeight = Math.ceil(254 * DEVICE_WIDTH_RATIO);
let backgroundHeight = Math.ceil(list.size / 2) * (rowHeight+rowMarginHorizontal) + 20;
countNumb++;
result.length = backgroundHeight;
realContainerHeight += backgroundHeight;
}
}
if (countNumb == layoutIndex) {
return result;
}
});
}else if (item.key == 'productList') {
let brandFilterContainerHeight = this.props.fliter == '2' ? 84 : 40;
countNumb++; // filter
if (countNumb == layoutIndex) {
return {
length: brandFilterContainerHeight,
offset: realContainerHeight
}
}else {
let rowHeight = Math.ceil(254 * width / 320);
let rowMarginTop = Math.ceil(10 * DEVICE_WIDTH_RATIO);
let rowMarginBottom = Math.ceil(4 * DEVICE_WIDTH_RATIO);
realContainerHeight += brandFilterContainerHeight;
result.length = rowHeight + rowMarginTop + rowMarginBottom;
result.offset = realContainerHeight + (layoutIndex - countNumb) * result.length;
return result;
}
}
});
return {
length: 0,
offset: realContainerHeight,
}
}
getItemLayout(data, index){
let sectionInfo = this._calculateSectionRealHeight(this.sectionData, index);
return {length: sectionInfo.length, offset: sectionInfo.offset, index}
}
renderSectionHeader(section) {
let sectionID = section.section.key;
let {fliter,shopsdecorator} = this.props;
switch(sectionID) {
case 'brandReource': {
if (shopsdecorator && shopsdecorator.template_type == '1') {
return <View style={{height:0}}></View>;
} else {
return (<RedBrandStoreFilter key={'sec' + sectionID} resource={fliter} onPressStoreFilter={this._onPressFilter}/>);
}
}
case 'productList': {
let noFilterValue = true;
this.props.filterFactors.map((value, key) => {
if (value) {
noFilterValue = false;
}
});
let productListIsEmpty = !this.props.productList || !this.props.productList.list || this.props.productList.list.size == 0;
if (productListIsEmpty && noFilterValue) {
return null;
}
let brandFilterContainerHeight = this.props.fliter == '2' ? 84 : 40;
return (
<View key={'sec' + sectionID} style={[styles.brandFilterContainer,{height:brandFilterContainerHeight}]} onLayout={
(evt) => {yPosition = evt.nativeEvent.layout.y;}}>
{this.props.fliter != '0' ?
<RedBrandStoreFilter resource={fliter} onPressStoreFilter={this._onPressFilter}/>
:null
}
{this.props.fliter == '2' || this.props.fliter == '0' ?
<BrandProductFilter
onPressFilter={this._onPressProductFilter}
lastSelected={this.props.productList.isFilter}
moreFilter={this.props.productList.isMoreFilter}
selectOrder={this.props.productList.order}
/>
:null
}
</View>
);
}
default:
return null;
}
return null;
}
renderItem(item) {
let pageName = 'iFP_RedPersonBrand';
if (Platform.OS === 'android') {
pageName = 'aFP_RedPersonBrand';
}
let rowData = item.item;
let rowID = item.index;
let sectionID = item.section.key;
if (sectionID == 'ShopBanner') {
let {launchProfile, shopsdecorator} = this.props;
let resList = shopsdecorator.modules?shopsdecorator.modules.toArray():[];
return(<Header resource={rowData} launchProfile={launchProfile} onPressLaunchProfile={this._onPressLaunchProfile} onPressCollection={this.props.onPressCollection} onPressLink={this.props.onPressLink}/>);
} else if(sectionID == 'brandReource'){
let params = {
P_NAME : pageName,
F_ID : rowID,
TAB_NAME : '首页',
TAB_ID : 0,
F_NAME : rowData.get('module_type'),
P_PARAM: this.props.shopId,
exposureEnd : 1,
};
if (rowData.get('module_type') == 'coupon') {
return(<CouponCell yh_exposureData={params} resource={rowData} onPressCoupon={this.props.onPressCoupon}/>);
}else if (rowData.get('module_type') == 'CarouselImage') {
return(<RedBrandSwiper yh_exposureData={params} resource={rowData} onPressSlideItem={this.props.onPressProduct}/>);
}else if (rowData.get('module_type') == 'Title') {
return(<Title yh_exposureData={params} resource={rowData} onPressProduct={this.props.onPressProduct}/>);
}else if (rowData.get('module_type') == 'SingleImage') {
return(<SingleImage yh_exposureData={params} resource={rowData} onPressProduct={this.props.onPressProduct}/>);
}else if (rowData.get('module_type') == 'DoubleImage') {
return(<DoubleImage yh_exposureData={params} resource={rowData} onPressProduct={this.props.onPressProduct}/>);
}else if (rowData.get('module_type') == 'Video') {
return(<Video yh_exposureData={params} resource={rowData} videoCounts={videoCounts} onPressVideo={this.props.onPressVideo}/>);
}else if (rowData.get('module_type') == 'TripleImage') {
return(<TripleImage yh_exposureData={params} resource={rowData} onPressProduct={this.props.onPressProduct}/>);
}else if (rowData.get('module_type') == 'FourImage') {
return(<FourImages yh_exposureData={params} resource={rowData} onPressProduct={this.props.onPressProduct}/>);
}else if (rowData.get('module_type') == 'AppRecommendProduct') {
return(<GoodsGroupList yh_exposureData={params} resource={rowData} onPressProductRecommend={this.props.onPressProductRecommend}/>);
}else {
return (<View style={{height:0,width:width,backgroundColor:'red'}}/>);
}
} else if (sectionID == 'productList' || sectionID == 'newProductList') {
return (
<RedBrandTwoProductCell
left={rowData.left}
right={rowData.right}
key={'row'+ sectionID + rowID}
rowID={rowID}
onPressProduct={this.props.onPressProductCell}
/>
);
}
return null;
}
getCellKey(item, index) {
if (!item) {
return index + '';
}
let type = item.get('recommend_type', '');
if (type) {
return type + index + '';
} else {
let skn = item.get('product_skn', '');
if (skn) {
return skn + '';
}
}
return index + '';
}
render() {
let {
shopId,
productList,
launchProfile,
productListForNew,
fliter,
categoryFilterList,
filterCategoryDetailFilterList,
filterNameFactors,
filterFactors,
shopIntro,
shopsdecorator,
receiveCouponResult,
coupon,
} = this.props;
let isFetching = (productList.list.size > 0 && productList.isFetching && productList.currentPage == 0);
videoCounts = shopsdecorator.counts;
let resList = shopsdecorator.modules?shopsdecorator.modules.toArray():[];
coupon?resList.unshift(coupon):null;
let curPageProductList = productList.list?productList.list.toArray():[];
if (fliter == 1) {
curPageProductList = productListForNew.list?productListForNew.list.toArray():[];
}
let productListSize = curPageProductList.length / 2;
let newCurPageProductList = [];
for(let i = 0; i < productListSize; i ++) {
let leftIndex = i * 2;
let rightIndex = i * 2 + 1;
let left = curPageProductList[leftIndex];
let right = curPageProductList[rightIndex];
let key = this.getCellKey(left, leftIndex) + this.getCellKey(right, rightIndex);
newCurPageProductList.push({
left,
right,
key,
});
}
let dataSource = null;
if (fliter == 0) {
dataSource = [{data: [shopIntro],key:'ShopBanner'},
{data: resList, key:'brandReource'},
{data: newCurPageProductList, key:'productList'}
];
} else if (fliter == 1) {
dataSource = [{data: [shopIntro],key:'ShopBanner'},
{data: newCurPageProductList, key:'productList'}
];
} else if (fliter == 2) {
dataSource = [{data: [shopIntro],key:'ShopBanner'},
{data: newCurPageProductList, key:'productList'}
];
}
this.sectionData = dataSource;
let isLoadingMore = productList.isFetching && productList.currentPage > 0;
let endReached = productList.endReached;
let needShowToast = this.props.receiveCouponResult.isNeedShow;
let showToastMessage = this.props.receiveCouponResult.showMessage;
const DEVICE_WIDTH_RATIO = width / 320;
let rowHeight = Math.ceil(254 * DEVICE_WIDTH_RATIO);
return (
<View style={styles.container}>
<SectionList
ref='redBrandList'
contentContainerStyle={styles.contentContainer}
removeClippedSubviews={true}
enableVirtualization={true}
debug={false}
disableVirtualization={false}
refreshing={false}
sections={dataSource}
renderItem={this.renderItem}
renderSectionHeader={this.renderSectionHeader}
ListFooterComponent={()=>{
if (fliter == 0) {return <View style={styles.placeholder} />;}
if (endReached) {
return <View style={styles.placeholder} />;
} else {
return <LoadMoreIndicator isVisible={isLoadingMore} animating={true}/>;
}
}}
onEndReached={() => {
if (productList && productList.list && productList.list.size > 0) {
this.props.onEndReached && this.props.onEndReached(fliter);
}
}}
getItemLayout={this.getItemLayout}
viewabilityConfig={VIEWABILITY_CONFIG}
/>
{productList.isFilter ?
<ProductCategoryList
productList={productList}
onPressFilter={this._onPressProductFilter}
lastSelected={this.props.productList.isFilter}
moreFilter={this.props.productList.isMoreFilter}
selectOrder={this.props.productList.order}
categoryFilterList={categoryFilterList}
filterCategoryDetailFilterList={filterCategoryDetailFilterList}
onPressProductFilterLeftItem={this.props.onPressProductFilterLeftItem}
filterNameFactors={filterNameFactors}
onPressProductFilterRightItem={this.props.onPressProductFilterRightItem}
onPressCloseMoreFilter={this.props.onPressCloseMoreFilter}
onPressMoreFilter={this.props.onPressMoreFilter}/> : null}
{needShowToast ? <Prompt
text={showToastMessage}
duration={1000}
onPromptHidden={this.props.resetReceiveCouponResult}
/> : null}
<LoadingIndicator
isVisible={isFetching}
/>
</View>
);
}
}
let {width, height} = Dimensions.get('window');
let rowWidth = Math.ceil(137.5 * width / 320);
let rowHeight = Math.ceil(254 * width / 320);
let rowMarginTop = Math.ceil(10 * width / 320);
let rowMarginHorizontal = (width - rowWidth * 2) / 3;
let yPosition = 0;
let videoCounts;
let realHeight = rowHeight + rowMarginTop;
let featuredHight = Math.ceil(((width-30)*220)/690);
const DEVICE_WIDTH_RATIO = width / 320;
let styles = StyleSheet.create({
container: {
flex: 1,
},
contentContainer:{
flexDirection: 'row',
flexWrap: 'wrap',
},
listContainer: {
width: width / 2,
},
brandFilterContainer: {
marginLeft: -1,
width: width + 2,
height: 84,
},
placeholder: {
width,
height: 15,
},
});
... ...
'use strict';
import React, {Component} from 'react';
import ReactNative, {
View,
Text,
Image,
ListView,
StyleSheet,
Dimensions,
TouchableOpacity,
InteractionManager,
Platform,
} from 'react-native';
import Immutable, {Map} from 'immutable';
import BrandProductListCell from '../../../common/components/ListCell/ProductListCell';
export default class RedBrandTwoProductCell extends Component {
constructor(props) {
super(props);
}
render() {
let {left, right, index, similarIndex} = this.props;
return (
<View style={styles.container}>
<View style={styles.subContainer}>
{left ? <BrandProductListCell
style={[styles.listContainer, {paddingLeft: rowMarginHorizontal / 2 }]}
data={left}
onPressProduct={this.props.onPressProductCell}
rowID={index * 2}
/> : null}
{right ? <BrandProductListCell
style={[styles.listContainer, {paddingLeft: rowMarginHorizontal}]}
data={right}
rowID={index * 2 + 1}
onPressProduct={this.props.onPressProductCell}
/> : null}
</View>
</View>
);
}
}
let {width, height} = Dimensions.get('window');
const DEVICE_WIDTH_RATIO = width / 320;
let rowHeight = Math.ceil(254 * width / 320);
let rowMarginTop = Math.ceil(10 * DEVICE_WIDTH_RATIO);
let rowMarginBottom = Math.ceil(4 * DEVICE_WIDTH_RATIO);
let rowWidth = Math.ceil(137.5 * width / 320);
let rowMarginHorizontal = (width - rowWidth * 2) / 3;
let styles = StyleSheet.create({
container: {
width: width,
height: rowHeight + rowMarginTop + rowMarginBottom,
overflow: 'hidden',
},
subContainer: {
flexDirection: 'row',
width: width,
height: Platform.OS === 'ios'? rowHeight : rowHeight + 15 * DEVICE_WIDTH_RATIO,
},
listContainer: {
width: width / 2,
},
});
... ...