@plusscommunities/pluss-core-app 6.1.7 → 6.1.8-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 +21 -28
  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 +36 -34
  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 +253 -0
  76. package/dist/module/components/DocumentUploader.js.map +1 -0
  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 +237 -77
  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 +22 -13
  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 +32 -32
  124. package/dist/module/components/MediaPlayer.js.map +1 -1
  125. package/dist/module/components/MiddlePopup.js +9 -9
  126. package/dist/module/components/MiddlePopup.js.map +1 -1
  127. package/dist/module/components/PDFPopup.js +36 -36
  128. package/dist/module/components/PDFPopup.js.map +1 -1
  129. package/dist/module/components/PlussChat.js +234 -146
  130. package/dist/module/components/PlussChat.js.map +1 -1
  131. package/dist/module/components/PlussChatMessage.js +75 -38
  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 +29 -28
  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 -57
  176. package/dist/module/components/index.js.map +1 -1
  177. package/dist/module/components/react-native-expo-image-cropper/ExpoImageManipulator.js +90 -58
  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 +6 -1
  182. package/dist/module/config.js.map +1 -1
  183. package/dist/module/constants.js +3 -3
  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 +6 -6
  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 +2 -2
  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 +4 -1
  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 +19 -27
  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 +363 -309
  242. package/src/components/CommentSection.js +974 -782
  243. package/src/components/ConfirmPopup.js +141 -110
  244. package/src/components/ConfirmationPopup.js +80 -69
  245. package/src/components/DocumentUploader.js +255 -0
  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 -206
  262. package/src/components/ImageUploadProgress.js +49 -41
  263. package/src/components/ImageUploader.js +23 -13
  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 +50 -32
  271. package/src/components/PDFPopup.js +198 -159
  272. package/src/components/PlussChat.js +1271 -986
  273. package/src/components/PlussChatMessage.js +330 -262
  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 +136 -122
  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 -57
  296. package/src/components/react-native-expo-image-cropper/ExpoImageManipulator.js +442 -358
  297. package/src/components/react-native-expo-image-cropper/ImageCropOverlay.js +420 -324
  298. package/src/config.js +5 -0
  299. package/src/constants.js +8 -8
  300. package/src/helper.js +469 -438
  301. package/src/index.js +24 -12
  302. package/src/js/images/detectFaces.js +27 -20
  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 +2 -2
  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 -6
  320. package/src/fonts/pluss60-icons.json +0 -1097
@@ -1,214 +1,433 @@
1
- import React, { Component } from 'react';
2
- import _ from 'lodash';
3
- import moment from 'moment';
4
- import { Dimensions, Modal, TouchableOpacity, StyleSheet, View, ImageBackground, Text } from 'react-native';
5
- import ImageViewer from 'react-native-image-zoom-viewer';
6
- import { Icon } from 'react-native-elements';
7
- import { TEXT_DARK } from '../colours';
8
- import { StatusBarHeight, isVideo, get1400 } from '../helper';
9
- import { Pl60Icon } from '../fonts';
10
- import { SharingTools } from './SharingTools';
11
- import { VideoPopup } from './VideoPopup';
12
- import { ProfilePic } from './ProfilePic';
13
-
14
- const SCREEN_WIDTH = Dimensions.get('window').width;
15
- const SCREEN_HEIGHT = Dimensions.get('window').height;
1
+ import React, { Component } from "react";
2
+ import { Text } from "@plusscommunities/pluss-core-app/components";
3
+ import _ from "lodash";
4
+ import moment from "moment";
5
+ import {
6
+ Dimensions,
7
+ Modal,
8
+ TouchableOpacity,
9
+ StyleSheet,
10
+ View,
11
+ Image,
12
+ } from "react-native";
13
+ import ImageViewer from "react-native-image-zoom-viewer";
14
+ import { Icon } from "@rneui/themed";
15
+ import { StatusBarHeight, isVideo, get1400 } from "../helper";
16
+ import { FontAwesome } from "./Icon";
17
+ import { SharingTools } from "./SharingTools";
18
+ import { VideoPopup } from "./VideoPopup";
19
+ import { ProfilePic } from "./ProfilePic";
20
+ import { LoadingIndicator } from "./";
21
+
22
+ const SCREEN_WIDTH = Dimensions.get("window").width;
23
+ const SCREEN_HEIGHT = Dimensions.get("window").height;
24
+ const MAX_IMAGE_HEIGHT = SCREEN_HEIGHT * 0.65;
16
25
 
17
26
  class ImagePopup extends Component {
18
- constructor(props) {
19
- super(props);
20
- this.state = {
21
- index: 0,
22
- images: [],
23
- showFullscreenVideo: false,
24
- currentVideoUrl: '',
25
- };
26
- }
27
-
28
- componentDidMount() {
29
- this.setupUrls();
30
- }
31
-
32
- componentDidUpdate(prevProps) {
33
- const { visible, index } = this.props;
34
- if (!prevProps.visible && visible) this.setupUrls();
35
- if (prevProps.index !== index) this.setState({ index });
36
- }
37
-
38
- setupUrls = () => {
39
- if (!this.props.images) return;
40
-
41
- const images = this.props.images.map(image => {
42
- if (typeof image === 'string') {
43
- return { url: get1400(image), original: image, isVideo: isVideo(image) };
44
- }
45
- return { url: get1400(image?.uri), original: image?.uri, isVideo: isVideo(image?.uri), date: image?.date, user: image?.user };
46
- });
47
-
48
- this.setState({ images, index: this.state.index || this.props.index || 0 });
49
- };
50
-
51
- onChange = index => {
52
- this.setState({ index });
53
- };
54
-
55
- scrollTo(index) {
56
- this.setState({
57
- index,
58
- });
59
- }
60
-
61
- toggleFullscreenVideo = url => {
62
- if (typeof url !== 'string') url = '';
63
- this.setState({ showFullscreenVideo: url.length > 0, currentVideoUrl: url });
64
- };
65
-
66
- renderClose() {
67
- return (
68
- <TouchableOpacity style={styles.menuIconContainer} onPress={this.props.onClose} activeOpacity={0.6}>
69
- <Pl60Icon name="close" style={[styles.menuIcon]} />
70
- </TouchableOpacity>
71
- );
72
- }
73
-
74
- renderImage = props => {
75
- const media = this.state.images.find(image => image.url === props.source.uri);
76
- const isVideo = !_.isNil(media) && media.isVideo;
77
-
78
- let dateText, timeText;
79
- if (!_.isNil(media.date)) {
80
- const imageDate = moment(media.date);
81
- dateText = imageDate.format('MMMM D, YYYY');
82
- timeText = imageDate.format('hh:mm A');
83
- }
84
-
85
- return (
86
- <View>
87
- <ImageBackground {...props}>
88
- {isVideo && (
89
- <View style={styles.videoOverlay}>
90
- <TouchableOpacity onPress={this.toggleFullscreenVideo.bind(this, media.original)}>
91
- <Icon name="play" type="font-awesome" iconStyle={styles.videoPlayIcon} />
92
- </TouchableOpacity>
93
- </View>
94
- )}
95
- </ImageBackground>
96
- {(!_.isNil(media.user) || !_.isNil(media.date)) && (
97
- <View style={styles.imageInfoContainer}>
98
- <ProfilePic Diameter={42} ProfilePic={media?.user?.profilePic} />
99
- <View style={styles.imageTextContainer}>
100
- <Text style={styles.imageTextName}>{media?.user?.displayName}</Text>
101
- <Text numberOfLines={2} style={styles.iamgeTextDate}>{`Uploaded ${dateText} • ${timeText}`}</Text>
102
- </View>
103
- </View>
104
- )}
105
- </View>
106
- );
107
- };
108
-
109
- renderVideoPlayerPopup() {
110
- const { showFullscreenVideo, currentVideoUrl } = this.state;
111
- if (!currentVideoUrl) return;
112
-
113
- return <VideoPopup uri={currentVideoUrl} visible={showFullscreenVideo} onClose={this.toggleFullscreenVideo} />;
114
- }
115
-
116
- render() {
117
- const { visible, onClose } = this.props;
118
- const { index, images } = this.state;
119
-
120
- if (_.isEmpty(images)) {
121
- return null;
122
- }
123
- return (
124
- <Modal visible={visible} animationType="slide" onRequestClose={onClose} style={styles.modal}>
125
- <ImageViewer
126
- style={styles.scrollable}
127
- index={index}
128
- onChange={this.onChange}
129
- onSwipeDown={onClose}
130
- enableSwipeDown
131
- imageUrls={images}
132
- saveToLocalByLongPress={false}
133
- renderImage={this.renderImage}
134
- />
135
- {this.renderClose()}
136
- <SharingTools uri={images[index].original} />
137
- {this.renderVideoPlayerPopup()}
138
- </Modal>
139
- );
140
- }
27
+ constructor(props) {
28
+ super(props);
29
+ this.state = {
30
+ index: 0,
31
+ images: [],
32
+ showFullscreenVideo: false,
33
+ currentVideoUrl: "",
34
+ imageDimensions: {},
35
+ isLoadingDimensions: false,
36
+ };
37
+ }
38
+
39
+ componentDidMount() {
40
+ this.setupUrls();
41
+ }
42
+
43
+ componentDidUpdate(prevProps) {
44
+ const { visible, index } = this.props;
45
+ if (!prevProps.visible && visible) this.setupUrls();
46
+ if (prevProps.index !== index) this.setState({ index });
47
+ }
48
+
49
+ setupUrls = async () => {
50
+ if (!this.props.images) return;
51
+
52
+ const images = this.props.images.map((image) => {
53
+ if (typeof image === "string") {
54
+ return {
55
+ url: get1400(image),
56
+ original: image,
57
+ isVideo: isVideo(image),
58
+ };
59
+ }
60
+ return {
61
+ url: get1400(image?.uri),
62
+ original: image?.uri,
63
+ isVideo: isVideo(image?.uri),
64
+ date: image?.date,
65
+ user: image?.user,
66
+ caption: image?.caption,
67
+ };
68
+ });
69
+
70
+ this.setState({ isLoadingDimensions: true });
71
+
72
+ const dimensions = {};
73
+ await Promise.all(
74
+ images.map(async (image) => {
75
+ if (!image.url) return;
76
+ try {
77
+ const { width, height } = await new Promise((resolve, reject) => {
78
+ Image.getSize(
79
+ image.url,
80
+ (w, h) => resolve({ width: w, height: h }),
81
+ reject,
82
+ );
83
+ });
84
+ dimensions[image.url] = { width, height };
85
+ } catch (err) {
86
+ console.log("Failed to get dimensions for", image.url, err);
87
+ dimensions[image.url] = {
88
+ width: SCREEN_WIDTH,
89
+ height: SCREEN_HEIGHT,
90
+ };
91
+ }
92
+ }),
93
+ );
94
+
95
+ this.setState({
96
+ images,
97
+ index: this.state.index || this.props.index || 0,
98
+ imageDimensions: dimensions,
99
+ isLoadingDimensions: false,
100
+ });
101
+ };
102
+
103
+ onChange = (index) => {
104
+ this.setState({ index });
105
+ };
106
+
107
+ scrollTo(index) {
108
+ this.setState({
109
+ index,
110
+ });
111
+ }
112
+
113
+ toggleFullscreenVideo = (url) => {
114
+ if (typeof url !== "string") url = "";
115
+ this.setState({
116
+ showFullscreenVideo: url.length > 0,
117
+ currentVideoUrl: url,
118
+ });
119
+ };
120
+
121
+ renderClose() {
122
+ return (
123
+ <TouchableOpacity
124
+ style={styles.menuIconContainer}
125
+ onPress={this.props.onClose}
126
+ activeOpacity={0.6}
127
+ >
128
+ <FontAwesome name="x" style={[styles.menuIcon]} />
129
+ </TouchableOpacity>
130
+ );
131
+ }
132
+
133
+ renderImageFooter = (media) => {
134
+ if (!media.user || !media.date) return null;
135
+
136
+ let dateText, timeText;
137
+ if (!_.isNil(media.date)) {
138
+ const imageDate = moment(media.date);
139
+ dateText = imageDate.format("MMMM D, YYYY");
140
+ timeText = imageDate.format("hh:mm A");
141
+ }
142
+
143
+ return (
144
+ <View style={styles.imageInfoContainer}>
145
+ <ProfilePic Diameter={36} ProfilePic={media?.user?.profilePic} />
146
+ <View style={styles.imageTextContainer}>
147
+ <Text style={styles.imageTextName}>{media?.user?.displayName}</Text>
148
+ <Text
149
+ numberOfLines={2}
150
+ style={styles.iamgeTextDate}
151
+ >{`Uploaded ${dateText} • ${timeText}`}</Text>
152
+ </View>
153
+ </View>
154
+ );
155
+ };
156
+
157
+ renderCaption = (media) => {
158
+ if (!media.caption) return null;
159
+
160
+ return (
161
+ <View style={styles.captionContainer}>
162
+ <Text numberOfLines={3} style={styles.captionText}>
163
+ {media.caption}
164
+ </Text>
165
+ </View>
166
+ );
167
+ };
168
+
169
+ getImageDimensions = (media) => {
170
+ const cachedDimensions = this.state.imageDimensions[media?.url] || {
171
+ width: SCREEN_WIDTH,
172
+ height: SCREEN_HEIGHT,
173
+ };
174
+
175
+ const aspectRatio = cachedDimensions.width / cachedDimensions.height;
176
+ let imageWidth = SCREEN_WIDTH;
177
+ let imageHeight = imageWidth / aspectRatio;
178
+
179
+ // Cap at 70% of screen height
180
+ if (imageHeight > MAX_IMAGE_HEIGHT) {
181
+ imageHeight = MAX_IMAGE_HEIGHT;
182
+ imageWidth = imageHeight * aspectRatio;
183
+ }
184
+
185
+ return { imageWidth, imageHeight };
186
+ };
187
+
188
+ renderImage = (props) => {
189
+ const media = this.state.images.find(
190
+ (image) => image.url === props.source.uri,
191
+ );
192
+ const isVideoMedia = !_.isNil(media) && media.isVideo;
193
+ const { imageWidth, imageHeight } = this.getImageDimensions(media);
194
+
195
+ return (
196
+ <View style={styles.imageContainer}>
197
+ <Image
198
+ source={{ uri: media?.url }}
199
+ style={{ width: imageWidth, height: imageHeight }}
200
+ resizeMode="contain"
201
+ />
202
+ {isVideoMedia && (
203
+ <View
204
+ style={[
205
+ styles.videoOverlay,
206
+ { width: imageWidth, height: imageHeight },
207
+ ]}
208
+ >
209
+ <TouchableOpacity
210
+ onPress={this.toggleFullscreenVideo.bind(this, media.original)}
211
+ >
212
+ <Icon
213
+ name="play"
214
+ type="font-awesome"
215
+ iconStyle={styles.videoPlayIcon}
216
+ />
217
+ </TouchableOpacity>
218
+ </View>
219
+ )}
220
+ </View>
221
+ );
222
+ };
223
+
224
+ renderVideoPlayerPopup() {
225
+ const { showFullscreenVideo, currentVideoUrl } = this.state;
226
+ if (!currentVideoUrl) return;
227
+
228
+ return (
229
+ <VideoPopup
230
+ uri={currentVideoUrl}
231
+ visible={showFullscreenVideo}
232
+ onClose={this.toggleFullscreenVideo}
233
+ />
234
+ );
235
+ }
236
+
237
+ renderBottomContent = () => {
238
+ const { index, images } = this.state;
239
+ const media = images[index];
240
+
241
+ if (!media) return null;
242
+
243
+ const hasCaption = !_.isNil(media.caption);
244
+ const hasUserInfo = !_.isNil(media.user) || !_.isNil(media.date);
245
+
246
+ if (!hasCaption && !hasUserInfo) return null;
247
+
248
+ // Calculate where the image ends (for caption positioning)
249
+ const { imageHeight } = this.getImageDimensions(media);
250
+ const imageTop = (SCREEN_HEIGHT - imageHeight) / 2;
251
+ const imageBottom = imageTop + imageHeight;
252
+ const captionTop = imageBottom + 16;
253
+
254
+ return (
255
+ <>
256
+ {/* Caption positioned below the image */}
257
+ {hasCaption && (
258
+ <View style={[styles.captionWrapper, { top: captionTop }]}>
259
+ {this.renderCaption(media)}
260
+ </View>
261
+ )}
262
+
263
+ {/* User info anchored to bottom of screen */}
264
+ {hasUserInfo && (
265
+ <View style={styles.userInfoWrapper}>
266
+ {this.renderImageFooter(media)}
267
+ </View>
268
+ )}
269
+ </>
270
+ );
271
+ };
272
+
273
+ render() {
274
+ const { visible, onClose } = this.props;
275
+ const { index, images, isLoadingDimensions } = this.state;
276
+
277
+ if (_.isEmpty(images)) {
278
+ return null;
279
+ }
280
+
281
+ if (isLoadingDimensions) {
282
+ return (
283
+ <Modal
284
+ visible={visible}
285
+ animationType="slide"
286
+ onRequestClose={onClose}
287
+ style={styles.modal}
288
+ >
289
+ <LoadingIndicator visible={true} />
290
+ </Modal>
291
+ );
292
+ }
293
+
294
+ const imagesWithSizes = images.map((image) => {
295
+ return {
296
+ ...image,
297
+ width: SCREEN_WIDTH,
298
+ height: SCREEN_HEIGHT,
299
+ };
300
+ });
301
+
302
+ return (
303
+ <Modal
304
+ visible={visible}
305
+ animationType="slide"
306
+ onRequestClose={onClose}
307
+ style={styles.modal}
308
+ >
309
+ <View style={styles.container}>
310
+ {/* Full screen image viewer */}
311
+ <ImageViewer
312
+ style={styles.imageViewer}
313
+ index={index}
314
+ onChange={this.onChange}
315
+ onSwipeDown={onClose}
316
+ enableSwipeDown
317
+ imageUrls={imagesWithSizes}
318
+ saveToLocalByLongPress={false}
319
+ renderImage={this.renderImage}
320
+ backgroundColor="#000"
321
+ />
322
+
323
+ {/* Absolutely positioned bottom content */}
324
+ {this.renderBottomContent()}
325
+
326
+ {/* Overlay controls */}
327
+ {this.renderClose()}
328
+ <SharingTools uri={images[index]?.original} />
329
+ </View>
330
+ {this.renderVideoPlayerPopup()}
331
+ </Modal>
332
+ );
333
+ }
141
334
  }
142
335
 
143
336
  const styles = StyleSheet.create({
144
- modal: {
145
- backgroundColor: '#000',
146
- },
147
- scrollable: {
148
- width: SCREEN_WIDTH,
149
- height: SCREEN_HEIGHT,
150
- backgroundColor: '#000',
151
- },
152
- image: {
153
- width: SCREEN_WIDTH,
154
- height: SCREEN_HEIGHT,
155
- backgroundColor: '#000',
156
- },
157
- menuIconContainer: {
158
- position: 'absolute',
159
- top: StatusBarHeight(0),
160
- right: 0,
161
- width: 55,
162
- height: 55,
163
- zIndex: 3,
164
- },
165
- menuIcon: {
166
- fontSize: 25,
167
- padding: 15,
168
- width: 55,
169
- textAlign: 'center',
170
- color: '#fff',
171
- zIndex: 3,
172
- },
173
- videoOverlay: {
174
- position: 'absolute',
175
- top: 0,
176
- left: 0,
177
- right: 0,
178
- bottom: 0,
179
- alignItems: 'center',
180
- justifyContent: 'center',
181
- },
182
- videoPlayIcon: {
183
- color: '#fff',
184
- fontSize: 30,
185
- textShadowColor: 'rgba(0,0,0,0.3)',
186
- textShadowOffset: { width: 2, height: 2 },
187
- },
188
- imageInfoContainer: {
189
- flexDirection: 'row',
190
- paddingHorizontal: 12,
191
- height: 70,
192
- backgroundColor: '#fff',
193
- alignItems: 'center',
194
- },
195
- imageTextContainer: {
196
- marginLeft: 12,
197
- flexDirection: 'column',
198
- flex: 1,
199
- height: 42,
200
- justifyContent: 'space-around',
201
- },
202
- imageTextName: {
203
- fontFamily: 'sf-semibold',
204
- fontSize: 14,
205
- color: TEXT_DARK,
206
- },
207
- iamgeTextDate: {
208
- fontFamily: 'sf-regular',
209
- fontSize: 12,
210
- color: TEXT_DARK,
211
- },
337
+ modal: {
338
+ backgroundColor: "#000",
339
+ },
340
+ container: {
341
+ flex: 1,
342
+ backgroundColor: "#000",
343
+ },
344
+ imageViewer: {
345
+ flex: 1,
346
+ backgroundColor: "#000",
347
+ },
348
+ imageContainer: {
349
+ flex: 1,
350
+ justifyContent: "center",
351
+ alignItems: "center",
352
+ },
353
+ captionWrapper: {
354
+ position: "absolute",
355
+ left: 16,
356
+ right: 16,
357
+ zIndex: 10,
358
+ },
359
+ userInfoWrapper: {
360
+ position: "absolute",
361
+ bottom: 40, // Safe area padding
362
+ left: 16,
363
+ right: 16,
364
+ zIndex: 10,
365
+ },
366
+ menuIconContainer: {
367
+ position: "absolute",
368
+ top: StatusBarHeight(0),
369
+ right: 0,
370
+ width: 55,
371
+ height: 55,
372
+ zIndex: 3,
373
+ },
374
+ menuIcon: {
375
+ fontSize: 25,
376
+ padding: 15,
377
+ width: 55,
378
+ textAlign: "center",
379
+ color: "#fff",
380
+ zIndex: 3,
381
+ },
382
+ videoOverlay: {
383
+ position: "absolute",
384
+ alignItems: "center",
385
+ justifyContent: "center",
386
+ },
387
+ videoPlayIcon: {
388
+ color: "#fff",
389
+ fontSize: 30,
390
+ textShadowColor: "rgba(0,0,0,0.3)",
391
+ textShadowOffset: { width: 2, height: 2 },
392
+ },
393
+ imageInfoContainer: {
394
+ flexDirection: "row",
395
+ paddingHorizontal: 12,
396
+ paddingVertical: 12,
397
+ gap: 4,
398
+ borderRadius: 8,
399
+ alignItems: "center",
400
+ },
401
+ imageTextContainer: {
402
+ marginLeft: 12,
403
+ flexDirection: "column",
404
+ gap: 4,
405
+ flex: 1,
406
+ justifyContent: "space-around",
407
+ },
408
+ imageTextName: {
409
+ fontFamily: "sf-semibold",
410
+ fontSize: 14,
411
+ color: "#fff",
412
+ },
413
+ iamgeTextDate: {
414
+ fontFamily: "sf-regular",
415
+ fontSize: 12,
416
+ color: "rgba(255, 255, 255, 0.8)",
417
+ },
418
+ captionContainer: {
419
+ borderRadius: 16,
420
+ padding: 0,
421
+ alignItems: "center",
422
+ justifyContent: "center",
423
+ },
424
+ captionText: {
425
+ fontFamily: "sf-regular",
426
+ fontSize: 15,
427
+ color: "#fff",
428
+ textAlign: "center",
429
+ lineHeight: 20,
430
+ },
212
431
  });
213
432
 
214
433
  export { ImagePopup };