@plusscommunities/pluss-core-app 1.2.4 → 1.4.2-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 +21 -16
- package/src/apis/index.js +1 -0
- package/src/apis/notificationActions.js +47 -0
- package/src/components/CommentReply.js +5 -5
- package/src/components/CommentSection.js +160 -17
- package/src/components/ImageUploadProgress.js +1 -1
- package/src/components/ImageUploader.js +5 -5
- package/src/components/PlussChat.js +1 -1
- package/src/components/VideoPopup.js +2 -1
- package/src/components/expo-image-picker-multiple/ImageBrowser.js +3 -3
package/package.json
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@plusscommunities/pluss-core-app",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.4.2-beta.0",
|
|
4
4
|
"description": "Core extension package for Pluss Communities platform",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"scripts": {
|
|
7
|
+
"prepatch": "npm version prepatch --preid=beta",
|
|
7
8
|
"patch": "npm version patch",
|
|
9
|
+
"preupload": "npm publish --access public --tag beta && rm -rf node_modules",
|
|
10
|
+
"preupload:p": "npm run prepatch && npm run preupload",
|
|
8
11
|
"upload": "npm publish --access public && rm -rf node_modules",
|
|
9
12
|
"upload:p": "npm run patch && npm run upload"
|
|
10
13
|
},
|
|
@@ -12,31 +15,33 @@
|
|
|
12
15
|
"license": "ISC",
|
|
13
16
|
"dependencies": {
|
|
14
17
|
"@expo/vector-icons": "^12.0.0",
|
|
15
|
-
"
|
|
16
|
-
"
|
|
17
|
-
"
|
|
18
|
-
"
|
|
19
|
-
"
|
|
20
|
-
"expo-
|
|
21
|
-
"expo-
|
|
22
|
-
"expo-
|
|
23
|
-
"expo-
|
|
24
|
-
"expo-
|
|
25
|
-
"expo-
|
|
26
|
-
"expo-
|
|
18
|
+
"@react-native-async-storage/async-storage": "~1.15.0",
|
|
19
|
+
"@react-native-community/netinfo": "7.1.3",
|
|
20
|
+
"@react-native-picker/picker": "2.2.1",
|
|
21
|
+
"aws-amplify": "^4.3.11",
|
|
22
|
+
"aws-amplify-react-native": "^6.0.2",
|
|
23
|
+
"expo-av": "~10.2.0",
|
|
24
|
+
"expo-constants": "~13.0.0",
|
|
25
|
+
"expo-file-system": "~13.1.0",
|
|
26
|
+
"expo-image-manipulator": "~10.2.0",
|
|
27
|
+
"expo-image-picker": "~12.0.1",
|
|
28
|
+
"expo-linear-gradient": "~11.0.0",
|
|
29
|
+
"expo-media-library": "~14.0.0",
|
|
30
|
+
"expo-screen-orientation": "~4.1.1",
|
|
31
|
+
"expo-sharing": "~10.1.0",
|
|
27
32
|
"expo-video-player": "^1.6.0",
|
|
28
33
|
"js-cookie": "^2.2.1",
|
|
29
34
|
"lodash": "^4.17.4",
|
|
30
35
|
"mime-types": "^2.1.24",
|
|
31
36
|
"moment": "^2.18.1",
|
|
32
|
-
"react": "
|
|
33
|
-
"react-native": "
|
|
37
|
+
"react": "17.0.1",
|
|
38
|
+
"react-native": "0.64.3",
|
|
34
39
|
"react-native-auto-height-image": "3.1.3",
|
|
35
40
|
"react-native-elements": "^0.17.0",
|
|
36
41
|
"react-native-image-zoom-viewer": "^3.0.1",
|
|
37
42
|
"react-native-iphone-x-helper": "^1.3.1",
|
|
38
43
|
"react-native-vimeo-iframe": "^1.0.4",
|
|
39
|
-
"react-native-webview": "11.
|
|
44
|
+
"react-native-webview": "11.15.0",
|
|
40
45
|
"react-native-youtube-iframe": "^2.2.1",
|
|
41
46
|
"react-redux": "^5.0.5"
|
|
42
47
|
},
|
package/src/apis/index.js
CHANGED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { getUrl } from '../helper';
|
|
2
|
+
import { authedFunction } from '../session';
|
|
3
|
+
|
|
4
|
+
export const notificationActions = {
|
|
5
|
+
getAppNotificationSetting: () => {
|
|
6
|
+
return authedFunction({
|
|
7
|
+
method: 'GET',
|
|
8
|
+
url: getUrl('notifications', 'getState/get', {
|
|
9
|
+
type: 'app',
|
|
10
|
+
}),
|
|
11
|
+
});
|
|
12
|
+
},
|
|
13
|
+
muteApp: () => {
|
|
14
|
+
return authedFunction({
|
|
15
|
+
method: 'POST',
|
|
16
|
+
url: getUrl('notifications', 'updateState/mute'),
|
|
17
|
+
data: { type: 'app' },
|
|
18
|
+
});
|
|
19
|
+
},
|
|
20
|
+
unmuteApp: () => {
|
|
21
|
+
return authedFunction({
|
|
22
|
+
method: 'POST',
|
|
23
|
+
url: getUrl('notifications', 'updateState/unmute'),
|
|
24
|
+
data: { type: 'app' },
|
|
25
|
+
});
|
|
26
|
+
},
|
|
27
|
+
getEntityNotificationSetting: (type, id) => {
|
|
28
|
+
return authedFunction({
|
|
29
|
+
method: 'GET',
|
|
30
|
+
url: getUrl('notifications', 'getState/get', { type, id }),
|
|
31
|
+
});
|
|
32
|
+
},
|
|
33
|
+
muteEntity: (type, id) => {
|
|
34
|
+
return authedFunction({
|
|
35
|
+
method: 'POST',
|
|
36
|
+
url: getUrl('notifications', 'updateState/mute'),
|
|
37
|
+
data: { type, id },
|
|
38
|
+
});
|
|
39
|
+
},
|
|
40
|
+
unmuteEntity: (type, id) => {
|
|
41
|
+
return authedFunction({
|
|
42
|
+
method: 'POST',
|
|
43
|
+
url: getUrl('notifications', 'updateState/unmute'),
|
|
44
|
+
data: { type, id },
|
|
45
|
+
});
|
|
46
|
+
},
|
|
47
|
+
};
|
|
@@ -28,7 +28,7 @@ class CommentReply extends Component {
|
|
|
28
28
|
componentDidMount() {
|
|
29
29
|
if (this.props.commentSection) {
|
|
30
30
|
this.setState({
|
|
31
|
-
commentsLoading: this.props.commentSection.
|
|
31
|
+
commentsLoading: this.props.commentSection.isLoading(),
|
|
32
32
|
});
|
|
33
33
|
}
|
|
34
34
|
}
|
|
@@ -93,13 +93,13 @@ class CommentReply extends Component {
|
|
|
93
93
|
});
|
|
94
94
|
Keyboard.dismiss();
|
|
95
95
|
if (this.props.commentSection) {
|
|
96
|
-
this.props.commentSection.
|
|
96
|
+
this.props.commentSection.startedAddingComment();
|
|
97
97
|
}
|
|
98
98
|
reactionActions
|
|
99
99
|
.addComment(this.props.entityId, this.props.entityType, this.props.entityName, this.props.site, text, image)
|
|
100
100
|
.then(res => {
|
|
101
101
|
if (this.props.commentSection) {
|
|
102
|
-
this.props.commentSection.
|
|
102
|
+
this.props.commentSection.commentAdded(res.data);
|
|
103
103
|
}
|
|
104
104
|
this.setState({
|
|
105
105
|
addingComment: false,
|
|
@@ -125,7 +125,7 @@ class CommentReply extends Component {
|
|
|
125
125
|
if (this.state.uploadingCommentImage || !_.isEmpty(this.state.commentImageInput)) {
|
|
126
126
|
return;
|
|
127
127
|
}
|
|
128
|
-
this.commentImageUploader.
|
|
128
|
+
this.commentImageUploader.showUploadMenu();
|
|
129
129
|
}
|
|
130
130
|
|
|
131
131
|
renderImageAttachment() {
|
|
@@ -329,5 +329,5 @@ const mapStateToProps = state => {
|
|
|
329
329
|
return { user };
|
|
330
330
|
};
|
|
331
331
|
|
|
332
|
-
const commentReply = connect(mapStateToProps, {}, null, {
|
|
332
|
+
const commentReply = connect(mapStateToProps, {}, null, { forwardRef: true })(CommentReply);
|
|
333
333
|
export { commentReply as CommentReply };
|
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
import React, { Component } from 'react';
|
|
2
|
-
import { View, Text, TouchableOpacity, Image } from 'react-native';
|
|
2
|
+
import { View, Text, TouchableOpacity, Image, StyleSheet } from 'react-native';
|
|
3
3
|
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 } from '../helper';
|
|
7
|
+
import { getPluralS, getThumb300, get1400, getSiteSettingFromState } from '../helper';
|
|
8
8
|
import { getMainBrandingColourFromState, TEXT_DARKEST, BG_GREY, TEXT_LIGHT, LINEGREY } from '../colours';
|
|
9
|
-
import {
|
|
10
|
-
import { reactionActions } from '../apis';
|
|
9
|
+
import { reactionActions, notificationActions } from '../apis';
|
|
11
10
|
import { ConfirmPopup } from './ConfirmPopup';
|
|
12
11
|
import { ProfilePic } from './ProfilePic';
|
|
13
12
|
import { ImagePopup } from './ImagePopup';
|
|
13
|
+
import { InlineButton } from './InlineButton';
|
|
14
|
+
import { Spinner } from './Spinner';
|
|
14
15
|
|
|
15
16
|
class CommentSection extends Component {
|
|
16
17
|
constructor(props) {
|
|
@@ -23,10 +24,15 @@ class CommentSection extends Component {
|
|
|
23
24
|
commentToReport: null,
|
|
24
25
|
commentReportedStatus: null,
|
|
25
26
|
reportLoading: false,
|
|
27
|
+
processing: false,
|
|
28
|
+
muteExpiry: null,
|
|
29
|
+
muteLoaded: false,
|
|
26
30
|
};
|
|
27
31
|
}
|
|
28
32
|
|
|
29
33
|
componentDidMount() {
|
|
34
|
+
this.getNotificationSate();
|
|
35
|
+
|
|
30
36
|
if (!_.includes(this.props.user.hidden, 'viewComment')) {
|
|
31
37
|
this.getComments();
|
|
32
38
|
}
|
|
@@ -94,9 +100,67 @@ class CommentSection extends Component {
|
|
|
94
100
|
}
|
|
95
101
|
|
|
96
102
|
onGoToAdd() {
|
|
97
|
-
this.props.commentReply.
|
|
103
|
+
this.props.commentReply.focusInput();
|
|
98
104
|
}
|
|
99
105
|
|
|
106
|
+
onMute = () => {
|
|
107
|
+
const { entityType, entityId } = this.props;
|
|
108
|
+
this.setState({ processing: true }, async () => {
|
|
109
|
+
try {
|
|
110
|
+
const { data } = await notificationActions.muteEntity(entityType, entityId);
|
|
111
|
+
// console.log('onMute', data);
|
|
112
|
+
const muteExpiry = moment(data.Expiry);
|
|
113
|
+
this.setState({ muteExpiry, processing: false });
|
|
114
|
+
} catch (error) {
|
|
115
|
+
console.error('onMute', error);
|
|
116
|
+
this.setState({ processing: false });
|
|
117
|
+
}
|
|
118
|
+
});
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
onUnmute = () => {
|
|
122
|
+
const { entityType, entityId } = this.props;
|
|
123
|
+
this.setState({ processing: true }, async () => {
|
|
124
|
+
try {
|
|
125
|
+
const { data } = await notificationActions.unmuteEntity(entityType, entityId);
|
|
126
|
+
// console.log('onUnmute', data);
|
|
127
|
+
this.setState({ muteExpiry: null, processing: false });
|
|
128
|
+
} catch (error) {
|
|
129
|
+
console.error('onUnmute', error);
|
|
130
|
+
this.setState({ processing: false });
|
|
131
|
+
}
|
|
132
|
+
});
|
|
133
|
+
};
|
|
134
|
+
|
|
135
|
+
isMuted = () => {
|
|
136
|
+
const { muteExpiry } = this.state;
|
|
137
|
+
return muteExpiry && moment() <= muteExpiry;
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
getMuteRemaining = () => {
|
|
141
|
+
const { muteExpiry } = this.state;
|
|
142
|
+
const actual = muteExpiry ? moment.duration(muteExpiry.diff(moment())).asHours() : 0;
|
|
143
|
+
return Math.abs(Math.ceil(actual));
|
|
144
|
+
};
|
|
145
|
+
|
|
146
|
+
getNotificationSate = () => {
|
|
147
|
+
const { processing } = this.state;
|
|
148
|
+
const { entityType, entityId, notificationsForComments } = this.props;
|
|
149
|
+
if (processing || !notificationsForComments) return;
|
|
150
|
+
|
|
151
|
+
this.setState({ processing: true }, async () => {
|
|
152
|
+
try {
|
|
153
|
+
const { data } = await notificationActions.getEntityNotificationSetting(entityType, entityId);
|
|
154
|
+
// console.log('getNotificationSate', data);
|
|
155
|
+
const muteExpiry = data ? moment(data.Expiry) : null;
|
|
156
|
+
this.setState({ muteExpiry, muteLoaded: true, processing: false });
|
|
157
|
+
} catch (error) {
|
|
158
|
+
console.error('getNotificationSate', error);
|
|
159
|
+
this.setState({ processing: false });
|
|
160
|
+
}
|
|
161
|
+
});
|
|
162
|
+
};
|
|
163
|
+
|
|
100
164
|
getAdjustedSize(size) {
|
|
101
165
|
if (this.props.scaleFont) {
|
|
102
166
|
return size + this.props.user.fontScale;
|
|
@@ -111,7 +175,7 @@ class CommentSection extends Component {
|
|
|
111
175
|
commentsLoading: true,
|
|
112
176
|
});
|
|
113
177
|
if (this.props.commentReply) {
|
|
114
|
-
this.props.commentReply.
|
|
178
|
+
this.props.commentReply.loadingStarted();
|
|
115
179
|
}
|
|
116
180
|
this.loadComments();
|
|
117
181
|
}
|
|
@@ -145,7 +209,7 @@ class CommentSection extends Component {
|
|
|
145
209
|
},
|
|
146
210
|
);
|
|
147
211
|
if (this.props.commentReply) {
|
|
148
|
-
this.props.commentReply.
|
|
212
|
+
this.props.commentReply.loadingCompleted();
|
|
149
213
|
}
|
|
150
214
|
if (this.props.live) {
|
|
151
215
|
this.loadTimer = setTimeout(() => {
|
|
@@ -288,6 +352,47 @@ class CommentSection extends Component {
|
|
|
288
352
|
);
|
|
289
353
|
}
|
|
290
354
|
|
|
355
|
+
renderMute() {
|
|
356
|
+
const { notificationsForComments } = this.props;
|
|
357
|
+
const { muteLoaded, muteExpiry, processing } = this.state;
|
|
358
|
+
if (!notificationsForComments || !muteLoaded) return null;
|
|
359
|
+
|
|
360
|
+
if (processing)
|
|
361
|
+
return (
|
|
362
|
+
<View style={styles.muteSpinnerContainer}>
|
|
363
|
+
<Spinner size={'small'} color={this.props.colourBrandingMain} />
|
|
364
|
+
</View>
|
|
365
|
+
);
|
|
366
|
+
|
|
367
|
+
const isMuted = this.isMuted();
|
|
368
|
+
const hours = this.getMuteRemaining();
|
|
369
|
+
const mutedFor = `Muted for ${hours} hour${getPluralS(hours)}`;
|
|
370
|
+
// console.log(muteExpiry.format('DD MMM YYYY hh:mm a'));
|
|
371
|
+
|
|
372
|
+
return (
|
|
373
|
+
<View style={styles.muteContainer}>
|
|
374
|
+
{isMuted && muteExpiry ? <Text style={[{ color: this.props.colourBrandingMain }, styles.mutedForText]}>{mutedFor}</Text> : null}
|
|
375
|
+
<InlineButton
|
|
376
|
+
onPress={isMuted ? this.onUnmute : this.onMute}
|
|
377
|
+
color="#fff"
|
|
378
|
+
style={[{ borderColor: this.props.colourBrandingMain }, styles.muteButton]}
|
|
379
|
+
disabled={processing}
|
|
380
|
+
disabledOpacity
|
|
381
|
+
noText
|
|
382
|
+
>
|
|
383
|
+
<View style={styles.muteButtonInner}>
|
|
384
|
+
<Icon
|
|
385
|
+
name={isMuted ? 'bell-o' : 'bell-slash-o'}
|
|
386
|
+
type={'font-awesome'}
|
|
387
|
+
iconStyle={[{ color: this.props.colourBrandingMain }, styles.muteButtonIcon]}
|
|
388
|
+
/>
|
|
389
|
+
<Text style={[{ color: this.props.colourBrandingMain }, styles.muteButtonText]}>{isMuted ? 'Unmute' : 'Mute'}</Text>
|
|
390
|
+
</View>
|
|
391
|
+
</InlineButton>
|
|
392
|
+
</View>
|
|
393
|
+
);
|
|
394
|
+
}
|
|
395
|
+
|
|
291
396
|
renderComments() {
|
|
292
397
|
if (this.state.commentsLoading) {
|
|
293
398
|
return (
|
|
@@ -317,11 +422,14 @@ class CommentSection extends Component {
|
|
|
317
422
|
<View style={styles.commentSection}>
|
|
318
423
|
{!this.isEmpty() && (
|
|
319
424
|
<View style={styles.commentSectionTitleRow}>
|
|
320
|
-
{
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
425
|
+
<View style={{ alignItems: 'flex-end' }}>
|
|
426
|
+
{this.renderMute()}
|
|
427
|
+
{!this.props.hideAddComment && this.state.comments.length > 2 && (
|
|
428
|
+
<TouchableOpacity onPress={this.onGoToAdd.bind(this)}>
|
|
429
|
+
<Text style={[styles.goToText, { color: this.props.colourBrandingMain }]}>Add a comment</Text>
|
|
430
|
+
</TouchableOpacity>
|
|
431
|
+
)}
|
|
432
|
+
</View>
|
|
325
433
|
<Text style={[styles.commentCount, { fontSize: this.getAdjustedSize(15) }]}>
|
|
326
434
|
{this.state.comments.length}
|
|
327
435
|
{` comment${getPluralS(this.state.comments.length)}`}
|
|
@@ -374,22 +482,22 @@ class CommentSection extends Component {
|
|
|
374
482
|
}
|
|
375
483
|
}
|
|
376
484
|
|
|
377
|
-
const styles = {
|
|
485
|
+
const styles = StyleSheet.create({
|
|
378
486
|
commentSectionOuter: {
|
|
379
487
|
flex: 1,
|
|
380
488
|
paddingHorizontal: 16,
|
|
381
489
|
},
|
|
382
490
|
commentSection: {
|
|
383
491
|
flex: 1,
|
|
384
|
-
paddingVertical:
|
|
492
|
+
paddingVertical: 12,
|
|
385
493
|
borderTopColor: LINEGREY,
|
|
386
494
|
borderTopWidth: 1,
|
|
387
|
-
borderTopStyle: 'solid',
|
|
388
495
|
},
|
|
389
496
|
commentCount: {
|
|
390
497
|
fontFamily: 'sf-semibold',
|
|
391
498
|
color: TEXT_DARKEST,
|
|
392
499
|
flex: 1,
|
|
500
|
+
marginTop: 4,
|
|
393
501
|
},
|
|
394
502
|
comment: {
|
|
395
503
|
marginTop: 16,
|
|
@@ -463,14 +571,49 @@ const styles = {
|
|
|
463
571
|
reportLoadingContainer: {
|
|
464
572
|
paddingVertical: 10,
|
|
465
573
|
},
|
|
466
|
-
|
|
574
|
+
goToText: {
|
|
575
|
+
marginTop: 4,
|
|
576
|
+
},
|
|
577
|
+
muteSpinnerContainer: {
|
|
578
|
+
width: 100,
|
|
579
|
+
marginBottom: 6,
|
|
580
|
+
},
|
|
581
|
+
muteContainer: {
|
|
582
|
+
flexDirection: 'row',
|
|
583
|
+
alignItems: 'center',
|
|
584
|
+
justifyContent: 'flex-end',
|
|
585
|
+
marginBottom: 6,
|
|
586
|
+
},
|
|
587
|
+
mutedForText: {
|
|
588
|
+
fontFamily: 'sf-semibold',
|
|
589
|
+
fontSize: 13,
|
|
590
|
+
marginRight: 8,
|
|
591
|
+
},
|
|
592
|
+
muteButton: {
|
|
593
|
+
borderWidth: 1,
|
|
594
|
+
paddingHorizontal: 8,
|
|
595
|
+
},
|
|
596
|
+
muteButtonInner: {
|
|
597
|
+
flexDirection: 'row',
|
|
598
|
+
alignItems: 'center',
|
|
599
|
+
},
|
|
600
|
+
muteButtonIcon: {
|
|
601
|
+
fontSize: 14,
|
|
602
|
+
},
|
|
603
|
+
muteButtonText: {
|
|
604
|
+
fontFamily: 'sf-semibold',
|
|
605
|
+
fontSize: 14,
|
|
606
|
+
marginLeft: 6,
|
|
607
|
+
},
|
|
608
|
+
});
|
|
467
609
|
|
|
468
610
|
const mapStateToProps = state => {
|
|
469
611
|
return {
|
|
470
612
|
colourBrandingMain: getMainBrandingColourFromState(state),
|
|
471
613
|
user: state.user,
|
|
614
|
+
notificationsForComments: getSiteSettingFromState(state, 'NotificationsForComments', false),
|
|
472
615
|
};
|
|
473
616
|
};
|
|
474
617
|
|
|
475
|
-
const commentSection = connect(mapStateToProps, {}, null, {
|
|
618
|
+
const commentSection = connect(mapStateToProps, {}, null, { forwardRef: true })(CommentSection);
|
|
476
619
|
export { commentSection as CommentSection };
|
|
@@ -5,7 +5,7 @@ import { Spinner } from './Spinner';
|
|
|
5
5
|
|
|
6
6
|
class ImageUploadProgress extends Component {
|
|
7
7
|
onRetryUpload = (imageUri, uploadUri) => {
|
|
8
|
-
this.props.uploader.
|
|
8
|
+
this.props.uploader.retryUpload(imageUri, uploadUri);
|
|
9
9
|
};
|
|
10
10
|
|
|
11
11
|
render() {
|
|
@@ -3,7 +3,7 @@ import { View, ScrollView, TouchableOpacity, Text, Platform, Linking, Modal, Dim
|
|
|
3
3
|
import { connect } from 'react-redux';
|
|
4
4
|
import { Icon } from 'react-native-elements';
|
|
5
5
|
import _ from 'lodash';
|
|
6
|
-
import
|
|
6
|
+
import { Camera } from 'expo-camera';
|
|
7
7
|
import * as MediaLibrary from 'expo-media-library';
|
|
8
8
|
import * as ImageManipulator from 'expo-image-manipulator';
|
|
9
9
|
import * as ImagePicker from 'expo-image-picker';
|
|
@@ -60,7 +60,7 @@ class ImageUploader extends Component {
|
|
|
60
60
|
}
|
|
61
61
|
|
|
62
62
|
loadLocalAlbums = async () => {
|
|
63
|
-
const hasPermission = await
|
|
63
|
+
const hasPermission = await MediaLibrary.getPermissionsAsync();
|
|
64
64
|
if (!hasPermission.granted) return;
|
|
65
65
|
|
|
66
66
|
this.setState({ loadingLocalFolders: true }, async () => {
|
|
@@ -254,8 +254,8 @@ class ImageUploader extends Component {
|
|
|
254
254
|
}
|
|
255
255
|
|
|
256
256
|
askPermissionsAsync = async () => {
|
|
257
|
-
const cameraPermission = await
|
|
258
|
-
const rollPermission = await
|
|
257
|
+
const cameraPermission = await Camera.requestCameraPermissionsAsync();
|
|
258
|
+
const rollPermission = await MediaLibrary.requestPermissionsAsync();
|
|
259
259
|
if (cameraPermission.status !== 'granted' || rollPermission.status !== 'granted') {
|
|
260
260
|
this.showWarningPopup(cameraPermission.status !== 'granted', rollPermission.status !== 'granted');
|
|
261
261
|
return false;
|
|
@@ -786,4 +786,4 @@ const mapStateToProps = state => {
|
|
|
786
786
|
};
|
|
787
787
|
};
|
|
788
788
|
|
|
789
|
-
export default connect(mapStateToProps, { stockImagesLoaded, imageLibraryLoaded }, null, {
|
|
789
|
+
export default connect(mapStateToProps, { stockImagesLoaded, imageLibraryLoaded }, null, { forwardRef: true })(ImageUploader);
|
|
@@ -3,7 +3,8 @@ import { Platform, View, Modal, TouchableOpacity, StyleSheet } from 'react-nativ
|
|
|
3
3
|
import * as ScreenOrientation from 'expo-screen-orientation';
|
|
4
4
|
import { StatusBarHeight, getCompressed, imageExists } from '../helper';
|
|
5
5
|
import { Pl60Icon } from '../fonts';
|
|
6
|
-
import { SharingTools
|
|
6
|
+
import { SharingTools } from './SharingTools';
|
|
7
|
+
import { MediaPlayer } from './MediaPlayer';
|
|
7
8
|
|
|
8
9
|
class VideoPopup extends Component {
|
|
9
10
|
constructor(props) {
|
|
@@ -3,7 +3,7 @@ import { StyleSheet, View, FlatList, Dimensions, ActivityIndicator, Platform } f
|
|
|
3
3
|
import _ from 'lodash';
|
|
4
4
|
import * as ScreenOrientation from 'expo-screen-orientation';
|
|
5
5
|
import * as MediaLibrary from 'expo-media-library';
|
|
6
|
-
import
|
|
6
|
+
import { Camera } from 'expo-camera';
|
|
7
7
|
import { isVideo } from '../../helper';
|
|
8
8
|
import ImageTile from './ImageTile';
|
|
9
9
|
|
|
@@ -49,8 +49,8 @@ export default class ImageBrowser extends React.Component {
|
|
|
49
49
|
};
|
|
50
50
|
|
|
51
51
|
getPermissionsAsync = async () => {
|
|
52
|
-
const { status: camera } = await
|
|
53
|
-
const { status: cameraRoll } = await
|
|
52
|
+
const { status: camera } = await Camera.requestCameraPermissionsAsync();
|
|
53
|
+
const { status: cameraRoll } = await MediaLibrary.requestPermissionsAsync();
|
|
54
54
|
this.setState({
|
|
55
55
|
hasCameraPermission: camera === 'granted',
|
|
56
56
|
hasCameraRollPermission: cameraRoll === 'granted',
|