Merge branch 'guang' into 5.4
Conflicts: js/plustar/Plustar.js
Showing
25 changed files
with
447 additions
and
202 deletions
js/common/utils/urlHandler.js
0 → 100644
1 | + | ||
2 | +export function urlAddParamOfType(url, type='0') { | ||
3 | + if (!type) { | ||
4 | + return url; | ||
5 | + } | ||
6 | + | ||
7 | + let strs= new Array(); | ||
8 | + let dataString = ''; | ||
9 | + if (url.indexOf('yohobuy=') !== -1) { | ||
10 | + strs = url.split("yohobuy="); | ||
11 | + if (strs.length == 1) { | ||
12 | + dataString = strs[0]; | ||
13 | + } else { | ||
14 | + dataString = strs[1]; | ||
15 | + } | ||
16 | + } else { | ||
17 | + strs = url.split("yohobuy="); | ||
18 | + if (strs.length == 1) { | ||
19 | + dataString = strs[0]; | ||
20 | + } else { | ||
21 | + dataString = strs[1]; | ||
22 | + } | ||
23 | + } | ||
24 | + var obj = JSON.parse(dataString); //由JSON字符串转换为JSON对象 | ||
25 | + obj.params.type = type + ''; // params增加type参数 | ||
26 | + let totalUrlWithType = "yohobuy=" + JSON.stringify(obj); | ||
27 | + if (strs.length > 1) { | ||
28 | + totalUrlWithType = strs[0] + totalUrlWithType; | ||
29 | + } | ||
30 | + | ||
31 | + return totalUrlWithType; | ||
32 | +} |
@@ -12,7 +12,7 @@ import Header from './Header'; | @@ -12,7 +12,7 @@ import Header from './Header'; | ||
12 | import MoreLink from './MoreLink'; | 12 | import MoreLink from './MoreLink'; |
13 | import GoodsGroupHeader from './GoodsGroupHeader'; | 13 | import GoodsGroupHeader from './GoodsGroupHeader'; |
14 | import GoodsGroupList from './GoodsGroupList'; | 14 | import GoodsGroupList from './GoodsGroupList'; |
15 | -import Small_pic from './Small_pic'; | 15 | +import SmallPic from './SmallPic'; |
16 | import Weixin from './Weixin'; | 16 | import Weixin from './Weixin'; |
17 | import LoadingIndicator from '../../../common/components/LoadingIndicator'; | 17 | import LoadingIndicator from '../../../common/components/LoadingIndicator'; |
18 | 18 | ||
@@ -85,7 +85,7 @@ export default class Detail extends Component { | @@ -85,7 +85,7 @@ export default class Detail extends Component { | ||
85 | ); | 85 | ); |
86 | }else if (template_name == 'small_pic') { | 86 | }else if (template_name == 'small_pic') { |
87 | return ( | 87 | return ( |
88 | - <Small_pic resource={rowData}/> | 88 | + <SmallPic resource={rowData}/> |
89 | ); | 89 | ); |
90 | }else if (template_name == 'goods_group') { | 90 | }else if (template_name == 'goods_group') { |
91 | let {resource} = this.props; | 91 | let {resource} = this.props; |
@@ -95,7 +95,7 @@ export default class Detail extends Component { | @@ -95,7 +95,7 @@ export default class Detail extends Component { | ||
95 | 95 | ||
96 | return ( | 96 | return ( |
97 | <View style={styles.GoodsGroupHeader} onLayout={this.onLayout.bind(this, rowID)}> | 97 | <View style={styles.GoodsGroupHeader} onLayout={this.onLayout.bind(this, rowID)}> |
98 | - <GoodsGroupHeader resource={{rowData,goods_group_Filter}} onPressFilter= {this.props.onPressFilter} scrollTo={this.scrollTo}/> | 98 | + <GoodsGroupHeader resource={rowData} goods_group_Filter={goods_group_Filter} onPressFilter= {this.props.onPressFilter} scrollTo={this.scrollTo}/> |
99 | <GoodsGroupList resource={list} onPressProduct={this.props.onPressProduct}/> | 99 | <GoodsGroupList resource={list} onPressProduct={this.props.onPressProduct}/> |
100 | </View> | 100 | </View> |
101 | ); | 101 | ); |
@@ -114,11 +114,11 @@ export default class Detail extends Component { | @@ -114,11 +114,11 @@ export default class Detail extends Component { | ||
114 | ); | 114 | ); |
115 | }else if (sectionID == 'detailBrand') { | 115 | }else if (sectionID == 'detailBrand') { |
116 | return ( | 116 | return ( |
117 | - <DetailBrand resource={rowData}/> | 117 | + <DetailBrand resource={rowData} onPressBrand={this.props.onPressBrand}/> |
118 | ); | 118 | ); |
119 | }else if (sectionID == 'detailOtherArticle') { | 119 | }else if (sectionID == 'detailOtherArticle') { |
120 | return ( | 120 | return ( |
121 | - <OtherArticle resource={rowData}/> | 121 | + <OtherArticle resource={rowData} onPressArticle={this.props.onPressArticle}/> |
122 | ); | 122 | ); |
123 | } else if (sectionID == 'tags'){ | 123 | } else if (sectionID == 'tags'){ |
124 | return ( | 124 | return ( |
@@ -150,11 +150,11 @@ export default class Detail extends Component { | @@ -150,11 +150,11 @@ export default class Detail extends Component { | ||
150 | detailOtherArticle: [otherArticle], | 150 | detailOtherArticle: [otherArticle], |
151 | }; | 151 | }; |
152 | 152 | ||
153 | - let isFetching = content.isFetching; | 153 | + let isFetching = content.isFetching || article.isFetching || author.isFetching; |
154 | 154 | ||
155 | return ( | 155 | return ( |
156 | <View style={styles.container}> | 156 | <View style={styles.container}> |
157 | - <ListView | 157 | + {!isFetching?<ListView |
158 | ref={(ref)=>this.listView=ref} | 158 | ref={(ref)=>this.listView=ref} |
159 | contentContainerStyle={styles.contentContainer} | 159 | contentContainerStyle={styles.contentContainer} |
160 | enableEmptySections={true} | 160 | enableEmptySections={true} |
@@ -162,7 +162,7 @@ export default class Detail extends Component { | @@ -162,7 +162,7 @@ export default class Detail extends Component { | ||
162 | dataSource={this.dataSource.cloneWithRowsAndSections(dataSource)} | 162 | dataSource={this.dataSource.cloneWithRowsAndSections(dataSource)} |
163 | renderRow={this.renderRow} | 163 | renderRow={this.renderRow} |
164 | renderHeader={this.renderHeader} | 164 | renderHeader={this.renderHeader} |
165 | - /> | 165 | + />:null} |
166 | <LoadingIndicator | 166 | <LoadingIndicator |
167 | isVisible={isFetching} | 167 | isVisible={isFetching} |
168 | /> | 168 | /> |
@@ -33,20 +33,20 @@ export default class DetailBrand extends React.Component { | @@ -33,20 +33,20 @@ export default class DetailBrand extends React.Component { | ||
33 | } | 33 | } |
34 | } | 34 | } |
35 | _renderRow(rowData, sectionID, rowID) { | 35 | _renderRow(rowData, sectionID, rowID) { |
36 | + let {url} = rowData; | ||
36 | if ((rowID+1)%4 == 0) { | 37 | if ((rowID+1)%4 == 0) { |
37 | return ( | 38 | return ( |
38 | - <View style={styles.lastCell}> | ||
39 | - <Image style={styles.cellImg} source={{uri:rowData.thumb}}/> | ||
40 | - <Text style={styles.cellTitle}>{rowData.name}</Text> | ||
41 | - </View> | 39 | + <TouchableOpacity style={styles.lastCell} onPress={()=>{this.props.onPressBrand&&this.props.onPressBrand(url)}}> |
40 | + <Image style={styles.cellImg} source={{uri:rowData.thumb}}/> | ||
41 | + <Text style={styles.cellTitle}>{rowData.name}</Text> | ||
42 | + </TouchableOpacity> | ||
42 | ); | 43 | ); |
43 | } else { | 44 | } else { |
44 | return ( | 45 | return ( |
45 | - | ||
46 | - <View style={styles.cell}> | ||
47 | - <Image style={styles.cellImg} source={{uri:rowData.thumb}}/> | ||
48 | - <Text style={styles.cellTitle}>{rowData.name}</Text> | ||
49 | - </View> | 46 | + <TouchableOpacity style={styles.cell} onPress={()=>{this.props.onPressBrand&&this.props.onPressBrand(url)}}> |
47 | + <Image style={styles.cellImg} source={{uri:rowData.thumb}}/> | ||
48 | + <Text style={styles.cellTitle}>{rowData.name}</Text> | ||
49 | + </TouchableOpacity> | ||
50 | ); | 50 | ); |
51 | } | 51 | } |
52 | } | 52 | } |
@@ -69,7 +69,6 @@ export default class DetailBrand extends React.Component { | @@ -69,7 +69,6 @@ export default class DetailBrand extends React.Component { | ||
69 | renderRow={this._renderRow} | 69 | renderRow={this._renderRow} |
70 | scrollEnabled={false} | 70 | scrollEnabled={false} |
71 | scrollsToTop={false} | 71 | scrollsToTop={false} |
72 | - horizontal={true} | ||
73 | /> | 72 | /> |
74 | </View> | 73 | </View> |
75 | ); | 74 | ); |
@@ -134,7 +133,7 @@ let styles = StyleSheet.create({ | @@ -134,7 +133,7 @@ let styles = StyleSheet.create({ | ||
134 | justifyContent: 'space-between', | 133 | justifyContent: 'space-between', |
135 | }, | 134 | }, |
136 | cellImg: { | 135 | cellImg: { |
137 | - backgroundColor: 'gray', | 136 | + backgroundColor: 'white', |
138 | marginLeft: (cellWidth-55)/2, | 137 | marginLeft: (cellWidth-55)/2, |
139 | width: 55, | 138 | width: 55, |
140 | height: 55, | 139 | height: 55, |
@@ -97,12 +97,13 @@ export default class DetailText extends React.Component { | @@ -97,12 +97,13 @@ export default class DetailText extends React.Component { | ||
97 | let template_name = resource.get('data'); | 97 | let template_name = resource.get('data'); |
98 | let text = template_name.get('text'); | 98 | let text = template_name.get('text'); |
99 | 99 | ||
100 | - text = '<html><body>' + text + '</body></html>'; | 100 | + text = '<html><style type="text/css">img {max-width: 100%;}</style><body>' + text + '</body></html>' |
101 | 101 | ||
102 | let hasLink = false; | 102 | let hasLink = false; |
103 | if (text.indexOf('<a href=') >= 0) { | 103 | if (text.indexOf('<a href=') >= 0) { |
104 | hasLink = true; | 104 | hasLink = true; |
105 | } | 105 | } |
106 | + | ||
106 | return ( | 107 | return ( |
107 | <View style={{width: width,height: this.state.realContentHeight,backgroundColor: 'white'}}> | 108 | <View style={{width: width,height: this.state.realContentHeight,backgroundColor: 'white'}}> |
108 | <WebView style={{width: width-40,height: this.state.realContentHeight,backgroundColor: 'white',marginRight: 20,marginLeft: 20}} | 109 | <WebView style={{width: width-40,height: this.state.realContentHeight,backgroundColor: 'white',marginRight: 20,marginLeft: 20}} |
@@ -125,8 +126,5 @@ export default class DetailText extends React.Component { | @@ -125,8 +126,5 @@ export default class DetailText extends React.Component { | ||
125 | let {width, height} = Dimensions.get('window'); | 126 | let {width, height} = Dimensions.get('window'); |
126 | 127 | ||
127 | let styles = StyleSheet.create({ | 128 | let styles = StyleSheet.create({ |
128 | - webview_style: { | ||
129 | - backgroundColor: 'red', | ||
130 | - height: 100, | ||
131 | - }, | 129 | + |
132 | }); | 130 | }); |
@@ -62,16 +62,15 @@ export default class GoodsGroupHeader extends React.Component { | @@ -62,16 +62,15 @@ export default class GoodsGroupHeader extends React.Component { | ||
62 | } | 62 | } |
63 | 63 | ||
64 | render() { | 64 | render() { |
65 | - let {resource} = this.props; | ||
66 | - let rowData = resource?resource.rowData:null; | ||
67 | - this.selectedIndex = resource?resource.goods_group_Filter:0; | 65 | + let {resource,goods_group_Filter} = this.props; |
66 | + this.selectedIndex = goods_group_Filter; | ||
68 | 67 | ||
69 | - let list = rowData.get('data'); | 68 | + let list = resource?resource.get('data'):null; |
70 | if (!list || list.size == 0) { | 69 | if (!list || list.size == 0) { |
71 | return null; | 70 | return null; |
72 | } | 71 | } |
73 | 72 | ||
74 | - let n = ((Math.ceil(this.selectedIndex)+1) *2 - 1)*10 + (itemW-20) * ((Math.ceil(this.selectedIndex)+1) - 0.5) - 8; | 73 | + let arrow_up_offset = ((Math.ceil(this.selectedIndex)+1) *2 - 1)*10 + (itemW-20) * ((Math.ceil(this.selectedIndex)+1) - 0.5) - 8; |
75 | 74 | ||
76 | return ( | 75 | return ( |
77 | <View style={[styles.container]}> | 76 | <View style={[styles.container]}> |
@@ -86,8 +85,8 @@ export default class GoodsGroupHeader extends React.Component { | @@ -86,8 +85,8 @@ export default class GoodsGroupHeader extends React.Component { | ||
86 | <View style={{width: width,height: 10,backgroundColor: 'white',}}> | 85 | <View style={{width: width,height: 10,backgroundColor: 'white',}}> |
87 | </View> | 86 | </View> |
88 | <View style={{width: width,height: 9,backgroundColor: 'white'}}> | 87 | <View style={{width: width,height: 9,backgroundColor: 'white'}}> |
89 | - <View style={{position: 'absolute',marginTop:8,width: width,height: 1,backgroundColor: '#e0e0e0'}}/> | ||
90 | - <Image source={require('../../image/global_arrow_up.png')} style={{marginLeft: n,width: 16,height: 9,backgroundColor: 'transparent'}}> | 88 | + <View style={styles.line}/> |
89 | + <Image source={require('../../image/global_arrow_up.png')} style={{marginLeft: arrow_up_offset,width: 16,height: 9,backgroundColor: 'transparent'}}> | ||
91 | </Image> | 90 | </Image> |
92 | </View> | 91 | </View> |
93 | </View> | 92 | </View> |
@@ -116,4 +115,11 @@ let styles = StyleSheet.create({ | @@ -116,4 +115,11 @@ let styles = StyleSheet.create({ | ||
116 | height: itemH + 20, | 115 | height: itemH + 20, |
117 | backgroundColor:'white', | 116 | backgroundColor:'white', |
118 | }, | 117 | }, |
118 | + line: { | ||
119 | + position: 'absolute', | ||
120 | + marginTop:8, | ||
121 | + width: width, | ||
122 | + height: 1, | ||
123 | + backgroundColor: '#e0e0e0', | ||
124 | + } | ||
119 | }); | 125 | }); |
@@ -48,19 +48,21 @@ export default class Header extends React.Component { | @@ -48,19 +48,21 @@ export default class Header extends React.Component { | ||
48 | 48 | ||
49 | let author_data = author.get('data'); | 49 | let author_data = author.get('data'); |
50 | let article_data = article.get('data'); | 50 | let article_data = article.get('data'); |
51 | + let hasData = true; | ||
51 | if (!author_data || !article_data) { | 52 | if (!author_data || !article_data) { |
52 | - return null; | 53 | + hasData = false; |
53 | } | 54 | } |
54 | 55 | ||
55 | - let author_desc = author_data.get('author_desc'); | ||
56 | - let author_avatar = author_data.get('avatar'); | ||
57 | - let author_name = author_data.get('name'); | ||
58 | - let author_url = author_data.get('url'); | 56 | + let author_desc = hasData?author_data.get('author_desc'):''; |
57 | + let author_avatar = hasData?author_data.get('avatar'):''; | ||
58 | + let author_name = hasData?author_data.get('name'):''; | ||
59 | + let author_url = hasData?author_data.get('url'):''; | ||
59 | let num = this.getStrSize(author_desc); | 60 | let num = this.getStrSize(author_desc); |
60 | 61 | ||
61 | - let article_title = article_data.get('article_title'); | ||
62 | - let pageViews = article_data.get('pageViews'); | ||
63 | - let publishTime = article_data.get('publishTime'); | 62 | + let article_title = hasData?article_data.get('article_title'):''; |
63 | + let pageViews = hasData?article_data.get('pageViews'):'99999'; | ||
64 | + let publishTime = hasData?article_data.get('publishTime'):'12月12日 12:00'; | ||
65 | + | ||
64 | return( | 66 | return( |
65 | <View style={styles.contentContainer}> | 67 | <View style={styles.contentContainer}> |
66 | <TouchableOpacity activeOpacity={0.5} onPress={() => { | 68 | <TouchableOpacity activeOpacity={0.5} onPress={() => { |
@@ -69,7 +71,7 @@ export default class Header extends React.Component { | @@ -69,7 +71,7 @@ export default class Header extends React.Component { | ||
69 | <View style={styles.header}> | 71 | <View style={styles.header}> |
70 | <Image source={{uri: author_avatar}} style={styles.thumb}></Image> | 72 | <Image source={{uri: author_avatar}} style={styles.thumb}></Image> |
71 | <Text style={styles.name}>{author_name}</Text> | 73 | <Text style={styles.name}>{author_name}</Text> |
72 | - {(num > 25)?null:<Text style={styles.desc}>{author_desc}</Text>} | 74 | + {(num > 25)?null:<Text style={styles.desc} numberOfLines={1}>{author_desc}</Text>} |
73 | </View> | 75 | </View> |
74 | </TouchableOpacity> | 76 | </TouchableOpacity> |
75 | {(num > 25)?<Text style={styles.desc2}>{author_desc}</Text>:null} | 77 | {(num > 25)?<Text style={styles.desc2}>{author_desc}</Text>:null} |
@@ -117,9 +119,9 @@ let styles = StyleSheet.create({ | @@ -117,9 +119,9 @@ let styles = StyleSheet.create({ | ||
117 | desc2: { | 119 | desc2: { |
118 | marginLeft: 20, | 120 | marginLeft: 20, |
119 | color: '#e5e5e5', | 121 | color: '#e5e5e5', |
120 | - height: 40, | ||
121 | width: width, | 122 | width: width, |
122 | fontSize: 15, | 123 | fontSize: 15, |
124 | + minHeight: 40, | ||
123 | }, | 125 | }, |
124 | article_title: { | 126 | article_title: { |
125 | marginLeft: 20, | 127 | marginLeft: 20, |
@@ -21,7 +21,7 @@ export default class OtherArticle extends React.Component { | @@ -21,7 +21,7 @@ export default class OtherArticle extends React.Component { | ||
21 | super(props); | 21 | super(props); |
22 | this._renderRow = this._renderRow.bind(this); | 22 | this._renderRow = this._renderRow.bind(this); |
23 | this.dataSource = new ListView.DataSource({ | 23 | this.dataSource = new ListView.DataSource({ |
24 | - rowHasChanged: (r1, r2) => r1.key != r2.key, | 24 | + rowHasChanged: (r1, r2) => !Immutable.is(r1, r2), |
25 | }); | 25 | }); |
26 | } | 26 | } |
27 | 27 | ||
@@ -34,27 +34,26 @@ export default class OtherArticle extends React.Component { | @@ -34,27 +34,26 @@ export default class OtherArticle extends React.Component { | ||
34 | } | 34 | } |
35 | 35 | ||
36 | _renderRow(rowData, sectionID, rowID) { | 36 | _renderRow(rowData, sectionID, rowID) { |
37 | + let {url} = rowData; | ||
37 | return ( | 38 | return ( |
38 | - <View style={styles.cell}> | ||
39 | - <Image style={styles.cellImage} source={{uri:rowData.thumb}}/> | 39 | + <TouchableOpacity style={styles.cell} onPress={()=>{this.props.onPressArticle&&this.props.onPressArticle(rowData.get('url'))}}> |
40 | + <Image style={styles.cellImage} source={{uri:rowData.get('thumb')}}/> | ||
40 | <View style={styles.cellContent}> | 41 | <View style={styles.cellContent}> |
41 | <Text style={styles.cellTitle} numberOfLines={2}> | 42 | <Text style={styles.cellTitle} numberOfLines={2}> |
42 | - {rowData.title} | 43 | + {rowData.get('title')} |
43 | </Text> | 44 | </Text> |
44 | <View style={styles.bottomContent}> | 45 | <View style={styles.bottomContent}> |
45 | <Image source={require('../../image/time_icon.png')} style={styles.clockIcon}/> | 46 | <Image source={require('../../image/time_icon.png')} style={styles.clockIcon}/> |
46 | - <Text style={styles.timeText}>{rowData.publishTime}</Text> | 47 | + <Text style={styles.timeText}>{rowData.get('publishTime')}</Text> |
47 | </View> | 48 | </View> |
48 | </View> | 49 | </View> |
49 | - </View> | 50 | + </TouchableOpacity> |
50 | ); | 51 | ); |
51 | } | 52 | } |
52 | 53 | ||
53 | render() { | 54 | render() { |
54 | - let {data} = this.props.resource.toJS(); | ||
55 | - if (!data.length) { | ||
56 | - return null; | ||
57 | - } | 55 | + let data = this.props.resource.get('data').toArray(); |
56 | + | ||
58 | return( | 57 | return( |
59 | <View style={styles.container}> | 58 | <View style={styles.container}> |
60 | <View style={styles.headerView}> | 59 | <View style={styles.headerView}> |
@@ -63,7 +62,7 @@ export default class OtherArticle extends React.Component { | @@ -63,7 +62,7 @@ export default class OtherArticle extends React.Component { | ||
63 | <ListView | 62 | <ListView |
64 | style={styles.articleContainer} | 63 | style={styles.articleContainer} |
65 | enableEmptySections={true} | 64 | enableEmptySections={true} |
66 | - initialListSize={data.length} | 65 | + initialListSize={data.size} |
67 | dataSource={this.dataSource.cloneWithRows(data)} | 66 | dataSource={this.dataSource.cloneWithRows(data)} |
68 | renderRow={this._renderRow} | 67 | renderRow={this._renderRow} |
69 | scrollEnabled={false} | 68 | scrollEnabled={false} |
@@ -38,7 +38,9 @@ export default class SingleImage extends React.Component { | @@ -38,7 +38,9 @@ export default class SingleImage extends React.Component { | ||
38 | let template_name = resource.get('data'); | 38 | let template_name = resource.get('data'); |
39 | let src = template_name.get('src'); | 39 | let src = template_name.get('src'); |
40 | Image.getSize(src, (width, height) => { | 40 | Image.getSize(src, (width, height) => { |
41 | - this.setState({width, height}); | 41 | + if (this.imageView) { |
42 | + this.setState({width, height}); | ||
43 | + } | ||
42 | }); | 44 | }); |
43 | } | 45 | } |
44 | 46 | ||
@@ -47,19 +49,17 @@ export default class SingleImage extends React.Component { | @@ -47,19 +49,17 @@ export default class SingleImage extends React.Component { | ||
47 | let template_name = resource.get('data'); | 49 | let template_name = resource.get('data'); |
48 | let src = template_name.get('src'); | 50 | let src = template_name.get('src'); |
49 | return ( | 51 | return ( |
50 | - <View style={{width: Dimensions.get('window').width,height: (this.state.height/this.state.width)*Dimensions.get('window').width}}> | ||
51 | - <Image | ||
52 | - source={{uri: src}} | ||
53 | - style={{width: Dimensions.get('window').width,height: (this.state.height/this.state.width)*Dimensions.get('window').width}} | ||
54 | - > | ||
55 | - </Image> | ||
56 | - </View> | 52 | + <Image |
53 | + ref={(ref)=>this.imageView=ref} | ||
54 | + source={{uri: src}} | ||
55 | + style={{width: screenWidth,height: (this.state.height/this.state.width)*screenWidth}} | ||
56 | + /> | ||
57 | ); | 57 | ); |
58 | - return null; | ||
59 | } | 58 | } |
60 | }; | 59 | }; |
61 | 60 | ||
62 | - | 61 | +let screenWidth = Dimensions.get('window').width; |
62 | +let imageView = null; | ||
63 | let styles = StyleSheet.create({ | 63 | let styles = StyleSheet.create({ |
64 | 64 | ||
65 | }); | 65 | }); |
@@ -16,7 +16,7 @@ const { | @@ -16,7 +16,7 @@ const { | ||
16 | } = ReactNative; | 16 | } = ReactNative; |
17 | 17 | ||
18 | 18 | ||
19 | -export default class Small_pic extends React.Component { | 19 | +export default class SmallPic extends React.Component { |
20 | constructor(props) { | 20 | constructor(props) { |
21 | super(props); | 21 | super(props); |
22 | this.state = { | 22 | this.state = { |
@@ -24,27 +24,33 @@ export default class Tags extends React.Component { | @@ -24,27 +24,33 @@ export default class Tags extends React.Component { | ||
24 | 24 | ||
25 | render() { | 25 | render() { |
26 | let {resource} = this.props; | 26 | let {resource} = this.props; |
27 | - let data = resource.get('data')?resource.get('data').toJS():null; | ||
28 | - let tags = data?data.tags:[]; | 27 | + let data = resource.get('data') ? resource.get('data').toJS() : null; |
28 | + let tags = data ? data.tags : []; | ||
29 | 29 | ||
30 | - if (!tags||!tags.length) { | 30 | + if (!tags || !tags.length) { |
31 | return null; | 31 | return null; |
32 | } | 32 | } |
33 | - return( | 33 | + |
34 | + return ( | ||
34 | <View style={styles.container}> | 35 | <View style={styles.container}> |
35 | <Image style={styles.tagImage}/> | 36 | <Image style={styles.tagImage}/> |
36 | <View style={styles.tagContainer}> | 37 | <View style={styles.tagContainer}> |
37 | - {tags.map( | ||
38 | - (value, i) => { | ||
39 | - return ( | ||
40 | - <Text style={styles.tag} onPress={()=>{this.props.onPressTag&&this.props.onPressTag(value.url)}}>{value.name}</Text> | ||
41 | - ); | ||
42 | - } | ||
43 | - )} | 38 | + {tags.map((value, i) => { |
39 | + return ( | ||
40 | + <Text | ||
41 | + key={i} | ||
42 | + style={styles.tag} | ||
43 | + onPress={()=>{ | ||
44 | + this.props.onPressTag && this.props.onPressTag(value.url) | ||
45 | + }} | ||
46 | + > | ||
47 | + {value.name} | ||
48 | + </Text> | ||
49 | + ); | ||
50 | + })} | ||
44 | </View> | 51 | </View> |
45 | </View> | 52 | </View> |
46 | ); | 53 | ); |
47 | - return null; | ||
48 | } | 54 | } |
49 | }; | 55 | }; |
50 | 56 |
@@ -22,13 +22,10 @@ export default class Weixin extends React.Component { | @@ -22,13 +22,10 @@ export default class Weixin extends React.Component { | ||
22 | super(props); | 22 | super(props); |
23 | } | 23 | } |
24 | 24 | ||
25 | - componentDidMount() { | ||
26 | - } | ||
27 | - | ||
28 | render() { | 25 | render() { |
29 | let {resource} = this.props; | 26 | let {resource} = this.props; |
30 | 27 | ||
31 | - let data = resource.get('data')?resource.get('data').toJS():null; | 28 | + let data = resource.get('data') ? resource.get('data').toJS() : null; |
32 | if (!data) { | 29 | if (!data) { |
33 | return null; | 30 | return null; |
34 | } | 31 | } |
@@ -15,6 +15,7 @@ import ReactNative, { | @@ -15,6 +15,7 @@ import ReactNative, { | ||
15 | import HeaderCell from './HeaderCell'; | 15 | import HeaderCell from './HeaderCell'; |
16 | import ListCell from './ListCell'; | 16 | import ListCell from './ListCell'; |
17 | import LoadMoreIndicator from '../../../common/components/LoadMoreIndicator'; | 17 | import LoadMoreIndicator from '../../../common/components/LoadMoreIndicator'; |
18 | +import LoadingIndicator from '../../../common/components/LoadingIndicator'; | ||
18 | 19 | ||
19 | 20 | ||
20 | export default class List extends Component { | 21 | export default class List extends Component { |
@@ -48,15 +49,27 @@ export default class List extends Component { | @@ -48,15 +49,27 @@ export default class List extends Component { | ||
48 | } | 49 | } |
49 | 50 | ||
50 | renderHeader() { | 51 | renderHeader() { |
52 | + if (this.props.data.type == 'editor') { | ||
53 | + return( | ||
54 | + <HeaderCell resource={this.state.author}/> | ||
55 | + ); | ||
56 | + } else { | ||
57 | + return null; | ||
58 | + } | ||
51 | 59 | ||
52 | - return( | ||
53 | - <HeaderCell resource={this.state.author}/> | ||
54 | - ); | ||
55 | } | 60 | } |
56 | 61 | ||
57 | renderRow(rowData,sectionID,rowID) { | 62 | renderRow(rowData,sectionID,rowID) { |
63 | + let type = this.props.data.get('type'); | ||
58 | return( | 64 | return( |
59 | - <ListCell resource={rowData}/> | 65 | + <ListCell |
66 | + resource={rowData} | ||
67 | + type={type} | ||
68 | + onPressCell={this.props.onPressCell} | ||
69 | + onPressShare={this.props.onPressShare} | ||
70 | + onPressLike={this.props.onPressLike} | ||
71 | + onPressHeader={this.props.onPressHeader} | ||
72 | + /> | ||
60 | ); | 73 | ); |
61 | } | 74 | } |
62 | 75 | ||
@@ -90,6 +103,9 @@ export default class List extends Component { | @@ -90,6 +103,9 @@ export default class List extends Component { | ||
90 | } | 103 | } |
91 | }} | 104 | }} |
92 | /> | 105 | /> |
106 | + <LoadingIndicator | ||
107 | + isVisible={isFetching} | ||
108 | + /> | ||
93 | </View> | 109 | </View> |
94 | ); | 110 | ); |
95 | } | 111 | } |
@@ -38,12 +38,16 @@ export default class List extends Component { | @@ -38,12 +38,16 @@ export default class List extends Component { | ||
38 | } | 38 | } |
39 | 39 | ||
40 | _renderHeader() { | 40 | _renderHeader() { |
41 | - return null; | 41 | + if (this.props.type == 'editor') { |
42 | + return null; | ||
43 | + } | ||
42 | return ( | 44 | return ( |
45 | + <TouchableOpacity onPress={()=>{this.props.onPressHeader&&this.props.onPressHeader(this.props.resource.author.url)}}> | ||
43 | <View style={styles.headerContainer}> | 46 | <View style={styles.headerContainer}> |
44 | <Image style={styles.avatar} source={{uri:this.props.resource.author.avatar}}/> | 47 | <Image style={styles.avatar} source={{uri:this.props.resource.author.avatar}}/> |
45 | <Text style={styles.name}>Sphinx</Text> | 48 | <Text style={styles.name}>Sphinx</Text> |
46 | </View> | 49 | </View> |
50 | + </TouchableOpacity> | ||
47 | ) | 51 | ) |
48 | } | 52 | } |
49 | 53 | ||
@@ -66,16 +70,27 @@ export default class List extends Component { | @@ -66,16 +70,27 @@ export default class List extends Component { | ||
66 | src, | 70 | src, |
67 | title, | 71 | title, |
68 | views_num, | 72 | views_num, |
73 | + url, | ||
74 | + share, | ||
75 | + id, | ||
69 | } = this.props.resource; | 76 | } = this.props.resource; |
77 | + let urlAry = url.split('&'); | ||
78 | + let shareParam = { | ||
79 | + title, | ||
80 | + 'content': intro, | ||
81 | + 'image': src, | ||
82 | + 'url': urlAry[0], | ||
83 | + }; | ||
70 | let bigPic = getSlicedUrl(src, 640, 640, 2); | 84 | let bigPic = getSlicedUrl(src, 640, 640, 2); |
71 | let tagImg = tagMap[category_name]; | 85 | let tagImg = tagMap[category_name]; |
72 | if (!tagImg) { | 86 | if (!tagImg) { |
73 | tagImg = "../../image/chaopin_icon.png"; | 87 | tagImg = "../../image/chaopin_icon.png"; |
74 | } | 88 | } |
75 | let likeImg = isPraise == 'N'?require('../../image/wsc_icon.png'):require('../../image/sc_icon.png'); | 89 | let likeImg = isPraise == 'N'?require('../../image/wsc_icon.png'):require('../../image/sc_icon.png'); |
90 | + let isLike = isPraise == 'N'; | ||
76 | return ( | 91 | return ( |
77 | <TouchableOpacity activeOpacity={0.5} onPress={() => { | 92 | <TouchableOpacity activeOpacity={0.5} onPress={() => { |
78 | - // this.props.onPressBrandItem && this.props.onPressBrandItem(rowData.url, rowID); | 93 | + this.props.onPressCell&&this.props.onPressCell(url); |
79 | }}> | 94 | }}> |
80 | <View style={styles.container}> | 95 | <View style={styles.container}> |
81 | <View style={styles.sapatorView}/> | 96 | <View style={styles.sapatorView}/> |
@@ -92,10 +107,10 @@ export default class List extends Component { | @@ -92,10 +107,10 @@ export default class List extends Component { | ||
92 | <Text style={styles.text}>{publish_time}</Text> | 107 | <Text style={styles.text}>{publish_time}</Text> |
93 | <Image source={require('../../image/shared_view_icon.png')} style={styles.iconThumb}resizeMode={'contain'}></Image> | 108 | <Image source={require('../../image/shared_view_icon.png')} style={styles.iconThumb}resizeMode={'contain'}></Image> |
94 | <Text style={styles.text}>{views_num}</Text> | 109 | <Text style={styles.text}>{views_num}</Text> |
95 | - <TouchableOpacity style={styles.likeButton}> | 110 | + <TouchableOpacity style={styles.likeButton} onPress={()=>{this.props.onPressLike&&this.props.onPressLike(id, isLike)}}> |
96 | <Image source={likeImg}/> | 111 | <Image source={likeImg}/> |
97 | </TouchableOpacity> | 112 | </TouchableOpacity> |
98 | - <TouchableOpacity style={styles.shareButton}> | 113 | + <TouchableOpacity style={styles.shareButton} onPress={()=>{this.props.onPressShare&&this.props.onPressShare(shareParam)}}> |
99 | <Image source={require('../../image/shared_sharebuttom_highlighted.png')}/> | 114 | <Image source={require('../../image/shared_sharebuttom_highlighted.png')}/> |
100 | </TouchableOpacity> | 115 | </TouchableOpacity> |
101 | </View> | 116 | </View> |
@@ -117,7 +132,7 @@ let styles = StyleSheet.create({ | @@ -117,7 +132,7 @@ let styles = StyleSheet.create({ | ||
117 | backgroundColor: 'white', | 132 | backgroundColor: 'white', |
118 | }, | 133 | }, |
119 | sapatorView: { | 134 | sapatorView: { |
120 | - backgroundColor: '#f0f0f0', | 135 | + backgroundColor: 'white', |
121 | width: width, | 136 | width: width, |
122 | height: 16, | 137 | height: 16, |
123 | borderColor: 'rgb(215, 215, 215)', | 138 | borderColor: 'rgb(215, 215, 215)', |
@@ -18,7 +18,7 @@ import {Map} from 'immutable'; | @@ -18,7 +18,7 @@ import {Map} from 'immutable'; | ||
18 | import * as detailActions from '../reducers/detail/detailActions'; | 18 | import * as detailActions from '../reducers/detail/detailActions'; |
19 | 19 | ||
20 | import Detail from '../components/detail/Detail'; | 20 | import Detail from '../components/detail/Detail'; |
21 | - | 21 | +import {urlAddParamOfType} from '../../common/utils/urlHandler'; |
22 | 22 | ||
23 | const actions = [ | 23 | const actions = [ |
24 | detailActions, | 24 | detailActions, |
@@ -47,8 +47,6 @@ class DetailContainer extends Component { | @@ -47,8 +47,6 @@ class DetailContainer extends Component { | ||
47 | constructor(props) { | 47 | constructor(props) { |
48 | super(props); | 48 | super(props); |
49 | 49 | ||
50 | - this._onRefresh = this._onRefresh.bind(this); | ||
51 | - this._onEndReached = this._onEndReached.bind(this); | ||
52 | this._onPressFilter = this._onPressFilter.bind(this); | 50 | this._onPressFilter = this._onPressFilter.bind(this); |
53 | this._onPressAuthor = this._onPressAuthor.bind(this); | 51 | this._onPressAuthor = this._onPressAuthor.bind(this); |
54 | this._onPressMoreLink = this._onPressMoreLink.bind(this); | 52 | this._onPressMoreLink = this._onPressMoreLink.bind(this); |
@@ -57,6 +55,8 @@ class DetailContainer extends Component { | @@ -57,6 +55,8 @@ class DetailContainer extends Component { | ||
57 | this._onPressGoodY = this._onPressGoodY.bind(this); | 55 | this._onPressGoodY = this._onPressGoodY.bind(this); |
58 | this._onPressLink = this._onPressLink.bind(this); | 56 | this._onPressLink = this._onPressLink.bind(this); |
59 | this._onPressTag = this._onPressTag.bind(this); | 57 | this._onPressTag = this._onPressTag.bind(this); |
58 | + this._onPressBrand = this._onPressBrand.bind(this); | ||
59 | + this._onPressArticle = this._onPressArticle.bind(this); | ||
60 | } | 60 | } |
61 | 61 | ||
62 | componentDidMount() { | 62 | componentDidMount() { |
@@ -70,18 +70,6 @@ class DetailContainer extends Component { | @@ -70,18 +70,6 @@ class DetailContainer extends Component { | ||
70 | 70 | ||
71 | } | 71 | } |
72 | 72 | ||
73 | - _onRefresh() { | ||
74 | - InteractionManager.runAfterInteractions(() => { | ||
75 | - | ||
76 | - }); | ||
77 | - } | ||
78 | - | ||
79 | - _onEndReached() { | ||
80 | - InteractionManager.runAfterInteractions(() => { | ||
81 | - | ||
82 | - }); | ||
83 | - } | ||
84 | - | ||
85 | _onPressFilter(value) { | 73 | _onPressFilter(value) { |
86 | this.props.actions.setGoodsGroupFilter(value); | 74 | this.props.actions.setGoodsGroupFilter(value); |
87 | } | 75 | } |
@@ -91,6 +79,15 @@ class DetailContainer extends Component { | @@ -91,6 +79,15 @@ class DetailContainer extends Component { | ||
91 | } | 79 | } |
92 | 80 | ||
93 | _onPressAuthor(url) { | 81 | _onPressAuthor(url) { |
82 | + let authorUrl = urlAddParamOfType(url, '11') | ||
83 | + ReactNative.NativeModules.YH_CommonHelper.jumpWithUrl(authorUrl); | ||
84 | + } | ||
85 | + | ||
86 | + _onPressBrand(url) { | ||
87 | + ReactNative.NativeModules.YH_CommonHelper.jumpWithUrl(url); | ||
88 | + } | ||
89 | + | ||
90 | + _onPressArticle(url) { | ||
94 | ReactNative.NativeModules.YH_CommonHelper.jumpWithUrl(url); | 91 | ReactNative.NativeModules.YH_CommonHelper.jumpWithUrl(url); |
95 | } | 92 | } |
96 | 93 | ||
@@ -99,7 +96,8 @@ class DetailContainer extends Component { | @@ -99,7 +96,8 @@ class DetailContainer extends Component { | ||
99 | } | 96 | } |
100 | 97 | ||
101 | _onPressTag(url) { | 98 | _onPressTag(url) { |
102 | - ReactNative.NativeModules.YH_CommonHelper.jumpWithUrl(url); | 99 | + let taggedUrl = urlAddParamOfType(url, '12') |
100 | + ReactNative.NativeModules.YH_CommonHelper.jumpWithUrl(taggedUrl); | ||
103 | } | 101 | } |
104 | _onPressMoreLink(url) { | 102 | _onPressMoreLink(url) { |
105 | ReactNative.NativeModules.YH_CommonHelper.jumpWithUrl(url); | 103 | ReactNative.NativeModules.YH_CommonHelper.jumpWithUrl(url); |
@@ -125,12 +123,7 @@ class DetailContainer extends Component { | @@ -125,12 +123,7 @@ class DetailContainer extends Component { | ||
125 | return ( | 123 | return ( |
126 | <View style={styles.container}> | 124 | <View style={styles.container}> |
127 | <Detail | 125 | <Detail |
128 | - ref={(c) => { | ||
129 | - this.detail = c; | ||
130 | - }} | ||
131 | resource={detail} | 126 | resource={detail} |
132 | - onRefresh={this._onRefresh} | ||
133 | - onEndReached={this._onEndReached} | ||
134 | onPressFilter= {this._onPressFilter} | 127 | onPressFilter= {this._onPressFilter} |
135 | onPressAuthor={this._onPressAuthor} | 128 | onPressAuthor={this._onPressAuthor} |
136 | onPressMoreLink={this._onPressMoreLink} | 129 | onPressMoreLink={this._onPressMoreLink} |
@@ -139,6 +132,8 @@ class DetailContainer extends Component { | @@ -139,6 +132,8 @@ class DetailContainer extends Component { | ||
139 | onPressGoodY={this._onPressGoodY} | 132 | onPressGoodY={this._onPressGoodY} |
140 | onPressLink={this._onPressLink} | 133 | onPressLink={this._onPressLink} |
141 | onPressTag={this._onPressTag} | 134 | onPressTag={this._onPressTag} |
135 | + onPressBrand={this._onPressBrand} | ||
136 | + onPressArticle={this._onPressArticle} | ||
142 | /> | 137 | /> |
143 | </View> | 138 | </View> |
144 | ); | 139 | ); |
@@ -19,7 +19,7 @@ import {Map} from 'immutable'; | @@ -19,7 +19,7 @@ import {Map} from 'immutable'; | ||
19 | import * as listActions from '../reducers/list/listActions'; | 19 | import * as listActions from '../reducers/list/listActions'; |
20 | 20 | ||
21 | import List from '../components/list/List'; | 21 | import List from '../components/list/List'; |
22 | - | 22 | +import {urlAddParamOfType} from '../../common/utils/urlHandler'; |
23 | 23 | ||
24 | const actions = [ | 24 | const actions = [ |
25 | listActions, | 25 | listActions, |
@@ -50,6 +50,10 @@ class ListContainer extends Component { | @@ -50,6 +50,10 @@ class ListContainer extends Component { | ||
50 | 50 | ||
51 | this._onRefresh = this._onRefresh.bind(this); | 51 | this._onRefresh = this._onRefresh.bind(this); |
52 | this._onEndReached = this._onEndReached.bind(this); | 52 | this._onEndReached = this._onEndReached.bind(this); |
53 | + this._onPressCell = this._onPressCell.bind(this); | ||
54 | + this._onPressShare = this._onPressShare.bind(this); | ||
55 | + this._onPressLike = this._onPressLike.bind(this); | ||
56 | + this._onPressHeader = this._onPressHeader.bind(this); | ||
53 | this.subscription = NativeAppEventEmitter.addListener( | 57 | this.subscription = NativeAppEventEmitter.addListener( |
54 | 'ChannelDidChangeEvent', | 58 | 'ChannelDidChangeEvent', |
55 | (reminder) => { | 59 | (reminder) => { |
@@ -66,12 +70,29 @@ class ListContainer extends Component { | @@ -66,12 +70,29 @@ class ListContainer extends Component { | ||
66 | this.subscription && this.subscription.remove(); | 70 | this.subscription && this.subscription.remove(); |
67 | } | 71 | } |
68 | 72 | ||
73 | + _onPressCell(url) { | ||
74 | + ReactNative.NativeModules.YH_CommonHelper.jumpWithUrl(url); | ||
75 | + } | ||
76 | + | ||
77 | + _onPressHeader(url) { | ||
78 | + let taggedUrl = urlAddParamOfType(url, '11') | ||
79 | + ReactNative.NativeModules.YH_CommonHelper.jumpWithUrl(taggedUrl); | ||
80 | + } | ||
81 | + | ||
69 | _onRefresh() { | 82 | _onRefresh() { |
70 | InteractionManager.runAfterInteractions(() => { | 83 | InteractionManager.runAfterInteractions(() => { |
71 | this.props.actions.getArticleList(true); | 84 | this.props.actions.getArticleList(true); |
72 | }); | 85 | }); |
73 | } | 86 | } |
74 | 87 | ||
88 | + _onPressShare(param) { | ||
89 | + ReactNative.NativeModules.YH_CommonHelper.shareWithParam(param); | ||
90 | + } | ||
91 | + | ||
92 | + _onPressLike(article_id, isLike) { | ||
93 | + this.props.actions.onPressLike(article_id, isLike); | ||
94 | + } | ||
95 | + | ||
75 | _onEndReached() { | 96 | _onEndReached() { |
76 | InteractionManager.runAfterInteractions(() => { | 97 | InteractionManager.runAfterInteractions(() => { |
77 | this.props.actions.getArticleList(); | 98 | this.props.actions.getArticleList(); |
@@ -89,7 +110,11 @@ class ListContainer extends Component { | @@ -89,7 +110,11 @@ class ListContainer extends Component { | ||
89 | this.sale = c; | 110 | this.sale = c; |
90 | }} | 111 | }} |
91 | data={list} | 112 | data={list} |
113 | + onPressCell={this._onPressCell} | ||
92 | onEndReached={this._onEndReached} | 114 | onEndReached={this._onEndReached} |
115 | + onPressShare={this._onPressShare} | ||
116 | + onPressLike={this._onPressLike} | ||
117 | + onPressHeader={this._onPressHeader} | ||
93 | /> | 118 | /> |
94 | </View> | 119 | </View> |
95 | ); | 120 | ); |
@@ -12,6 +12,7 @@ const { | @@ -12,6 +12,7 @@ const { | ||
12 | GET_ARTICLE_LIST_SUCCESS, | 12 | GET_ARTICLE_LIST_SUCCESS, |
13 | GET_ARTICLE_LIST_FAILURE, | 13 | GET_ARTICLE_LIST_FAILURE, |
14 | 14 | ||
15 | + LIKE_ARTICLE, | ||
15 | } = require('../../constants/actionTypes').default; | 16 | } = require('../../constants/actionTypes').default; |
16 | 17 | ||
17 | export function setListType(type) { | 18 | export function setListType(type) { |
@@ -56,6 +57,45 @@ function getArticleListFailure(error) { | @@ -56,6 +57,45 @@ function getArticleListFailure(error) { | ||
56 | }; | 57 | }; |
57 | } | 58 | } |
58 | 59 | ||
60 | +function likeArticle(json) { | ||
61 | + return { | ||
62 | + type: LIKE_ARTICLE, | ||
63 | + payload: json, | ||
64 | + } | ||
65 | +} | ||
66 | + | ||
67 | +export function onPressLike(article_id, isLike) { | ||
68 | + return (dispatch, getState) => { | ||
69 | + let {app, list} = getState(); | ||
70 | + | ||
71 | + let likeRequest = (article_id, uid, isLike) => { | ||
72 | + dispatch(likeArticle({article_id, isLike})); | ||
73 | + | ||
74 | + if (isLike) { | ||
75 | + return new ListService(app.serviceHost).setArticleFavorite(article_id, uid) | ||
76 | + }else { | ||
77 | + return new ListService(app.serviceHost).cancleArticleFavorite(article_id, uid) | ||
78 | + } | ||
79 | + } | ||
80 | + | ||
81 | + ReactNative.NativeModules.YH_CommonHelper.uid() | ||
82 | + .then(uid => { | ||
83 | + likeRequest(article_id, uid, isLike); | ||
84 | + }) | ||
85 | + .catch(error => { | ||
86 | + ReactNative.NativeModules.YH_CommonHelper.login() | ||
87 | + .then(uid => { | ||
88 | + likeRequest(article_id, uid, isLike); | ||
89 | + }) | ||
90 | + .catch(error => { | ||
91 | + | ||
92 | + }); | ||
93 | + }); | ||
94 | + | ||
95 | + | ||
96 | + }; | ||
97 | +} | ||
98 | + | ||
59 | export function getArticleList(reload = false) { | 99 | export function getArticleList(reload = false) { |
60 | return (dispatch, getState) => { | 100 | return (dispatch, getState) => { |
61 | 101 |
@@ -12,6 +12,8 @@ const { | @@ -12,6 +12,8 @@ const { | ||
12 | GET_ARTICLE_LIST_SUCCESS, | 12 | GET_ARTICLE_LIST_SUCCESS, |
13 | GET_ARTICLE_LIST_FAILURE, | 13 | GET_ARTICLE_LIST_FAILURE, |
14 | 14 | ||
15 | + LIKE_ARTICLE, | ||
16 | + | ||
15 | } = require('../../constants/actionTypes').default; | 17 | } = require('../../constants/actionTypes').default; |
16 | 18 | ||
17 | const initialState = new InitialState; | 19 | const initialState = new InitialState; |
@@ -56,6 +58,25 @@ export default function listReducer(state=initialState, action) { | @@ -56,6 +58,25 @@ export default function listReducer(state=initialState, action) { | ||
56 | return newState; | 58 | return newState; |
57 | } | 59 | } |
58 | 60 | ||
61 | + case LIKE_ARTICLE: { | ||
62 | + let { | ||
63 | + article_id, | ||
64 | + isLike, | ||
65 | + } = action.payload; | ||
66 | + let originAry = state.get('articles').get('list').toJS(); | ||
67 | + for (var i = 0; i < originAry.length; i++) { | ||
68 | + if (originAry[i].id == article_id) { | ||
69 | + console.log('......find....'); | ||
70 | + originAry[i].isPraise = isLike?'Y':'N'; | ||
71 | + } | ||
72 | + } | ||
73 | + let newState = state.setIn(['articles', 'list'], Immutable.fromJS(originAry)); | ||
74 | + | ||
75 | + return newState; | ||
76 | + } | ||
77 | + | ||
78 | + break; | ||
79 | + | ||
59 | case GET_ARTICLE_LIST_FAILURE: { | 80 | case GET_ARTICLE_LIST_FAILURE: { |
60 | return state.setIn(['articles', 'isFetching'], false) | 81 | return state.setIn(['articles', 'isFetching'], false) |
61 | .setIn(['articles', 'error'], action.payload) | 82 | .setIn(['articles', 'error'], action.payload) |
@@ -11,18 +11,19 @@ export default class ListService { | @@ -11,18 +11,19 @@ export default class ListService { | ||
11 | } | 11 | } |
12 | this.api = new Request(baseURL); | 12 | this.api = new Request(baseURL); |
13 | } | 13 | } |
14 | - | 14 | + |
15 | // 获取资讯 | 15 | // 获取资讯 |
16 | async getArticleList(author_id, tag, gender='1,3', uid=0, page=1, limit=20, sort_id=0) { | 16 | async getArticleList(author_id, tag, gender='1,3', uid=0, page=1, limit=20, sort_id=0) { |
17 | + console.log(uid); | ||
17 | return await this.api.get({ | 18 | return await this.api.get({ |
18 | url: '/guang/api/v2/article/getList', | 19 | url: '/guang/api/v2/article/getList', |
19 | body: { | 20 | body: { |
20 | gender, | 21 | gender, |
21 | sort_id, | 22 | sort_id, |
22 | uid, | 23 | uid, |
23 | - tag, | 24 | + tag, |
24 | author_id, | 25 | author_id, |
25 | - page, | 26 | + page, |
26 | limit, | 27 | limit, |
27 | } | 28 | } |
28 | }) | 29 | }) |
@@ -33,5 +34,36 @@ export default class ListService { | @@ -33,5 +34,36 @@ export default class ListService { | ||
33 | throw(error); | 34 | throw(error); |
34 | }); | 35 | }); |
35 | } | 36 | } |
36 | - | 37 | + |
38 | + async setArticleFavorite(article_id, uid=0) { | ||
39 | + return await this.api.get({ | ||
40 | + url: '/guang/api/v1/favorite/setFavorite', | ||
41 | + body: { | ||
42 | + article_id, | ||
43 | + uid, | ||
44 | + } | ||
45 | + }) | ||
46 | + .then((json) => { | ||
47 | + return json; | ||
48 | + }) | ||
49 | + .catch((error) => { | ||
50 | + throw(error); | ||
51 | + }); | ||
52 | + } | ||
53 | + | ||
54 | + async cancleArticleFavorite(article_id, uid=0) { | ||
55 | + return await this.api.get({ | ||
56 | + url: '/guang/api/v1/favorite/cancelFavorite', | ||
57 | + body: { | ||
58 | + article_id, | ||
59 | + uid, | ||
60 | + } | ||
61 | + }) | ||
62 | + .then((json) => { | ||
63 | + return json; | ||
64 | + }) | ||
65 | + .catch((error) => { | ||
66 | + throw(error); | ||
67 | + }); | ||
68 | + } | ||
37 | } | 69 | } |
@@ -103,7 +103,7 @@ export default function native(platform) { | @@ -103,7 +103,7 @@ export default function native(platform) { | ||
103 | let gender = this.props.genderType; | 103 | let gender = this.props.genderType; |
104 | store.dispatch(setGender(gender)); | 104 | store.dispatch(setGender(gender)); |
105 | } | 105 | } |
106 | - | 106 | + |
107 | return ( | 107 | return ( |
108 | <Provider store={store}> | 108 | <Provider store={store}> |
109 | <PlustarContainer /> | 109 | <PlustarContainer /> |
@@ -25,6 +25,7 @@ export default class BrandArticleList extends Component { | @@ -25,6 +25,7 @@ export default class BrandArticleList extends Component { | ||
25 | 25 | ||
26 | this._renderRow = this._renderRow.bind(this); | 26 | this._renderRow = this._renderRow.bind(this); |
27 | this._renderHeader = this._renderHeader.bind(this); | 27 | this._renderHeader = this._renderHeader.bind(this); |
28 | + this._renderSeparator = this._renderSeparator.bind(this); | ||
28 | 29 | ||
29 | this.dataSource = new ListView.DataSource({ | 30 | this.dataSource = new ListView.DataSource({ |
30 | rowHasChanged: (r1, r2) => !Immutable.is(r1, r2), | 31 | rowHasChanged: (r1, r2) => !Immutable.is(r1, r2), |
@@ -55,12 +56,18 @@ export default class BrandArticleList extends Component { | @@ -55,12 +56,18 @@ export default class BrandArticleList extends Component { | ||
55 | } | 56 | } |
56 | 57 | ||
57 | _renderSeparator(sectionID, rowID, adjacentRowHighlighted) { | 58 | _renderSeparator(sectionID, rowID, adjacentRowHighlighted) { |
59 | + | ||
60 | + //最后一条记录无需Separator | ||
61 | + if (!this.props || !this.props.articleList || (this.props.articleList.length - rowID) == 1) { | ||
62 | + return null; | ||
63 | + } | ||
58 | return ( | 64 | return ( |
59 | <View key={'sep' + rowID} style={styles.separator}></View> | 65 | <View key={'sep' + rowID} style={styles.separator}></View> |
60 | ); | 66 | ); |
61 | } | 67 | } |
62 | 68 | ||
63 | render() { | 69 | render() { |
70 | + | ||
64 | let {articleList} = this.props; | 71 | let {articleList} = this.props; |
65 | 72 | ||
66 | if (!articleList || articleList.length == 0) { | 73 | if (!articleList || articleList.length == 0) { |
@@ -36,7 +36,7 @@ export default class BrandIntro extends Component { | @@ -36,7 +36,7 @@ export default class BrandIntro extends Component { | ||
36 | let titleFoldArrowIcon = brandIntro.titleUnfold ? require("../../images/arrow_small_up.png") : require("../../images/arrow_small_down.png"); | 36 | let titleFoldArrowIcon = brandIntro.titleUnfold ? require("../../images/arrow_small_up.png") : require("../../images/arrow_small_down.png"); |
37 | return ( | 37 | return ( |
38 | <View style={styles.container}> | 38 | <View style={styles.container}> |
39 | - <SlicedImage style={styles.coverImage} source={{uri: detail.cover_img}} style={{width, height:coverImageHeight}}/> | 39 | + <SlicedImage style={[styles.coverImage, {width, height:coverImageHeight}]} source={{uri: detail.cover_img}}/> |
40 | 40 | ||
41 | <View style={styles.titleLikeView}> | 41 | <View style={styles.titleLikeView}> |
42 | 42 | ||
@@ -93,7 +93,6 @@ let styles = StyleSheet.create({ | @@ -93,7 +93,6 @@ let styles = StyleSheet.create({ | ||
93 | position: 'absolute', | 93 | position: 'absolute', |
94 | top: 116 * DEVICE_WIDTH_RATIO, | 94 | top: 116 * DEVICE_WIDTH_RATIO, |
95 | left: 25 * DEVICE_WIDTH_RATIO, | 95 | left: 25 * DEVICE_WIDTH_RATIO, |
96 | - borderWidth: 1, | ||
97 | height: brandIconWidth, | 96 | height: brandIconWidth, |
98 | width: brandIconWidth, | 97 | width: brandIconWidth, |
99 | borderWidth: 1, | 98 | borderWidth: 1, |
js/plustar/components/detail/Detail.js
0 → 100644
1 | +'use strict' | ||
2 | + | ||
3 | +import React, {Component} from 'react'; | ||
4 | +import ReactNative, { | ||
5 | + StyleSheet, | ||
6 | + Dimensions, | ||
7 | + Platform, | ||
8 | + View, | ||
9 | + NativeModules, | ||
10 | + InteractionManager, | ||
11 | + NativeAppEventEmitter, | ||
12 | + ListView, | ||
13 | +} from 'react-native' | ||
14 | + | ||
15 | +import {Map} from 'immutable'; | ||
16 | +import BrandIntro from './BrandIntro' | ||
17 | +import BrandArticleList from './BrandArticleList' | ||
18 | +import BrandArticleCell from './BrandArticleCell' | ||
19 | +import NewArrival from './NewArrival' | ||
20 | +import Prompt from '../../../coupon/components/coupon/Prompt'; | ||
21 | + | ||
22 | +export default class Detail extends React.Component{ | ||
23 | + | ||
24 | + constructor(props) { | ||
25 | + super(props); | ||
26 | + | ||
27 | + this.renderRow = this.renderRow.bind(this); | ||
28 | + this.dataSource = new ListView.DataSource({ | ||
29 | + rowHasChanged: (r1, r2) => !Immutable.is(r1, r2), | ||
30 | + sectionHeaderHasChanged: (s1, s2) => !Immutable.is(s1, s2), | ||
31 | + }); | ||
32 | + } | ||
33 | + | ||
34 | + | ||
35 | + | ||
36 | + componentWillReceiveProps(nextProps) { | ||
37 | + if (this.props.detail.get('brandInfo').get('titleUnfold') && !nextProps.detail.get('brandInfo').get('titleUnfold')) { | ||
38 | + this.listView.scrollTo({x: 0, y: 0, animated: false, }); | ||
39 | + } | ||
40 | + } | ||
41 | + | ||
42 | + renderRow(rowData, sectionID, rowID, highlightRow) { | ||
43 | + if (!rowData && rowData.length == 0) { | ||
44 | + return null; | ||
45 | + } | ||
46 | + switch (rowID) { | ||
47 | + case 'brandInfo': | ||
48 | + return( | ||
49 | + <BrandIntro | ||
50 | + brandIntro={rowData} | ||
51 | + brandFav={this.props.detail.get('brandFav')} | ||
52 | + onPressFav={this.props.onPressFav} | ||
53 | + onPressBrandIntroMore={this.props.onPressBrandIntroMore} | ||
54 | + addCanelFavTipRemove={this.props.addCanelFavTipRemove} | ||
55 | + /> | ||
56 | + ); | ||
57 | + case 'productList': | ||
58 | + console.log(rowData); | ||
59 | + console.log('rowData'); | ||
60 | + return ( | ||
61 | + <NewArrival | ||
62 | + prodcutList={rowData} | ||
63 | + onPressMoreProducts={this.props.onPressMoreProducts} | ||
64 | + onPressProduct={this.props.onPressProduct} | ||
65 | + moreProductUrl={this.props.detail.get('moreProductUrl')} | ||
66 | + /> | ||
67 | + ); | ||
68 | + case 'articleList': | ||
69 | + return( | ||
70 | + <BrandArticleList | ||
71 | + articleList={rowData} | ||
72 | + onPressArticle={this.props.onPressArticle} | ||
73 | + onPressArticleLike={this.props.onPressArticleLike} /> | ||
74 | + ); | ||
75 | + default: | ||
76 | + return null; | ||
77 | + | ||
78 | + } | ||
79 | + } | ||
80 | + | ||
81 | + | ||
82 | + render() { | ||
83 | + let {detail} = this.props; | ||
84 | + | ||
85 | + let dataSource = { | ||
86 | + brandInfo: detail.get('brandInfo'), | ||
87 | + productList: detail.get('productList').toArray(), | ||
88 | + articleList: detail.get('articleList').toArray(), | ||
89 | + }; | ||
90 | + | ||
91 | + return ( | ||
92 | + <View style={styles.container}> | ||
93 | + <ListView | ||
94 | + ref={(c) => { | ||
95 | + this.listView = c; | ||
96 | + }} | ||
97 | + contentContainerStyle={styles.contentContainer} | ||
98 | + enableEmptySections={true} | ||
99 | + dataSource={this.dataSource.cloneWithRows(dataSource)} | ||
100 | + renderRow={this.renderRow} | ||
101 | + /> | ||
102 | + | ||
103 | + | ||
104 | + {detail.get('brandInfo').get('addCancelTip') !== '' ? <Prompt | ||
105 | + text={detail.get('brandInfo').get('addCancelTip')} | ||
106 | + duration={800} | ||
107 | + onPromptHidden={this.props.addCanelFavTipRemove} | ||
108 | + /> : null} | ||
109 | + </View> | ||
110 | + ); | ||
111 | + } | ||
112 | +}; | ||
113 | + | ||
114 | +let styles = StyleSheet.create({ | ||
115 | + container: { | ||
116 | + flex: 1, | ||
117 | + backgroundColor: '#f0f0f0', | ||
118 | + }, | ||
119 | + contentContainer:{ | ||
120 | + flexDirection: 'column', | ||
121 | + flexWrap: 'wrap', | ||
122 | + }, | ||
123 | +}); |
@@ -16,11 +16,7 @@ import {bindActionCreators} from 'redux'; | @@ -16,11 +16,7 @@ import {bindActionCreators} from 'redux'; | ||
16 | import {connect} from 'react-redux'; | 16 | import {connect} from 'react-redux'; |
17 | import {Map} from 'immutable'; | 17 | import {Map} from 'immutable'; |
18 | import * as detailActions from '../reducers/detail/detailActions'; | 18 | import * as detailActions from '../reducers/detail/detailActions'; |
19 | -import BrandIntro from '../components/detail/BrandIntro' | ||
20 | -import BrandArticleList from '../components/detail/BrandArticleList' | ||
21 | -import BrandArticleCell from '../components/detail/BrandArticleCell' | ||
22 | -import NewArrival from '../components/detail/NewArrival' | ||
23 | -import Prompt from '../../coupon/components/coupon/Prompt'; | 19 | +import Detail from '../components/detail/Detail' |
24 | 20 | ||
25 | const actions = [ | 21 | const actions = [ |
26 | detailActions, | 22 | detailActions, |
@@ -46,9 +42,12 @@ function mapDispatchToProps(dispatch) { | @@ -46,9 +42,12 @@ function mapDispatchToProps(dispatch) { | ||
46 | } | 42 | } |
47 | 43 | ||
48 | class DetailContainer extends Component { | 44 | class DetailContainer extends Component { |
45 | + | ||
49 | componentDidMount() { | 46 | componentDidMount() { |
50 | - this.props.actions.getBrandInfo(); | 47 | + this.props.actions.uidBrandFav(); |
48 | + this.props.actions.brandInfo(); | ||
51 | } | 49 | } |
50 | + | ||
52 | constructor(props) { | 51 | constructor(props) { |
53 | super(props); | 52 | super(props); |
54 | this._onPressArticle = this._onPressArticle.bind(this); | 53 | this._onPressArticle = this._onPressArticle.bind(this); |
@@ -57,23 +56,7 @@ class DetailContainer extends Component { | @@ -57,23 +56,7 @@ class DetailContainer extends Component { | ||
57 | this._onPressBrandIntroMore = this._onPressBrandIntroMore.bind(this); | 56 | this._onPressBrandIntroMore = this._onPressBrandIntroMore.bind(this); |
58 | this._onPressMoreProducts = this._onPressMoreProducts.bind(this); | 57 | this._onPressMoreProducts = this._onPressMoreProducts.bind(this); |
59 | this._addCanelFavTipRemove = this._addCanelFavTipRemove.bind(this); | 58 | this._addCanelFavTipRemove = this._addCanelFavTipRemove.bind(this); |
60 | - | ||
61 | - this.renderRow = this.renderRow.bind(this); | ||
62 | - this.dataSource = new ListView.DataSource({ | ||
63 | - rowHasChanged: (r1, r2) => !Immutable.is(r1, r2), | ||
64 | - sectionHeaderHasChanged: (s1, s2) => !Immutable.is(s1, s2), | ||
65 | - }); | ||
66 | - } | ||
67 | - | ||
68 | - componentDidMount() { | ||
69 | - this.props.actions.uidBrandFav(); | ||
70 | - this.props.actions.brandInfo(); | ||
71 | - } | ||
72 | - | ||
73 | - componentWillReceiveProps(nextProps) { | ||
74 | - if (this.props.detail.get('brandInfo').get('titleUnfold') && !nextProps.detail.get('brandInfo').get('titleUnfold')) { | ||
75 | - this.listView.scrollTo({x: 0, y: 0, animated: false, }); | ||
76 | - } | 59 | + this._onPressProduct = this._onPressProduct.bind(this); |
77 | } | 60 | } |
78 | 61 | ||
79 | _onPressArticle(url) { | 62 | _onPressArticle(url) { |
@@ -115,73 +98,21 @@ class DetailContainer extends Component { | @@ -115,73 +98,21 @@ class DetailContainer extends Component { | ||
115 | this.props.actions.addCanelFavTipRemove(); | 98 | this.props.actions.addCanelFavTipRemove(); |
116 | } | 99 | } |
117 | 100 | ||
118 | - renderRow(rowData, sectionID, rowID, highlightRow) { | ||
119 | - if (!rowData && rowData.length == 0) { | ||
120 | - return null; | ||
121 | - } | ||
122 | - switch (rowID) { | ||
123 | - case 'brandInfo': | ||
124 | - return( | ||
125 | - <BrandIntro | ||
126 | - brandIntro={rowData} | ||
127 | - brandFav={this.props.detail.get('brandFav')} | ||
128 | - onPressFav={this._onPressFav} | ||
129 | - onPressBrandIntroMore={this._onPressBrandIntroMore} | ||
130 | - addCanelFavTipRemove={this._addCanelFavTipRemove} | ||
131 | - /> | ||
132 | - ); | ||
133 | - case 'productList': | ||
134 | - console.log(rowData); | ||
135 | - console.log('rowData'); | ||
136 | - return ( | ||
137 | - <NewArrival | ||
138 | - prodcutList={rowData} | ||
139 | - onPressMoreProducts={this._onPressMoreProducts} | ||
140 | - onPressProduct={this._onPressProduct} | ||
141 | - moreProductUrl={this.props.detail.get('moreProductUrl')} | ||
142 | - /> | ||
143 | - ); | ||
144 | - case 'articleList': | ||
145 | - return( | ||
146 | - <BrandArticleList | ||
147 | - articleList={rowData} | ||
148 | - onPressArticle={this._onPressArticle} | ||
149 | - onPressArticleLike={this._onPressArticleLike} /> | ||
150 | - ); | ||
151 | - default: | ||
152 | - return null; | ||
153 | - | ||
154 | - } | ||
155 | - } | ||
156 | - | ||
157 | 101 | ||
158 | render() { | 102 | render() { |
159 | let {detail} = this.props; | 103 | let {detail} = this.props; |
160 | - | ||
161 | - let dataSource = { | ||
162 | - brandInfo: detail.get('brandInfo'), | ||
163 | - productList: detail.get('productList').toArray(), | ||
164 | - articleList: detail.get('articleList').toArray(), | ||
165 | - }; | ||
166 | - | ||
167 | return ( | 104 | return ( |
168 | <View style={styles.container}> | 105 | <View style={styles.container}> |
169 | - <ListView | ||
170 | - ref={(c) => { | ||
171 | - this.listView = c; | ||
172 | - }} | ||
173 | - contentContainerStyle={styles.contentContainer} | ||
174 | - enableEmptySections={true} | ||
175 | - dataSource={this.dataSource.cloneWithRows(dataSource)} | ||
176 | - renderRow={this.renderRow} | 106 | + <Detail |
107 | + detail={detail} | ||
108 | + onPressArticle={this._onPressArticle} | ||
109 | + onPressArticleLike={this._onPressArticleLike} | ||
110 | + onPressFav={this._onPressFav} | ||
111 | + onPressBrandIntroMore={this._onPressBrandIntroMore} | ||
112 | + onPressMoreProducts={this._onPressMoreProducts} | ||
113 | + addCanelFavTipRemove={this._addCanelFavTipRemove} | ||
114 | + onPressProduct={this._onPressProduct} | ||
177 | /> | 115 | /> |
178 | - | ||
179 | - | ||
180 | - {detail.get('brandInfo').get('addCancelTip') !== '' ? <Prompt | ||
181 | - text={detail.get('brandInfo').get('addCancelTip')} | ||
182 | - duration={800} | ||
183 | - onPromptHidden={this._addCanelFavTipRemove} | ||
184 | - /> : null} | ||
185 | </View> | 116 | </View> |
186 | ); | 117 | ); |
187 | } | 118 | } |
@@ -158,7 +158,7 @@ export function jumpWithUrl(url) { | @@ -158,7 +158,7 @@ export function jumpWithUrl(url) { | ||
158 | } | 158 | } |
159 | //拼接type | 159 | //拼接type |
160 | url = urlAddParamOfType(url); | 160 | url = urlAddParamOfType(url); |
161 | - ReactNative.NativeModules.YH_PlustarHelper.jumpWithUrl(url); | 161 | + ReactNative.NativeModules.YH_CommonHelper.jumpWithUrl(url); |
162 | return { | 162 | return { |
163 | type: JUMP_WITH_URL, | 163 | type: JUMP_WITH_URL, |
164 | payload: url | 164 | payload: url |
-
Please register or login to post a comment