@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
|
@@ -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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
-
|
|
178
|
-
|
|
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(
|
|
199
|
-
|
|
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
|
-
|
|
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
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
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
|
-
<
|
|
346
|
-
{
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
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,
|