Authored by 陈林

Merge commit '983d3c88' into V6.8.9

@@ -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)
  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 Immutable, {Record, List, Map} from 'immutable';
  4 +
  5 +let InitialState = Record({
  6 + contentListId: 0,
  7 + contentCategoryName: '',
  8 + contentTipFlag: 0,
  9 +
  10 +});
  11 +
  12 +export default InitialState;
  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;
  1 +'use strict';
  2 +
  3 +import Request from '../../common/services/NativeRequest';
  4 +
  5 +export default class ContentService {
  6 +
  7 + constructor (host) {
  8 + let baseURL = 'http://api.yoho.cn';
  9 + if(host){
  10 + baseURL = host;
  11 + }
  12 + this.api = new Request(baseURL);
  13 + }
  14 +
  15 +}