Showing
17 changed files
with
575 additions
and
16 deletions
@@ -20,6 +20,7 @@ import YH_SearchBar from '../../../common/components/YH_SearchBar'; | @@ -20,6 +20,7 @@ import YH_SearchBar from '../../../common/components/YH_SearchBar'; | ||
20 | import ChannelFliter from './ChannelFliter'; | 20 | import ChannelFliter from './ChannelFliter'; |
21 | import AllBrandListCell from './AllBrandListCell'; | 21 | import AllBrandListCell from './AllBrandListCell'; |
22 | import NewHotBannerListCell from './NewHotBannerListCell'; | 22 | import NewHotBannerListCell from './NewHotBannerListCell'; |
23 | +import BrandSearch from './BrandSearch'; | ||
23 | 24 | ||
24 | 25 | ||
25 | export default class Brand extends Component { | 26 | export default class Brand extends Component { |
@@ -66,7 +67,14 @@ export default class Brand extends Component { | @@ -66,7 +67,14 @@ export default class Brand extends Component { | ||
66 | 67 | ||
67 | return ( | 68 | return ( |
68 | <View style={styles.header}> | 69 | <View style={styles.header}> |
69 | - <YH_SearchBar/> | 70 | + <TouchableOpacity |
71 | + activeOpacity={1} | ||
72 | + onPress={() => { | ||
73 | + this.props.onPressSearch && this.props.onPressSearch(); | ||
74 | + }} | ||
75 | + > | ||
76 | + <YH_SearchBar editable={false} /> | ||
77 | + </TouchableOpacity> | ||
70 | {banner?<BrandSwiper resource={banner} onPressSlideItem={this.props.onPressSlideItem}/>:null} | 78 | {banner?<BrandSwiper resource={banner} onPressSlideItem={this.props.onPressSlideItem}/>:null} |
71 | {custom_brands?<BannerReourceList resource={custom_brands} onPressSlideItem={this.props.onPressSlideItem}/>:null} | 79 | {custom_brands?<BannerReourceList resource={custom_brands} onPressSlideItem={this.props.onPressSlideItem}/>:null} |
72 | {brandsText?<BrandFliter dataSource={brandsText} selectID={brandFliter} onPressFilter={this.props.onPressFilter}/>:null} | 80 | {brandsText?<BrandFliter dataSource={brandsText} selectID={brandFliter} onPressFilter={this.props.onPressFilter}/>:null} |
@@ -97,6 +105,7 @@ export default class Brand extends Component { | @@ -97,6 +105,7 @@ export default class Brand extends Component { | ||
97 | render() { | 105 | render() { |
98 | 106 | ||
99 | let { | 107 | let { |
108 | + showSearch, | ||
100 | brandFliter, | 109 | brandFliter, |
101 | channelFliter, | 110 | channelFliter, |
102 | brandListForBoy, | 111 | brandListForBoy, |
@@ -107,6 +116,7 @@ export default class Brand extends Component { | @@ -107,6 +116,7 @@ export default class Brand extends Component { | ||
107 | reourceForGirl, | 116 | reourceForGirl, |
108 | reourceForKid, | 117 | reourceForKid, |
109 | reourceForLifeStyle, | 118 | reourceForLifeStyle, |
119 | + search, | ||
110 | } = this.props; | 120 | } = this.props; |
111 | 121 | ||
112 | let data; | 122 | let data; |
@@ -148,6 +158,7 @@ export default class Brand extends Component { | @@ -148,6 +158,7 @@ export default class Brand extends Component { | ||
148 | return ( | 158 | return ( |
149 | <View style={styles.container}> | 159 | <View style={styles.container}> |
150 | <ChannelFliter selectID={channelFliter} onChannelPressFliter={this.props.onChannelPressFliter}/> | 160 | <ChannelFliter selectID={channelFliter} onChannelPressFliter={this.props.onChannelPressFliter}/> |
161 | + | ||
151 | <ListView | 162 | <ListView |
152 | contentContainerStyle={contentContainerStyle} | 163 | contentContainerStyle={contentContainerStyle} |
153 | enableEmptySections={true} | 164 | enableEmptySections={true} |
@@ -156,6 +167,8 @@ export default class Brand extends Component { | @@ -156,6 +167,8 @@ export default class Brand extends Component { | ||
156 | renderSectionHeader={renderSectionHeader} | 167 | renderSectionHeader={renderSectionHeader} |
157 | renderHeader={this.renderHeader} | 168 | renderHeader={this.renderHeader} |
158 | /> | 169 | /> |
170 | + | ||
171 | + {showSearch ? <BrandSearch style={styles.search} data={search}/> : null} | ||
159 | </View> | 172 | </View> |
160 | ); | 173 | ); |
161 | } | 174 | } |
@@ -166,6 +179,7 @@ let {width, height} = Dimensions.get('window'); | @@ -166,6 +179,7 @@ let {width, height} = Dimensions.get('window'); | ||
166 | let styles = StyleSheet.create({ | 179 | let styles = StyleSheet.create({ |
167 | container: { | 180 | container: { |
168 | flex: 1, | 181 | flex: 1, |
182 | + backgroundColor: 'white', | ||
169 | }, | 183 | }, |
170 | contentContainerOne:{ | 184 | contentContainerOne:{ |
171 | 185 | ||
@@ -191,4 +205,8 @@ let styles = StyleSheet.create({ | @@ -191,4 +205,8 @@ let styles = StyleSheet.create({ | ||
191 | width, | 205 | width, |
192 | backgroundColor: '#444', | 206 | backgroundColor: '#444', |
193 | }, | 207 | }, |
208 | + search: { | ||
209 | + | ||
210 | + | ||
211 | + }, | ||
194 | }); | 212 | }); |
js/classify/components/brand/BrandSearch.js
0 → 100644
1 | +'use strict'; | ||
2 | + | ||
3 | +import React, {Component} from 'react'; | ||
4 | +import ReactNative, { | ||
5 | + View, | ||
6 | + Text, | ||
7 | + Image, | ||
8 | + ListView, | ||
9 | + StyleSheet, | ||
10 | + Dimensions, | ||
11 | + TouchableOpacity, | ||
12 | +} from 'react-native'; | ||
13 | + | ||
14 | +import KeywordCell from './KeywordCell'; | ||
15 | +import YH_SearchBar from '../../../common/components/YH_SearchBar'; | ||
16 | + | ||
17 | +export default class SearchKeyword extends Component { | ||
18 | + | ||
19 | + constructor(props) { | ||
20 | + super(props); | ||
21 | + | ||
22 | + this._renderRow = this._renderRow.bind(this); | ||
23 | + this._renderSeparator = this._renderSeparator.bind(this); | ||
24 | + | ||
25 | + this.dataSource = new ListView.DataSource({ | ||
26 | + rowHasChanged: (r1, r2) => !Immutable.is(r1, r2), | ||
27 | + sectionHeaderHasChanged: (s1, s2) => !Immutable.is(s1, s2), | ||
28 | + }); | ||
29 | + } | ||
30 | + | ||
31 | + componentDidMount() { | ||
32 | + this.searchBar && this.searchBar.focus(); | ||
33 | + } | ||
34 | + | ||
35 | + _renderRow(rowData, sectionID, rowID) { | ||
36 | + if (rowData.size == 0) { | ||
37 | + return null; | ||
38 | + } | ||
39 | + | ||
40 | + let icon = rowID == 0 ? require('../../images/shijian.png') : require('../../images/huo.png'); | ||
41 | + let title = rowID == 0 ? '最近搜索' : '热门搜索'; | ||
42 | + let onPressAction = rowID == 0 ? this.props.onPressClearHistory : null; | ||
43 | + return ( | ||
44 | + <KeywordCell | ||
45 | + key={'row' + rowID} | ||
46 | + icon={icon} | ||
47 | + title={title} | ||
48 | + list={rowData} | ||
49 | + onPressAction={onPressAction} | ||
50 | + onPressKeyword={this.props.onPressKeyword} | ||
51 | + /> | ||
52 | + ); | ||
53 | + } | ||
54 | + | ||
55 | + _renderSeparator(sectionID, rowID, adjacentRowHighlighted) { | ||
56 | + if (rowID == 0 && this.props.data.history.size > 0) { | ||
57 | + return ( | ||
58 | + <View key={'sep' + rowID} style={styles.separator}> | ||
59 | + <View style={styles.line}/> | ||
60 | + </View> | ||
61 | + ); | ||
62 | + } | ||
63 | + | ||
64 | + return null; | ||
65 | + } | ||
66 | + | ||
67 | + render() { | ||
68 | + let {history, hot, style} = this.props.data; | ||
69 | + let list = [history, hot]; | ||
70 | + | ||
71 | + return ( | ||
72 | + <View style={[styles.container, style]}> | ||
73 | + <YH_SearchBar | ||
74 | + ref={(c) => { | ||
75 | + this.searchBar = c; | ||
76 | + }} | ||
77 | + /> | ||
78 | + <ListView | ||
79 | + contentContainerStyle={styles.contentContainer} | ||
80 | + enableEmptySections={true} | ||
81 | + dataSource={this.dataSource.cloneWithRows(list)} | ||
82 | + renderRow={this._renderRow} | ||
83 | + renderSeparator={this._renderSeparator} | ||
84 | + keyboardDismissMode={'on-drag'} | ||
85 | + /> | ||
86 | + | ||
87 | + </View> | ||
88 | + ); | ||
89 | + } | ||
90 | +} | ||
91 | + | ||
92 | +let {width, height} = Dimensions.get('window'); | ||
93 | + | ||
94 | + | ||
95 | +let styles = StyleSheet.create({ | ||
96 | + container: { | ||
97 | + flex: 1, | ||
98 | + position: 'absolute', | ||
99 | + top: 0, | ||
100 | + left: 0, | ||
101 | + width, | ||
102 | + height, | ||
103 | + backgroundColor: 'white', | ||
104 | + }, | ||
105 | + contentContainer: { | ||
106 | + | ||
107 | + }, | ||
108 | + separator: { | ||
109 | + height: 15, | ||
110 | + }, | ||
111 | + line: { | ||
112 | + marginHorizontal: 30, | ||
113 | + top: 10 , | ||
114 | + height: 1, | ||
115 | + backgroundColor: '#e5e5e5', | ||
116 | + }, | ||
117 | +}); |
js/classify/components/brand/KeywordCell.js
0 → 100644
1 | +'use strict'; | ||
2 | + | ||
3 | +import React from 'react'; | ||
4 | +import ReactNative from 'react-native'; | ||
5 | + | ||
6 | +const { | ||
7 | + View, | ||
8 | + Image, | ||
9 | + Text, | ||
10 | + ScrollView, | ||
11 | + TouchableOpacity, | ||
12 | + Dimensions, | ||
13 | + StyleSheet, | ||
14 | +} = ReactNative; | ||
15 | + | ||
16 | +import KeywordHeader from './KeywordHeader'; | ||
17 | +import KeywordText from './KeywordText'; | ||
18 | + | ||
19 | +export default class KeywordCell extends React.Component { | ||
20 | + | ||
21 | + constructor(props) { | ||
22 | + super (props); | ||
23 | + | ||
24 | + } | ||
25 | + | ||
26 | + render() { | ||
27 | + | ||
28 | + let {icon, title, list, onPressAction, onPressKeyword} = this.props; | ||
29 | + | ||
30 | + return ( | ||
31 | + <View style={styles.container}> | ||
32 | + <KeywordHeader | ||
33 | + icon={icon} | ||
34 | + title={title} | ||
35 | + onPressAction={onPressAction} | ||
36 | + /> | ||
37 | + <View style={styles.textContainer}> | ||
38 | + {list.toJS().map((item, i) => { | ||
39 | + return <KeywordText key={i} keyword={item.keyword} onPressKeyword={onPressKeyword}/>; | ||
40 | + })} | ||
41 | + </View> | ||
42 | + | ||
43 | + </View> | ||
44 | + ); | ||
45 | + } | ||
46 | +} | ||
47 | + | ||
48 | +let styles = StyleSheet.create({ | ||
49 | + container: { | ||
50 | + | ||
51 | + }, | ||
52 | + textContainer: { | ||
53 | + marginHorizontal: 26, | ||
54 | + flexDirection: 'row', | ||
55 | + flexWrap: 'wrap', | ||
56 | + }, | ||
57 | +}); |
1 | +'use strict'; | ||
2 | + | ||
3 | +import React from 'react'; | ||
4 | +import ReactNative from 'react-native'; | ||
5 | + | ||
6 | +const { | ||
7 | + View, | ||
8 | + Image, | ||
9 | + Text, | ||
10 | + TouchableOpacity, | ||
11 | + Dimensions, | ||
12 | + StyleSheet, | ||
13 | +} = ReactNative; | ||
14 | + | ||
15 | +export default class KeywordHeader extends React.Component { | ||
16 | + | ||
17 | + constructor(props) { | ||
18 | + super (props); | ||
19 | + | ||
20 | + } | ||
21 | + | ||
22 | + renderAction() { | ||
23 | + if (this.props.onPressAction) { | ||
24 | + return ( | ||
25 | + <TouchableOpacity style={styles.action} onPress={() => { | ||
26 | + this.props.onPressAction && this.props.onPressAction(); | ||
27 | + }}> | ||
28 | + <Image | ||
29 | + style={styles.delete} | ||
30 | + source={require('../../images/shanchu.png')} | ||
31 | + resizeMode={'contain'} | ||
32 | + /> | ||
33 | + </TouchableOpacity> | ||
34 | + ); | ||
35 | + } | ||
36 | + | ||
37 | + return null; | ||
38 | + } | ||
39 | + | ||
40 | + render() { | ||
41 | + let {icon, title, onPressAction} = this.props; | ||
42 | + return ( | ||
43 | + <View style={styles.container}> | ||
44 | + <Image | ||
45 | + style={styles.icon} | ||
46 | + source={icon} | ||
47 | + resizeMode={'contain'} | ||
48 | + /> | ||
49 | + <Text style={styles.text}>{title}</Text> | ||
50 | + | ||
51 | + {this.renderAction()} | ||
52 | + </View> | ||
53 | + ); | ||
54 | + } | ||
55 | +} | ||
56 | + | ||
57 | +let styles = StyleSheet.create({ | ||
58 | + container: { | ||
59 | + flexDirection: 'row', | ||
60 | + alignItems: 'center', | ||
61 | + width: Dimensions.get('window').width, | ||
62 | + height: 40, | ||
63 | + }, | ||
64 | + icon: { | ||
65 | + marginLeft: 15, | ||
66 | + width: 13, | ||
67 | + height: 17, | ||
68 | + }, | ||
69 | + text: { | ||
70 | + marginLeft: 10, | ||
71 | + color: '#b0b0b0', | ||
72 | + fontSize: 12, | ||
73 | + }, | ||
74 | + action: { | ||
75 | + position: 'absolute', | ||
76 | + right: 10, | ||
77 | + height: 40, | ||
78 | + }, | ||
79 | + delete: { | ||
80 | + width: 28, | ||
81 | + height: 28, | ||
82 | + top: 6, | ||
83 | + }, | ||
84 | +}); |
js/classify/components/brand/KeywordText.js
0 → 100644
1 | +'use strict'; | ||
2 | + | ||
3 | +import React from 'react'; | ||
4 | +import ReactNative from 'react-native'; | ||
5 | + | ||
6 | +const { | ||
7 | + View, | ||
8 | + Image, | ||
9 | + Text, | ||
10 | + TouchableHighlight, | ||
11 | + Dimensions, | ||
12 | + StyleSheet, | ||
13 | +} = ReactNative; | ||
14 | + | ||
15 | +export default class KeywordText extends React.Component { | ||
16 | + | ||
17 | + constructor(props) { | ||
18 | + super (props); | ||
19 | + | ||
20 | + this.state = { | ||
21 | + helight: false, | ||
22 | + } | ||
23 | + } | ||
24 | + | ||
25 | + render() { | ||
26 | + let {keyword, onPressKeyword} = this.props; | ||
27 | + let textColor = this.state.helight ? {color: 'rgb(66, 66, 66)'} : {color: 'rgb(191, 191, 191)'}; | ||
28 | + return ( | ||
29 | + <TouchableHighlight | ||
30 | + style={styles.container} | ||
31 | + underlayColor={'rgb(255, 255, 255)'} | ||
32 | + onPress={() => { | ||
33 | + onPressKeyword && onPressKeyword(keyword); | ||
34 | + }} | ||
35 | + onPressIn={() => { | ||
36 | + this.setState({ | ||
37 | + helight: !this.state.helight, | ||
38 | + }); | ||
39 | + }} | ||
40 | + onPressOut={() => { | ||
41 | + this.setState({ | ||
42 | + helight: !this.state.helight, | ||
43 | + }); | ||
44 | + }} | ||
45 | + > | ||
46 | + <Text style={[styles.text, textColor]}>{keyword}</Text> | ||
47 | + </TouchableHighlight> | ||
48 | + ); | ||
49 | + } | ||
50 | +} | ||
51 | + | ||
52 | +let styles = StyleSheet.create({ | ||
53 | + container: { | ||
54 | + flexDirection: 'row', | ||
55 | + alignItems: 'center', | ||
56 | + alignSelf: 'flex-start', | ||
57 | + height: 25, | ||
58 | + backgroundColor: 'rgb(255, 255, 255)', | ||
59 | + borderColor: 'rgb(191, 191, 191)', | ||
60 | + borderRadius: 3, | ||
61 | + borderWidth: 1, | ||
62 | + margin: 4, | ||
63 | + }, | ||
64 | + text: { | ||
65 | + marginHorizontal: 10, | ||
66 | + marginVertical: 6, | ||
67 | + fontSize: 13, | ||
68 | + }, | ||
69 | +}); |
@@ -23,10 +23,6 @@ export default keyMirror({ | @@ -23,10 +23,6 @@ export default keyMirror({ | ||
23 | 23 | ||
24 | LOAD_CACHED_INTEREST_LIST: null, | 24 | LOAD_CACHED_INTEREST_LIST: null, |
25 | 25 | ||
26 | - GET_COUPON_REQUEST: null, | ||
27 | - GET_COUPON_SUCCESS: null, | ||
28 | - GET_COUPON_FAILURE: null, | ||
29 | - | ||
30 | GET_BRAND_LIST_FOR_BOY_REQUEST: null, | 26 | GET_BRAND_LIST_FOR_BOY_REQUEST: null, |
31 | GET_BRAND_LIST_FOR_BOY_SUCCESS: null, | 27 | GET_BRAND_LIST_FOR_BOY_SUCCESS: null, |
32 | GET_BRAND_LIST_FOR_BOY_FAILURE: null, | 28 | GET_BRAND_LIST_FOR_BOY_FAILURE: null, |
@@ -62,9 +58,14 @@ export default keyMirror({ | @@ -62,9 +58,14 @@ export default keyMirror({ | ||
62 | SET_BRAND_FILTER: null, | 58 | SET_BRAND_FILTER: null, |
63 | SET_CHANNEL_FILTER: null, | 59 | SET_CHANNEL_FILTER: null, |
64 | 60 | ||
65 | - JUMP_WITH_URL: null, | 61 | + BRAND_SHOW_SEARCH: null, |
62 | + FETCH_BRAND_SEARCH_HISTORY: null, | ||
63 | + INSERT_BRAND_SEARCH_HISTORY: null, | ||
64 | + CLEAR_BRAND_SEARCH_HISTORY: null, | ||
65 | + BRAND_HOT_KEYWORD_REQUEST: null, | ||
66 | + BRAND_HOT_KEYWORD_SUCCESS: null, | ||
67 | + BRAND_HOT_KEYWORD_FAILURE: null, | ||
66 | 68 | ||
67 | - HIDE_SUCCESS_PROMPT: null, | ||
68 | - HIDE_NET_ERROR_PROMPT: null, | 69 | + JUMP_WITH_URL: null, |
69 | 70 | ||
70 | }); | 71 | }); |
@@ -50,23 +50,27 @@ class BrandContainer extends Component { | @@ -50,23 +50,27 @@ class BrandContainer extends Component { | ||
50 | this._onPressSlideItem = this._onPressSlideItem.bind(this); | 50 | this._onPressSlideItem = this._onPressSlideItem.bind(this); |
51 | this._onPressFilter = this._onPressFilter.bind(this); | 51 | this._onPressFilter = this._onPressFilter.bind(this); |
52 | this._onChannelPressFliter = this._onChannelPressFliter.bind(this); | 52 | this._onChannelPressFliter = this._onChannelPressFliter.bind(this); |
53 | + this._onPressSearch = this._onPressSearch.bind(this); | ||
54 | + this._onPressClearHistory = this._onPressClearHistory.bind(this); | ||
53 | 55 | ||
54 | } | 56 | } |
55 | 57 | ||
56 | componentDidMount() { | 58 | componentDidMount() { |
57 | this.props.actions.getBrandList(0); | 59 | this.props.actions.getBrandList(0); |
58 | this.props.actions.getBrandResource(0); | 60 | this.props.actions.getBrandResource(0); |
61 | + this.props.actions.searchHistory(); | ||
62 | + this.props.actions.hotKeyword(); | ||
59 | } | 63 | } |
60 | 64 | ||
61 | componentWillUnmount() { | 65 | componentWillUnmount() { |
62 | 66 | ||
63 | } | 67 | } |
64 | 68 | ||
65 | - _onPressSlideItem(url){ | 69 | + _onPressSlideItem(url) { |
66 | console.log('aaa'); | 70 | console.log('aaa'); |
67 | } | 71 | } |
68 | 72 | ||
69 | - _onPressFilter(value){ | 73 | + _onPressFilter(value) { |
70 | this.props.actions.setBrandFilter(value); | 74 | this.props.actions.setBrandFilter(value); |
71 | } | 75 | } |
72 | 76 | ||
@@ -107,8 +111,17 @@ class BrandContainer extends Component { | @@ -107,8 +111,17 @@ class BrandContainer extends Component { | ||
107 | this.props.actions.setChannelFilter(value); | 111 | this.props.actions.setChannelFilter(value); |
108 | } | 112 | } |
109 | 113 | ||
114 | + _onPressSearch() { | ||
115 | + this.props.actions.setShowSearch(!this.props.brand.showSearch); | ||
116 | + } | ||
117 | + | ||
118 | + _onPressClearHistory() { | ||
119 | + this.props.actions.clearSearchHistory(); | ||
120 | + } | ||
121 | + | ||
110 | render() { | 122 | render() { |
111 | let { | 123 | let { |
124 | + showSearch, | ||
112 | channelFliter, | 125 | channelFliter, |
113 | brandFliter, | 126 | brandFliter, |
114 | brandListForBoy, | 127 | brandListForBoy, |
@@ -119,8 +132,9 @@ class BrandContainer extends Component { | @@ -119,8 +132,9 @@ class BrandContainer extends Component { | ||
119 | reourceForGirl, | 132 | reourceForGirl, |
120 | reourceForKid, | 133 | reourceForKid, |
121 | reourceForLifeStyle, | 134 | reourceForLifeStyle, |
135 | + search, | ||
122 | } = this.props.brand; | 136 | } = this.props.brand; |
123 | - console.log(this.props.brand); | 137 | + |
124 | return ( | 138 | return ( |
125 | <View style={styles.container}> | 139 | <View style={styles.container}> |
126 | <Brand | 140 | <Brand |
@@ -137,6 +151,10 @@ class BrandContainer extends Component { | @@ -137,6 +151,10 @@ class BrandContainer extends Component { | ||
137 | onPressFilter= {this._onPressFilter} | 151 | onPressFilter= {this._onPressFilter} |
138 | onPressSlideItem= {this._onPressSlideItem} | 152 | onPressSlideItem= {this._onPressSlideItem} |
139 | onChannelPressFliter={this._onChannelPressFliter} | 153 | onChannelPressFliter={this._onChannelPressFliter} |
154 | + showSearch={showSearch} | ||
155 | + search={search} | ||
156 | + onPressSearch={this._onPressSearch} | ||
157 | + onPressClearHistory={this._onPressClearHistory} | ||
140 | /> | 158 | /> |
141 | </View> | 159 | </View> |
142 | ); | 160 | ); |
js/classify/images/huo@2x.png
0 → 100644
1.44 KB
js/classify/images/huo@3x.png
0 → 100644
1.7 KB
js/classify/images/shanchu@2x.png
0 → 100644
1.58 KB
js/classify/images/shanchu@3x.png
0 → 100644
1.4 KB
js/classify/images/shijian@2x.png
0 → 100644
1.41 KB
js/classify/images/shijian@3x.png
0 → 100644
1.83 KB
@@ -41,6 +41,13 @@ const { | @@ -41,6 +41,13 @@ const { | ||
41 | GET_BRAND_RESOURCE_FOR_LIFESTYLE_SUCCESS, | 41 | GET_BRAND_RESOURCE_FOR_LIFESTYLE_SUCCESS, |
42 | GET_BRAND_RESOURCE_FOR_LIFESTYLE_FAILURE, | 42 | GET_BRAND_RESOURCE_FOR_LIFESTYLE_FAILURE, |
43 | 43 | ||
44 | + BRAND_SHOW_SEARCH, | ||
45 | + FETCH_BRAND_SEARCH_HISTORY, | ||
46 | + INSERT_BRAND_SEARCH_HISTORY, | ||
47 | + CLEAR_BRAND_SEARCH_HISTORY, | ||
48 | + BRAND_HOT_KEYWORD_REQUEST, | ||
49 | + BRAND_HOT_KEYWORD_SUCCESS, | ||
50 | + BRAND_HOT_KEYWORD_FAILURE, | ||
44 | 51 | ||
45 | } = require('../../constants/actionTypes').default; | 52 | } = require('../../constants/actionTypes').default; |
46 | 53 | ||
@@ -59,6 +66,13 @@ export function setChannelFilter(filter) { | @@ -59,6 +66,13 @@ export function setChannelFilter(filter) { | ||
59 | }; | 66 | }; |
60 | } | 67 | } |
61 | 68 | ||
69 | +export function setShowSearch(show) { | ||
70 | + return { | ||
71 | + type: BRAND_SHOW_SEARCH, | ||
72 | + payload: show | ||
73 | + }; | ||
74 | +} | ||
75 | + | ||
62 | export function getBrandListForBoyRequest() { | 76 | export function getBrandListForBoyRequest() { |
63 | return { | 77 | return { |
64 | type: GET_BRAND_LIST_FOR_BOY_REQUEST, | 78 | type: GET_BRAND_LIST_FOR_BOY_REQUEST, |
@@ -331,3 +345,130 @@ export function parseResourceResources(json) { | @@ -331,3 +345,130 @@ export function parseResourceResources(json) { | ||
331 | brandsText, | 345 | brandsText, |
332 | }; | 346 | }; |
333 | } | 347 | } |
348 | + | ||
349 | + | ||
350 | +export function searchHistory() { | ||
351 | + return (dispatch, getState) => { | ||
352 | + ReactNative.NativeModules.YH_ClassifyHelper.fetchSearchHistory() | ||
353 | + .then(data => { | ||
354 | + dispatch({ | ||
355 | + type: FETCH_BRAND_SEARCH_HISTORY, | ||
356 | + payload: parseSearchHistory(data) | ||
357 | + }); | ||
358 | + }) | ||
359 | + .catch(error => { | ||
360 | + | ||
361 | + }); | ||
362 | + }; | ||
363 | +} | ||
364 | + | ||
365 | +export function insertSearchHistory(keyword) { | ||
366 | + return (dispatch, getState) => { | ||
367 | + ReactNative.NativeModules.YH_ClassifyHelper.insertSearchHistory(keyword) | ||
368 | + .then(data => { | ||
369 | + dispatch({ | ||
370 | + type: INSERT_BRAND_SEARCH_HISTORY, | ||
371 | + payload: parseSearchHistory(data) | ||
372 | + }); | ||
373 | + }) | ||
374 | + .catch(error => { | ||
375 | + | ||
376 | + }); | ||
377 | + }; | ||
378 | +} | ||
379 | + | ||
380 | +export function clearSearchHistory() { | ||
381 | + return (dispatch, getState) => { | ||
382 | + ReactNative.NativeModules.YH_ClassifyHelper.clearSearchHistory() | ||
383 | + .then(data => { | ||
384 | + dispatch({ | ||
385 | + type: CLEAR_BRAND_SEARCH_HISTORY, | ||
386 | + payload: parseSearchHistory(data) | ||
387 | + }); | ||
388 | + }) | ||
389 | + .catch(error => { | ||
390 | + | ||
391 | + }); | ||
392 | + }; | ||
393 | +} | ||
394 | + | ||
395 | +function parseSearchHistory(data) { | ||
396 | + let list = []; | ||
397 | + data.map((item, i) => { | ||
398 | + list.push({keyword: item}); | ||
399 | + }); | ||
400 | + | ||
401 | + return list; | ||
402 | +} | ||
403 | + | ||
404 | +export function hotKeywordRequest() { | ||
405 | + return { | ||
406 | + type: BRAND_HOT_KEYWORD_REQUEST, | ||
407 | + }; | ||
408 | +} | ||
409 | + | ||
410 | +export function hotKeywordSuccess(json) { | ||
411 | + return { | ||
412 | + type: BRAND_HOT_KEYWORD_SUCCESS, | ||
413 | + payload: json | ||
414 | + }; | ||
415 | +} | ||
416 | + | ||
417 | +export function hotKeywordFailure(error) { | ||
418 | + return { | ||
419 | + type: BRAND_HOT_KEYWORD_FAILURE, | ||
420 | + payload: error | ||
421 | + }; | ||
422 | +} | ||
423 | + | ||
424 | + | ||
425 | +export function hotKeyword(reload=false) { | ||
426 | + return (dispatch, getState) => { | ||
427 | + let {app, brand} = getState(); | ||
428 | + let {search} = brand; | ||
429 | + let {isFetching} = search; | ||
430 | + if (reload) { | ||
431 | + // 强制刷新数据 | ||
432 | + | ||
433 | + } else { | ||
434 | + if (isFetching) { | ||
435 | + return; | ||
436 | + } | ||
437 | + } | ||
438 | + | ||
439 | + let fetchHotKeyword = (uid) => { | ||
440 | + dispatch(hotKeywordRequest()); | ||
441 | + return new BrandService(app.host).fetchHotKeyword(uid) | ||
442 | + .then(json => { | ||
443 | + let payload = parseHotKeyword(json); | ||
444 | + dispatch(hotKeywordSuccess(payload)); | ||
445 | + }) | ||
446 | + .catch(error => { | ||
447 | + dispatch(hotKeywordFailure(error)); | ||
448 | + }); | ||
449 | + } | ||
450 | + | ||
451 | + ReactNative.NativeModules.YH_CommonHelper.uid() | ||
452 | + .then(uid => { | ||
453 | + fetchHotKeyword(uid); | ||
454 | + }) | ||
455 | + .catch(error => { | ||
456 | + fetchHotKeyword(0); | ||
457 | + }); | ||
458 | + }; | ||
459 | +} | ||
460 | + | ||
461 | +function parseHotKeyword(json) { | ||
462 | + let list = []; | ||
463 | + Array.isArray(json) && json.map((item, i) => { | ||
464 | + let brandName = item.brandName ? item.brandName : ''; | ||
465 | + let keyword = brandName; | ||
466 | + let brandDomain = item.brandDomain ? item.brandDomain : ''; | ||
467 | + let brandId = item.brandId ? item.brandId : ''; | ||
468 | + list.push({keyword, brandName, brandDomain, brandId}); | ||
469 | + }); | ||
470 | + | ||
471 | + return { | ||
472 | + list, | ||
473 | + }; | ||
474 | +} |
@@ -53,6 +53,13 @@ let InitialState = Record({ | @@ -53,6 +53,13 @@ let InitialState = Record({ | ||
53 | brandsText: List(), | 53 | brandsText: List(), |
54 | hasSuccess: false, | 54 | hasSuccess: false, |
55 | })), | 55 | })), |
56 | + showSearch: false, | ||
57 | + search: new (Record({ | ||
58 | + history: List(), | ||
59 | + isFetching: false, | ||
60 | + error: null, | ||
61 | + hot: List(), | ||
62 | + })), | ||
56 | }); | 63 | }); |
57 | 64 | ||
58 | export default InitialState; | 65 | export default InitialState; |
@@ -41,24 +41,33 @@ const { | @@ -41,24 +41,33 @@ const { | ||
41 | GET_BRAND_RESOURCE_FOR_LIFESTYLE_SUCCESS, | 41 | GET_BRAND_RESOURCE_FOR_LIFESTYLE_SUCCESS, |
42 | GET_BRAND_RESOURCE_FOR_LIFESTYLE_FAILURE, | 42 | GET_BRAND_RESOURCE_FOR_LIFESTYLE_FAILURE, |
43 | 43 | ||
44 | + BRAND_SHOW_SEARCH, | ||
45 | + FETCH_BRAND_SEARCH_HISTORY, | ||
46 | + INSERT_BRAND_SEARCH_HISTORY, | ||
47 | + CLEAR_BRAND_SEARCH_HISTORY, | ||
48 | + BRAND_HOT_KEYWORD_REQUEST, | ||
49 | + BRAND_HOT_KEYWORD_SUCCESS, | ||
50 | + BRAND_HOT_KEYWORD_FAILURE, | ||
51 | + | ||
44 | } = require('../../constants/actionTypes').default; | 52 | } = require('../../constants/actionTypes').default; |
45 | 53 | ||
46 | const initialState = new InitialState; | 54 | const initialState = new InitialState; |
47 | 55 | ||
48 | export default function brandReducer(state=initialState, action) { | 56 | export default function brandReducer(state=initialState, action) { |
49 | switch(action.type) { | 57 | switch(action.type) { |
50 | - case SET_TYPE: { | ||
51 | - return state.set('type', action.payload); | ||
52 | - } | ||
53 | 58 | ||
54 | - case SET_BRAND_FILTER:{ | 59 | + case SET_BRAND_FILTER: { |
55 | return state.set('brandFliter', action.payload); | 60 | return state.set('brandFliter', action.payload); |
56 | } | 61 | } |
57 | 62 | ||
58 | - case SET_CHANNEL_FILTER:{ | 63 | + case SET_CHANNEL_FILTER: { |
59 | return state.set('channelFliter', action.payload); | 64 | return state.set('channelFliter', action.payload); |
60 | } | 65 | } |
61 | 66 | ||
67 | + case BRAND_SHOW_SEARCH: { | ||
68 | + return state.set('showSearch', action.payload); | ||
69 | + } | ||
70 | + | ||
62 | case GET_BRAND_LIST_FOR_BOY_REQUEST: | 71 | case GET_BRAND_LIST_FOR_BOY_REQUEST: |
63 | { | 72 | { |
64 | return state; | 73 | return state; |
@@ -232,6 +241,28 @@ export default function brandReducer(state=initialState, action) { | @@ -232,6 +241,28 @@ export default function brandReducer(state=initialState, action) { | ||
232 | return state.setIn(['reourceForLifeStyle', 'hasSuccess'], false); | 241 | return state.setIn(['reourceForLifeStyle', 'hasSuccess'], false); |
233 | } | 242 | } |
234 | 243 | ||
244 | + case FETCH_BRAND_SEARCH_HISTORY: | ||
245 | + case INSERT_BRAND_SEARCH_HISTORY: | ||
246 | + case CLEAR_BRAND_SEARCH_HISTORY: { | ||
247 | + return state.setIn(['search', 'history'], Immutable.fromJS(action.payload)); | ||
248 | + } | ||
249 | + | ||
250 | + case BRAND_HOT_KEYWORD_REQUEST: { | ||
251 | + return state.setIn(['search', 'isFetching'], true) | ||
252 | + .setIn(['search', 'error'], null); | ||
253 | + } | ||
254 | + | ||
255 | + case BRAND_HOT_KEYWORD_SUCCESS: { | ||
256 | + let {list} = action.payload; | ||
257 | + return state.setIn(['search', 'isFetching'], false) | ||
258 | + .setIn(['search', 'error'], null) | ||
259 | + .setIn(['search', 'hot'], Immutable.fromJS(list)); | ||
260 | + } | ||
261 | + | ||
262 | + case BRAND_HOT_KEYWORD_FAILURE: { | ||
263 | + return state.setIn(['search', 'isFetching'], false) | ||
264 | + .setIn(['search', 'error'], action.payload); | ||
265 | + } | ||
235 | } | 266 | } |
236 | 267 | ||
237 | return state; | 268 | return state; |
@@ -45,4 +45,20 @@ export default class BrandService { | @@ -45,4 +45,20 @@ export default class BrandService { | ||
45 | }); | 45 | }); |
46 | } | 46 | } |
47 | 47 | ||
48 | + async fetchHotKeyword(uid, sourcePage='iFP_SearchProList') { | ||
49 | + return await this.api.get({ | ||
50 | + url: '', | ||
51 | + body: { | ||
52 | + method: 'app.search.hotBrands', | ||
53 | + uid, | ||
54 | + sourcePage, | ||
55 | + } | ||
56 | + }) | ||
57 | + .then((json) => { | ||
58 | + return json; | ||
59 | + }) | ||
60 | + .catch((error) => { | ||
61 | + throw(error); | ||
62 | + }); | ||
63 | + } | ||
48 | } | 64 | } |
-
Please register or login to post a comment