@plusscommunities/pluss-maintenance-app 7.0.0-beta.0 → 7.0.0-beta.1

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.
Files changed (58) hide show
  1. package/dist/module/actions/JobActions.js +44 -1
  2. package/dist/module/actions/JobActions.js.map +1 -1
  3. package/dist/module/actions/types.js +3 -0
  4. package/dist/module/actions/types.js.map +1 -1
  5. package/dist/module/apis/index.js +2 -0
  6. package/dist/module/apis/index.js.map +1 -1
  7. package/dist/module/apis/maintenanceActions.js +21 -6
  8. package/dist/module/apis/maintenanceActions.js.map +1 -1
  9. package/dist/module/components/FilterPopupMenu.js +34 -18
  10. package/dist/module/components/FilterPopupMenu.js.map +1 -1
  11. package/dist/module/components/MaintenanceList.js +47 -56
  12. package/dist/module/components/MaintenanceList.js.map +1 -1
  13. package/dist/module/components/MaintenanceListItem.js +39 -26
  14. package/dist/module/components/MaintenanceListItem.js.map +1 -1
  15. package/dist/module/components/MaintenanceWidgetItem.js +12 -12
  16. package/dist/module/components/MaintenanceWidgetItem.js.map +1 -1
  17. package/dist/module/components/PrioritySelectorPopup.js +82 -0
  18. package/dist/module/components/PrioritySelectorPopup.js.map +1 -0
  19. package/dist/module/components/StatusSelectorPopup.js +9 -14
  20. package/dist/module/components/StatusSelectorPopup.js.map +1 -1
  21. package/dist/module/components/WidgetSmall.js +7 -3
  22. package/dist/module/components/WidgetSmall.js.map +1 -1
  23. package/dist/module/helper.js +39 -25
  24. package/dist/module/helper.js.map +1 -1
  25. package/dist/module/reducers/JobsReducer.js +31 -2
  26. package/dist/module/reducers/JobsReducer.js.map +1 -1
  27. package/dist/module/screens/RequestDetail.js +90 -18
  28. package/dist/module/screens/RequestDetail.js.map +1 -1
  29. package/dist/module/screens/RequestNotes.js +430 -21
  30. package/dist/module/screens/RequestNotes.js.map +1 -1
  31. package/dist/module/values.config.a.js +6 -1
  32. package/dist/module/values.config.a.js.map +1 -1
  33. package/dist/module/values.config.default.js +6 -1
  34. package/dist/module/values.config.default.js.map +1 -1
  35. package/dist/module/values.config.forms.js +6 -1
  36. package/dist/module/values.config.forms.js.map +1 -1
  37. package/dist/module/values.config.js +34 -29
  38. package/dist/module/values.config.js.map +1 -1
  39. package/package.json +2 -2
  40. package/src/actions/JobActions.js +53 -1
  41. package/src/actions/types.js +4 -0
  42. package/src/apis/index.js +4 -0
  43. package/src/apis/maintenanceActions.js +18 -6
  44. package/src/components/FilterPopupMenu.js +40 -21
  45. package/src/components/MaintenanceList.js +38 -47
  46. package/src/components/MaintenanceListItem.js +35 -21
  47. package/src/components/MaintenanceWidgetItem.js +16 -12
  48. package/src/components/PrioritySelectorPopup.js +79 -0
  49. package/src/components/StatusSelectorPopup.js +8 -14
  50. package/src/components/WidgetSmall.js +5 -3
  51. package/src/helper.js +50 -21
  52. package/src/reducers/JobsReducer.js +25 -1
  53. package/src/screens/RequestDetail.js +87 -24
  54. package/src/screens/RequestNotes.js +429 -30
  55. package/src/values.config.a.js +5 -0
  56. package/src/values.config.default.js +5 -0
  57. package/src/values.config.forms.js +5 -0
  58. package/src/values.config.js +34 -29
@@ -2,7 +2,7 @@ function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object
2
2
  function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
3
3
  function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
4
4
  import React, { Component } from 'react';
5
- import { ScrollView, View, Text, TouchableOpacity, Modal, KeyboardAvoidingView, Platform } from 'react-native';
5
+ import { ScrollView, View, Text, TouchableOpacity, Modal, KeyboardAvoidingView, Platform, FlatList, Dimensions, ImageBackground, Keyboard } from 'react-native';
6
6
  import { connect } from 'react-redux';
7
7
  import { Icon } from '@rneui/themed';
8
8
  import _ from 'lodash';
@@ -13,6 +13,8 @@ import { getBottomSpace } from 'react-native-iphone-x-helper';
13
13
  import { Services } from '../feature.config';
14
14
  import { Components, Colours, Helper } from '../core.config';
15
15
  import { values } from '../values.config';
16
+ const SCREEN_WIDTH = Dimensions.get('window').width;
17
+ const PHOTO_SIZE = (SCREEN_WIDTH - 64) / 3;
16
18
  class RequestNotes extends Component {
17
19
  constructor(props) {
18
20
  super(props);
@@ -56,12 +58,10 @@ class RequestNotes extends Component {
56
58
  });
57
59
  });
58
60
  _defineProperty(this, "isReadyToSaveNote", () => {
59
- if (_.some(this.state.noteAttachments, n => {
60
- return n.Uploading;
61
- })) {
62
- return false;
63
- }
64
- return !_.isEmpty(this.state.noteInput) || !_.isEmpty(this.state.noteAttachments);
61
+ const uploadingAttachments = _.some(this.state.noteAttachments, n => n.Uploading);
62
+ const uploadingImages = _.some(this.state.noteImages, n => n.uploading);
63
+ if (uploadingAttachments || uploadingImages) return false;
64
+ return !_.isEmpty(this.state.noteInput) || !_.isEmpty(this.state.noteAttachments) || !_.isEmpty(this.state.noteImages.filter(img => !img.add));
65
65
  });
66
66
  _defineProperty(this, "openAddNote", () => {
67
67
  this.setState({
@@ -77,12 +77,20 @@ class RequestNotes extends Component {
77
77
  if (!!this.state.editingNote) {
78
78
  newState.noteInput = '';
79
79
  newState.noteAttachments = [];
80
+ newState.noteImages = [];
80
81
  }
81
82
  this.setState(newState);
82
83
  });
83
84
  _defineProperty(this, "openEditNote", n => {
85
+ const noteImages = [...(n.Images || []).map(i => ({
86
+ url: i,
87
+ thumbNailUrl: Helper.getThumb300(i)
88
+ })), {
89
+ add: true
90
+ }];
84
91
  this.setState({
85
92
  noteAttachments: n.Attachments || [],
93
+ noteImages,
86
94
  noteInput: n.Note || '',
87
95
  addNoteOpen: true,
88
96
  editingNote: n.Id,
@@ -97,23 +105,24 @@ class RequestNotes extends Component {
97
105
  this.setState({
98
106
  submittingNote: true
99
107
  });
100
- const res = await (this.state.editingNote ? maintenanceActions.editNote(this.props.job.id, this.state.editingNote, this.state.noteInput, this.state.noteAttachments.map(a => {
101
- return {
102
- Title: a.Title,
103
- Source: a.Source
104
- };
105
- })) : maintenanceActions.addNote(this.props.job.id, this.state.noteInput, this.state.noteAttachments.map(a => {
108
+ const attachments = this.state.noteAttachments.filter(a => !a.add).map(a => {
106
109
  return {
107
110
  Title: a.Title,
108
111
  Source: a.Source
109
112
  };
110
- })));
113
+ });
114
+ const images = this.state.noteImages.filter(img => !img.add).map(img => img.url);
115
+ const res = await (this.state.editingNote ? maintenanceActions.editNote(this.props.job.id, this.state.editingNote, this.state.noteInput, attachments, images) : maintenanceActions.addNote(this.props.job.id, this.state.noteInput, attachments, images));
111
116
  this.setState({
112
117
  job: res.data.job,
113
118
  submittingNote: false,
114
119
  addNoteOpen: false,
115
120
  noteInput: '',
116
121
  noteAttachments: [],
122
+ noteImages: [{
123
+ add: true
124
+ }],
125
+ uploadingImage: false,
117
126
  editingNote: null
118
127
  }, () => {
119
128
  this.props.jobAdded(res.data.job);
@@ -123,17 +132,157 @@ class RequestNotes extends Component {
123
132
  console.log('error');
124
133
  console.log(err);
125
134
  this.setState({
126
- submittingNote: false
135
+ submittingNote: false,
136
+ uploadingImage: false
127
137
  });
128
138
  }
129
139
  });
140
+ _defineProperty(this, "setImages", (noteImages, uploadingImage = false, callback = null) => {
141
+ this.setState({
142
+ noteImages,
143
+ uploadingImage
144
+ }, callback);
145
+ });
146
+ _defineProperty(this, "getImages", () => {
147
+ const {
148
+ noteImages
149
+ } = this.state;
150
+ const imagesList = _.cloneDeep(noteImages);
151
+ if (!imagesList || !Array.isArray(imagesList) || imagesList.length === 0) {
152
+ return [{
153
+ add: true
154
+ }];
155
+ }
156
+ return imagesList;
157
+ });
158
+ _defineProperty(this, "getImageUrls", () => {
159
+ const imagesList = this.getImages();
160
+ return _.filter(imagesList, img => {
161
+ return !img.uploading && !img.add;
162
+ }).map(img => {
163
+ return img.url;
164
+ });
165
+ });
166
+ _defineProperty(this, "waitForThumbnails", () => {
167
+ if (this.checkThumb) return;
168
+ this.checkThumb = setInterval(async () => {
169
+ const imagesList = this.getImages();
170
+ const imagesUpdate = [];
171
+ await Promise.all(imagesList.map(image => {
172
+ return new Promise(async resolve => {
173
+ const newImage = {
174
+ ...image
175
+ };
176
+ imagesUpdate.push(newImage);
177
+ if (newImage.url && !newImage.thumbNailExists) {
178
+ newImage.uploading = false;
179
+ newImage.allowRetry = false;
180
+ newImage.thumbNailExists = await Helper.imageExists(newImage.thumbNailUrl);
181
+ resolve(newImage.thumbNailExists);
182
+ }
183
+ resolve(true);
184
+ });
185
+ }));
186
+ const thumbnailsExist = imagesUpdate.every(image => !image.url || image.thumbNailExists);
187
+ if (thumbnailsExist) {
188
+ clearInterval(this.checkThumb);
189
+ this.checkThumb = null;
190
+ this.setImages(imagesUpdate);
191
+ }
192
+ }, 2000);
193
+ });
194
+ _defineProperty(this, "removeImage", index => {
195
+ const imagesUpdate = this.getImages();
196
+ imagesUpdate.splice(index, 1);
197
+ this.setImages(imagesUpdate);
198
+ });
199
+ _defineProperty(this, "showUploadMenu", () => {
200
+ Keyboard.dismiss();
201
+ const {
202
+ uploadingImage,
203
+ submittingNote
204
+ } = this.state;
205
+ if (uploadingImage || submittingNote) return;
206
+ this.imageUploader.showUploadMenu();
207
+ });
208
+ _defineProperty(this, "toggleFullscreenVideo", url => {
209
+ if (typeof url !== 'string') url = '';
210
+ this.setState({
211
+ showFullscreenVideo: url.length > 0,
212
+ currentVideoUrl: url
213
+ });
214
+ });
215
+ _defineProperty(this, "onUploadStarted", (uploadUri, imageUri) => {
216
+ const imagesUpdate = this.getImages();
217
+ imagesUpdate.splice(imagesUpdate.length - 1, 0, {
218
+ uploading: true,
219
+ uploadProgress: '0%',
220
+ uploadUri,
221
+ imageUri,
222
+ allowRetry: true
223
+ });
224
+ this.setImages(imagesUpdate, true);
225
+ });
226
+ _defineProperty(this, "onUploadProgress", progress => {
227
+ const imagesUpdate = this.getImages();
228
+ imagesUpdate.map(img => {
229
+ if (img.uploadUri === progress.uri) {
230
+ img.uploadProgress = progress.percentage;
231
+ img.uploading = true;
232
+ img.allowRetry = true;
233
+ }
234
+ });
235
+ this.setImages(imagesUpdate, true);
236
+ });
237
+ _defineProperty(this, "onUploadSuccess", async (uri, uploadUri) => {
238
+ const imagesUpdate = this.getImages();
239
+ imagesUpdate.map(img => {
240
+ if (img.uploadUri === uploadUri && img.uploading) {
241
+ img.url = uri.replace('/general/', '/general1400/');
242
+ img.thumbNailExists = false;
243
+ img.thumbNailUrl = Helper.getThumb300(img.url);
244
+ img.allowRetry = true;
245
+ }
246
+ });
247
+ this.setImages(imagesUpdate, false, () => this.waitForThumbnails());
248
+ });
249
+ _defineProperty(this, "onUploadFailed", uploadUri => {
250
+ const imagesUpdate = this.getImages();
251
+ imagesUpdate.map(img => {
252
+ if (img.uploadUri === uploadUri) {
253
+ img.uploading = true; // Requried for retry
254
+ img.uploadProgress = '';
255
+ img.allowRetry = true;
256
+ }
257
+ });
258
+ this.setImages(imagesUpdate);
259
+ });
260
+ _defineProperty(this, "onLibrarySelected", uri => {
261
+ const imagesUpdate = this.getImages();
262
+ imagesUpdate.splice(imagesUpdate.length - 1, 0, {
263
+ uploading: false,
264
+ allowRetry: false,
265
+ url: Helper.get1400(uri),
266
+ thumbNailExists: true,
267
+ thumbNailUrl: Helper.getThumb300(uri)
268
+ });
269
+ this.setImages(imagesUpdate);
270
+ });
130
271
  this.state = {
131
272
  job: {},
132
273
  selectedPDF: null,
133
274
  noteAttachments: [],
134
275
  noteInput: '',
135
- addNoteOpen: false
276
+ addNoteOpen: false,
277
+ noteImages: [{
278
+ add: true
279
+ }],
280
+ uploadingImage: false,
281
+ galleryOpen: false,
282
+ galleryImages: [],
283
+ galleryIndex: 0
136
284
  };
285
+ this.checkThumb = null;
137
286
  }
138
287
  componentDidMount() {
139
288
  this.updateJobState();
@@ -143,12 +292,29 @@ class RequestNotes extends Component {
143
292
  this.updateJobState();
144
293
  }
145
294
  }
295
+ componentWillUnmount() {
296
+ clearInterval(this.checkThumb);
297
+ }
146
298
  updateJobState() {
147
299
  const job = _.find(this.props.jobs, j => j.id === this.props.job.id) || this.props.job;
148
300
  this.setState({
149
301
  job
150
302
  });
151
303
  }
304
+ openGallery(images, index) {
305
+ this.setState({
306
+ galleryOpen: true,
307
+ galleryImages: images,
308
+ galleryIndex: index
309
+ });
310
+ }
311
+ closeGallery() {
312
+ this.setState({
313
+ galleryOpen: false,
314
+ galleryImages: [],
315
+ galleryIndex: 0
316
+ });
317
+ }
152
318
  renderAttachment(a, i) {
153
319
  return /*#__PURE__*/React.createElement(Components.Attachment, {
154
320
  onPress: () => {
@@ -158,6 +324,67 @@ class RequestNotes extends Component {
158
324
  title: a.Title
159
325
  });
160
326
  }
327
+ renderPlayableImageUrl(images, index, containerStyle) {
328
+ const url = images[index];
329
+ const thumbUrl = Helper.getThumb300(url);
330
+ if (Helper.isVideo(url)) {
331
+ return /*#__PURE__*/React.createElement(ImageBackground, {
332
+ style: [{
333
+ flex: 1
334
+ }, containerStyle],
335
+ source: {
336
+ uri: thumbUrl
337
+ }
338
+ }, /*#__PURE__*/React.createElement(View, {
339
+ style: styles.imagePlayContainer
340
+ }, /*#__PURE__*/React.createElement(TouchableOpacity, {
341
+ onPress: this.toggleFullscreenVideo.bind(this, url)
342
+ }, /*#__PURE__*/React.createElement(Icon, {
343
+ name: "play",
344
+ type: "font-awesome",
345
+ iconStyle: styles.imageControlIcon
346
+ }))));
347
+ }
348
+ const imageUrl = Helper.get1400(url);
349
+ return /*#__PURE__*/React.createElement(TouchableOpacity, {
350
+ style: containerStyle,
351
+ onPress: this.openGallery.bind(this, images, index || 0)
352
+ }, /*#__PURE__*/React.createElement(ImageBackground, {
353
+ resizeMode: "cover",
354
+ style: styles.imageContainer,
355
+ source: {
356
+ uri: imageUrl
357
+ }
358
+ }));
359
+ }
360
+ renderImages(note) {
361
+ if (!note) return null;
362
+ if (!_.isNil(note.Images) && !_.isEmpty(note.Images)) {
363
+ return /*#__PURE__*/React.createElement(ScrollView, {
364
+ horizontal: true,
365
+ style: styles.sideBySideImages
366
+ }, note.Images.map((_p, index) => this.renderPlayableImageUrl(note.Images, index, styles.sideBySideImageContainer)));
367
+ }
368
+ return null;
369
+ }
370
+ renderImagePopup() {
371
+ const {
372
+ galleryOpen,
373
+ galleryImages,
374
+ galleryIndex
375
+ } = this.state;
376
+ console.log('renderimagepopup', {
377
+ galleryOpen,
378
+ galleryImages,
379
+ galleryIndex
380
+ });
381
+ return /*#__PURE__*/React.createElement(Components.ImagePopup, {
382
+ visible: galleryOpen,
383
+ images: galleryImages,
384
+ index: galleryIndex,
385
+ onClose: this.closeGallery.bind(this)
386
+ });
387
+ }
161
388
  renderNote(n) {
162
389
  return /*#__PURE__*/React.createElement(View, {
163
390
  style: styles.noteContainer,
@@ -200,7 +427,7 @@ class RequestNotes extends Component {
200
427
  style: styles.noteContainerName
201
428
  }, n.User.displayName)))), /*#__PURE__*/React.createElement(Text, {
202
429
  style: styles.noteContainerText
203
- }, n.Note), (n.Attachments || []).map((a, i) => this.renderAttachment(a, i)), /*#__PURE__*/React.createElement(Text, {
430
+ }, n.Note), (n.Attachments || []).map((a, i) => this.renderAttachment(a, i)), this.renderImages(n), /*#__PURE__*/React.createElement(Text, {
204
431
  style: styles.noteTimestamp
205
432
  }, moment.utc(n.Timestamp).local().format(Helper.TIMESTAMP_FORMAT)));
206
433
  }
@@ -240,6 +467,108 @@ class RequestNotes extends Component {
240
467
  large: true
241
468
  }, "Save");
242
469
  }
470
+ renderUploadMenu() {
471
+ return /*#__PURE__*/React.createElement(Components.ImageUploader, {
472
+ ref: ref => this.imageUploader = ref,
473
+ onUploadStarted: this.onUploadStarted,
474
+ onUploadSuccess: this.onUploadSuccess,
475
+ onUploadFailed: this.onUploadFailed,
476
+ onUploadProgress: this.onUploadProgress,
477
+ onLibrarySelected: this.onLibrarySelected,
478
+ size: {
479
+ width: 1400
480
+ },
481
+ quality: 0.8,
482
+ fileName: 'serviceNoteImage',
483
+ popupTitle: 'Upload Image',
484
+ userId: this.props.user.uid,
485
+ allowsEditing: false,
486
+ multiple: true,
487
+ hideLibrary: true
488
+ });
489
+ }
490
+ renderImage(item, index) {
491
+ const isVideoUrl = Helper.isVideo(item.url);
492
+ const imagesList = this.getImages();
493
+ if (item.add) {
494
+ return /*#__PURE__*/React.createElement(TouchableOpacity, {
495
+ activeOpacity: 0.8,
496
+ onPress: () => this.showUploadMenu()
497
+ }, /*#__PURE__*/React.createElement(View, {
498
+ style: [styles.imageContainer, imagesList.length > 1 && styles.imageContainerNotEmpty, index % 3 === 0 && {
499
+ marginLeft: 0
500
+ }, index > 2 && {
501
+ marginTop: 8
502
+ }]
503
+ }, /*#__PURE__*/React.createElement(View, {
504
+ style: styles.imageCircle
505
+ }, /*#__PURE__*/React.createElement(Icon, {
506
+ name: "camera",
507
+ type: "font-awesome",
508
+ iconStyle: styles.addImageIcon
509
+ }))));
510
+ }
511
+ return /*#__PURE__*/React.createElement(View, {
512
+ style: [styles.imageContainer, imagesList.length > 1 && styles.imageContainerNotEmpty, index % 3 === 0 && {
513
+ marginLeft: 0
514
+ }, index > 2 && {
515
+ marginTop: 8
516
+ }]
517
+ }, item.uploading ? /*#__PURE__*/React.createElement(Components.ImageUploadProgress, {
518
+ uploader: this.imageUploader,
519
+ image: item,
520
+ color: this.props.colourBrandingMain
521
+ }) : /*#__PURE__*/React.createElement(ImageBackground, {
522
+ style: styles.imageBackground,
523
+ source: Helper.getImageSource(item.thumbNailExists ? item.thumbNailUrl : item.url || item)
524
+ }, isVideoUrl && /*#__PURE__*/React.createElement(View, {
525
+ style: styles.imagePlayContainer
526
+ }, /*#__PURE__*/React.createElement(TouchableOpacity, {
527
+ onPress: this.toggleFullscreenVideo.bind(this, item.url)
528
+ }, /*#__PURE__*/React.createElement(Icon, {
529
+ name: "play",
530
+ type: "font-awesome",
531
+ iconStyle: styles.imageControlIcon
532
+ }))), /*#__PURE__*/React.createElement(TouchableOpacity, {
533
+ style: styles.removeImage,
534
+ onPress: () => this.removeImage(index)
535
+ }, /*#__PURE__*/React.createElement(Icon, {
536
+ name: "remove",
537
+ type: "font-awesome",
538
+ iconStyle: styles.imageControlIcon,
539
+ style: styles.removeImage
540
+ }))));
541
+ }
542
+ renderImageList() {
543
+ const imagesList = this.getImages();
544
+ return /*#__PURE__*/React.createElement(View, {
545
+ style: styles.imageListContainer
546
+ }, /*#__PURE__*/React.createElement(FlatList, {
547
+ keyboardShouldPersistTaps: "always",
548
+ enableEmptySections: true,
549
+ data: imagesList,
550
+ renderItem: ({
551
+ item,
552
+ index
553
+ }) => this.renderImage(item, index),
554
+ keyExtractor: (item, index) => index,
555
+ numColumns: 3,
556
+ scrollEnabled: false
557
+ }));
558
+ }
559
+ renderVideoPlayerPopup() {
560
+ const {
561
+ showFullscreenVideo,
562
+ currentVideoUrl
563
+ } = this.state;
564
+ if (!currentVideoUrl) return;
565
+ return /*#__PURE__*/React.createElement(Components.VideoPopup, {
566
+ uri: currentVideoUrl,
567
+ visible: showFullscreenVideo,
568
+ showFullscreenButton: false,
569
+ onClose: this.toggleFullscreenVideo
570
+ });
571
+ }
243
572
  renderAdd() {
244
573
  return /*#__PURE__*/React.createElement(Modal, {
245
574
  animationType: "slide",
@@ -247,7 +576,7 @@ class RequestNotes extends Component {
247
576
  }, /*#__PURE__*/React.createElement(KeyboardAvoidingView, {
248
577
  style: styles.container,
249
578
  behavior: Platform.OS === 'ios' && 'padding'
250
- }, /*#__PURE__*/React.createElement(Components.Header, {
579
+ }, this.renderUploadMenu(), /*#__PURE__*/React.createElement(Components.Header, {
251
580
  leftText: "Cancel",
252
581
  onPressLeft: this.closeAddNote,
253
582
  text: ""
@@ -277,12 +606,12 @@ class RequestNotes extends Component {
277
606
  }), /*#__PURE__*/React.createElement(Components.GenericInputSection, {
278
607
  label: "Attachments",
279
608
  sectionStyle: styles.inputSection
280
- }, this.state.editingNote ? (this.state.noteAttachments || []).map((a, i) => this.renderAttachment(a, i)) : /*#__PURE__*/React.createElement(Components.TextStyle, {
609
+ }, this.renderImageList(), this.state.editingNote ? (this.state.noteAttachments || []).map((a, i) => this.renderAttachment(a, i)) : /*#__PURE__*/React.createElement(Components.TextStyle, {
281
610
  type: "body",
282
611
  style: styles.attachmentInfo
283
612
  }, "PDFs can only be attached to notes from the Community Manager."))), /*#__PURE__*/React.createElement(View, {
284
613
  style: styles.popupFooter
285
- }, this.renderFooterContent())));
614
+ }, this.renderFooterContent()), this.renderVideoPlayerPopup()));
286
615
  }
287
616
  render() {
288
617
  return /*#__PURE__*/React.createElement(View, {
@@ -296,7 +625,7 @@ class RequestNotes extends Component {
296
625
  contentContainerStyle: styles.innerContainer
297
626
  }, this.renderNotes()), /*#__PURE__*/React.createElement(Components.AddButton, {
298
627
  onPress: this.openAddNote
299
- }));
628
+ }), this.renderImagePopup());
300
629
  }
301
630
  }
302
631
  const styles = {
@@ -374,6 +703,86 @@ const styles = {
374
703
  },
375
704
  attachmentInfo: {
376
705
  marginTop: 8
706
+ },
707
+ imageListContainer: {
708
+ marginVertical: 8
709
+ },
710
+ imageContainer: {
711
+ width: PHOTO_SIZE,
712
+ height: PHOTO_SIZE,
713
+ borderStyle: 'dashed',
714
+ justifyContent: 'center',
715
+ alignItems: 'center',
716
+ borderWidth: 1,
717
+ borderColor: Colours.LINEGREY,
718
+ backgroundColor: Colours.BOXGREY,
719
+ borderRadius: 4,
720
+ marginLeft: 8
721
+ },
722
+ imageContainerNotEmpty: {
723
+ borderWidth: 1,
724
+ borderColor: Colours.LINEGREY,
725
+ backgroundColor: '#fff',
726
+ borderStyle: 'dashed'
727
+ },
728
+ imageBackground: {
729
+ flex: 1,
730
+ height: '100%',
731
+ width: '100%',
732
+ borderRadius: 4
733
+ },
734
+ imageCircle: {
735
+ width: 90,
736
+ height: 90,
737
+ borderRadius: 45,
738
+ backgroundColor: Colours.PINKISH_GREY,
739
+ justifyContent: 'center'
740
+ },
741
+ addImageIcon: {
742
+ color: '#fff',
743
+ fontSize: 32
744
+ },
745
+ imagePlayContainer: {
746
+ position: 'absolute',
747
+ top: 0,
748
+ left: 0,
749
+ right: 0,
750
+ bottom: 0,
751
+ alignItems: 'center',
752
+ justifyContent: 'center'
753
+ },
754
+ imageControlIcon: {
755
+ color: '#fff',
756
+ fontSize: 20,
757
+ textShadowColor: 'rgba(0,0,0,0.3)',
758
+ textShadowOffset: {
759
+ width: 2,
760
+ height: 2
761
+ }
762
+ },
763
+ removeImage: {
764
+ position: 'absolute',
765
+ top: 0,
766
+ right: 0,
767
+ padding: 4,
768
+ width: 40,
769
+ height: 40,
770
+ alignItems: 'center',
771
+ justifyContent: 'center'
772
+ },
773
+ sideBySideImages: {
774
+ flex: 1,
775
+ flexDirection: 'row',
776
+ marginTop: 12,
777
+ marginHorizontal: -8
778
+ },
779
+ sideBySideImageContainer: {
780
+ backgroundColor: '#fff',
781
+ width: 60,
782
+ height: 50,
783
+ borderRadius: 2,
784
+ overflow: 'hidden',
785
+ marginRight: 2
377
786
  }
378
787
  };
379
788
  const mapStateToProps = state => {