Comment list of post detail page. reviewed by redding.
Showing
8 changed files
with
112 additions
and
17 deletions
@@ -317,6 +317,7 @@ export default function community(platform) { | @@ -317,6 +317,7 @@ export default function community(platform) { | ||
317 | }, | 317 | }, |
318 | 318 | ||
319 | homeOnRight(state) { | 319 | homeOnRight(state) { |
320 | + // Actions.SubjectPost(); | ||
320 | state.dispatch(startEditPost(state.getPostingState())); | 321 | state.dispatch(startEditPost(state.getPostingState())); |
321 | }, | 322 | }, |
322 | /* | 323 | /* |
@@ -8,6 +8,8 @@ import { | @@ -8,6 +8,8 @@ import { | ||
8 | Image, | 8 | Image, |
9 | } from 'react-native' | 9 | } from 'react-native' |
10 | 10 | ||
11 | +import SlicedImage from '../../../common/components/SlicedImage'; | ||
12 | + | ||
11 | export default class SubjectContent extends Component { | 13 | export default class SubjectContent extends Component { |
12 | constructor(props) { | 14 | constructor(props) { |
13 | super(props); | 15 | super(props); |
@@ -7,10 +7,12 @@ import { | @@ -7,10 +7,12 @@ import { | ||
7 | ListView, | 7 | ListView, |
8 | StyleSheet, | 8 | StyleSheet, |
9 | Image, | 9 | Image, |
10 | + Dimensions, | ||
10 | } from 'react-native' | 11 | } from 'react-native' |
11 | import UserBrief from '../home/UserBrief'; | 12 | import UserBrief from '../home/UserBrief'; |
12 | 13 | ||
13 | import SubjectContent from './SubjectContent' | 14 | import SubjectContent from './SubjectContent' |
15 | +import LoadMoreIndicator from '../../../common/components/LoadMoreIndicator'; | ||
14 | 16 | ||
15 | export default class SubjectPost extends Component { | 17 | export default class SubjectPost extends Component { |
16 | constructor(props) { | 18 | constructor(props) { |
@@ -31,7 +33,7 @@ export default class SubjectPost extends Component { | @@ -31,7 +33,7 @@ export default class SubjectPost extends Component { | ||
31 | <UserBrief | 33 | <UserBrief |
32 | avatar={rowData.headIcon} | 34 | avatar={rowData.headIcon} |
33 | name={rowData.nickName} | 35 | name={rowData.nickName} |
34 | - timeago={this.props.timeagoStr} | 36 | + timeago={rowData.timeago} |
35 | isOwner={rowData.LZ} | 37 | isOwner={rowData.LZ} |
36 | onPressAvatar={() => { | 38 | onPressAvatar={() => { |
37 | this.props.onPressAvatar && this.props.onPressAvatar(); | 39 | this.props.onPressAvatar && this.props.onPressAvatar(); |
@@ -61,26 +63,42 @@ export default class SubjectPost extends Component { | @@ -61,26 +63,42 @@ export default class SubjectPost extends Component { | ||
61 | {this.renderLikeAvatar(rowData.praiseUsers)} | 63 | {this.renderLikeAvatar(rowData.praiseUsers)} |
62 | <Text style={styles.likeText}>{rowData.praise + '人点赞'}</Text> | 64 | <Text style={styles.likeText}>{rowData.praise + '人点赞'}</Text> |
63 | </View> | 65 | </View> |
64 | - <View style={styles.rightContainer}> | 66 | + <View style={styles.rightLikeContainer}> |
65 | <Text style={styles.browseText}>{rowData.browse + '人看过'}</Text> | 67 | <Text style={styles.browseText}>{rowData.browse + '人看过'}</Text> |
66 | </View> | 68 | </View> |
67 | </View> | 69 | </View> |
68 | ); | 70 | ); |
69 | break; | 71 | break; |
72 | + case 'comments': | ||
73 | + return ( | ||
74 | + <View style={styles.commentContainer}> | ||
75 | + <UserBrief | ||
76 | + avatar={rowData.headIcon} | ||
77 | + name={rowData.nickName} | ||
78 | + timeago={rowData.timeago} | ||
79 | + isOwner={rowData.LZ} | ||
80 | + onPressAvatar={() => { | ||
81 | + this.props.onPressAvatar && this.props.onPressAvatar(); | ||
82 | + }} | ||
83 | + /> | ||
84 | + <SubjectContent blocks={rowData.blocks}/> | ||
85 | + <View style={styles.commentSeparator}/> | ||
86 | + </View> | ||
87 | + ); | ||
88 | + break; | ||
70 | default: | 89 | default: |
71 | break; | 90 | break; |
72 | } | 91 | } |
73 | } | 92 | } |
74 | 93 | ||
75 | renderLikeAvatar(avatars) { | 94 | renderLikeAvatar(avatars) { |
76 | - console.log(avatars); | ||
77 | if (avatars.length) { | 95 | if (avatars.length) { |
78 | avatars.reverse(); | 96 | avatars.reverse(); |
79 | return ( | 97 | return ( |
80 | <View style={styles.avatarPannel}> | 98 | <View style={styles.avatarPannel}> |
81 | {avatars.map((item, i)=> { | 99 | {avatars.map((item, i)=> { |
82 | return ( | 100 | return ( |
83 | - <Image style={[styles.likeAvatar,{right:10*i}]} source={{uri:item.headIcon}}/> | 101 | + <Image key={i} style={[styles.likeAvatar,{right:10*i}]} source={{uri:item.headIcon}}/> |
84 | ); | 102 | ); |
85 | })} | 103 | })} |
86 | </View> | 104 | </View> |
@@ -94,11 +112,28 @@ export default class SubjectPost extends Component { | @@ -94,11 +112,28 @@ export default class SubjectPost extends Component { | ||
94 | dataSource={this.dataSource.cloneWithRowsAndSections(this.props.dataBlob)} | 112 | dataSource={this.dataSource.cloneWithRowsAndSections(this.props.dataBlob)} |
95 | renderRow={this.renderRow} | 113 | renderRow={this.renderRow} |
96 | enableEmptySections={true} | 114 | enableEmptySections={true} |
115 | + onEndReached={() => { | ||
116 | + this.props.onEndReached && this.props.onEndReached(); | ||
117 | + }} | ||
118 | + renderFooter={()=>{ | ||
119 | + if (this.props.endReached) { | ||
120 | + return <LoadMoreIndicator | ||
121 | + isVisible={true} | ||
122 | + text={'没有更多啦'} | ||
123 | + /> | ||
124 | + } else { | ||
125 | + return <LoadMoreIndicator | ||
126 | + isVisible={true} | ||
127 | + animating={this.props.isFetching} | ||
128 | + /> | ||
129 | + } | ||
130 | + }} | ||
97 | /> | 131 | /> |
98 | ); | 132 | ); |
99 | } | 133 | } |
100 | } | 134 | } |
101 | 135 | ||
136 | +let {width, height} = Dimensions.get('window'); | ||
102 | const styles = StyleSheet.create({ | 137 | const styles = StyleSheet.create({ |
103 | container: { | 138 | container: { |
104 | top: 0, | 139 | top: 0, |
@@ -134,7 +169,7 @@ const styles = StyleSheet.create({ | @@ -134,7 +169,7 @@ const styles = StyleSheet.create({ | ||
134 | flex: 1, | 169 | flex: 1, |
135 | flexDirection: 'row', | 170 | flexDirection: 'row', |
136 | alignItems: 'center', | 171 | alignItems: 'center', |
137 | - justifyContent: 'flex-end' | 172 | + justifyContent: 'flex-end', |
138 | }, | 173 | }, |
139 | likeAvatar: { | 174 | likeAvatar: { |
140 | width: 30, | 175 | width: 30, |
@@ -143,7 +178,7 @@ const styles = StyleSheet.create({ | @@ -143,7 +178,7 @@ const styles = StyleSheet.create({ | ||
143 | }, | 178 | }, |
144 | likeText: { | 179 | likeText: { |
145 | fontSize: 14, | 180 | fontSize: 14, |
146 | - left: 10, | 181 | + left: -10, |
147 | }, | 182 | }, |
148 | browseText: { | 183 | browseText: { |
149 | fontSize: 14, | 184 | fontSize: 14, |
@@ -156,6 +191,17 @@ const styles = StyleSheet.create({ | @@ -156,6 +191,17 @@ const styles = StyleSheet.create({ | ||
156 | backgroundColor: 'white', | 191 | backgroundColor: 'white', |
157 | paddingLeft: 15, | 192 | paddingLeft: 15, |
158 | }, | 193 | }, |
194 | + commentContainer: { | ||
195 | + paddingTop: 10, | ||
196 | + paddingLeft: 15, | ||
197 | + paddingRight: 15, | ||
198 | + backgroundColor: 'white', | ||
199 | + }, | ||
200 | + commentSeparator: { | ||
201 | + backgroundColor: '#a0a0a0', | ||
202 | + height: 0.5, | ||
203 | + width: width-30, | ||
204 | + }, | ||
159 | headerRight: { | 205 | headerRight: { |
160 | flex: 1, | 206 | flex: 1, |
161 | flexDirection: 'row', | 207 | flexDirection: 'row', |
@@ -75,8 +75,6 @@ class PostingContainer extends Component{ | @@ -75,8 +75,6 @@ class PostingContainer extends Component{ | ||
75 | if (shouldHideTabBar(this.props.navigationState)) { | 75 | if (shouldHideTabBar(this.props.navigationState)) { |
76 | NativeModules.YH_CommunityHelper.hideTabBar(); | 76 | NativeModules.YH_CommunityHelper.hideTabBar(); |
77 | } | 77 | } |
78 | - | ||
79 | - | ||
80 | } | 78 | } |
81 | 79 | ||
82 | _onGetBordList() { | 80 | _onGetBordList() { |
@@ -52,16 +52,21 @@ function mapDispatchToProps(dispatch) { | @@ -52,16 +52,21 @@ function mapDispatchToProps(dispatch) { | ||
52 | class SubjectPostContainer extends Component { | 52 | class SubjectPostContainer extends Component { |
53 | constructor(props) { | 53 | constructor(props) { |
54 | super(props); | 54 | super(props); |
55 | - | 55 | + this.onEndReached = this.onEndReached.bind(this); |
56 | } | 56 | } |
57 | componentDidMount () { | 57 | componentDidMount () { |
58 | this.props.actions.requestPostContent(300); | 58 | this.props.actions.requestPostContent(300); |
59 | this.props.actions.requestPostComments(300); | 59 | this.props.actions.requestPostComments(300); |
60 | } | 60 | } |
61 | + onEndReached() { | ||
62 | + if (this.props.subject.currentPage>=this.props.subject.totalPages) { | ||
63 | + return; | ||
64 | + } | ||
65 | + this.props.actions.requestPostComments(300, this.props.subject.lastedTime); | ||
66 | + } | ||
61 | render() { | 67 | render() { |
62 | let {headIcon,nickName} = this.props.subject.authorInfo; | 68 | let {headIcon,nickName} = this.props.subject.authorInfo; |
63 | let timeagoStr = timeago().format(this.props.subject.createTime, 'zh_CN'); | 69 | let timeagoStr = timeago().format(this.props.subject.createTime, 'zh_CN'); |
64 | - | ||
65 | let header = { | 70 | let header = { |
66 | headIcon, | 71 | headIcon, |
67 | nickName, | 72 | nickName, |
@@ -74,6 +79,7 @@ class SubjectPostContainer extends Component { | @@ -74,6 +79,7 @@ class SubjectPostContainer extends Component { | ||
74 | praise: this.props.subject.praise, | 79 | praise: this.props.subject.praise, |
75 | browse: this.props.subject.browse, | 80 | browse: this.props.subject.browse, |
76 | } | 81 | } |
82 | + | ||
77 | let dataBlob = { | 83 | let dataBlob = { |
78 | header : [header], | 84 | header : [header], |
79 | // 'title': [this.props.subject.postsTitle], | 85 | // 'title': [this.props.subject.postsTitle], |
@@ -98,18 +104,19 @@ class SubjectPostContainer extends Component { | @@ -98,18 +104,19 @@ class SubjectPostContainer extends Component { | ||
98 | ],], | 104 | ],], |
99 | 105 | ||
100 | like: [likeData], | 106 | like: [likeData], |
107 | + comments: this.props.subject.commentList.toJS(), | ||
101 | }; | 108 | }; |
102 | return ( | 109 | return ( |
103 | <View style={styles.container}> | 110 | <View style={styles.container}> |
104 | <SubjectPost | 111 | <SubjectPost |
105 | dataBlob={dataBlob} | 112 | dataBlob={dataBlob} |
113 | + onEndReached={this.onEndReached} | ||
114 | + endReached={this.props.subject.currentPage>=this.props.subject.totalPages} | ||
115 | + isFetching={this.props.subject.isCommentsFetching} | ||
106 | /> | 116 | /> |
107 | </View> | 117 | </View> |
108 | ); | 118 | ); |
109 | } | 119 | } |
110 | - constructDataBlob() { | ||
111 | - | ||
112 | - } | ||
113 | } | 120 | } |
114 | 121 | ||
115 | let {width, height} = Dimensions.get('window'); | 122 | let {width, height} = Dimensions.get('window'); |
@@ -11,6 +11,7 @@ import Immutable, {List, Record} from 'immutable'; | @@ -11,6 +11,7 @@ import Immutable, {List, Record} from 'immutable'; | ||
11 | import { | 11 | import { |
12 | NativeModules, | 12 | NativeModules, |
13 | } from 'react-native'; | 13 | } from 'react-native'; |
14 | +import timeago from 'timeago.js'; | ||
14 | 15 | ||
15 | const { | 16 | const { |
16 | SUBJECT_CONTENT_REQUEST, | 17 | SUBJECT_CONTENT_REQUEST, |
@@ -74,10 +75,12 @@ export function requestPostComments(postsId, lastedTime) { | @@ -74,10 +75,12 @@ export function requestPostComments(postsId, lastedTime) { | ||
74 | }; | 75 | }; |
75 | new PostingService().getPostComments(params) | 76 | new PostingService().getPostComments(params) |
76 | .then(json => { | 77 | .then(json => { |
78 | + console.log(json); | ||
77 | dispatch(commentsRequestSuccess(json)); | 79 | dispatch(commentsRequestSuccess(json)); |
78 | 80 | ||
79 | }) | 81 | }) |
80 | .catch(error => { | 82 | .catch(error => { |
83 | + console.log(error); | ||
81 | dispatch(commentsRequestFailure(error)); | 84 | dispatch(commentsRequestFailure(error)); |
82 | }); | 85 | }); |
83 | } | 86 | } |
@@ -90,6 +93,32 @@ export function doRequestComments() { | @@ -90,6 +93,32 @@ export function doRequestComments() { | ||
90 | } | 93 | } |
91 | 94 | ||
92 | export function commentsRequestSuccess(json) { | 95 | export function commentsRequestSuccess(json) { |
96 | + let {list} = json; | ||
97 | + let newList = []; | ||
98 | + list && list.map((obj,i)=> { | ||
99 | + let {createTime, reply, replyTo, blocks} = obj; | ||
100 | + let timeagoStr = timeago().format(createTime, 'zh_CN'); | ||
101 | + let newBlocks = []; | ||
102 | + blocks && blocks.map((blockItem, i) => { | ||
103 | + let {commentId,content,templateKey,orderBy} = blockItem; | ||
104 | + let newItem = { | ||
105 | + "contentData": content, | ||
106 | + "order": orderBy, | ||
107 | + "templateKey": templateKey, | ||
108 | + }; | ||
109 | + newBlocks.push(newItem); | ||
110 | + }) | ||
111 | + let newObj={ | ||
112 | + timeago: timeagoStr, | ||
113 | + headIcon: reply.headIcon, | ||
114 | + nickName: reply.nickName, | ||
115 | + LZ:false, | ||
116 | + blocks: newBlocks, | ||
117 | + } | ||
118 | + newList.push(newObj); | ||
119 | + }) | ||
120 | + | ||
121 | + json.list = newList; | ||
93 | return { | 122 | return { |
94 | type: SUBJECT_COMMENTS_SUCCESS, | 123 | type: SUBJECT_COMMENTS_SUCCESS, |
95 | payload: json, | 124 | payload: json, |
1 | -/** | 1 | + /** |
2 | * # sunbjectPostInitialState.js | 2 | * # sunbjectPostInitialState.js |
3 | * | 3 | * |
4 | * | 4 | * |
@@ -43,6 +43,9 @@ let InitialState = Record({ | @@ -43,6 +43,9 @@ let InitialState = Record({ | ||
43 | publishTimeString: '', | 43 | publishTimeString: '', |
44 | shareProductSkn: 0, | 44 | shareProductSkn: 0, |
45 | LZ: false,//楼主 | 45 | LZ: false,//楼主 |
46 | + lastedTime: 0, | ||
47 | + totalPages: 0, | ||
48 | + currentPage: 0, | ||
46 | commentList: List(),// | 49 | commentList: List(),// |
47 | }); | 50 | }); |
48 | 51 |
@@ -94,9 +94,18 @@ export default function postingReducer(state = initialState, action) { | @@ -94,9 +94,18 @@ export default function postingReducer(state = initialState, action) { | ||
94 | } | 94 | } |
95 | break; | 95 | break; |
96 | case SUBJECT_COMMENTS_SUCCESS:{ | 96 | case SUBJECT_COMMENTS_SUCCESS:{ |
97 | - let existedAry = state.commentList.toJS; | ||
98 | - let nextData = [...existedAry,...action.payload]; | ||
99 | - let nextState = state.set('commentList',Immutable.fromJS(nextData)); | 97 | + let {lastedTime, total, list, pageSize} = action.payload; |
98 | + let tailCount = (total%pageSize)>0?1:0; | ||
99 | + let totalPages = total/pageSize + tailCount; | ||
100 | + | ||
101 | + let existedAry = state.commentList.toJS(); | ||
102 | + let nextData = [...existedAry,...list]; | ||
103 | + let page = state.currentPage; | ||
104 | + page++; | ||
105 | + let nextState = state.set('commentList',Immutable.fromJS(nextData)) | ||
106 | + .set('lastedTime',lastedTime) | ||
107 | + .set('totalPages',totalPages) | ||
108 | + .set('currentPage',page); | ||
100 | return nextState; | 109 | return nextState; |
101 | } | 110 | } |
102 | break; | 111 | break; |
-
Please register or login to post a comment