Merge commit '983d3c88' into V6.8.9
Showing
29 changed files
with
995 additions
and
1 deletions
@@ -18,9 +18,11 @@ import {Record, List, Map} from 'immutable'; | @@ -18,9 +18,11 @@ import {Record, List, Map} from 'immutable'; | ||
18 | import appInitialState from './reducers/app/appInitialState'; | 18 | import appInitialState from './reducers/app/appInitialState'; |
19 | import messageInitialState from './reducers/message/messageInitialState'; | 19 | import messageInitialState from './reducers/message/messageInitialState'; |
20 | import listInitialState from './reducers/list/listInitialState'; | 20 | import listInitialState from './reducers/list/listInitialState'; |
21 | +import contentInitialState from './reducers/content/contentInitialState'; | ||
21 | 22 | ||
22 | import MessageContainer from './containers/MessageContainer'; | 23 | import MessageContainer from './containers/MessageContainer'; |
23 | import MessageListContainer from './containers/MessageListContainer'; | 24 | import MessageListContainer from './containers/MessageListContainer'; |
25 | +import ContentMessageContainer from './containers/ContentMessageContainer'; | ||
24 | 26 | ||
25 | import { | 27 | import { |
26 | setPlatform, | 28 | setPlatform, |
@@ -33,12 +35,19 @@ import { | @@ -33,12 +35,19 @@ import { | ||
33 | setCategoryName, | 35 | setCategoryName, |
34 | } from './reducers/list/listActions'; | 36 | } from './reducers/list/listActions'; |
35 | 37 | ||
38 | +import { | ||
39 | + setContentListId, | ||
40 | + setContentCategoryName, | ||
41 | + setContentTipFlag | ||
42 | +} from './reducers/content/contentActions'; | ||
43 | + | ||
36 | 44 | ||
37 | function getInitialState() { | 45 | function getInitialState() { |
38 | const _initState = { | 46 | const _initState = { |
39 | app: (new appInitialState()), | 47 | app: (new appInitialState()), |
40 | message: (new messageInitialState()), | 48 | message: (new messageInitialState()), |
41 | list: (new listInitialState()), | 49 | list: (new listInitialState()), |
50 | + content: (new contentInitialState()), | ||
42 | }; | 51 | }; |
43 | return _initState; | 52 | return _initState; |
44 | } | 53 | } |
@@ -48,7 +57,7 @@ export default function native(platform) { | @@ -48,7 +57,7 @@ export default function native(platform) { | ||
48 | let YH_Message = createReactClass({ | 57 | let YH_Message = createReactClass({ |
49 | 58 | ||
50 | render() { | 59 | render() { |
51 | - const store = configureStore(getInitialState()); | 60 | + const store = configureStore(getInitialState()); |
52 | store.dispatch(setPlatform(platform)); | 61 | store.dispatch(setPlatform(platform)); |
53 | store.dispatch(setHost(this.props.host)); | 62 | store.dispatch(setHost(this.props.host)); |
54 | store.dispatch(setServiceHost(this.props.serviceHost)); | 63 | store.dispatch(setServiceHost(this.props.serviceHost)); |
@@ -68,6 +77,15 @@ export default function native(platform) { | @@ -68,6 +77,15 @@ export default function native(platform) { | ||
68 | <MessageListContainer /> | 77 | <MessageListContainer /> |
69 | </Provider> | 78 | </Provider> |
70 | ); | 79 | ); |
80 | + } else if (type == 'content') { | ||
81 | + store.dispatch(setContentListId(this.props.listId)); | ||
82 | + store.dispatch(setContentCategoryName(this.props.categoryName)); | ||
83 | + store.dispatch(setContentTipFlag(this.props.tipFlag)); | ||
84 | + return ( | ||
85 | + <Provider store={store}> | ||
86 | + <ContentMessageContainer /> | ||
87 | + </Provider> | ||
88 | + ); | ||
71 | } | 89 | } |
72 | return null; | 90 | return null; |
73 | } | 91 | } |
1 | +/** | ||
2 | + * Created by zzz on 2019/3/12. | ||
3 | + */ | ||
4 | +'use strict'; | ||
5 | + | ||
6 | +import React, {Component} from 'react'; | ||
7 | +import {Dimensions, Image, StyleSheet, Text, TouchableOpacity, View, NativeModules} from 'react-native'; | ||
8 | +import {Immutable} from "immutable"; | ||
9 | +import YH_Image from '../../../common/components/YH_Image'; | ||
10 | + | ||
11 | +export default class ContentFansListCell extends Component { | ||
12 | + constructor(props) { | ||
13 | + super(props); | ||
14 | + } | ||
15 | + | ||
16 | + render() { | ||
17 | + let ico = 'http://head.static.yhbimg.com/yhb-head/2018/07/02/16/01fc258bbe83d5b332f3b2631897b80ec9.591188.jpg?imageView2/{mode}/w/{width}/h/{height}'; | ||
18 | + let imageUrl = YH_Image.getSlicedUrl(ico, 50, 50, 2); | ||
19 | + | ||
20 | + function onHeadIconPress() { | ||
21 | + console.log('onHeadIconPress'); | ||
22 | + } | ||
23 | + | ||
24 | + function onFanPress() { | ||
25 | + console.log('onFanPress'); | ||
26 | + } | ||
27 | + | ||
28 | + return ( | ||
29 | + <View> | ||
30 | + <View style={styles.headerBackground}> | ||
31 | + <TouchableOpacity activeOpacity={1} onPress={()=> {onHeadIconPress()}}> | ||
32 | + <YH_Image style={styles.headIcon} url={imageUrl} circle={true}/> | ||
33 | + </TouchableOpacity> | ||
34 | + | ||
35 | + <View style={styles.textView}> | ||
36 | + <Text> | ||
37 | + <Text style={styles.nicknameText}>PINKA</Text> | ||
38 | + <Text style={styles.defaultReplyText} numberOfLines={2}> 关注了你</Text> | ||
39 | + </Text> | ||
40 | + <Text style={styles.startTimeText}>{'2018.03.05 10:00:00'}</Text> | ||
41 | + </View> | ||
42 | + <TouchableOpacity activeOpacity={1} style={styles.fanContainer} onPress={()=> {onFanPress()}}> | ||
43 | + <Image style={styles.fanImage} source={require('../../images/content_fan.png')}/> | ||
44 | + </TouchableOpacity> | ||
45 | + </View> | ||
46 | + <View style={styles.lineView}/> | ||
47 | + </View> | ||
48 | + ); | ||
49 | + } | ||
50 | +} | ||
51 | + | ||
52 | +let { width, height } = Dimensions.get('window'); | ||
53 | +const DEVICE_HEIGHT_RATIO = height / 667; | ||
54 | + | ||
55 | +let styles = StyleSheet.create({ | ||
56 | + headerBackground: { | ||
57 | + width: width, | ||
58 | + height: 80, | ||
59 | + backgroundColor: 'white', | ||
60 | + flexDirection: 'row', | ||
61 | + }, | ||
62 | + headIcon: { | ||
63 | + width: 50, | ||
64 | + height: 50, | ||
65 | + marginLeft: 15, | ||
66 | + marginTop: 15, | ||
67 | + marginRight:15, | ||
68 | + overflow: 'hidden', | ||
69 | + borderRadius: 25, | ||
70 | + }, | ||
71 | + textView: { | ||
72 | + flexDirection: 'column', | ||
73 | + justifyContent: 'space-between', | ||
74 | + alignItems: 'flex-start', | ||
75 | + marginTop: 15, | ||
76 | + marginBottom: 20, | ||
77 | + }, | ||
78 | + startTimeText: { | ||
79 | + fontFamily: 'PingFang-SC-Regular', | ||
80 | + fontSize: 12, | ||
81 | + color: '#B0B0B0', | ||
82 | + height: 17 | ||
83 | + }, | ||
84 | + nicknameText: { | ||
85 | + fontSize: 14, | ||
86 | + fontFamily: 'PingFang-SC-Medium', | ||
87 | + color: 'black', | ||
88 | + fontWeight: 'bold' | ||
89 | + }, | ||
90 | + fanContainer: { | ||
91 | + position: 'absolute', | ||
92 | + top: 27, | ||
93 | + right: 15, | ||
94 | + width: 60, | ||
95 | + height: 25, | ||
96 | + }, | ||
97 | + fanImage: { | ||
98 | + width: 60, | ||
99 | + height: 25, | ||
100 | + }, | ||
101 | + lineView: { | ||
102 | + marginLeft:15, | ||
103 | + marginRight: 0, | ||
104 | + width: width-15, | ||
105 | + height: 1, | ||
106 | + backgroundColor: '#e0e0e0' | ||
107 | + }, | ||
108 | + }); |
1 | +/** | ||
2 | + * Created by zzz on 2019/3/12. | ||
3 | + */ | ||
4 | +'use strict'; | ||
5 | + | ||
6 | +import React, {Component} from 'react'; | ||
7 | +import {Dimensions, Image, ListView, StyleSheet, Text, TouchableOpacity, View, NativeModules} from 'react-native'; | ||
8 | +import {Immutable} from "immutable"; | ||
9 | +import YH_Image from '../../../common/components/YH_Image'; | ||
10 | + | ||
11 | +export default class ContentLikedListCell extends Component { | ||
12 | + constructor(props) { | ||
13 | + super(props); | ||
14 | + } | ||
15 | + | ||
16 | + render() { | ||
17 | + let ico = 'http://head.static.yhbimg.com/yhb-head/2018/07/02/16/01fc258bbe83d5b332f3b2631897b80ec9.591188.jpg?imageView2/{mode}/w/{width}/h/{height}'; | ||
18 | + let picUrl = 'http://img10.static.yhbimg.com/unionimg/2018/09/11/16/012d77a863813f5789f7b9cb92a561ec87.jpg'; | ||
19 | + let imageUrl = YH_Image.getSlicedUrl(ico, 50, 50, 2); | ||
20 | + | ||
21 | + function onHeadIconPress() { | ||
22 | + | ||
23 | + } | ||
24 | + | ||
25 | + function onOriginPress() { | ||
26 | + | ||
27 | + } | ||
28 | + | ||
29 | + return ( | ||
30 | + <View> | ||
31 | + <View style={styles.headerBackground}> | ||
32 | + <TouchableOpacity activeOpacity={1} onPress={()=> {onHeadIconPress()}}> | ||
33 | + <YH_Image style={styles.headIcon} url={imageUrl} circle={true}/> | ||
34 | + </TouchableOpacity> | ||
35 | + | ||
36 | + <View style={styles.textView}> | ||
37 | + <Text style={styles.nicknameText}>社区用户昵称</Text> | ||
38 | + <Text style={styles.subnameText}>赞了你</Text> | ||
39 | + </View> | ||
40 | + </View> | ||
41 | + | ||
42 | + <TouchableOpacity activeOpacity={1} onPress={() => {onOriginPress()}}> | ||
43 | + <View style={ styles.originView} > | ||
44 | + <Text style={styles.copyText}>原文</Text> | ||
45 | + <YH_Image url={picUrl} style={styles.imageStyle} /> | ||
46 | + <Text style={styles.originText} numberOfLines={1}>这款Acne Studios 推出全新「The Johnny Winter Project」系列的东西很好很不错呢,我也很喜欢,太棒了</Text> | ||
47 | + </View> | ||
48 | + </TouchableOpacity> | ||
49 | + | ||
50 | + <View style={styles.timeView}> | ||
51 | + <Text style={styles.startTimeText}>{'2018.03.05'}</Text> | ||
52 | + </View> | ||
53 | + <View style={styles.lineView}/> | ||
54 | + </View> | ||
55 | + ); | ||
56 | + } | ||
57 | +} | ||
58 | + | ||
59 | +let { width, height } = Dimensions.get('window'); | ||
60 | +const DEVICE_HEIGHT_RATIO = height / 667; | ||
61 | + | ||
62 | +let styles = StyleSheet.create({ | ||
63 | + headerBackground: { | ||
64 | + width: width, | ||
65 | + height: 70, | ||
66 | + backgroundColor: 'white', | ||
67 | + flexDirection: 'row', | ||
68 | + }, | ||
69 | + headIcon: { | ||
70 | + width: 40, | ||
71 | + height: 40, | ||
72 | + marginLeft: 15, | ||
73 | + marginTop: 15, | ||
74 | + marginRight:10, | ||
75 | + overflow: 'hidden', | ||
76 | + borderRadius: 20, | ||
77 | + }, | ||
78 | + textView: { | ||
79 | + flexDirection: 'column', | ||
80 | + justifyContent: 'space-between', | ||
81 | + alignItems: 'flex-start', | ||
82 | + marginTop: 18, | ||
83 | + marginBottom: 15, | ||
84 | + }, | ||
85 | + nicknameText: { | ||
86 | + fontSize: 14, | ||
87 | + fontFamily: 'PingFang-SC-Medium', | ||
88 | + color: '#222222', | ||
89 | + }, | ||
90 | + subnameText: { | ||
91 | + fontSize: 12, | ||
92 | + fontFamily: 'PingFang-SC-Regular', | ||
93 | + color: '#B0B0B0', | ||
94 | + }, | ||
95 | + originView: { | ||
96 | + flex: 1, | ||
97 | + marginLeft: 15, | ||
98 | + marginRight: 15, | ||
99 | + marginBottom: 10, | ||
100 | + backgroundColor: '#f0f0f0' | ||
101 | + }, | ||
102 | + copyText: { | ||
103 | + fontFamily: 'PingFang-SC-Regular', | ||
104 | + fontSize: 12, | ||
105 | + color: '#444444', | ||
106 | + marginTop: 10, | ||
107 | + marginLeft: 10, | ||
108 | + }, | ||
109 | + imageStyle: { | ||
110 | + marginTop: 10, | ||
111 | + marginBottom: 4, | ||
112 | + marginLeft: 10, | ||
113 | + width: 50 * DEVICE_HEIGHT_RATIO, | ||
114 | + height: 50 * DEVICE_HEIGHT_RATIO, | ||
115 | + }, | ||
116 | + originText: { | ||
117 | + fontFamily: 'PingFang-SC-Regular', | ||
118 | + fontSize: 12, | ||
119 | + color: '#b0b0b0', | ||
120 | + marginLeft: 10, | ||
121 | + marginRight: 15, | ||
122 | + marginBottom: 9, | ||
123 | + }, | ||
124 | + timeView: { | ||
125 | + alignItems: 'flex-start', | ||
126 | + marginBottom: 10, | ||
127 | + marginLeft: 15, | ||
128 | + }, | ||
129 | + startTimeText: { | ||
130 | + fontFamily: 'PingFang-SC-Regular', | ||
131 | + fontSize: 12, | ||
132 | + color: '#B0B0B0', | ||
133 | + height: 17 | ||
134 | + }, | ||
135 | + lineView: { | ||
136 | + marginLeft:15, | ||
137 | + marginRight: 0, | ||
138 | + width: width-15, | ||
139 | + height: 1, | ||
140 | + backgroundColor: '#e0e0e0' | ||
141 | + }, | ||
142 | + }); |
1 | +/** | ||
2 | + * Created by zzz on 2019/3/12. | ||
3 | + */ | ||
4 | +'use strict'; | ||
5 | + | ||
6 | +import React, {Component} from 'react'; | ||
7 | +import {DeviceEventEmitter, Dimensions, Image, ListView, StyleSheet, Text, TouchableOpacity, View, NativeModules} from 'react-native'; | ||
8 | +import {Immutable} from "immutable"; | ||
9 | +import YH_Image from '../../../common/components/YH_Image'; | ||
10 | + | ||
11 | +export default class ContentMessageCellView extends Component { | ||
12 | + constructor(props) { | ||
13 | + super(props); | ||
14 | + } | ||
15 | + | ||
16 | + render() { | ||
17 | + let ico = 'http://head.static.yhbimg.com/yhb-head/2018/07/02/16/01fc258bbe83d5b332f3b2631897b80ec9.591188.jpg?imageView2/{mode}/w/{width}/h/{height}'; | ||
18 | + let picUrl = 'http://img10.static.yhbimg.com/unionimg/2018/09/11/16/012d77a863813f5789f7b9cb92a561ec87.jpg'; | ||
19 | + let imageUrl = YH_Image.getSlicedUrl(ico, 50, 50, 2); | ||
20 | + let status = true; | ||
21 | + | ||
22 | + function onReplyPress() { | ||
23 | + // NativeModules.YH_CommonHelper.showkeyBoardView(); | ||
24 | + } | ||
25 | + | ||
26 | + return ( | ||
27 | + <View> | ||
28 | + <View style={styles.headerBackground}> | ||
29 | + <YH_Image style={styles.headIcon} url={imageUrl} circle={true}/> | ||
30 | + <View style={styles.textView}> | ||
31 | + <Text style={styles.nicknameText}>社区用户昵称</Text> | ||
32 | + <Text style={styles.subnameText}>赞了你</Text> | ||
33 | + </View> | ||
34 | + <TouchableOpacity activeOpacity={1} style={styles.replyContainer} onPress={()=> {onReplyPress()}}> | ||
35 | + <Image style={styles.replyImage} source={require('../../images/content_reply.png')}/> | ||
36 | + </TouchableOpacity> | ||
37 | + </View> | ||
38 | + | ||
39 | + <View style={styles.replyTextView}> | ||
40 | + <Text style={styles.replyText} numberOfLines={2}>这款Acne Studios 推出全新「The Johnny Winter Project」系列的东西很好很不错呢,我也很喜欢,太棒了</Text> | ||
41 | + </View> | ||
42 | + | ||
43 | + { status ? | ||
44 | + | ||
45 | + <View style={styles.ownerReplyView}> | ||
46 | + <Text style={{paddingLeft: 10, paddingTop: 14, paddingRight: 1, paddingBottom: 12}}> | ||
47 | + <Text style={styles.replyText}>我的评论:</Text> | ||
48 | + <Text style={styles.defaultReplyText} numberOfLines={2}>送你一颗小心心,这个鞋子也是我很想入的一款。非常酷棒极了,详情具体关注你的后续文章</Text> | ||
49 | + </Text> | ||
50 | + </View> | ||
51 | + | ||
52 | + : | ||
53 | + | ||
54 | + <TouchableOpacity activeOpacity={1} onPress={() => {}}> | ||
55 | + <View style={ styles.originContainerView} > | ||
56 | + <Text style={styles.copyText}>原文</Text> | ||
57 | + <YH_Image url={picUrl} style={styles.imageStyle} /> | ||
58 | + <Text style={styles.originText} numberOfLines={1}>这款Acne Studios 推出全新「The Johnny Winter Project」系列的东西很好很不错呢,我也很喜欢,太棒了</Text> | ||
59 | + </View> | ||
60 | + </TouchableOpacity> } | ||
61 | + | ||
62 | + <View style={styles.timeView}> | ||
63 | + <Text style={styles.startTimeText}>{'2018.03.05'}</Text> | ||
64 | + </View> | ||
65 | + <View style={styles.lineView}/> | ||
66 | + </View> | ||
67 | + ); | ||
68 | + } | ||
69 | +} | ||
70 | + | ||
71 | +let { width, height } = Dimensions.get('window'); | ||
72 | +const DEVICE_WIDTH_RATIO = width / 375; | ||
73 | +const DEVICE_HEIGHT_RATIO = height / 667; | ||
74 | + | ||
75 | +let styles = StyleSheet.create({ | ||
76 | + headerBackground: { | ||
77 | + width: width, | ||
78 | + height: 70, | ||
79 | + backgroundColor: 'white', | ||
80 | + flexDirection: 'row', | ||
81 | + }, | ||
82 | + headIcon: { | ||
83 | + width: 40, | ||
84 | + height: 40, | ||
85 | + marginLeft: 15, | ||
86 | + marginTop: 15, | ||
87 | + marginRight:10, | ||
88 | + overflow: 'hidden', | ||
89 | + borderRadius: 20, | ||
90 | + }, | ||
91 | + textView: { | ||
92 | + flexDirection: 'column', | ||
93 | + justifyContent: 'space-between', | ||
94 | + alignItems: 'flex-start', | ||
95 | + marginTop: 18, | ||
96 | + marginBottom: 15, | ||
97 | + }, | ||
98 | + nicknameText: { | ||
99 | + fontSize: 14, | ||
100 | + fontFamily: 'PingFang-SC-Medium', | ||
101 | + color: '#222222', | ||
102 | + }, | ||
103 | + subnameText: { | ||
104 | + fontSize: 12, | ||
105 | + fontFamily: 'PingFang-SC-Regular', | ||
106 | + color: '#B0B0B0', | ||
107 | + }, | ||
108 | + replyContainer: { | ||
109 | + position: 'absolute', | ||
110 | + top: 23, | ||
111 | + right: 15, | ||
112 | + width: 60, | ||
113 | + height: 25, | ||
114 | + }, | ||
115 | + replyImage: { | ||
116 | + width: 60, | ||
117 | + height: 25, | ||
118 | + }, | ||
119 | + replyTextView: { | ||
120 | + width: width - 30, | ||
121 | + marginBottom: 15, | ||
122 | + marginLeft: 15, | ||
123 | + }, | ||
124 | + replyText: { | ||
125 | + fontFamily: 'PingFang-SC-Regular', | ||
126 | + fontSize: 12, | ||
127 | + color: '#444444', | ||
128 | + }, | ||
129 | + ownerReplyView : { | ||
130 | + flexDirection: 'row', | ||
131 | + alignItems: 'center', | ||
132 | + width: width - 30, | ||
133 | + marginLeft: 15, | ||
134 | + backgroundColor: '#F0F0F0', | ||
135 | + marginBottom: 10, | ||
136 | + }, | ||
137 | + defaultReplyText: { | ||
138 | + fontFamily: 'PingFang-SC-Regular', | ||
139 | + fontSize: 12, | ||
140 | + color: '#a8a8a8', | ||
141 | + }, | ||
142 | + originContainerView: { | ||
143 | + flex: 1, | ||
144 | + marginLeft: 15, | ||
145 | + marginRight: 15, | ||
146 | + marginBottom: 10, | ||
147 | + backgroundColor: '#f0f0f0' | ||
148 | + }, | ||
149 | + copyText: { | ||
150 | + fontFamily: 'PingFang-SC-Regular', | ||
151 | + fontSize: 12, | ||
152 | + color: '#444444', | ||
153 | + marginTop: 10, | ||
154 | + marginLeft: 9, | ||
155 | + }, | ||
156 | + imageStyle: { | ||
157 | + marginTop: 10, | ||
158 | + marginBottom: 4, | ||
159 | + marginLeft: 9, | ||
160 | + width: 50 * DEVICE_HEIGHT_RATIO, | ||
161 | + height: 50 * DEVICE_HEIGHT_RATIO, | ||
162 | + }, | ||
163 | + originText: { | ||
164 | + fontFamily: 'PingFang-SC-Regular', | ||
165 | + fontSize: 12, | ||
166 | + color: '#b0b0b0', | ||
167 | + marginLeft: 9, | ||
168 | + marginRight: 16, | ||
169 | + marginBottom: 9, | ||
170 | + }, | ||
171 | + timeView: { | ||
172 | + alignItems: 'flex-start', | ||
173 | + marginBottom: 10, | ||
174 | + marginLeft: 15, | ||
175 | + }, | ||
176 | + startTimeText: { | ||
177 | + fontFamily: 'PingFang-SC-Regular', | ||
178 | + fontSize: 12, | ||
179 | + color: '#B0B0B0', | ||
180 | + height: 17 | ||
181 | + }, | ||
182 | + lineView: { | ||
183 | + marginLeft:15, | ||
184 | + marginRight: 0, | ||
185 | + width: width-15, | ||
186 | + height: 1, | ||
187 | + backgroundColor: '#e0e0e0' | ||
188 | + }, | ||
189 | + }); |
1 | +/** | ||
2 | + * Created by zzz on 2019/3/5. | ||
3 | + */ | ||
4 | +'use strict'; | ||
5 | +import React, {Component} from "react"; | ||
6 | +import {StyleSheet, Text, View, Image, ART} from "react-native"; | ||
7 | +import YH_Image from "../../../common/components/YH_Image"; | ||
8 | +const {Path, Shape, Surface, Group} = ART; | ||
9 | +const INVALID_POSITION = -1; | ||
10 | +const IMAGE_WIDTH = 50; | ||
11 | +const IMAGE_HEIGHT = 50; | ||
12 | + | ||
13 | +export default class ContentMessageTabView extends Component { | ||
14 | + constructor(props) { | ||
15 | + super(props); | ||
16 | + this.state = { | ||
17 | + badgeX: INVALID_POSITION, | ||
18 | + badgeY: INVALID_POSITION, | ||
19 | + badgeWidth: INVALID_POSITION, | ||
20 | + badgeHeight: INVALID_POSITION | ||
21 | + }; | ||
22 | + this.onImageLayout = this.onImageLayout.bind(this) | ||
23 | + this.onBadgeLayout = this.onBadgeLayout.bind(this) | ||
24 | + } | ||
25 | + | ||
26 | + onImageLayout(event) { | ||
27 | + let imageLayout = event.nativeEvent.layout | ||
28 | + this.setState({ | ||
29 | + badgeY: imageLayout.y - 4, | ||
30 | + badgeX: imageLayout.x + imageLayout.width / 2 + 17, | ||
31 | + }) | ||
32 | + } | ||
33 | + | ||
34 | + onBadgeLayout(event) { | ||
35 | + let badgeLayout = event.nativeEvent.layout | ||
36 | + this.setState({badgeWidth: badgeLayout.width, badgeHeight: badgeLayout.height}) | ||
37 | + } | ||
38 | + | ||
39 | + renderSurface() { | ||
40 | + if (this.state.badgeWidth != INVALID_POSITION && this.state.badgeHeight != INVALID_POSITION) { | ||
41 | + let width = this.state.badgeWidth, height = this.state.badgeHeight | ||
42 | + let strokeWidth = 1.5 | ||
43 | + const radius = (height - strokeWidth) / 2, x = strokeWidth / 2 + radius, y = (height) / 2; | ||
44 | + const path = new Path() | ||
45 | + .moveTo(x, y - radius) | ||
46 | + .counterArc(0, radius * 2, radius) | ||
47 | + .lineTo(width - radius - strokeWidth / 2, y + radius) | ||
48 | + .counterArc(0, -radius * 2, radius).close(); | ||
49 | + return <View style={styles.surfaceContainer}> | ||
50 | + <Surface width={width} height={height}> | ||
51 | + <Group> | ||
52 | + <Shape d={path} stroke={'#FB2330'} fill={'#FB2330'} strokeWidth={strokeWidth}/> | ||
53 | + </Group> | ||
54 | + </Surface> | ||
55 | + </View> | ||
56 | + } | ||
57 | + return null; | ||
58 | + } | ||
59 | + | ||
60 | + render() { | ||
61 | + return <View style={[styles.container, this.props.style]}> | ||
62 | + <Image style={styles.icon} source={this.props.icon} onLayout={this.onImageLayout}/> | ||
63 | + <Text style={styles.title}>{this.props.title}</Text> | ||
64 | + {this.props.badge > 0 && this.state.badgeX != INVALID_POSITION && this.state.badgeY != INVALID_POSITION && | ||
65 | + <View style={[styles.badgeContainer, {left: this.state.badgeX, top: this.state.badgeY}]} | ||
66 | + onLayout={this.onBadgeLayout}> | ||
67 | + {this.renderSurface()} | ||
68 | + <Text style={styles.badgeTitle}>{this.props.badge}</Text> | ||
69 | + </View> | ||
70 | + } | ||
71 | + </View> | ||
72 | + } | ||
73 | +} | ||
74 | + | ||
75 | +let styles = StyleSheet.create({ | ||
76 | + container: { | ||
77 | + marginTop: 33, | ||
78 | + marginBottom: 40, | ||
79 | + flexDirection: 'column', | ||
80 | + justifyContent: 'center', | ||
81 | + paddingLeft: 30, | ||
82 | + paddingRight: 30, | ||
83 | + }, | ||
84 | + title: { | ||
85 | + fontFamily: 'PingFang-SC-Medium', | ||
86 | + fontSize: 14, | ||
87 | + marginTop: 15, | ||
88 | + color: '#4A4A4A', | ||
89 | + textAlign:'center', | ||
90 | + }, | ||
91 | + icon: { | ||
92 | + width: 50, | ||
93 | + height: 50, | ||
94 | + }, | ||
95 | + badgeContainer: { | ||
96 | + backgroundColor: 'transparent', | ||
97 | + height: 17, | ||
98 | + minWidth: 17, | ||
99 | + alignItems: 'center', | ||
100 | + justifyContent: 'center', | ||
101 | + flex: 0, | ||
102 | + position: 'absolute' | ||
103 | + }, | ||
104 | + surfaceContainer: { | ||
105 | + position: 'absolute', | ||
106 | + left: 0, | ||
107 | + top: 0, | ||
108 | + right: 0, | ||
109 | + bottom: 0, | ||
110 | + }, | ||
111 | + badgeTitle: { | ||
112 | + marginLeft: 5, | ||
113 | + marginRight: 5, | ||
114 | + fontSize: 10, | ||
115 | + color: 'white', | ||
116 | + fontWeight: 'bold', | ||
117 | + } | ||
118 | +}); |
1 | +/** | ||
2 | + * Created by zzz on 2019/3/5. | ||
3 | + */ | ||
4 | +'use strict'; | ||
5 | +import React, {Component} from "react"; | ||
6 | +import ReactNative, {View, Text, Image, ListView, StyleSheet, Dimensions, TouchableOpacity, Platform, RefreshControl, NativeModules | ||
7 | +} from 'react-native'; | ||
8 | +import YH_PtrRefresh from '../../../common/components/YH_PtrRefresh'; | ||
9 | + | ||
10 | +import ContentMessageTabView from "./ContentMessageTabView"; | ||
11 | +import ContentMessageCell from "./ContentMessageCell"; | ||
12 | + | ||
13 | +export default class ContentMessageView extends Component { | ||
14 | + constructor(props) { | ||
15 | + super(props); | ||
16 | + | ||
17 | + this._renderRow = this._renderRow.bind(this); | ||
18 | + this._renderHeader = this._renderHeader.bind(this); | ||
19 | + this.dataSource = new ListView.DataSource({ | ||
20 | + rowHasChanged: (r1, r2) => !Immutable.is(r1, r2), | ||
21 | + }); | ||
22 | + } | ||
23 | + | ||
24 | + _renderRow(rowData, sectionID, rowID) { | ||
25 | + return ( | ||
26 | + <ContentMessageCell | ||
27 | + key={'row'+ rowID} | ||
28 | + data={rowData} | ||
29 | + /> | ||
30 | + ); | ||
31 | + } | ||
32 | + | ||
33 | + _renderHeader() { | ||
34 | + let tipHeight = this.props.contentTipFlag==='0'?40:0; | ||
35 | + let lineHeight = this.props.contentTipFlag==='0'?1:0; | ||
36 | + let buttonHeight = this.props.contentTipFlag==='0'?25:0; | ||
37 | + | ||
38 | + let tabButtons = [{ | ||
39 | + imgSource: require('../../images/content_zan.png'), | ||
40 | + type: 1, | ||
41 | + description: "获赞收藏", | ||
42 | + unReadCount: 0 | ||
43 | + }, { | ||
44 | + imgSource: require('../../images/content_gz.png'), | ||
45 | + type: 2, | ||
46 | + description: "关注", | ||
47 | + unReadCount: 2 | ||
48 | + }, { | ||
49 | + imgSource: require('../../images/content_tz.png'), | ||
50 | + type: 3, | ||
51 | + description: "通知", | ||
52 | + unReadCount: 0 | ||
53 | + }]; | ||
54 | + | ||
55 | + | ||
56 | + function onNotifyPress() { | ||
57 | + NativeModules.YH_CommonHelper.jumpToUpdateNotificationStatus(); | ||
58 | + } | ||
59 | + | ||
60 | + function onPress(description, messageType) { | ||
61 | + | ||
62 | + } | ||
63 | + | ||
64 | + return (<View> | ||
65 | + <View style={[styles.tipContainer,{height: tipHeight}]}> | ||
66 | + <Text style={[styles.tipStyle]}>{'开启推送通知,第一时间收到互动消息'}</Text> | ||
67 | + <TouchableOpacity style={{width:60, height: buttonHeight}} onPress={()=> {onNotifyPress()}}> | ||
68 | + <Image style={styles.openImage} source={require('../../images/open_btn.png')}/> | ||
69 | + </TouchableOpacity> | ||
70 | + <View style={{backgroundColor: '#EEEEEE', left: 0, right: 0, bottom: 0, position: 'absolute', height: lineHeight}}/> | ||
71 | + </View> | ||
72 | + | ||
73 | + <View style={styles.tabContainer}> | ||
74 | + {tabButtons.map((button, index)=> { | ||
75 | + return <TouchableOpacity style={styles.tabItemContainer} key={index} onPress={()=> { | ||
76 | + onPress(button.description, button.type) | ||
77 | + }}> | ||
78 | + <ContentMessageTabView icon={button.imgSource} title={button.description} badge={button.unReadCount}/> | ||
79 | + </TouchableOpacity> | ||
80 | + })} | ||
81 | + </View> | ||
82 | + | ||
83 | + <View style={{backgroundColor: '#F0F0F0', left: 0, right: 0, bottom: 0, position: 'absolute', height: 10}}/> | ||
84 | + </View> | ||
85 | + ) | ||
86 | + } | ||
87 | + | ||
88 | + componentDidMount() { | ||
89 | + } | ||
90 | + | ||
91 | + componentWillReceiveProps(nextProps) { | ||
92 | + | ||
93 | + } | ||
94 | + | ||
95 | + render() { | ||
96 | + let listData = [{ | ||
97 | + date: 1542598633, | ||
98 | + inviterUid: 500031912, | ||
99 | + uid: 500027570, | ||
100 | + orderAmount: 0.00, | ||
101 | + dateStr: "2018.11.19", | ||
102 | + name: "********27242140", | ||
103 | + orderNum: 0, | ||
104 | + orderAmountStr: "¥0.00" | ||
105 | + }, { | ||
106 | + date: 1539584520, | ||
107 | + inviterUid: 500031912, | ||
108 | + uid: 600032910, | ||
109 | + orderAmount: 0.00, | ||
110 | + dateStr: "2018.10.15", | ||
111 | + name: "YOHO-1c3da9037", | ||
112 | + orderNum: 0, | ||
113 | + orderAmountStr: "¥0.00" | ||
114 | + }]; | ||
115 | + | ||
116 | + return ( | ||
117 | + <View style={styles.container}> | ||
118 | + { | ||
119 | + Platform.OS === 'ios' ? | ||
120 | + <ListView | ||
121 | + ref={(c) => { | ||
122 | + this.listView = c; | ||
123 | + }} | ||
124 | + contentContainerStyle={styles.contentContainer} | ||
125 | + dataSource={this.dataSource.cloneWithRows(listData)} | ||
126 | + renderRow={this._renderRow} | ||
127 | + renderHeader={this._renderHeader} | ||
128 | + enableEmptySections={true} | ||
129 | + enablePullToRefresh={true} | ||
130 | + // isOnPullToRefresh={isPullToRefresh} | ||
131 | + // onRefreshData={() => { | ||
132 | + // this.props.onRefresh && this.props.onRefresh(); | ||
133 | + // }} | ||
134 | + /> | ||
135 | + : | ||
136 | + <ListView | ||
137 | + ref={(c) => { | ||
138 | + this.listView = c; | ||
139 | + }} | ||
140 | + contentContainerStyle={styles.contentContainer} | ||
141 | + dataSource={this.dataSource.cloneWithRows(listData)} | ||
142 | + renderRow={this._renderRow} | ||
143 | + renderHeader={this._renderHeader} | ||
144 | + enableEmptySections={true} | ||
145 | + enablePullToRefresh={true} | ||
146 | + // refreshControl={ | ||
147 | + // <YH_PtrRefresh | ||
148 | + // refreshing={isPullToRefresh} | ||
149 | + // onRefresh={() => { | ||
150 | + // this.props.onRefresh && this.props.onRefresh(); | ||
151 | + // }} | ||
152 | + // colors={['#000000', '#ff0000']} | ||
153 | + // progressBackgroundColor="#ffffff" | ||
154 | + // /> | ||
155 | + // } | ||
156 | + /> | ||
157 | + } | ||
158 | + </View> | ||
159 | + ); | ||
160 | + } | ||
161 | +} | ||
162 | + | ||
163 | +let {width} = Dimensions.get('window'); | ||
164 | +const ROW_COLUMN = 3 | ||
165 | + | ||
166 | +let styles = StyleSheet.create({ | ||
167 | + container: { | ||
168 | + flex: 1, | ||
169 | + backgroundColor: 'white', | ||
170 | + }, | ||
171 | + contentContainer: { | ||
172 | + }, | ||
173 | + tabContainer: { | ||
174 | + flex: 1, | ||
175 | + flexDirection: 'row', | ||
176 | + flexWrap: 'wrap', | ||
177 | + backgroundColor: 'white' | ||
178 | + }, | ||
179 | + tabItemContainer: { | ||
180 | + width: width / ROW_COLUMN, | ||
181 | + alignItems: 'center', | ||
182 | + justifyContent: 'center', | ||
183 | + }, | ||
184 | + sectionTitle: { | ||
185 | + fontWeight: 'bold', | ||
186 | + fontSize: 20, | ||
187 | + marginTop: 10, | ||
188 | + marginBottom: 10, | ||
189 | + marginLeft: 20, | ||
190 | + color: 'black', | ||
191 | + }, | ||
192 | + sectionContainer: { | ||
193 | + backgroundColor: 'white', | ||
194 | + }, | ||
195 | + emptyContainer: { | ||
196 | + marginTop: 56, | ||
197 | + alignItems: 'center', | ||
198 | + justifyContent: 'center', | ||
199 | + }, | ||
200 | + emptyTitle: { | ||
201 | + fontWeight: 'bold', | ||
202 | + fontSize: 24, | ||
203 | + color: '#CCCCCC' | ||
204 | + }, | ||
205 | + | ||
206 | + tipContainer: { | ||
207 | + flexDirection: 'row', | ||
208 | + alignItems: 'center', | ||
209 | + backgroundColor: '#ffffff', | ||
210 | + justifyContent: 'space-between', | ||
211 | + paddingLeft: 11, | ||
212 | + paddingRight: 14, | ||
213 | + }, | ||
214 | + tipStyle: { | ||
215 | + fontFamily: 'PingFang-SC-Medium', | ||
216 | + fontSize: 14, | ||
217 | + color: '#4A4A4A', | ||
218 | + backgroundColor: 'transparent', | ||
219 | + textAlign: 'center', | ||
220 | + }, | ||
221 | + openImage: { | ||
222 | + width: 60, | ||
223 | + height: 25, | ||
224 | + marginRight: 14 | ||
225 | + }, | ||
226 | + line: { | ||
227 | + backgroundColor: '#EEEEEE', | ||
228 | + left: 0, | ||
229 | + right: 0, | ||
230 | + bottom: 0, | ||
231 | + position: 'absolute' | ||
232 | + }, | ||
233 | + | ||
234 | +}) |
@@ -26,4 +26,9 @@ export default keyMirror({ | @@ -26,4 +26,9 @@ export default keyMirror({ | ||
26 | 26 | ||
27 | MESSAGE_LIST_CHANGE_EDIT_STATUS: null, | 27 | MESSAGE_LIST_CHANGE_EDIT_STATUS: null, |
28 | MESSAGE_LIST_CHANGE_SELECTED_STATUS: null, | 28 | MESSAGE_LIST_CHANGE_SELECTED_STATUS: null, |
29 | + | ||
30 | + //内容消息 | ||
31 | + SET_CONTENT_LIST_ID: null, | ||
32 | + SET_CONTENT_CATEGORY_NAME: null, | ||
33 | + SET_CONTENT_TIP_FLAG: null, | ||
29 | }); | 34 | }); |
1 | +/** | ||
2 | + * Created by zzz on 2019/3/5. | ||
3 | + */ | ||
4 | + | ||
5 | +'use strict' | ||
6 | + | ||
7 | +import React, {Component} from "react"; | ||
8 | +import ReactNative, { StyleSheet, Dimensions, Platform, View, Text, NativeModules, InteractionManager, NativeAppEventEmitter, | ||
9 | +} from 'react-native' | ||
10 | + | ||
11 | +import {bindActionCreators} from "redux"; | ||
12 | +import {connect} from "react-redux"; | ||
13 | +import {Map} from "immutable"; | ||
14 | +import * as contentActions from "../reducers/content/contentActions"; | ||
15 | + | ||
16 | +import ContentMessageView from '../components/content/ContentMessageView'; | ||
17 | + | ||
18 | +const actions = [ | ||
19 | + contentActions, | ||
20 | +] | ||
21 | + | ||
22 | +function mapStateToProps(state) { | ||
23 | + return { | ||
24 | + contentTipFlag: state.content.contentTipFlag, | ||
25 | + }; | ||
26 | +} | ||
27 | + | ||
28 | +function mapDispatchToProps(dispatch) { | ||
29 | + | ||
30 | + const creators = Map() | ||
31 | + .merge(...actions) | ||
32 | + .filter(value => typeof value === 'function') | ||
33 | + .toObject(); | ||
34 | + | ||
35 | + return { | ||
36 | + actions: bindActionCreators(creators, dispatch), | ||
37 | + dispatch | ||
38 | + }; | ||
39 | +} | ||
40 | + | ||
41 | +class ContentMessageContainer extends Component { | ||
42 | + constructor(props) { | ||
43 | + super(props); | ||
44 | + this._onEndReached = this._onEndReached.bind(this); | ||
45 | + } | ||
46 | + | ||
47 | + componentDidMount() { | ||
48 | + | ||
49 | + } | ||
50 | + | ||
51 | + componentWillUnmount() { | ||
52 | + | ||
53 | + } | ||
54 | + | ||
55 | + | ||
56 | + onRefresh() { | ||
57 | + | ||
58 | + } | ||
59 | + | ||
60 | + _onEndReached() { | ||
61 | + | ||
62 | + } | ||
63 | + | ||
64 | + render() { | ||
65 | + let { | ||
66 | + contentTipFlag, | ||
67 | + } = this.props | ||
68 | + let isFetching = false; | ||
69 | + return ( | ||
70 | + <View style={styles.container}> | ||
71 | + <ContentMessageView | ||
72 | + ref={(view) => { | ||
73 | + this.messageView = view | ||
74 | + }} | ||
75 | + contentTipFlag={contentTipFlag}/> | ||
76 | + </View> | ||
77 | + ) | ||
78 | + } | ||
79 | +} | ||
80 | + | ||
81 | +let styles = StyleSheet.create({ | ||
82 | + container: { | ||
83 | + flex: 1, | ||
84 | + }, | ||
85 | +}); | ||
86 | + | ||
87 | +export default connect(mapStateToProps, mapDispatchToProps, null, {withRef: true})(ContentMessageContainer) |
js/message/images/content_attentioned@2x.png
0 → 100644
1.93 KB
js/message/images/content_attentioned@3x.png
0 → 100644
2.91 KB
js/message/images/content_fan@2x.png
0 → 100644
1.82 KB
js/message/images/content_fan@3x.png
0 → 100644
2.83 KB
js/message/images/content_gz@2x.png
0 → 100644
2.31 KB
js/message/images/content_gz@3x.png
0 → 100644
3.69 KB
js/message/images/content_icon@2x.png
0 → 100644
1.85 KB
js/message/images/content_icon@3x.png
0 → 100644
2.95 KB
js/message/images/content_reply@2x.png
0 → 100644
1.34 KB
js/message/images/content_reply@3x.png
0 → 100644
2.04 KB
js/message/images/content_tz@2x.png
0 → 100644
1.81 KB
js/message/images/content_tz@3x.png
0 → 100644
2.88 KB
js/message/images/content_zan@2x.png
0 → 100644
1.57 KB
js/message/images/content_zan@3x.png
0 → 100644
2.53 KB
js/message/images/open_btn@2x.png
0 → 100644
1.22 KB
js/message/images/open_btn@3x.png
0 → 100644
1.86 KB
1 | +'use strict'; | ||
2 | + | ||
3 | +import ReactNative from 'react-native'; | ||
4 | +import ContentService from '../../services/ContentService'; | ||
5 | +import Moment from "moment"; | ||
6 | + | ||
7 | +const { | ||
8 | + SET_CONTENT_LIST_ID, | ||
9 | + SET_CONTENT_CATEGORY_NAME, | ||
10 | + SET_CONTENT_TIP_FLAG, | ||
11 | + | ||
12 | +} = require('../../constants/actionTypes').default; | ||
13 | + | ||
14 | +export function setContentListId(id) { | ||
15 | + return { | ||
16 | + type: SET_CONTENT_LIST_ID, | ||
17 | + payload: id, | ||
18 | + }; | ||
19 | +} | ||
20 | + | ||
21 | +export function setContentCategoryName(name) { | ||
22 | + return { | ||
23 | + type: SET_CONTENT_CATEGORY_NAME, | ||
24 | + payload: name, | ||
25 | + }; | ||
26 | +} | ||
27 | + | ||
28 | +export function setContentTipFlag(value) { | ||
29 | + return { | ||
30 | + type: SET_CONTENT_TIP_FLAG, | ||
31 | + payload: value, | ||
32 | + }; | ||
33 | +} |
1 | +'use strict'; | ||
2 | + | ||
3 | +import InitialState from './contentInitialState'; | ||
4 | +import Immutable, {Map} from 'immutable'; | ||
5 | + | ||
6 | +const { | ||
7 | + SET_CONTENT_LIST_ID, | ||
8 | + SET_CONTENT_CATEGORY_NAME, | ||
9 | + SET_CONTENT_TIP_FLAG, | ||
10 | + | ||
11 | +} = require('../../constants/actionTypes').default; | ||
12 | + | ||
13 | +const initialState = new InitialState; | ||
14 | + | ||
15 | +export default function grassReducer(state=initialState, action) { | ||
16 | + switch(action.type) { | ||
17 | + case SET_CONTENT_LIST_ID: { | ||
18 | + return state.set('contentListId', action.payload); | ||
19 | + } | ||
20 | + | ||
21 | + case SET_CONTENT_CATEGORY_NAME: { | ||
22 | + return state.set('contentCategoryName', action.payload); | ||
23 | + } | ||
24 | + | ||
25 | + case SET_CONTENT_TIP_FLAG: { | ||
26 | + return state.set('contentTipFlag', action.payload); | ||
27 | + } | ||
28 | + | ||
29 | + } | ||
30 | + return state; | ||
31 | + } |
@@ -2,11 +2,13 @@ import {combineReducers} from 'redux'; | @@ -2,11 +2,13 @@ import {combineReducers} from 'redux'; | ||
2 | import app from './app/appReducer'; | 2 | import app from './app/appReducer'; |
3 | import message from './message/messageReducer'; | 3 | import message from './message/messageReducer'; |
4 | import list from './list/listReducer'; | 4 | import list from './list/listReducer'; |
5 | +import content from './content/contentReducer'; | ||
5 | 6 | ||
6 | const rootReducer = combineReducers({ | 7 | const rootReducer = combineReducers({ |
7 | app, | 8 | app, |
8 | message, | 9 | message, |
9 | list, | 10 | list, |
11 | + content | ||
10 | }); | 12 | }); |
11 | 13 | ||
12 | export default rootReducer; | 14 | export default rootReducer; |
js/message/services/ContentService.js
0 → 100644
-
Please register or login to post a comment