Authored by 于良

品牌品类顶部channel选择优化 review by 草莓

... ... @@ -32,9 +32,7 @@ export default class AllBrandListCell extends React.Component {
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.toJS());
... ...
... ... @@ -15,7 +15,7 @@ import {
import {Map} from 'immutable';
import BrandHeader from './BrandHeader';
import YH_SearchBar from '../../../common/components/YH_SearchBar';
import ChannelFliter from './ChannelFliter';
import ChannelSelector from '../../../common/components/ChannelSelector';
import AllBrandListCell from './AllBrandListCell';
import NewHotBannerListCell from './NewHotBannerListCell';
import BrandSearch from './search/BrandSearch';
... ... @@ -43,7 +43,7 @@ export default class Brand extends Component {
}
componentWillReceiveProps(nextProps) {
if (this.props.brandChannelFliter != nextProps.brandChannelFliter) {
if (this.props.selectedChannelId != nextProps.selectedChannelId) {
this.listView.scrollTo({x: 0, y: 0, animated: false});
}
}
... ... @@ -55,7 +55,7 @@ export default class Brand extends Component {
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);
this.props.setBrandData && this.props.setBrandData(this.sectionDataKey, this.props.selectedChannelId);
} else {
this.listView.scrollTo({x: 0, y: item.y, animated: false});
}
... ... @@ -66,7 +66,7 @@ export default class Brand extends Component {
let {y} = e.nativeEvent.layout;
if (this.sectionDataKey && this.sectionDataKey[sectionID].y != y) {
this.sectionDataKey[sectionID].y = y;
this.props.setBrandData && this.props.setBrandData(this.sectionDataKey,this.props.brandChannelFliter);
this.props.setBrandData && this.props.setBrandData(this.sectionDataKey, this.props.selectedChannelId);
if (this.needScrollSection == sectionID) {
this.listView.scrollTo({x: 0, y, animated: false});
}
... ... @@ -91,7 +91,7 @@ export default class Brand extends Component {
</TouchableOpacity>
<BrandHeader
brandChannelFliter= {this.props.brandChannelFliter}
selectedChannelId= {this.props.selectedChannelId}
reourceForBoy= {this.props.reourceForBoy}
reourceForGirl={this.props.reourceForGirl}
reourceForKid={this.props.reourceForKid}
... ... @@ -131,7 +131,7 @@ export default class Brand extends Component {
showSearch,
isFetching,
brandFliter,
brandChannelFliter,
selectedChannelId,
brandListForBoy,
brandListForGirl,
brandListForKid,
... ... @@ -146,13 +146,13 @@ export default class Brand extends Component {
let data;
if (brandChannelFliter == 1) {
if (selectedChannelId == 1) {
data = brandListForBoy;
} else if (brandChannelFliter == 2) {
} else if (selectedChannelId == 2) {
data = brandListForGirl;
} else if (brandChannelFliter == 3) {
} else if (selectedChannelId == 3) {
data = brandListForKid;
} else if (brandChannelFliter == 4) {
} else if (selectedChannelId == 4) {
data = brandListForLifeStyle;
}
... ... @@ -192,7 +192,7 @@ export default class Brand extends Component {
return (
<View style={styles.container}>
<ChannelFliter selectID={brandChannelFliter} onChannelPressFliter={this.props.onChannelPressFliter}/>
<ChannelSelector selectedChannelId={selectedChannelId} onSelectChannel={this.props.onSelectChannel}/>
<ListView
ref={(ref)=>this.listView=ref}
... ...
... ... @@ -27,15 +27,15 @@ export default class BrandHeader extends React.Component {
let data = this.props.reourceForBoy;
let brandFliter = this.props.brandFliter;
let brandChannelFliter = this.props.brandChannelFliter;
let selectedChannelId = this.props.selectedChannelId;
if (brandChannelFliter == 1) {
if (selectedChannelId == 1) {
data = this.props.reourceForBoy;
} else if (brandChannelFliter == 2) {
} else if (selectedChannelId == 2) {
data = this.props.reourceForGirl;
} else if (brandChannelFliter == 3) {
} else if (selectedChannelId == 3) {
data = this.props.reourceForKid;
} else if (brandChannelFliter == 4) {
} else if (selectedChannelId == 4) {
data = this.props.reourceForLifeStyle;
}
... ...
... ... @@ -6,13 +6,13 @@ import {getSlicedUrl} from '../../utils/Utils';
import Immutable, {Map} from 'immutable';
const {
StyleSheet,
Text,
View,
Image,
Dimensions,
TouchableOpacity,
PixelRatio,
StyleSheet,
Text,
View,
Image,
Dimensions,
TouchableOpacity,
PixelRatio,
} = ReactNative;
export default class NewHotBannerListCell extends React.Component {
... ... @@ -33,8 +33,6 @@ export default class NewHotBannerListCell extends React.Component {
let rowData = this.props.rowData;
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={() => {
... ... @@ -48,7 +46,7 @@ export default class NewHotBannerListCell extends React.Component {
>
</Image>
<View style={styles.itemTitle}>
<Text style={styles.itemText} numberOfLines={1}>{rowData.get('brand_name')}</Text>
<Text style={styles.itemText} numberOfLines={1}>{name}</Text>
</View>
</View>
</TouchableOpacity>
... ...
... ... @@ -51,7 +51,7 @@ export default class Brand extends Component {
renderRow(rowData, sectionID, rowID, highlightRow) {
return (
<AllBrandListCell rowData={rowData.toJS()} onPressSlideItem={(url) => {
<AllBrandListCell rowData={rowData} onPressSlideItem={(url) => {
this.props.onPressBrandSearchItem
&& this.props.onPressBrandSearchItem(url, rowData.get('brand_name', ''));
}}/>
... ...
... ... @@ -11,7 +11,7 @@ import ReactNative, {
TouchableOpacity,
} from 'react-native';
import ChannelFliter from './ChannelFliter';
import ChannelSelector from '../../../common/components/ChannelSelector';
import CategoryList from './CategoryList';
... ... @@ -25,15 +25,14 @@ export default class Category extends Component {
return (
<View style={styles.container}>
<ChannelFliter selectID={this.props.channelFliter} onChannelPressFliter={this.props.onChannelPressFliter}/>
<ChannelSelector selectedChannelValue={this.props.currentChannelId} onSelectChannel={this.props.onSelectChannel} />
<CategoryList
categoryList={this.props.categoryList}
pressLeftRow={this.props.pressLeftRow}
currentCateId={this.props.currentCateId}
currentChannelId={this.props.currentChannelId}
channelFliter= {this.props.channelFliter}
pressSubCateRow={this.props.pressSubCateRow}
/>
/>
</View>
);
}
... ...
... ... @@ -21,11 +21,11 @@ export default class CategoryList extends Component {
constructor(props) {
super(props);
this.renderRow = this.renderRow.bind(this);
this.renderSeparator=this.renderSeparator.bind(this);
this.subRenderSeparator=this.subRenderSeparator.bind(this);
this._pressLeftRow=this._pressLeftRow.bind(this);
this.renderSeparator = this.renderSeparator.bind(this);
this.subRenderSeparator = this.subRenderSeparator.bind(this);
this._pressLeftRow = this._pressLeftRow.bind(this);
this.dataSource = new ListView.DataSource({rowHasChanged: (r1, r2) => !immutable.is(r1, r2)});
this.subRenderRow=this.subRenderRow.bind(this);
this.subRenderRow = this.subRenderRow.bind(this);
this.state = {
offsetx: 0,
};
... ...
'use strict';
import React from 'react';
import ReactNative from 'react-native';
const {
View,
Text,
ListView,
TouchableOpacity,
Dimensions,
StyleSheet,
} = ReactNative;
export default class ChannelFliter extends React.Component {
constructor(props) {
super (props);
this._renderRow = this._renderRow.bind(this);
this._renderSeparator = this._renderSeparator.bind(this);
this.dataSource = new ListView.DataSource({
rowHasChanged: (r1, r2) => r1.key != r2.key,
});
this.state = {
filters: [
{
name: 'Boy',
value:'boy',
isSelect: false,
},
{
name: 'Girl',
value:'girl',
isSelect: false,
},
{
name: 'Kids',
value:'kids',
isSelect: false,
},
{
name: 'Lifestyle',
value:'lifestyle',
isSelect: false,
},
],
selectedIndex: this.props.selectID,
};
}
_renderRow(rowData, sectionID, rowID) {
let colorStyle = rowID == this.state.selectedIndex ? {color: '#444444'} : {color: '#b0b0b0'};
return (
<TouchableOpacity onPress={() => {
let filters = this.state.filters;
let filter = this.state.filters[rowID];
if (this.state.selectedIndex == rowID) {
return;
}
filter.isSelect = !filter.isSelect;
filters[rowID] = filter;
this.setState({
selectedIndex: rowID,
filters,
});
this.props.onChannelPressFliter && this.props.onChannelPressFliter(rowData.value);
}}>
<View key={'row' + rowID} style={styles.rowContainer}>
<Text style={[styles.name, colorStyle]}>{rowData.name}</Text>
</View>
</TouchableOpacity>
);
}
_renderSeparator(sectionID, rowID, adjacentRowHighlighted) {
return (
<View key={'sep' + rowID} style={styles.separator}>
</View>
);
}
render() {
let {style} = this.props;
return (
<View style={[styles.container, style]}>
<ListView
contentContainerStyle={[styles.contentContainer, style]}
enableEmptySections={true}
dataSource={this.dataSource.cloneWithRows(this.state.filters)}
renderRow={this._renderRow}
renderSeparator={this._renderSeparator}
scrollEnabled={false}
scrollsToTop={false}
/>
</View>
);
}
}
let {width, height} = Dimensions.get('window');
let styles = StyleSheet.create({
container: {
marginLeft: -1,
width: width + 2,
height: 50,
borderTopColor: 'transparent',
borderBottomColor: '#e5e5e5',
borderWidth: 0.5,
backgroundColor:'white',
},
contentContainer: {
flexDirection: 'row',
},
rowContainer: {
flexDirection: 'row',
justifyContent: 'center',
alignItems: 'center',
width: Math.ceil(width / 4),
height: 50,
backgroundColor:'white',
},
name: {
color: '#b0b0b0',
},
separator: {
width: 0.5,
top: 50 / 4,
height: 50 / 2,
backgroundColor: '#e5e5e5',
},
});
... ... @@ -61,7 +61,7 @@ export default keyMirror({
SET_BRAND_DATA_FOR_LIFESTYLE: null,
SET_BRAND_FILTER: null,
SET_BRAND_CHANNEL_FILTER: null,
SET_BRAND_SELECTED_CHANNEL: null,
BRAND_SHOW_SEARCH: null,
FETCH_BRAND_SEARCH_HISTORY: null,
... ...
... ... @@ -49,7 +49,7 @@ class BrandContainer extends Component {
this._onPressSlideItem = this._onPressSlideItem.bind(this);
this._onPressFilter = this._onPressFilter.bind(this);
this._onChannelPressFliter = this._onChannelPressFliter.bind(this);
this._onSelectChannel = this._onSelectChannel.bind(this);
this._onPressSearch = this._onPressSearch.bind(this);
this._onPressClearHistory = this._onPressClearHistory.bind(this);
this._onClickCancelSearch = this._onClickCancelSearch.bind(this);
... ... @@ -92,8 +92,7 @@ class BrandContainer extends Component {
this.props.actions.setInitialListSize(count);
}
_onChannelPressFliter(value){
_onSelectChannel(channel){
let {
brandListForBoy,
brandListForGirl,
... ... @@ -105,30 +104,31 @@ class BrandContainer extends Component {
reourceForLifeStyle,
} = this.props.brand;
let channelId = channel.id;
let brandListNeedRequest;
let reourceNeedRequest;
if (value == 1) {
if (channelId == 1) {
brandListNeedRequest = brandListForBoy.get('hasSuccess');
reourceNeedRequest = reourceForBoy.get('hasSuccess');
}else if (value == 2) {
}else if (channelId == 2) {
brandListNeedRequest = brandListForGirl.get('hasSuccess');
reourceNeedRequest = reourceForGirl.get('hasSuccess');
}else if (value == 3) {
}else if (channelId == 3) {
brandListNeedRequest = brandListForKid.get('hasSuccess');
reourceNeedRequest = reourceForKid.get('hasSuccess');
}else if (value == 4) {
}else if (channelId == 4) {
brandListNeedRequest = brandListForLifeStyle.get('hasSuccess');
reourceNeedRequest = reourceForLifeStyle.get('hasSuccess');
}
if (!brandListNeedRequest) {
this.props.actions.getBrandList(value);
this.props.actions.getBrandList(channelId);
}
if (!reourceNeedRequest) {
this.props.actions.getBrandResource(value);
this.props.actions.getBrandResource(channelId);
}
this.props.actions.setInitialListSize(0);
this.props.actions.setBrandChannelFilter(value);
this.props.actions.setBrandSelectedChannel(channelId);
}
_onPressSearch() {
... ... @@ -169,7 +169,7 @@ class BrandContainer extends Component {
showSearch,
initialListSize,
isFetching,
brandChannelFliter,
selectedChannelId,
brandFliter,
brandListForBoy,
brandListForGirl,
... ... @@ -187,7 +187,7 @@ class BrandContainer extends Component {
<Brand
isFetching={isFetching}
initialListSize={initialListSize}
brandChannelFliter= {brandChannelFliter}
selectedChannelId= {selectedChannelId}
brandFliter= {brandFliter}
brandListForBoy= {brandListForBoy}
brandListForGirl= {brandListForGirl}
... ... @@ -199,7 +199,7 @@ class BrandContainer extends Component {
reourceForLifeStyle={reourceForLifeStyle}
onPressFilter= {this._onPressFilter}
onPressSlideItem= {this._onPressSlideItem}
onChannelPressFliter={this._onChannelPressFliter}
onSelectChannel={this._onSelectChannel}
showSearch={showSearch}
search={search}
onPressSearch={this._onPressSearch}
... ...
... ... @@ -47,9 +47,9 @@ function mapDispatchToProps(dispatch) {
class CategoryContainer extends Component {
constructor(props) {
super(props);
this._onChannelPressFliter = this._onChannelPressFliter.bind(this);
this._pressLeftRow=this._pressLeftRow.bind(this);
this._pressSubCateRow=this._pressSubCateRow.bind(this);
this._onSelectChannel = this._onSelectChannel.bind(this);
this._pressLeftRow = this._pressLeftRow.bind(this);
this._pressSubCateRow = this._pressSubCateRow.bind(this);
}
componentDidMount() {
... ... @@ -59,21 +59,22 @@ class CategoryContainer extends Component {
componentWillUnmount() {
}
_onChannelPressFliter(value){
_onSelectChannel(channel) {
this.props.actions.setCurrentCateId(0);
this.props.actions.setCurrentChannelId(value);
this.props.actions.setCurrentChannelId(channel.value);
}
_pressLeftRow(value,rowID){
_pressLeftRow(value,rowID) {
this.props.actions.setCurrentCateId(rowID);
}
_pressSubCateRow(value, index){
_pressSubCateRow(value, index) {
this.props.actions.jumpToCategory(value, index, this.props.category.channelFliter);
}
render() {
let {
channelFliter,
categoryList,
currentChannelId,
currentCateId,
... ... @@ -85,9 +86,8 @@ class CategoryContainer extends Component {
categoryList={categoryList}
currentChannelId={currentChannelId}
currentCateId={currentCateId}
channelFliter= {channelFliter}
pressLeftRow={this._pressLeftRow}
onChannelPressFliter={this._onChannelPressFliter}
onSelectChannel={this._onSelectChannel}
pressSubCateRow={this._pressSubCateRow}
/>
</View>
... ...
... ... @@ -10,7 +10,7 @@ const {
SET_TYPE,
SET_BRAND_FILTER,
SET_BRAND_CHANNEL_FILTER,
SET_BRAND_SELECTED_CHANNEL,
SET_INITIALLISTSIZE,
GET_BRAND_LIST_FOR_BOY_REQUEST,
GET_BRAND_LIST_FOR_BOY_SUCCESS,
... ... @@ -69,10 +69,10 @@ export function setBrandFilter(filter) {
};
}
export function setBrandChannelFilter(filter) {
export function setBrandSelectedChannel(channelId) {
return {
type: SET_BRAND_CHANNEL_FILTER,
payload: filter
type: SET_BRAND_SELECTED_CHANNEL,
payload: channelId
};
}
... ...
... ... @@ -5,7 +5,7 @@ import {Record, List, Map} from 'immutable';
let InitialState = Record({
isFetching: false,
brandFliter: 0,
brandChannelFliter:1,
selectedChannelId: 1,
initialListSize: 0,
brandListForBoy: new (Record({
all_list: Map(),
... ...
... ... @@ -7,7 +7,7 @@ const {
SET_TYPE,
SET_BRAND_FILTER,
SET_BRAND_CHANNEL_FILTER,
SET_BRAND_SELECTED_CHANNEL,
SET_INITIALLISTSIZE,
GET_BRAND_LIST_FOR_BOY_REQUEST,
GET_BRAND_LIST_FOR_BOY_SUCCESS,
... ... @@ -67,8 +67,8 @@ export default function brandReducer(state=initialState, action) {
}
case SET_BRAND_CHANNEL_FILTER: {
return state.set('brandChannelFliter', action.payload);
case SET_BRAND_SELECTED_CHANNEL: {
return state.set('selectedChannelId', action.payload);
}
case GET_BRAND_LIST_FOR_BOY_REQUEST:
... ...
... ... @@ -3,9 +3,8 @@
import {Record, List, Map} from 'immutable';
let InitialState = Record({
channelFliter:0,
currentChannelId:'boy',
currentCateId:'0',
currentChannelId: 'boy',
currentCateId: '0',
categoryList: new (Record({
boy: List(),
girl: List(),
... ...
... ... @@ -2,6 +2,7 @@
import React from 'react';
import ReactNative from 'react-native';
import Immutable, {Map} from 'immutable';
const {
View,
... ... @@ -10,10 +11,11 @@ const {
TouchableOpacity,
Dimensions,
StyleSheet,
Platform,
} = ReactNative;
export default class ChannelFliter extends React.Component {
export default class ChannelSelector extends React.Component {
constructor(props) {
super (props);
... ... @@ -22,46 +24,65 @@ export default class ChannelFliter extends React.Component {
this._renderSeparator = this._renderSeparator.bind(this);
this.dataSource = new ListView.DataSource({
rowHasChanged: (r1, r2) => r1.key != r2.key,
rowHasChanged: (r1, r2) => r1.id != r2.id,
});
this.state = {
filters: [
{
name: 'Boy',
isSelect: false,
},
{
name: 'Girl',
isSelect: false,
},
{
name: 'Kid',
isSelect: false,
},
{
name: 'Lifestyle',
isSelect: false,
},
],
selectedIndex: this.props.selectID,
};
this.channels = [
{
name: 'Boy',
value: 'boy',
id: 1,
isSelect: false,
},
{
name: 'Girl',
value: 'girl',
id: 2,
isSelect: false,
},
{
name: 'Kids',
value: 'kids',
id: 3,
isSelect: false,
},
{
name: 'Lifestyle',
value: 'lifestyle',
id: 4,
isSelect: false,
},
];
}
shouldComponentUpdate(nextProps){
if ((nextProps.selectedChannelId == this.props.selectedChannelId)
&& (nextProps.selectedChannelValue == this.props.selectedChannelValue)) {
return false;
} else {
return true;
}
}
_renderRow(rowData, sectionID, rowID) {
let colorStyle = rowID == this.props.selectID-1 ? {color: '#444444',fontFamily: 'HelveticaNeue',fontSize: 17} : {color: '#b0b0b0',fontFamily: 'HelveticaNeue-Bold',fontSize: 14,};
let isRowSelected = false;
if (this.props.selectedChannelId >= 1) {
isRowSelected = (rowID == this.props.selectedChannelId - 1);
} else {
isRowSelected = (rowData.value == this.props.selectedChannelValue);
}
let colorStyle = isRowSelected ? {color: '#444444', fontFamily: 'HelveticaNeue', fontSize: 17} : {color: '#b0b0b0', fontFamily: 'HelveticaNeue-Bold', fontSize: 14,};
return (
<TouchableOpacity activeOpacity={1} onPress={() => {
let filters = this.state.filters;
let filter = this.state.filters[rowID];
if (this.props.selectID-1 == rowID) {
if (isRowSelected) {
return;
}
filter.isSelect = !(filter.isSelect-1);
filters[rowID] = filter;
this.props.onChannelPressFliter && this.props.onChannelPressFliter(Number(rowID)+1);
let channel = this.channels[rowID];
this.props.onSelectChannel && this.props.onSelectChannel(channel);
}}>
<View key={'row' + rowID} style={styles.rowContainer}>
<Text style={[styles.name, colorStyle]}>{rowData.name}</Text>
... ... @@ -86,7 +107,7 @@ export default class ChannelFliter extends React.Component {
<ListView
contentContainerStyle={[styles.contentContainer, style]}
enableEmptySections={true}
dataSource={this.dataSource.cloneWithRows(this.state.filters)}
dataSource={this.dataSource.cloneWithRows(this.channels)}
renderRow={this._renderRow}
renderSeparator={this._renderSeparator}
scrollEnabled={false}
... ... @@ -99,11 +120,13 @@ export default class ChannelFliter extends React.Component {
let {width, height} = Dimensions.get('window');
let viewHeight = (Platform.OS === 'ios') ? 44 : 50;
let styles = StyleSheet.create({
container: {
marginLeft: -1,
width: width + 2,
height: 44,
height: viewHeight,
borderTopColor: 'transparent',
borderBottomColor: '#e5e5e5',
borderWidth: 0.5,
... ... @@ -117,7 +140,7 @@ let styles = StyleSheet.create({
justifyContent: 'center',
alignItems: 'center',
width: Math.ceil(width / 4),
height: 44,
height: viewHeight,
backgroundColor:'white',
},
name: {
... ... @@ -125,8 +148,8 @@ let styles = StyleSheet.create({
},
separator: {
width: 0.5,
top: 44 / 4,
height: 44 / 2,
top: viewHeight / 4,
height: viewHeight / 2,
backgroundColor: '#e5e5e5',
},
});
... ...