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