@plusscommunities/pluss-core-app 1.4.3-beta.0 → 1.4.4-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@plusscommunities/pluss-core-app",
3
- "version": "1.4.3-beta.0",
3
+ "version": "1.4.4-beta.0",
4
4
  "description": "Core extension package for Pluss Communities platform",
5
5
  "main": "src/index.js",
6
6
  "scripts": {
@@ -26,13 +26,14 @@ export const reactionActions = {
26
26
  },
27
27
  });
28
28
  },
29
- addComment: (entityId, entityType, entityName, site, comment, image) => {
29
+ addComment: (entityId, entityType, entityName, site, comment, image, parentId) => {
30
30
  const data = {
31
31
  entityId,
32
32
  entityType,
33
33
  entityName,
34
34
  site,
35
35
  comment,
36
+ parentId,
36
37
  };
37
38
  if (!_.isEmpty(image)) data.image = image;
38
39
  return authedFunction({
@@ -2,6 +2,7 @@ import React, { Component } from 'react';
2
2
  import { connect } from 'react-redux';
3
3
  import { Keyboard, TextInput, View, ImageBackground, TouchableOpacity, Dimensions } from 'react-native';
4
4
  import { Icon } from 'react-native-elements';
5
+ import { getBottomSpace } from 'react-native-iphone-x-helper';
5
6
  import _ from 'lodash';
6
7
  import { getApiError } from '../session';
7
8
  import { getShadowStyle } from '../helper';
@@ -26,9 +27,9 @@ class CommentReply extends Component {
26
27
  }
27
28
 
28
29
  componentDidMount() {
29
- if (this.props.commentSection) {
30
+ if (this.props.commentSection && this.props.commentSection.current) {
30
31
  this.setState({
31
- commentsLoading: this.props.commentSection.isLoading(),
32
+ commentsLoading: this.props.commentSection.current.getWrappedInstance().isLoading(),
32
33
  });
33
34
  }
34
35
  }
@@ -39,7 +40,7 @@ class CommentReply extends Component {
39
40
  });
40
41
  setTimeout(() => {
41
42
  if (!this.props.noScroll) {
42
- this.props.scrollView.scrollToEnd({ animated: true });
43
+ this.props.scrollView?.current?.scrollToEnd({ animated: true });
43
44
  }
44
45
  }, 500);
45
46
  };
@@ -81,7 +82,7 @@ class CommentReply extends Component {
81
82
  addComment() {
82
83
  setTimeout(() => {
83
84
  if (!this.props.noScroll) {
84
- this.props.scrollView.scrollToEnd({ animated: true });
85
+ this.props.scrollView?.current?.scrollToEnd({ animated: true });
85
86
  }
86
87
  }, 500);
87
88
  const text = this.state.commentInput;
@@ -93,20 +94,20 @@ class CommentReply extends Component {
93
94
  });
94
95
  Keyboard.dismiss();
95
96
  if (this.props.commentSection) {
96
- this.props.commentSection.startedAddingComment();
97
+ this.props.commentSection?.current?.getWrappedInstance().startedAddingComment();
97
98
  }
98
99
  reactionActions
99
- .addComment(this.props.entityId, this.props.entityType, this.props.entityName, this.props.site, text, image)
100
+ .addComment(this.props.entityId, this.props.entityType, this.props.entityName, this.props.site, text, image, this.props.threadId)
100
101
  .then(res => {
101
102
  if (this.props.commentSection) {
102
- this.props.commentSection.commentAdded(res.data);
103
+ this.props.commentSection?.current?.getWrappedInstance().commentAdded(res.data);
103
104
  }
104
105
  this.setState({
105
106
  addingComment: false,
106
107
  });
107
108
  setTimeout(() => {
108
109
  if (!this.props.noScroll) {
109
- this.props.scrollView.scrollToEnd({ animated: true });
110
+ this.props.scrollView?.current?.scrollToEnd({ animated: true });
110
111
  }
111
112
  }, 500);
112
113
  })
@@ -181,9 +182,11 @@ class CommentReply extends Component {
181
182
 
182
183
  render() {
183
184
  if (_.includes(this.props.user.hidden, 'addComment')) {
185
+ console.log('no way');
184
186
  return null;
185
187
  }
186
188
  if (this.state.commentsLoading) {
189
+ console.log('still loading');
187
190
  return null;
188
191
  }
189
192
  return (
@@ -202,12 +205,12 @@ class CommentReply extends Component {
202
205
  value={this.state.commentInput}
203
206
  onFocus={() => {
204
207
  if (!this.props.noScroll) {
205
- this.props.scrollView.scrollToEnd({ animated: true });
208
+ this.props.scrollView?.current?.scrollToEnd({ animated: true });
206
209
  }
207
210
  }}
208
211
  onChangeText={value => {
209
212
  if (!this.props.noScroll) {
210
- this.props.scrollView.scrollToEnd({ animated: false });
213
+ this.props.scrollView?.current?.scrollToEnd({ animated: false });
211
214
  }
212
215
  this.setState({
213
216
  commentInput: value,
@@ -290,6 +293,7 @@ const styles = {
290
293
  backgroundColor: '#fff',
291
294
  paddingVertical: 8,
292
295
  paddingHorizontal: 8,
296
+ paddingBottom: 8 + getBottomSpace(),
293
297
  flexGrow: 1,
294
298
  },
295
299
  inputText: {
@@ -4,7 +4,7 @@ import _ from 'lodash';
4
4
  import moment from 'moment';
5
5
  import { connect } from 'react-redux';
6
6
  import { Icon } from 'react-native-elements';
7
- import { getPluralS, getThumb300, get1400, getSiteSettingFromState } from '../helper';
7
+ import { getPluralS, getThumb300, get1400, getSiteSettingFromState, getFirstName, getPluralOptions } from '../helper';
8
8
  import { getMainBrandingColourFromState, TEXT_DARKEST, BG_GREY, TEXT_LIGHT, LINEGREY } from '../colours';
9
9
  import { reactionActions, notificationActions } from '../apis';
10
10
  import { ConfirmPopup } from './ConfirmPopup';
@@ -12,6 +12,7 @@ import { ProfilePic } from './ProfilePic';
12
12
  import { ImagePopup } from './ImagePopup';
13
13
  import { InlineButton } from './InlineButton';
14
14
  import { Spinner } from './Spinner';
15
+ import { Services } from '../config';
15
16
 
16
17
  class CommentSection extends Component {
17
18
  constructor(props) {
@@ -103,6 +104,10 @@ class CommentSection extends Component {
103
104
  this.props.commentReply.focusInput();
104
105
  }
105
106
 
107
+ onOpenThread = comment => {
108
+ Services.navigation.navigate('thread', { ...this.props, threadId: comment.Id });
109
+ };
110
+
106
111
  onMute = () => {
107
112
  const { entityType, entityId } = this.props;
108
113
  this.setState({ processing: true }, async () => {
@@ -174,9 +179,8 @@ class CommentSection extends Component {
174
179
  commentsLoadStarted: true,
175
180
  commentsLoading: true,
176
181
  });
177
- if (this.props.commentReply) {
178
- this.props.commentReply.loadingStarted();
179
- }
182
+ this.props.commentReply?.current?.getWrappedInstance().loadingStarted();
183
+
180
184
  this.loadComments();
181
185
  }
182
186
  }
@@ -195,9 +199,17 @@ class CommentSection extends Component {
195
199
  this.setState(
196
200
  {
197
201
  comments: _.sortBy(
198
- _.uniqBy(_.concat(this.state.comments, res.data), c => {
199
- return c.Id;
200
- }),
202
+ _.uniqBy(
203
+ _.filter(_.concat(this.state.comments, res.data), c => {
204
+ if (!this.props.threadId) {
205
+ return true;
206
+ }
207
+ return c.Id === this.props.threadId || c.ParentId === this.props.threadId;
208
+ }),
209
+ c => {
210
+ return c.Id;
211
+ },
212
+ ),
201
213
  'Timestamp',
202
214
  ),
203
215
  commentsLoading: false,
@@ -208,9 +220,9 @@ class CommentSection extends Component {
208
220
  }
209
221
  },
210
222
  );
211
- if (this.props.commentReply) {
212
- this.props.commentReply.loadingCompleted();
213
- }
223
+ //if (this.props.commentReply) {
224
+ this.props.commentReply?.current?.getWrappedInstance().loadingCompleted();
225
+ //}
214
226
  if (this.props.live) {
215
227
  this.loadTimer = setTimeout(() => {
216
228
  this.loadComments();
@@ -314,6 +326,55 @@ class CommentSection extends Component {
314
326
  );
315
327
  }
316
328
 
329
+ renderReplyText = c => {
330
+ if (this.props.threadId || this.props.hideReplyButton) {
331
+ return null;
332
+ }
333
+
334
+ const threadComments = _.filter(this.state.comments, innerC => {
335
+ return innerC.ParentId === c.Id;
336
+ });
337
+
338
+ let content = null;
339
+
340
+ if (_.isEmpty(threadComments)) {
341
+ // no replies
342
+ content = (
343
+ <Text style={[styles.commentRepliesText, { color: this.props.colourBrandingMain }]}>{`Reply to ${getFirstName(
344
+ c.User ? c.User.displayName : 'comment',
345
+ )}`}</Text>
346
+ );
347
+ } else {
348
+ // existing replies
349
+ const profilePics = _.take(
350
+ _.uniqBy(threadComments, c => c.UserId),
351
+ 3,
352
+ );
353
+ content = (
354
+ <View style={styles.multiReplyContainer}>
355
+ {profilePics.map((c, i) => {
356
+ return <ProfilePic style={{ marginRight: -10 }} Diameter={20} ProfilePic={c.User.profilePic} />;
357
+ })}
358
+ <Text style={[styles.commentRepliesText, { marginLeft: 20, color: this.props.colourBrandingMain }]}>{`${
359
+ threadComments.length
360
+ } repl${getPluralOptions(threadComments.length, 'y', 'ies')}`}</Text>
361
+ </View>
362
+ );
363
+ }
364
+
365
+ return (
366
+ <View style={styles.commentReplies}>
367
+ <TouchableOpacity
368
+ onPress={() => {
369
+ this.onOpenThread(c);
370
+ }}
371
+ >
372
+ {content}
373
+ </TouchableOpacity>
374
+ </View>
375
+ );
376
+ };
377
+
317
378
  renderComment(c) {
318
379
  return (
319
380
  <View style={styles.comment} key={c.Id}>
@@ -327,27 +388,32 @@ class CommentSection extends Component {
327
388
  <Icon name="trash" type="font-awesome" iconStyle={styles.commentButtonIcon} />
328
389
  </View>
329
390
  </TouchableOpacity>
330
- ) : (
331
- !this.props.disableFlag && (
332
- <TouchableOpacity onPress={this.onPressReportComment.bind(this, c)}>
333
- <View style={[styles.commentButtonContainer, { backgroundColor: this.props.colourBrandingMain }]}>
334
- <Icon name="flag" type="font-awesome" iconStyle={styles.commentButtonIcon} />
335
- </View>
336
- </TouchableOpacity>
337
- )
338
- )}
391
+ ) : null
392
+ // (
393
+ // !this.props.disableFlag && (
394
+ // <TouchableOpacity onPress={this.onPressReportComment.bind(this, c)}>
395
+ // <View style={[styles.commentButtonContainer, { backgroundColor: this.props.colourBrandingMain }]}>
396
+ // <Icon name="flag" type="font-awesome" iconStyle={styles.commentButtonIcon} />
397
+ // </View>
398
+ // </TouchableOpacity>
399
+ // )
400
+ // )
401
+ }
339
402
  <Text style={[styles.commentName, { fontSize: this.getAdjustedSize(13) }]}>{c.User.displayName}</Text>
340
403
  </View>
341
404
  {!_.isEmpty(c.Comment) && <Text style={[styles.commentText, { fontSize: this.getAdjustedSize(13) }]}>{c.Comment}</Text>}
342
405
  {this.renderCommentImage(c)}
343
406
  </View>
344
407
  </View>
345
- <Text style={[styles.commentTime, { fontSize: this.getAdjustedSize(13) }]}>
346
- {moment
347
- .utc(c.Timestamp)
348
- .local()
349
- .format('D MMM • h:mma')}
350
- </Text>
408
+ <View style={styles.commentBottom}>
409
+ <Text style={[styles.commentTime, { fontSize: this.getAdjustedSize(13) }]}>
410
+ {moment
411
+ .utc(c.Timestamp)
412
+ .local()
413
+ .format('D MMM • h:mma')}
414
+ </Text>
415
+ {this.renderReplyText(c)}
416
+ </View>
351
417
  </View>
352
418
  );
353
419
  }
@@ -418,6 +484,11 @@ class CommentSection extends Component {
418
484
  if (this.props.reverseOrder) {
419
485
  source = source.reverse();
420
486
  }
487
+ if (!this.props.showReplies && !this.props.threadId) {
488
+ source = _.filter(source, c => {
489
+ return !c.ParentId;
490
+ });
491
+ }
421
492
  return (
422
493
  <View style={styles.commentSection}>
423
494
  {!this.isEmpty() && (
@@ -539,12 +610,30 @@ const styles = StyleSheet.create({
539
610
  fontFamily: 'sf-regular',
540
611
  color: TEXT_DARKEST,
541
612
  },
613
+ commentBottom: {
614
+ flexDirection: 'row-reverse',
615
+ justifyContent: 'space-between',
616
+ alignItems: 'center',
617
+ },
542
618
  commentTime: {
543
619
  fontFamily: 'sf-regular',
544
620
  marginTop: 4,
545
621
  color: TEXT_LIGHT,
546
622
  textAlign: 'right',
547
623
  },
624
+ commentReplies: {
625
+ flex: 1,
626
+ paddingLeft: 48,
627
+ },
628
+ commentRepliesText: {
629
+ fontFamily: 'sf-semibold',
630
+ fontSize: 15,
631
+ },
632
+ multiReplyContainer: {
633
+ flexDirection: 'row',
634
+ alignItems: 'center',
635
+ paddingVertical: 4,
636
+ },
548
637
  commentImageContainer: {
549
638
  marginTop: 8,
550
639
  width: 60,