@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,229 +1,433 @@
1
- import React, { Component } from 'react';
2
- import _ from 'lodash';
3
- import moment from 'moment';
4
- import { Dimensions, Modal, TouchableOpacity, StyleSheet, View, Text } from 'react-native';
5
- import ImageViewer from 'react-native-image-zoom-viewer';
6
- import { Icon } from '@rneui/themed';
7
- import AutoHeightImage from 'react-native-auto-height-image';
8
- import { TEXT_DARK } from '../colours';
9
- import { StatusBarHeight, isVideo, get1400 } from '../helper';
10
- import { Pl60Icon } from '../fonts';
11
- import { SharingTools } from './SharingTools';
12
- import { VideoPopup } from './VideoPopup';
13
- import { ProfilePic } from './ProfilePic';
14
-
15
- const SCREEN_WIDTH = Dimensions.get('window').width;
16
- 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;
17
25
 
18
26
  class ImagePopup extends Component {
19
- constructor(props) {
20
- super(props);
21
- this.state = {
22
- index: 0,
23
- images: [],
24
- showFullscreenVideo: false,
25
- currentVideoUrl: '',
26
- };
27
- }
28
-
29
- componentDidMount() {
30
- this.setupUrls();
31
- }
32
-
33
- componentDidUpdate(prevProps) {
34
- const { visible, index } = this.props;
35
- if (!prevProps.visible && visible) this.setupUrls();
36
- if (prevProps.index !== index) this.setState({ index });
37
- }
38
-
39
- setupUrls = () => {
40
- if (!this.props.images) return;
41
-
42
- const images = this.props.images.map(image => {
43
- if (typeof image === 'string') {
44
- return { url: get1400(image), original: image, isVideo: isVideo(image) };
45
- }
46
- return { url: get1400(image?.uri), original: image?.uri, isVideo: isVideo(image?.uri), date: image?.date, user: image?.user };
47
- });
48
-
49
- this.setState({ images, index: this.state.index || this.props.index || 0 });
50
- };
51
-
52
- onChange = index => {
53
- this.setState({ index });
54
- };
55
-
56
- scrollTo(index) {
57
- this.setState({
58
- index,
59
- });
60
- }
61
-
62
- toggleFullscreenVideo = url => {
63
- if (typeof url !== 'string') url = '';
64
- this.setState({ showFullscreenVideo: url.length > 0, currentVideoUrl: url });
65
- };
66
-
67
- renderClose() {
68
- return (
69
- <TouchableOpacity style={styles.menuIconContainer} onPress={this.props.onClose} activeOpacity={0.6}>
70
- <Pl60Icon name="close" style={[styles.menuIcon]} />
71
- </TouchableOpacity>
72
- );
73
- }
74
-
75
- renderImageFooter = (media, style) => {
76
- if (!media.user || !media.date) return null;
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 style={[styles.imageInfoContainer, style]}>
87
- <ProfilePic Diameter={42} ProfilePic={media?.user?.profilePic} />
88
- <View style={styles.imageTextContainer}>
89
- <Text style={styles.imageTextName}>{media?.user?.displayName}</Text>
90
- <Text numberOfLines={2} style={styles.iamgeTextDate}>{`Uploaded ${dateText} • ${timeText}`}</Text>
91
- </View>
92
- </View>
93
- );
94
- };
95
-
96
- renderImage = props => {
97
- const media = this.state.images.find(image => image.url === props.source.uri);
98
- const isVideo = !_.isNil(media) && media.isVideo;
99
-
100
- return (
101
- <View style={styles.imageContainer}>
102
- <AutoHeightImage source={{ uri: media.url }} width={SCREEN_WIDTH} resizeMode="contain" />
103
- {isVideo && (
104
- <View style={styles.videoOverlay}>
105
- <TouchableOpacity onPress={this.toggleFullscreenVideo.bind(this, media.original)}>
106
- <Icon name="play" type="font-awesome" iconStyle={styles.videoPlayIcon} />
107
- </TouchableOpacity>
108
- </View>
109
- )}
110
- {this.renderImageFooter(media)}
111
- </View>
112
- );
113
- };
114
-
115
- renderVideoPlayerPopup() {
116
- const { showFullscreenVideo, currentVideoUrl } = this.state;
117
- if (!currentVideoUrl) return;
118
-
119
- return <VideoPopup uri={currentVideoUrl} visible={showFullscreenVideo} onClose={this.toggleFullscreenVideo} />;
120
- }
121
-
122
- render() {
123
- const { visible, onClose } = this.props;
124
- const { index, images } = this.state;
125
-
126
- if (_.isEmpty(images)) {
127
- return null;
128
- }
129
-
130
- // This is required for the ImageViewer to render the image info section properly
131
- const imagesWithSizes = images.map(image => {
132
- return {
133
- ...image,
134
- width: SCREEN_WIDTH,
135
- height: SCREEN_HEIGHT,
136
- };
137
- });
138
- return (
139
- <Modal visible={visible} animationType="slide" onRequestClose={onClose} style={styles.modal}>
140
- <ImageViewer
141
- style={styles.scrollable}
142
- index={index}
143
- onChange={this.onChange}
144
- onSwipeDown={onClose}
145
- enableSwipeDown
146
- imageUrls={imagesWithSizes}
147
- saveToLocalByLongPress={false}
148
- renderImage={this.renderImage}
149
- />
150
- {this.renderClose()}
151
- <SharingTools uri={images[index].original} />
152
- {this.renderVideoPlayerPopup()}
153
- </Modal>
154
- );
155
- }
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
+ }
156
334
  }
157
335
 
158
336
  const styles = StyleSheet.create({
159
- modal: {
160
- backgroundColor: '#000',
161
- },
162
- scrollable: {
163
- width: SCREEN_WIDTH,
164
- height: SCREEN_HEIGHT,
165
- backgroundColor: '#000',
166
- },
167
- imageContainer: {
168
- flex: 1,
169
- justifyContent: 'center',
170
- alignItems: 'center',
171
- },
172
- menuIconContainer: {
173
- position: 'absolute',
174
- top: StatusBarHeight(0),
175
- right: 0,
176
- width: 55,
177
- height: 55,
178
- zIndex: 3,
179
- },
180
- menuIcon: {
181
- fontSize: 25,
182
- padding: 15,
183
- width: 55,
184
- textAlign: 'center',
185
- color: '#fff',
186
- zIndex: 3,
187
- },
188
- videoOverlay: {
189
- position: 'absolute',
190
- top: 0,
191
- left: 0,
192
- right: 0,
193
- bottom: 0,
194
- alignItems: 'center',
195
- justifyContent: 'center',
196
- },
197
- videoPlayIcon: {
198
- color: '#fff',
199
- fontSize: 30,
200
- textShadowColor: 'rgba(0,0,0,0.3)',
201
- textShadowOffset: { width: 2, height: 2 },
202
- },
203
- imageInfoContainer: {
204
- flexDirection: 'row',
205
- paddingHorizontal: 12,
206
- height: 70,
207
- backgroundColor: '#fff',
208
- alignItems: 'center',
209
- },
210
- imageTextContainer: {
211
- marginLeft: 12,
212
- flexDirection: 'column',
213
- flex: 1,
214
- height: 42,
215
- justifyContent: 'space-around',
216
- },
217
- imageTextName: {
218
- fontFamily: 'sf-semibold',
219
- fontSize: 14,
220
- color: TEXT_DARK,
221
- },
222
- iamgeTextDate: {
223
- fontFamily: 'sf-regular',
224
- fontSize: 12,
225
- color: TEXT_DARK,
226
- },
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
+ },
227
431
  });
228
432
 
229
433
  export { ImagePopup };