@plusscommunities/pluss-core-app 8.0.1 → 8.0.2-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 (320) hide show
  1. package/dist/module/actions/FollowerActions.js +4 -4
  2. package/dist/module/actions/FollowerActions.js.map +1 -1
  3. package/dist/module/actions/MediaActions.js +1 -1
  4. package/dist/module/actions/MediaActions.js.map +1 -1
  5. package/dist/module/actions/ResidentActions.js +1 -1
  6. package/dist/module/actions/ResidentActions.js.map +1 -1
  7. package/dist/module/actions/UserActions.js +1 -1
  8. package/dist/module/actions/UserActions.js.map +1 -1
  9. package/dist/module/actions/UserSettingsActions.js +1 -1
  10. package/dist/module/actions/UserSettingsActions.js.map +1 -1
  11. package/dist/module/actions/index.js +5 -5
  12. package/dist/module/actions/index.js.map +1 -1
  13. package/dist/module/actions/types.js +16 -16
  14. package/dist/module/actions/types.js.map +1 -1
  15. package/dist/module/apis/analyticsActions.js +5 -5
  16. package/dist/module/apis/analyticsActions.js.map +1 -1
  17. package/dist/module/apis/contactActions.js +6 -6
  18. package/dist/module/apis/contactActions.js.map +1 -1
  19. package/dist/module/apis/eventActions.js +28 -28
  20. package/dist/module/apis/eventActions.js.map +1 -1
  21. package/dist/module/apis/fileActions.js +15 -15
  22. package/dist/module/apis/fileActions.js.map +1 -1
  23. package/dist/module/apis/followerActions.js +8 -8
  24. package/dist/module/apis/followerActions.js.map +1 -1
  25. package/dist/module/apis/index.js +12 -12
  26. package/dist/module/apis/index.js.map +1 -1
  27. package/dist/module/apis/notificationActions.js +17 -17
  28. package/dist/module/apis/notificationActions.js.map +1 -1
  29. package/dist/module/apis/profileActions.js +4 -4
  30. package/dist/module/apis/profileActions.js.map +1 -1
  31. package/dist/module/apis/reactionActions.js +15 -15
  32. package/dist/module/apis/reactionActions.js.map +1 -1
  33. package/dist/module/apis/settingActions.js +6 -6
  34. package/dist/module/apis/settingActions.js.map +1 -1
  35. package/dist/module/apis/stringActions.js +8 -8
  36. package/dist/module/apis/stringActions.js.map +1 -1
  37. package/dist/module/apis/typeActions.js +4 -4
  38. package/dist/module/apis/typeActions.js.map +1 -1
  39. package/dist/module/apis/userActions.js +8 -8
  40. package/dist/module/apis/userActions.js.map +1 -1
  41. package/dist/module/assets/icons/fontawesome/fa-brands-400.ttf +0 -0
  42. package/dist/module/assets/icons/fontawesome/fa-light-300.ttf +0 -0
  43. package/dist/module/assets/icons/fontawesome/fa-regular-400.ttf +0 -0
  44. package/dist/module/assets/icons/fontawesome/fa-solid-900.ttf +0 -0
  45. package/dist/module/assets/icons/fontawesome/fa-thin-100.ttf +0 -0
  46. package/dist/module/assets/icons/fontawesome/fa7-glyphmap.json +4205 -0
  47. package/dist/module/colours.js +26 -29
  48. package/dist/module/colours.js.map +1 -1
  49. package/dist/module/components/AddButton.js +8 -8
  50. package/dist/module/components/AddButton.js.map +1 -1
  51. package/dist/module/components/AddToCalendarButton.js +30 -29
  52. package/dist/module/components/AddToCalendarButton.js.map +1 -1
  53. package/dist/module/components/Attachment.js +10 -9
  54. package/dist/module/components/Attachment.js.map +1 -1
  55. package/dist/module/components/AudienceSelectorLauncher.js +11 -11
  56. package/dist/module/components/AudienceSelectorLauncher.js.map +1 -1
  57. package/dist/module/components/AudienceSelectorPage.js +45 -44
  58. package/dist/module/components/AudienceSelectorPage.js.map +1 -1
  59. package/dist/module/components/AutoOffsetImage.js +13 -13
  60. package/dist/module/components/AutoOffsetImage.js.map +1 -1
  61. package/dist/module/components/BackButton.js +10 -10
  62. package/dist/module/components/BackButton.js.map +1 -1
  63. package/dist/module/components/CalendarPopup.js +21 -21
  64. package/dist/module/components/CalendarPopup.js.map +1 -1
  65. package/dist/module/components/CategoryTabs.js +30 -29
  66. package/dist/module/components/CategoryTabs.js.map +1 -1
  67. package/dist/module/components/CommentReply.js +43 -37
  68. package/dist/module/components/CommentReply.js.map +1 -1
  69. package/dist/module/components/CommentSection.js +74 -74
  70. package/dist/module/components/CommentSection.js.map +1 -1
  71. package/dist/module/components/ConfirmPopup.js +21 -20
  72. package/dist/module/components/ConfirmPopup.js.map +1 -1
  73. package/dist/module/components/ConfirmationPopup.js +11 -11
  74. package/dist/module/components/ConfirmationPopup.js.map +1 -1
  75. package/dist/module/components/DocumentUploader.js +50 -50
  76. package/dist/module/components/DocumentUploader.js.map +1 -1
  77. package/dist/module/components/DropDownItem.js +14 -13
  78. package/dist/module/components/DropDownItem.js.map +1 -1
  79. package/dist/module/components/DropDownMenu.js +5 -5
  80. package/dist/module/components/DropDownMenu.js.map +1 -1
  81. package/dist/module/components/EmptyStateMain.js +10 -9
  82. package/dist/module/components/EmptyStateMain.js.map +1 -1
  83. package/dist/module/components/EmptyStateWidget.js +7 -6
  84. package/dist/module/components/EmptyStateWidget.js.map +1 -1
  85. package/dist/module/components/FontScaleButton.js +5 -4
  86. package/dist/module/components/FontScaleButton.js.map +1 -1
  87. package/dist/module/components/FontScalePopup.js +11 -10
  88. package/dist/module/components/FontScalePopup.js.map +1 -1
  89. package/dist/module/components/Forbidden.js +13 -13
  90. package/dist/module/components/Forbidden.js.map +1 -1
  91. package/dist/module/components/FormCard.js +4 -4
  92. package/dist/module/components/FormCard.js.map +1 -1
  93. package/dist/module/components/FormCardSection.js +20 -18
  94. package/dist/module/components/FormCardSection.js.map +1 -1
  95. package/dist/module/components/FormCardSectionOptionLauncher.js +13 -12
  96. package/dist/module/components/FormCardSectionOptionLauncher.js.map +1 -1
  97. package/dist/module/components/FormattedText.js +18 -16
  98. package/dist/module/components/FormattedText.js.map +1 -1
  99. package/dist/module/components/GenericInput.js +24 -21
  100. package/dist/module/components/GenericInput.js.map +1 -1
  101. package/dist/module/components/GenericInputSection.js +27 -26
  102. package/dist/module/components/GenericInputSection.js.map +1 -1
  103. package/dist/module/components/Header.js +70 -69
  104. package/dist/module/components/Header.js.map +1 -1
  105. package/dist/module/components/Icon.js +109 -0
  106. package/dist/module/components/Icon.js.map +1 -0
  107. package/dist/module/components/ImagePopup.js +211 -73
  108. package/dist/module/components/ImagePopup.js.map +1 -1
  109. package/dist/module/components/ImageUploadProgress.js +10 -9
  110. package/dist/module/components/ImageUploadProgress.js.map +1 -1
  111. package/dist/module/components/ImageUploader.js +122 -97
  112. package/dist/module/components/ImageUploader.js.map +1 -1
  113. package/dist/module/components/InlineButton.js +9 -8
  114. package/dist/module/components/InlineButton.js.map +1 -1
  115. package/dist/module/components/Input.js +28 -26
  116. package/dist/module/components/Input.js.map +1 -1
  117. package/dist/module/components/LoadingCircles.js +20 -20
  118. package/dist/module/components/LoadingCircles.js.map +1 -1
  119. package/dist/module/components/LoadingIndicator.js +11 -11
  120. package/dist/module/components/LoadingIndicator.js.map +1 -1
  121. package/dist/module/components/LoadingStateWidget.js +5 -5
  122. package/dist/module/components/LoadingStateWidget.js.map +1 -1
  123. package/dist/module/components/MediaPlayer.js +31 -31
  124. package/dist/module/components/MediaPlayer.js.map +1 -1
  125. package/dist/module/components/MiddlePopup.js +17 -11
  126. package/dist/module/components/MiddlePopup.js.map +1 -1
  127. package/dist/module/components/PDFPopup.js +152 -46
  128. package/dist/module/components/PDFPopup.js.map +1 -1
  129. package/dist/module/components/PlussChat.js +168 -149
  130. package/dist/module/components/PlussChat.js.map +1 -1
  131. package/dist/module/components/PlussChatMessage.js +42 -42
  132. package/dist/module/components/PlussChatMessage.js.map +1 -1
  133. package/dist/module/components/PlussChatTime.js +18 -17
  134. package/dist/module/components/PlussChatTime.js.map +1 -1
  135. package/dist/module/components/Popup.js +20 -19
  136. package/dist/module/components/Popup.js.map +1 -1
  137. package/dist/module/components/PopupMenu.js +15 -14
  138. package/dist/module/components/PopupMenu.js.map +1 -1
  139. package/dist/module/components/PositionedImage.js +20 -20
  140. package/dist/module/components/PositionedImage.js.map +1 -1
  141. package/dist/module/components/ProfilePic.js +10 -10
  142. package/dist/module/components/ProfilePic.js.map +1 -1
  143. package/dist/module/components/RadioButton.js +10 -9
  144. package/dist/module/components/RadioButton.js.map +1 -1
  145. package/dist/module/components/Reaction.js +18 -17
  146. package/dist/module/components/Reaction.js.map +1 -1
  147. package/dist/module/components/Reactions.js +7 -7
  148. package/dist/module/components/Reactions.js.map +1 -1
  149. package/dist/module/components/SharingTools.js +78 -43
  150. package/dist/module/components/SharingTools.js.map +1 -1
  151. package/dist/module/components/Spinner.js +5 -5
  152. package/dist/module/components/Spinner.js.map +1 -1
  153. package/dist/module/components/StickyFooter.js +6 -6
  154. package/dist/module/components/StickyFooter.js.map +1 -1
  155. package/dist/module/components/Text.js +57 -0
  156. package/dist/module/components/Text.js.map +1 -0
  157. package/dist/module/components/TickIcon.js +6 -6
  158. package/dist/module/components/TickIcon.js.map +1 -1
  159. package/dist/module/components/Toggle.js +10 -9
  160. package/dist/module/components/Toggle.js.map +1 -1
  161. package/dist/module/components/TouchableSearchBar.js +18 -17
  162. package/dist/module/components/TouchableSearchBar.js.map +1 -1
  163. package/dist/module/components/UserListPopup.js +20 -19
  164. package/dist/module/components/UserListPopup.js.map +1 -1
  165. package/dist/module/components/UserListing.js +41 -40
  166. package/dist/module/components/UserListing.js.map +1 -1
  167. package/dist/module/components/VideoPopup.js +20 -20
  168. package/dist/module/components/VideoPopup.js.map +1 -1
  169. package/dist/module/components/WarningPopup.js +21 -20
  170. package/dist/module/components/WarningPopup.js.map +1 -1
  171. package/dist/module/components/expo-image-picker-multiple/ImageBrowser.js +13 -13
  172. package/dist/module/components/expo-image-picker-multiple/ImageBrowser.js.map +1 -1
  173. package/dist/module/components/expo-image-picker-multiple/ImageTile.js +24 -23
  174. package/dist/module/components/expo-image-picker-multiple/ImageTile.js.map +1 -1
  175. package/dist/module/components/index.js +59 -58
  176. package/dist/module/components/index.js.map +1 -1
  177. package/dist/module/components/react-native-expo-image-cropper/ExpoImageManipulator.js +113 -76
  178. package/dist/module/components/react-native-expo-image-cropper/ExpoImageManipulator.js.map +1 -1
  179. package/dist/module/components/react-native-expo-image-cropper/ImageCropOverlay.js +64 -64
  180. package/dist/module/components/react-native-expo-image-cropper/ImageCropOverlay.js.map +1 -1
  181. package/dist/module/config.js +15 -10
  182. package/dist/module/config.js.map +1 -1
  183. package/dist/module/constants.js +3 -4
  184. package/dist/module/constants.js.map +1 -1
  185. package/dist/module/helper.js +83 -82
  186. package/dist/module/helper.js.map +1 -1
  187. package/dist/module/index.js +12 -12
  188. package/dist/module/index.js.map +1 -1
  189. package/dist/module/js/images/detectFaces.js +11 -10
  190. package/dist/module/js/images/detectFaces.js.map +1 -1
  191. package/dist/module/js/images/findLandmarkRange.js +8 -8
  192. package/dist/module/js/images/findLandmarkRange.js.map +1 -1
  193. package/dist/module/js/images/getScaledOffset.js.map +1 -1
  194. package/dist/module/js/site/getSiteLevelFromState.js +2 -2
  195. package/dist/module/js/site/getSiteLevelFromState.js.map +1 -1
  196. package/dist/module/js/site/isTVEnabled.js +2 -2
  197. package/dist/module/js/site/isTVEnabled.js.map +1 -1
  198. package/dist/module/session.js +6 -6
  199. package/dist/module/session.js.map +1 -1
  200. package/dist/module/styles.js +17 -17
  201. package/dist/module/styles.js.map +1 -1
  202. package/dist/module/withNavigationFocus.js +30 -0
  203. package/dist/module/withNavigationFocus.js.map +1 -0
  204. package/package.json +81 -68
  205. package/src/actions/FollowerActions.js +36 -32
  206. package/src/actions/MediaActions.js +25 -20
  207. package/src/actions/ResidentActions.js +26 -21
  208. package/src/actions/UserActions.js +22 -22
  209. package/src/actions/UserSettingsActions.js +11 -11
  210. package/src/actions/index.js +5 -5
  211. package/src/actions/types.js +16 -16
  212. package/src/apis/analyticsActions.js +17 -17
  213. package/src/apis/contactActions.js +20 -20
  214. package/src/apis/eventActions.js +153 -144
  215. package/src/apis/fileActions.js +96 -86
  216. package/src/apis/followerActions.js +29 -29
  217. package/src/apis/index.js +12 -12
  218. package/src/apis/notificationActions.js +44 -44
  219. package/src/apis/profileActions.js +8 -8
  220. package/src/apis/reactionActions.js +81 -73
  221. package/src/apis/settingActions.js +15 -15
  222. package/src/apis/stringActions.js +29 -25
  223. package/src/apis/typeActions.js +10 -10
  224. package/src/apis/userActions.js +93 -93
  225. package/src/assets/icons/fontawesome/fa-brands-400.ttf +0 -0
  226. package/src/assets/icons/fontawesome/fa-light-300.ttf +0 -0
  227. package/src/assets/icons/fontawesome/fa-regular-400.ttf +0 -0
  228. package/src/assets/icons/fontawesome/fa-solid-900.ttf +0 -0
  229. package/src/assets/icons/fontawesome/fa-thin-100.ttf +0 -0
  230. package/src/assets/icons/fontawesome/fa7-glyphmap.json +4205 -0
  231. package/src/colours.js +116 -96
  232. package/src/components/AddButton.js +32 -27
  233. package/src/components/AddToCalendarButton.js +236 -202
  234. package/src/components/Attachment.js +59 -36
  235. package/src/components/AudienceSelectorLauncher.js +52 -48
  236. package/src/components/AudienceSelectorPage.js +353 -311
  237. package/src/components/AutoOffsetImage.js +237 -196
  238. package/src/components/BackButton.js +57 -41
  239. package/src/components/CalendarPopup.js +127 -97
  240. package/src/components/CategoryTabs.js +208 -163
  241. package/src/components/CommentReply.js +370 -309
  242. package/src/components/CommentSection.js +974 -781
  243. package/src/components/ConfirmPopup.js +141 -110
  244. package/src/components/ConfirmationPopup.js +80 -69
  245. package/src/components/DocumentUploader.js +245 -215
  246. package/src/components/DropDownItem.js +70 -60
  247. package/src/components/DropDownMenu.js +31 -27
  248. package/src/components/EmptyStateMain.js +51 -44
  249. package/src/components/EmptyStateWidget.js +47 -38
  250. package/src/components/FontScaleButton.js +29 -25
  251. package/src/components/FontScalePopup.js +67 -56
  252. package/src/components/Forbidden.js +48 -46
  253. package/src/components/FormCard.js +21 -17
  254. package/src/components/FormCardSection.js +284 -233
  255. package/src/components/FormCardSectionOptionLauncher.js +72 -46
  256. package/src/components/FormattedText.js +128 -111
  257. package/src/components/GenericInput.js +168 -136
  258. package/src/components/GenericInputSection.js +209 -161
  259. package/src/components/Header.js +620 -474
  260. package/src/components/Icon.js +119 -0
  261. package/src/components/ImagePopup.js +425 -221
  262. package/src/components/ImageUploadProgress.js +49 -41
  263. package/src/components/ImageUploader.js +973 -797
  264. package/src/components/InlineButton.js +79 -69
  265. package/src/components/Input.js +190 -156
  266. package/src/components/LoadingCircles.js +233 -233
  267. package/src/components/LoadingIndicator.js +87 -76
  268. package/src/components/LoadingStateWidget.js +47 -37
  269. package/src/components/MediaPlayer.js +416 -387
  270. package/src/components/MiddlePopup.js +62 -33
  271. package/src/components/PDFPopup.js +307 -159
  272. package/src/components/PlussChat.js +1224 -1025
  273. package/src/components/PlussChatMessage.js +329 -298
  274. package/src/components/PlussChatTime.js +57 -53
  275. package/src/components/Popup.js +138 -116
  276. package/src/components/PopupMenu.js +140 -110
  277. package/src/components/PositionedImage.js +281 -237
  278. package/src/components/ProfilePic.js +122 -113
  279. package/src/components/RadioButton.js +76 -52
  280. package/src/components/Reaction.js +134 -96
  281. package/src/components/Reactions.js +65 -63
  282. package/src/components/SharingTools.js +185 -134
  283. package/src/components/Spinner.js +13 -13
  284. package/src/components/StickyFooter.js +36 -26
  285. package/src/components/Text.js +62 -0
  286. package/src/components/TickIcon.js +20 -20
  287. package/src/components/Toggle.js +74 -73
  288. package/src/components/TouchableSearchBar.js +68 -50
  289. package/src/components/UserListPopup.js +161 -124
  290. package/src/components/UserListing.js +273 -238
  291. package/src/components/VideoPopup.js +110 -96
  292. package/src/components/WarningPopup.js +92 -71
  293. package/src/components/expo-image-picker-multiple/ImageBrowser.js +288 -256
  294. package/src/components/expo-image-picker-multiple/ImageTile.js +108 -84
  295. package/src/components/index.js +59 -58
  296. package/src/components/react-native-expo-image-cropper/ExpoImageManipulator.js +447 -359
  297. package/src/components/react-native-expo-image-cropper/ImageCropOverlay.js +420 -324
  298. package/src/config.js +26 -21
  299. package/src/constants.js +8 -10
  300. package/src/helper.js +469 -438
  301. package/src/index.js +24 -12
  302. package/src/js/images/detectFaces.js +28 -21
  303. package/src/js/images/findLandmarkRange.js +97 -90
  304. package/src/js/images/getScaledOffset.js +80 -75
  305. package/src/js/site/getSiteLevelFromState.js +26 -26
  306. package/src/js/site/isTVEnabled.js +10 -10
  307. package/src/session.js +32 -32
  308. package/src/styles.js +61 -61
  309. package/src/withNavigationFocus.js +28 -0
  310. package/dist/module/components/TextStyle.js +0 -45
  311. package/dist/module/components/TextStyle.js.map +0 -1
  312. package/dist/module/fonts/index.js +0 -2
  313. package/dist/module/fonts/index.js.map +0 -1
  314. package/dist/module/fonts/pluss60-icons.js +0 -5
  315. package/dist/module/fonts/pluss60-icons.js.map +0 -1
  316. package/dist/module/fonts/pluss60-icons.json +0 -1097
  317. package/src/components/TextStyle.js +0 -48
  318. package/src/fonts/index.js +0 -1
  319. package/src/fonts/pluss60-icons.js +0 -7
  320. package/src/fonts/pluss60-icons.json +0 -1097
@@ -1,375 +1,463 @@
1
- import React, { Component } from 'react';
1
+ import React, { Component } from "react";
2
+ import { Text } from "@plusscommunities/pluss-core-app/components";
2
3
  import {
3
- Dimensions,
4
- Image,
5
- ScrollView,
6
- Modal,
7
- View,
8
- Text,
9
- SafeAreaView,
10
- TouchableOpacity,
11
- StyleSheet,
12
- Platform,
13
- LogBox,
14
- } from 'react-native';
15
- import * as ImageManipulator from 'expo-image-manipulator';
16
- import PropTypes from 'prop-types';
17
- import AutoHeightImage from 'react-native-auto-height-image';
18
- import { isIphoneX, getStatusBarHeight } from 'react-native-iphone-x-helper';
19
- import ImageCropOverlay from './ImageCropOverlay';
20
-
21
- const { width } = Dimensions.get('window');
22
- const topMargin = getStatusBarHeight() + (Platform.OS === 'ios' ? 50 : 20);
23
-
24
- LogBox.ignoreLogs(['componentWillReceiveProps', 'componentWillUpdate', 'componentWillMount']);
4
+ Dimensions,
5
+ Image,
6
+ ScrollView,
7
+ Modal,
8
+ View,
9
+ TouchableOpacity,
10
+ StyleSheet,
11
+ LogBox,
12
+ Alert,
13
+ } from "react-native";
14
+ import * as ImageManipulator from "expo-image-manipulator";
15
+ import * as MediaLibrary from "expo-media-library";
16
+ import { File, Paths } from "expo-file-system";
17
+ import PropTypes from "prop-types";
18
+ import AutoHeightImage from "react-native-auto-height-image";
19
+ import {
20
+ withSafeAreaInsets,
21
+ SafeAreaView,
22
+ SafeAreaProvider,
23
+ } from "react-native-safe-area-context";
24
+ import ImageCropOverlay from "./ImageCropOverlay";
25
+
26
+ const { width } = Dimensions.get("window");
27
+
28
+ LogBox.ignoreLogs([
29
+ "componentWillReceiveProps",
30
+ "componentWillUpdate",
31
+ "componentWillMount",
32
+ ]);
25
33
  LogBox.ignoreLogs([
26
- 'Warning: componentWillMount is deprecated',
27
- 'Warning: componentWillReceiveProps is deprecated',
28
- 'Module RCTImageLoader requires',
34
+ "Warning: componentWillMount is deprecated",
35
+ "Warning: componentWillReceiveProps is deprecated",
36
+ "Module RCTImageLoader requires",
29
37
  ]);
30
38
 
31
39
  class ExpoImageManipulator extends Component {
32
- constructor(props) {
33
- super(props);
34
- const { squareAspect } = this.props;
35
- this.state = {
36
- cropMode: false,
37
- processing: false,
38
- squareAspect,
39
- };
40
-
41
- this.scrollOffset = 0;
42
- this.currentPos = { left: 0, top: 0 };
43
- this.currentSize = { width: 0, height: 0 };
44
- this.maxSizes = { width: 0, height: 0 };
45
- this.actualSize = { width: 0, height: 0 };
46
- }
47
-
48
- async componentDidMount() {
49
- await this.onConvertImageToEditableSize();
50
-
51
- // Set cropping by default
52
- this.setState({ cropMode: true });
53
- }
54
-
55
- async onConvertImageToEditableSize() {
56
- const {
57
- photo: { uri: rawUri },
58
- } = this.props;
59
- const { uri, width, height } = await ImageManipulator.manipulateAsync(rawUri, [{ resize: { width: 1080 } }]);
60
- this.setState({ uri });
61
- this.actualSize.width = width;
62
- this.actualSize.height = height;
63
- }
64
-
65
- onToggleModal = () => {
66
- this.props.onToggleModal();
67
- this.setState({ cropMode: false });
68
- };
69
-
70
- onCropImage = (callback = null) => {
71
- this.setState({ processing: true });
72
- const { uri } = this.state;
73
- Image.getSize(uri, async (actualWidth, actualHeight) => {
74
- let cropObj = this.getCropBounds(actualWidth, actualHeight);
75
- if (cropObj.height > 0 && cropObj.width > 0) {
76
- let uriToCrop = uri;
77
- const { uri: uriCroped, base64, width: croppedWidth, height: croppedHeight } = await this.crop(cropObj, uriToCrop);
78
-
79
- this.actualSize.width = croppedWidth;
80
- this.actualSize.height = croppedHeight;
81
-
82
- this.setState(
83
- {
84
- uri: uriCroped,
85
- base64,
86
- cropMode: false,
87
- processing: false,
88
- },
89
- () => {
90
- if (callback) callback();
91
- },
92
- );
93
- } else {
94
- this.setState({ cropMode: false, processing: false }, () => {
95
- if (callback) callback();
96
- });
97
- }
98
- });
99
- };
100
-
101
- onHandleScroll = event => {
102
- this.scrollOffset = event.nativeEvent.contentOffset.y;
103
- };
104
-
105
- getCropBounds = (actualWidth, actualHeight) => {
106
- let imageRatio = actualHeight / actualWidth;
107
- var originalHeight = Dimensions.get('window').height - 64;
108
- if (isIphoneX()) {
109
- originalHeight = Dimensions.get('window').height - 122;
110
- }
111
- let renderedImageWidth = imageRatio < originalHeight / width ? width : originalHeight / imageRatio;
112
- let renderedImageHeight = imageRatio < originalHeight / width ? width * imageRatio : originalHeight;
113
-
114
- let renderedImageY = (originalHeight - renderedImageHeight) / 2.0;
115
- let renderedImageX = (width - renderedImageWidth) / 2.0;
116
-
117
- const renderImageObj = {
118
- left: renderedImageX,
119
- top: renderedImageY,
120
- width: renderedImageWidth,
121
- height: renderedImageHeight,
122
- };
123
- const cropOverlayObj = {
124
- left: this.currentPos.left,
125
- top: this.currentPos.top,
126
- width: this.currentSize.width,
127
- height: this.currentSize.height,
128
- };
129
-
130
- var intersectAreaObj = {};
131
-
132
- let x = Math.max(renderImageObj.left, cropOverlayObj.left);
133
- let num1 = Math.min(renderImageObj.left + renderImageObj.width, cropOverlayObj.left + cropOverlayObj.width);
134
- let y = Math.max(renderImageObj.top, cropOverlayObj.top);
135
- let num2 = Math.min(renderImageObj.top + renderImageObj.height, cropOverlayObj.top + cropOverlayObj.height);
136
- if (num1 >= x && num2 >= y)
137
- intersectAreaObj = {
138
- originX: (x - renderedImageX) * (actualWidth / renderedImageWidth),
139
- originY: (y - renderedImageY) * (actualWidth / renderedImageWidth),
140
- width: (num1 - x) * (actualWidth / renderedImageWidth),
141
- height: (num2 - y) * (actualWidth / renderedImageWidth),
142
- };
143
- else {
144
- intersectAreaObj = {
145
- originX: x - renderedImageX,
146
- originY: y - renderedImageY,
147
- width: 0,
148
- height: 0,
149
- };
150
- }
151
- return intersectAreaObj;
152
- };
153
-
154
- crop = async (cropObj, uri) => {
155
- const { saveOptions } = this.props;
156
- if (cropObj.height > 0 && cropObj.width > 0) {
157
- const manipResult = await ImageManipulator.manipulateAsync(
158
- uri,
159
- [
160
- {
161
- crop: cropObj,
162
- },
163
- ],
164
- saveOptions,
165
- );
166
- return manipResult;
167
- }
168
- return {
169
- uri: null,
170
- base64: null,
171
- };
172
- };
173
-
174
- calculateMaxSizes = event => {
175
- let w1 = event.nativeEvent.layout.width || 100;
176
- let h1 = event.nativeEvent.layout.height || 100;
177
- if (this.state.squareAspect) {
178
- if (w1 < h1) h1 = w1;
179
- else w1 = h1;
180
- }
181
- this.maxSizes.width = w1;
182
- this.maxSizes.height = h1;
183
- };
184
-
185
- // eslint-disable-next-line camelcase
186
- async UNSAFE_componentWillReceiveProps() {
187
- await this.onConvertImageToEditableSize();
188
- }
189
-
190
- render() {
191
- const { isVisible, onPictureChoosed } = this.props;
192
- const { uri, base64, cropMode, processing } = this.state;
193
-
194
- let imageRatio = this.actualSize.height / this.actualSize.width;
195
- var originalHeight = Dimensions.get('window').height - 64;
196
- if (isIphoneX()) {
197
- originalHeight = Dimensions.get('window').height - 122;
198
- }
199
-
200
- let cropRatio = originalHeight / width;
201
-
202
- let cropWidth = imageRatio < cropRatio ? width : originalHeight / imageRatio;
203
- let cropHeight = imageRatio < cropRatio ? width * imageRatio : originalHeight;
204
-
205
- let cropInitialTop = (originalHeight - cropHeight) / 2.0;
206
- let cropInitialLeft = (width - cropWidth) / 2.0;
207
-
208
- if (this.currentSize.width == 0 && cropMode) {
209
- this.currentSize.width = cropWidth;
210
- this.currentSize.height = cropHeight;
211
-
212
- this.currentPos.top = cropInitialTop;
213
- this.currentPos.left = cropInitialLeft;
214
- }
215
-
216
- return (
217
- <Modal
218
- animationType="slide"
219
- transparent={true}
220
- visible={isVisible}
221
- hardwareAccelerated
222
- onRequestClose={() => {
223
- this.onToggleModal();
224
- }}
225
- >
226
- {uri !== undefined ? (
227
- <View style={styles.container}>
228
- <SafeAreaView style={[{ width }, styles.headerContainer]}>
229
- {!cropMode ? (
230
- <View style={[styles.headerButtonContainer, { justifyContent: 'flex-end' }]}>
231
- <TouchableOpacity
232
- onPress={() => {
233
- onPictureChoosed({ uri, base64 });
234
- this.onToggleModal();
235
- }}
236
- style={styles.headerButton}
237
- >
238
- <Text style={styles.headerButtonText}>{'Done'}</Text>
239
- </TouchableOpacity>
240
- </View>
241
- ) : (
242
- <View style={styles.headerButtonContainer}>
243
- <TouchableOpacity onPress={this.onToggleModal} style={styles.headerButton}>
244
- <Text style={styles.headerButtonText}>{'Cancel'}</Text>
245
- </TouchableOpacity>
246
- <TouchableOpacity
247
- onPress={() => {
248
- this.onCropImage(() => {
249
- onPictureChoosed({ uri: this.state.uri, base64: this.state.base64 });
250
- this.onToggleModal();
251
- });
252
- }}
253
- style={styles.headerButton}
254
- >
255
- <Text style={styles.headerButtonText}>{processing ? 'Processing' : 'Done'}</Text>
256
- </TouchableOpacity>
257
- </View>
258
- )}
259
- </SafeAreaView>
260
- <View style={[styles.contentContainer, { width: Dimensions.get('window').width }]}>
261
- <ScrollView
262
- style={{ position: 'relative', flex: 1 }}
263
- contentContainerStyle={{ backgroundColor: 'black' }}
264
- maximumZoomScale={5}
265
- minimumZoomScale={0.5}
266
- onScroll={this.onHandleScroll}
267
- bounces={false}
268
- showsHorizontalScrollIndicator={false}
269
- showsVerticalScrollIndicator={false}
270
- ref={c => (this.scrollView = c)}
271
- scrollEventThrottle={16}
272
- scrollEnabled={false}
273
- pinchGestureEnabled={false}
274
- >
275
- <AutoHeightImage
276
- style={{ backgroundColor: 'black', marginTop: cropInitialTop }}
277
- source={{ uri }}
278
- resizeMode={imageRatio >= 1 ? 'contain' : 'contain'}
279
- width={width}
280
- height={originalHeight}
281
- onLayout={this.calculateMaxSizes}
282
- />
283
- {!!cropMode && (
284
- <ImageCropOverlay
285
- onLayoutChanged={(top, left, width, height) => {
286
- this.currentSize.width = width;
287
- this.currentSize.height = height;
288
- this.currentPos.top = top;
289
- this.currentPos.left = left;
290
- }}
291
- initialWidth={cropWidth}
292
- initialHeight={cropHeight}
293
- initialTop={cropInitialTop}
294
- initialLeft={cropInitialLeft}
295
- minHeight={100}
296
- minWidth={100}
297
- topMargin={topMargin}
298
- />
299
- )}
300
- </ScrollView>
301
- </View>
302
- </View>
303
- ) : (
304
- <View style={styles.container}>
305
- <Text style={styles.prepareMessageText}>Preparing...</Text>
306
- </View>
307
- )}
308
- </Modal>
309
- );
310
- // }
311
- }
40
+ constructor(props) {
41
+ super(props);
42
+ const { squareAspect } = this.props;
43
+ this.state = {
44
+ cropMode: false,
45
+ processing: false,
46
+ squareAspect,
47
+ contentHeight: Dimensions.get("window").height - 100, // fallback until onLayout fires
48
+ };
49
+
50
+ this.scrollOffset = 0;
51
+ this.currentPos = { left: 0, top: 0 };
52
+ this.currentSize = { width: 0, height: 0 };
53
+ this.maxSizes = { width: 0, height: 0 };
54
+ this.actualSize = { width: 0, height: 0 };
55
+ }
56
+
57
+ async componentDidMount() {
58
+ await this.onConvertImageToEditableSize();
59
+
60
+ // Set cropping by default
61
+ this.setState({ cropMode: true });
62
+ }
63
+
64
+ async onConvertImageToEditableSize() {
65
+ try {
66
+ const {
67
+ photo: { uri: rawUri },
68
+ } = this.props;
69
+
70
+ // expo-image-manipulator only works with file:// URIs.
71
+ // Resolve ph:// (iOS Photo Library) and https:// (remote/stock images) first.
72
+ let resolvedUri = rawUri;
73
+ if (rawUri?.startsWith("ph://")) {
74
+ const assetId = rawUri.replace("ph://", "");
75
+ const assetInfo = await MediaLibrary.getAssetInfoAsync(assetId, {
76
+ shouldDownloadFromNetwork: true,
77
+ });
78
+ resolvedUri = assetInfo.localUri || rawUri;
79
+ } else if (rawUri?.startsWith("http")) {
80
+ const ext = rawUri.split(".").pop()?.split("?")[0] || "jpg";
81
+ const file = await File.downloadFileAsync(
82
+ rawUri,
83
+ new File(Paths.cache, `crop_${Date.now()}.${ext}`),
84
+ { idempotent: true },
85
+ );
86
+ resolvedUri = file.uri;
87
+ }
88
+
89
+ const manipulatePromise = ImageManipulator.manipulateAsync(resolvedUri, [
90
+ { resize: { width: 1080 } },
91
+ ]);
92
+ // manipulateAsync can hang forever on non-file:// URIs (promise never settles).
93
+ // Promise.race with a timeout ensures the catch block fires.
94
+ const timeoutPromise = new Promise((_, reject) =>
95
+ setTimeout(
96
+ () => reject(new Error("Image processing timed out")),
97
+ 15000,
98
+ ),
99
+ );
100
+ const { uri, width, height } = await Promise.race([
101
+ manipulatePromise,
102
+ timeoutPromise,
103
+ ]);
104
+ this.setState({ uri });
105
+ this.actualSize.width = width;
106
+ this.actualSize.height = height;
107
+ } catch (e) {
108
+ console.log("onConvertImageToEditableSize error", e);
109
+ this.onToggleModal();
110
+ Alert.alert(
111
+ "Error",
112
+ "Unable to prepare this image for editing. Please try a different image.",
113
+ );
114
+ }
115
+ }
116
+
117
+ onToggleModal = () => {
118
+ this.props.onToggleModal();
119
+ this.setState({ cropMode: false });
120
+ };
121
+
122
+ onCropImage = (callback = null) => {
123
+ this.setState({ processing: true });
124
+ const { uri } = this.state;
125
+ Image.getSize(uri, async (actualWidth, actualHeight) => {
126
+ let cropObj = this.getCropBounds(actualWidth, actualHeight);
127
+ if (cropObj.height > 0 && cropObj.width > 0) {
128
+ let uriToCrop = uri;
129
+ const {
130
+ uri: uriCroped,
131
+ base64,
132
+ width: croppedWidth,
133
+ height: croppedHeight,
134
+ } = await this.crop(cropObj, uriToCrop);
135
+
136
+ this.actualSize.width = croppedWidth;
137
+ this.actualSize.height = croppedHeight;
138
+
139
+ this.setState(
140
+ {
141
+ uri: uriCroped,
142
+ base64,
143
+ cropMode: false,
144
+ processing: false,
145
+ },
146
+ () => {
147
+ if (callback) callback();
148
+ },
149
+ );
150
+ } else {
151
+ this.setState({ cropMode: false, processing: false }, () => {
152
+ if (callback) callback();
153
+ });
154
+ }
155
+ });
156
+ };
157
+
158
+ onHandleScroll = (event) => {
159
+ this.scrollOffset = event.nativeEvent.contentOffset.y;
160
+ };
161
+
162
+ getCropBounds = (actualWidth, actualHeight) => {
163
+ const imageRatio = actualHeight / actualWidth;
164
+ const { contentHeight } = this.state;
165
+ const originalHeight = contentHeight;
166
+ let renderedImageWidth =
167
+ imageRatio < originalHeight / width ? width : originalHeight / imageRatio;
168
+ let renderedImageHeight =
169
+ imageRatio < originalHeight / width ? width * imageRatio : originalHeight;
170
+
171
+ let renderedImageY = (originalHeight - renderedImageHeight) / 2.0;
172
+ let renderedImageX = (width - renderedImageWidth) / 2.0;
173
+
174
+ const renderImageObj = {
175
+ left: renderedImageX,
176
+ top: renderedImageY,
177
+ width: renderedImageWidth,
178
+ height: renderedImageHeight,
179
+ };
180
+ const cropOverlayObj = {
181
+ left: this.currentPos.left,
182
+ top: this.currentPos.top,
183
+ width: this.currentSize.width,
184
+ height: this.currentSize.height,
185
+ };
186
+
187
+ var intersectAreaObj = {};
188
+
189
+ let x = Math.max(renderImageObj.left, cropOverlayObj.left);
190
+ let num1 = Math.min(
191
+ renderImageObj.left + renderImageObj.width,
192
+ cropOverlayObj.left + cropOverlayObj.width,
193
+ );
194
+ let y = Math.max(renderImageObj.top, cropOverlayObj.top);
195
+ let num2 = Math.min(
196
+ renderImageObj.top + renderImageObj.height,
197
+ cropOverlayObj.top + cropOverlayObj.height,
198
+ );
199
+ if (num1 >= x && num2 >= y)
200
+ intersectAreaObj = {
201
+ originX: (x - renderedImageX) * (actualWidth / renderedImageWidth),
202
+ originY: (y - renderedImageY) * (actualWidth / renderedImageWidth),
203
+ width: (num1 - x) * (actualWidth / renderedImageWidth),
204
+ height: (num2 - y) * (actualWidth / renderedImageWidth),
205
+ };
206
+ else {
207
+ intersectAreaObj = {
208
+ originX: x - renderedImageX,
209
+ originY: y - renderedImageY,
210
+ width: 0,
211
+ height: 0,
212
+ };
213
+ }
214
+ return intersectAreaObj;
215
+ };
216
+
217
+ crop = async (cropObj, uri) => {
218
+ const { saveOptions } = this.props;
219
+ if (cropObj.height > 0 && cropObj.width > 0) {
220
+ const manipResult = await ImageManipulator.manipulateAsync(
221
+ uri,
222
+ [
223
+ {
224
+ crop: cropObj,
225
+ },
226
+ ],
227
+ saveOptions,
228
+ );
229
+ return manipResult;
230
+ }
231
+ return {
232
+ uri: null,
233
+ base64: null,
234
+ };
235
+ };
236
+
237
+ calculateMaxSizes = (event) => {
238
+ let w1 = event.nativeEvent.layout.width || 100;
239
+ let h1 = event.nativeEvent.layout.height || 100;
240
+ if (this.state.squareAspect) {
241
+ if (w1 < h1) h1 = w1;
242
+ else w1 = h1;
243
+ }
244
+ this.maxSizes.width = w1;
245
+ this.maxSizes.height = h1;
246
+ };
247
+
248
+ // eslint-disable-next-line camelcase
249
+ async UNSAFE_componentWillReceiveProps() {
250
+ await this.onConvertImageToEditableSize();
251
+ }
252
+
253
+ onContentLayout = (event) => {
254
+ this.setState({
255
+ contentHeight: event.nativeEvent.layout.height,
256
+ });
257
+ };
258
+
259
+ render() {
260
+ const { isVisible, onPictureChoosed } = this.props;
261
+ const { uri, base64, cropMode, processing, contentHeight } = this.state;
262
+
263
+ const imageRatio = this.actualSize.height / this.actualSize.width;
264
+ const originalHeight = contentHeight;
265
+ const topMargin = (this.props.insets?.top ?? 0) + 50;
266
+
267
+ const cropRatio = originalHeight / width;
268
+
269
+ const cropWidth =
270
+ imageRatio < cropRatio ? width : originalHeight / imageRatio;
271
+ const cropHeight =
272
+ imageRatio < cropRatio ? width * imageRatio : originalHeight;
273
+
274
+ const cropInitialTop = (originalHeight - cropHeight) / 2.0;
275
+ const cropInitialLeft = (width - cropWidth) / 2.0;
276
+
277
+ if (this.currentSize.width == 0 && cropMode) {
278
+ this.currentSize.width = cropWidth;
279
+ this.currentSize.height = cropHeight;
280
+
281
+ this.currentPos.top = cropInitialTop;
282
+ this.currentPos.left = cropInitialLeft;
283
+ }
284
+
285
+ return (
286
+ <Modal
287
+ animationType="slide"
288
+ transparent={true}
289
+ visible={isVisible}
290
+ hardwareAccelerated
291
+ onRequestClose={() => {
292
+ this.onToggleModal();
293
+ }}
294
+ >
295
+ {uri !== undefined ? (
296
+ <SafeAreaProvider>
297
+ <View style={styles.container}>
298
+ <SafeAreaView style={[{ width }, styles.headerContainer]}>
299
+ {!cropMode ? (
300
+ <View
301
+ style={[
302
+ styles.headerButtonContainer,
303
+ { justifyContent: "flex-end" },
304
+ ]}
305
+ >
306
+ <TouchableOpacity
307
+ onPress={() => {
308
+ onPictureChoosed({ uri, base64 });
309
+ this.onToggleModal();
310
+ }}
311
+ style={styles.headerButton}
312
+ >
313
+ <Text style={styles.headerButtonText}>{"Done"}</Text>
314
+ </TouchableOpacity>
315
+ </View>
316
+ ) : (
317
+ <View style={styles.headerButtonContainer}>
318
+ <TouchableOpacity
319
+ onPress={this.onToggleModal}
320
+ style={styles.headerButton}
321
+ >
322
+ <Text style={styles.headerButtonText}>{"Cancel"}</Text>
323
+ </TouchableOpacity>
324
+ <TouchableOpacity
325
+ onPress={() => {
326
+ this.onCropImage(() => {
327
+ onPictureChoosed({
328
+ uri: this.state.uri,
329
+ base64: this.state.base64,
330
+ });
331
+ this.onToggleModal();
332
+ });
333
+ }}
334
+ style={styles.headerButton}
335
+ >
336
+ <Text style={styles.headerButtonText}>
337
+ {processing ? "Processing" : "Done"}
338
+ </Text>
339
+ </TouchableOpacity>
340
+ </View>
341
+ )}
342
+ </SafeAreaView>
343
+ <SafeAreaView
344
+ onLayout={this.onContentLayout}
345
+ style={[styles.contentContainer, { width }]}
346
+ edges={["bottom"]}
347
+ >
348
+ <ScrollView
349
+ style={{ position: "relative", flex: 1 }}
350
+ contentContainerStyle={{ backgroundColor: "black" }}
351
+ maximumZoomScale={5}
352
+ minimumZoomScale={0.5}
353
+ onScroll={this.onHandleScroll}
354
+ bounces={false}
355
+ showsHorizontalScrollIndicator={false}
356
+ showsVerticalScrollIndicator={false}
357
+ ref={(c) => (this.scrollView = c)}
358
+ scrollEventThrottle={16}
359
+ scrollEnabled={false}
360
+ pinchGestureEnabled={false}
361
+ >
362
+ <AutoHeightImage
363
+ style={{ backgroundColor: "black" }}
364
+ source={{ uri }}
365
+ resizeMode={imageRatio >= 1 ? "contain" : "contain"}
366
+ width={width}
367
+ height={originalHeight}
368
+ onLayout={this.calculateMaxSizes}
369
+ />
370
+ {!!cropMode && (
371
+ <ImageCropOverlay
372
+ onLayoutChanged={(top, left, width, height) => {
373
+ this.currentSize.width = width;
374
+ this.currentSize.height = height;
375
+ this.currentPos.top = top;
376
+ this.currentPos.left = left;
377
+ }}
378
+ initialWidth={cropWidth}
379
+ initialHeight={cropHeight}
380
+ initialTop={cropInitialTop}
381
+ initialLeft={cropInitialLeft}
382
+ minHeight={100}
383
+ minWidth={100}
384
+ topMargin={topMargin}
385
+ />
386
+ )}
387
+ </ScrollView>
388
+ </SafeAreaView>
389
+ </View>
390
+ </SafeAreaProvider>
391
+ ) : (
392
+ <View style={styles.container}>
393
+ <Text style={styles.prepareMessageText}>Preparing...</Text>
394
+ </View>
395
+ )}
396
+ </Modal>
397
+ );
398
+ // }
399
+ }
312
400
  }
313
401
 
314
402
  const styles = StyleSheet.create({
315
- headerContainer: {
316
- flexDirection: 'row',
317
- backgroundColor: 'black',
318
- justifyContent: 'space-between',
319
- },
320
- headerButtonContainer: {
321
- flex: 1,
322
- flexDirection: 'row',
323
- justifyContent: 'space-between',
324
- },
325
- headerButton: {
326
- marginHorizontal: 10,
327
- width: 60,
328
- height: 40,
329
- alignItems: 'center',
330
- justifyContent: 'center',
331
- },
332
- headerButtonText: {
333
- fontWeight: '500',
334
- color: 'white',
335
- fontSize: 18,
336
- },
337
- contentContainer: {
338
- flex: 1,
339
- backgroundColor: 'black',
340
- },
341
- container: {
342
- flex: 1,
343
- backgroundColor: '#000d',
344
- alignItems: 'center',
345
- justifyContent: 'center',
346
- },
347
- prepareMessageText: {
348
- fontFamily: 'sf-bold',
349
- fontSize: 20,
350
- color: '#fff',
351
- },
403
+ headerContainer: {
404
+ flexDirection: "row",
405
+ backgroundColor: "black",
406
+ justifyContent: "space-between",
407
+ },
408
+ headerButtonContainer: {
409
+ flex: 1,
410
+ flexDirection: "row",
411
+ justifyContent: "space-between",
412
+ },
413
+ headerButton: {
414
+ marginHorizontal: 10,
415
+ width: 60,
416
+ height: 40,
417
+ alignItems: "center",
418
+ justifyContent: "center",
419
+ },
420
+ headerButtonText: {
421
+ fontWeight: "500",
422
+ color: "white",
423
+ fontSize: 18,
424
+ },
425
+ contentContainer: {
426
+ flex: 1,
427
+ backgroundColor: "black",
428
+ },
429
+ container: {
430
+ flex: 1,
431
+ backgroundColor: "#000d",
432
+ alignItems: "center",
433
+ justifyContent: "center",
434
+ },
435
+ prepareMessageText: {
436
+ fontFamily: "sf-bold",
437
+ fontSize: 20,
438
+ color: "#fff",
439
+ },
352
440
  });
353
441
 
354
- export default ExpoImageManipulator;
442
+ export default withSafeAreaInsets(ExpoImageManipulator);
355
443
 
356
444
  ExpoImageManipulator.defaultProps = {
357
- onPictureChoosed: ({ uri, base64 }) => console.log('URI:', uri, base64),
358
- dragVelocity: 100,
359
- resizeVelocity: 50,
360
- saveOptions: {
361
- compress: 1,
362
- format: ImageManipulator.SaveFormat.PNG,
363
- base64: false,
364
- },
445
+ onPictureChoosed: ({ uri, base64 }) => console.log("URI:", uri, base64),
446
+ dragVelocity: 100,
447
+ resizeVelocity: 50,
448
+ saveOptions: {
449
+ compress: 1,
450
+ format: ImageManipulator.SaveFormat.PNG,
451
+ base64: false,
452
+ },
365
453
  };
366
454
 
367
455
  ExpoImageManipulator.propTypes = {
368
- isVisible: PropTypes.bool.isRequired,
369
- onPictureChoosed: PropTypes.func,
370
- saveOptions: PropTypes.object,
371
- photo: PropTypes.object.isRequired,
372
- onToggleModal: PropTypes.func.isRequired,
373
- dragVelocity: PropTypes.number,
374
- resizeVelocity: PropTypes.number,
456
+ isVisible: PropTypes.bool.isRequired,
457
+ onPictureChoosed: PropTypes.func,
458
+ saveOptions: PropTypes.object,
459
+ photo: PropTypes.object.isRequired,
460
+ onToggleModal: PropTypes.func.isRequired,
461
+ dragVelocity: PropTypes.number,
462
+ resizeVelocity: PropTypes.number,
375
463
  };