@plusscommunities/pluss-core-app 8.0.29 → 8.0.35

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 (211) hide show
  1. package/dist/module/actions/FollowerActions.js +34 -0
  2. package/dist/module/actions/FollowerActions.js.map +1 -0
  3. package/dist/module/actions/MediaActions.js +29 -0
  4. package/dist/module/actions/MediaActions.js.map +1 -0
  5. package/dist/module/actions/ResidentActions.js +26 -0
  6. package/dist/module/actions/ResidentActions.js.map +1 -0
  7. package/dist/module/actions/UserActions.js +223 -0
  8. package/dist/module/actions/UserActions.js.map +1 -0
  9. package/dist/module/actions/UserSettingsActions.js +14 -0
  10. package/dist/module/actions/UserSettingsActions.js.map +1 -0
  11. package/dist/module/actions/index.js +6 -0
  12. package/dist/module/actions/index.js.map +1 -0
  13. package/dist/module/actions/types.js +17 -0
  14. package/dist/module/actions/types.js.map +1 -0
  15. package/dist/module/apis/analyticsActions.js +20 -0
  16. package/dist/module/apis/analyticsActions.js.map +1 -0
  17. package/dist/module/apis/contactActions.js +27 -0
  18. package/dist/module/apis/contactActions.js.map +1 -0
  19. package/dist/module/apis/eventActions.js +161 -0
  20. package/dist/module/apis/eventActions.js.map +1 -0
  21. package/dist/module/apis/fileActions.js +93 -0
  22. package/dist/module/apis/fileActions.js.map +1 -0
  23. package/dist/module/apis/followerActions.js +38 -0
  24. package/dist/module/apis/followerActions.js.map +1 -0
  25. package/dist/module/apis/index.js +13 -0
  26. package/dist/module/apis/index.js.map +1 -0
  27. package/dist/module/apis/notificationActions.js +60 -0
  28. package/dist/module/apis/notificationActions.js.map +1 -0
  29. package/dist/module/apis/profileActions.js +14 -0
  30. package/dist/module/apis/profileActions.js.map +1 -0
  31. package/dist/module/apis/reactionActions.js +76 -0
  32. package/dist/module/apis/reactionActions.js.map +1 -0
  33. package/dist/module/apis/settingActions.js +22 -0
  34. package/dist/module/apis/settingActions.js.map +1 -0
  35. package/dist/module/apis/stringActions.js +30 -0
  36. package/dist/module/apis/stringActions.js.map +1 -0
  37. package/dist/module/apis/typeActions.js +15 -0
  38. package/dist/module/apis/typeActions.js.map +1 -0
  39. package/dist/module/apis/userActions.js +104 -0
  40. package/dist/module/apis/userActions.js.map +1 -0
  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/assets/icons/reactions/heart.png +0 -0
  48. package/dist/module/assets/icons/reactions/party.png +0 -0
  49. package/dist/module/assets/icons/reactions/sad.png +0 -0
  50. package/dist/module/assets/icons/reactions/smile.png +0 -0
  51. package/dist/module/colours.js +165 -0
  52. package/dist/module/colours.js.map +1 -0
  53. package/dist/module/components/AddButton.js +43 -0
  54. package/dist/module/components/AddButton.js.map +1 -0
  55. package/dist/module/components/AddToCalendarButton.js +225 -0
  56. package/dist/module/components/AddToCalendarButton.js.map +1 -0
  57. package/dist/module/components/Attachment.js +55 -0
  58. package/dist/module/components/Attachment.js.map +1 -0
  59. package/dist/module/components/AudienceSelectorLauncher.js +64 -0
  60. package/dist/module/components/AudienceSelectorLauncher.js.map +1 -0
  61. package/dist/module/components/AudienceSelectorPage.js +351 -0
  62. package/dist/module/components/AudienceSelectorPage.js.map +1 -0
  63. package/dist/module/components/AutoOffsetImage.js +184 -0
  64. package/dist/module/components/AutoOffsetImage.js.map +1 -0
  65. package/dist/module/components/BackButton.js +58 -0
  66. package/dist/module/components/BackButton.js.map +1 -0
  67. package/dist/module/components/CalendarPopup.js +126 -0
  68. package/dist/module/components/CalendarPopup.js.map +1 -0
  69. package/dist/module/components/CategoryTabs.js +155 -0
  70. package/dist/module/components/CategoryTabs.js.map +1 -0
  71. package/dist/module/components/CommentReply.js +334 -0
  72. package/dist/module/components/CommentReply.js.map +1 -0
  73. package/dist/module/components/CommentSection.js +832 -0
  74. package/dist/module/components/CommentSection.js.map +1 -0
  75. package/dist/module/components/ConfirmPopup.js +109 -0
  76. package/dist/module/components/ConfirmPopup.js.map +1 -0
  77. package/dist/module/components/ConfirmationPopup.js +72 -0
  78. package/dist/module/components/ConfirmationPopup.js.map +1 -0
  79. package/dist/module/components/DocumentUploader.js +253 -0
  80. package/dist/module/components/DocumentUploader.js.map +1 -0
  81. package/dist/module/components/DropDownItem.js +75 -0
  82. package/dist/module/components/DropDownItem.js.map +1 -0
  83. package/dist/module/components/DropDownMenu.js +41 -0
  84. package/dist/module/components/DropDownMenu.js.map +1 -0
  85. package/dist/module/components/EmptyStateMain.js +51 -0
  86. package/dist/module/components/EmptyStateMain.js.map +1 -0
  87. package/dist/module/components/EmptyStateWidget.js +48 -0
  88. package/dist/module/components/EmptyStateWidget.js.map +1 -0
  89. package/dist/module/components/FontScaleButton.js +37 -0
  90. package/dist/module/components/FontScaleButton.js.map +1 -0
  91. package/dist/module/components/FontScalePopup.js +76 -0
  92. package/dist/module/components/FontScalePopup.js.map +1 -0
  93. package/dist/module/components/Forbidden.js +58 -0
  94. package/dist/module/components/Forbidden.js.map +1 -0
  95. package/dist/module/components/FormCard.js +25 -0
  96. package/dist/module/components/FormCard.js.map +1 -0
  97. package/dist/module/components/FormCardSection.js +214 -0
  98. package/dist/module/components/FormCardSection.js.map +1 -0
  99. package/dist/module/components/FormCardSectionOptionLauncher.js +73 -0
  100. package/dist/module/components/FormCardSectionOptionLauncher.js.map +1 -0
  101. package/dist/module/components/FormattedText.js +133 -0
  102. package/dist/module/components/FormattedText.js.map +1 -0
  103. package/dist/module/components/GenericInput.js +151 -0
  104. package/dist/module/components/GenericInput.js.map +1 -0
  105. package/dist/module/components/GenericInputSection.js +173 -0
  106. package/dist/module/components/GenericInputSection.js.map +1 -0
  107. package/dist/module/components/Header.js +459 -0
  108. package/dist/module/components/Header.js.map +1 -0
  109. package/dist/module/components/Icon.js +109 -0
  110. package/dist/module/components/Icon.js.map +1 -0
  111. package/dist/module/components/ImagePopup.js +400 -0
  112. package/dist/module/components/ImagePopup.js.map +1 -0
  113. package/dist/module/components/ImageUploadProgress.js +69 -0
  114. package/dist/module/components/ImageUploadProgress.js.map +1 -0
  115. package/dist/module/components/ImageUploader.js +831 -0
  116. package/dist/module/components/ImageUploader.js.map +1 -0
  117. package/dist/module/components/InlineButton.js +66 -0
  118. package/dist/module/components/InlineButton.js.map +1 -0
  119. package/dist/module/components/Input.js +156 -0
  120. package/dist/module/components/Input.js.map +1 -0
  121. package/dist/module/components/LoadingCircles.js +219 -0
  122. package/dist/module/components/LoadingCircles.js.map +1 -0
  123. package/dist/module/components/LoadingIndicator.js +86 -0
  124. package/dist/module/components/LoadingIndicator.js.map +1 -0
  125. package/dist/module/components/LoadingStateWidget.js +46 -0
  126. package/dist/module/components/LoadingStateWidget.js.map +1 -0
  127. package/dist/module/components/MediaPlayer.js +407 -0
  128. package/dist/module/components/MediaPlayer.js.map +1 -0
  129. package/dist/module/components/MiddlePopup.js +49 -0
  130. package/dist/module/components/MiddlePopup.js.map +1 -0
  131. package/dist/module/components/PDFPopup.js +296 -0
  132. package/dist/module/components/PDFPopup.js.map +1 -0
  133. package/dist/module/components/PlussChat.js +1078 -0
  134. package/dist/module/components/PlussChat.js.map +1 -0
  135. package/dist/module/components/PlussChatMessage.js +299 -0
  136. package/dist/module/components/PlussChatMessage.js.map +1 -0
  137. package/dist/module/components/PlussChatTime.js +59 -0
  138. package/dist/module/components/PlussChatTime.js.map +1 -0
  139. package/dist/module/components/Popup.js +126 -0
  140. package/dist/module/components/Popup.js.map +1 -0
  141. package/dist/module/components/PopupMenu.js +120 -0
  142. package/dist/module/components/PopupMenu.js.map +1 -0
  143. package/dist/module/components/PositionedImage.js +313 -0
  144. package/dist/module/components/PositionedImage.js.map +1 -0
  145. package/dist/module/components/ProfilePic.js +105 -0
  146. package/dist/module/components/ProfilePic.js.map +1 -0
  147. package/dist/module/components/RadioButton.js +78 -0
  148. package/dist/module/components/RadioButton.js.map +1 -0
  149. package/dist/module/components/Reaction.js +117 -0
  150. package/dist/module/components/Reaction.js.map +1 -0
  151. package/dist/module/components/Reactions.js +71 -0
  152. package/dist/module/components/Reactions.js.map +1 -0
  153. package/dist/module/components/SharingTools.js +189 -0
  154. package/dist/module/components/SharingTools.js.map +1 -0
  155. package/dist/module/components/Spinner.js +22 -0
  156. package/dist/module/components/Spinner.js.map +1 -0
  157. package/dist/module/components/StickyFooter.js +34 -0
  158. package/dist/module/components/StickyFooter.js.map +1 -0
  159. package/dist/module/components/Text.js +57 -0
  160. package/dist/module/components/Text.js.map +1 -0
  161. package/dist/module/components/TickIcon.js +24 -0
  162. package/dist/module/components/TickIcon.js.map +1 -0
  163. package/dist/module/components/Toggle.js +66 -0
  164. package/dist/module/components/Toggle.js.map +1 -0
  165. package/dist/module/components/TouchableSearchBar.js +68 -0
  166. package/dist/module/components/TouchableSearchBar.js.map +1 -0
  167. package/dist/module/components/UserListPopup.js +136 -0
  168. package/dist/module/components/UserListPopup.js.map +1 -0
  169. package/dist/module/components/UserListing.js +268 -0
  170. package/dist/module/components/UserListing.js.map +1 -0
  171. package/dist/module/components/VideoPopup.js +113 -0
  172. package/dist/module/components/VideoPopup.js.map +1 -0
  173. package/dist/module/components/WarningPopup.js +85 -0
  174. package/dist/module/components/WarningPopup.js.map +1 -0
  175. package/dist/module/components/expo-image-picker-multiple/ImageBrowser.js +289 -0
  176. package/dist/module/components/expo-image-picker-multiple/ImageBrowser.js.map +1 -0
  177. package/dist/module/components/expo-image-picker-multiple/ImageTile.js +117 -0
  178. package/dist/module/components/expo-image-picker-multiple/ImageTile.js.map +1 -0
  179. package/dist/module/components/index.js +60 -0
  180. package/dist/module/components/index.js.map +1 -0
  181. package/dist/module/components/react-native-expo-image-cropper/ExpoImageManipulator.js +422 -0
  182. package/dist/module/components/react-native-expo-image-cropper/ExpoImageManipulator.js.map +1 -0
  183. package/dist/module/components/react-native-expo-image-cropper/ImageCropOverlay.js +387 -0
  184. package/dist/module/components/react-native-expo-image-cropper/ImageCropOverlay.js.map +1 -0
  185. package/dist/module/config.js +27 -0
  186. package/dist/module/config.js.map +1 -0
  187. package/dist/module/constants.js +18 -0
  188. package/dist/module/constants.js.map +1 -0
  189. package/dist/module/helper.js +424 -0
  190. package/dist/module/helper.js.map +1 -0
  191. package/dist/module/index.js +13 -0
  192. package/dist/module/index.js.map +1 -0
  193. package/dist/module/js/images/detectFaces.js +31 -0
  194. package/dist/module/js/images/detectFaces.js.map +1 -0
  195. package/dist/module/js/images/findLandmarkRange.js +93 -0
  196. package/dist/module/js/images/findLandmarkRange.js.map +1 -0
  197. package/dist/module/js/images/getScaledOffset.js +81 -0
  198. package/dist/module/js/images/getScaledOffset.js.map +1 -0
  199. package/dist/module/js/site/getSiteLevelFromState.js +29 -0
  200. package/dist/module/js/site/getSiteLevelFromState.js.map +1 -0
  201. package/dist/module/js/site/isTVEnabled.js +10 -0
  202. package/dist/module/js/site/isTVEnabled.js.map +1 -0
  203. package/dist/module/session.js +58 -0
  204. package/dist/module/session.js.map +1 -0
  205. package/dist/module/styles.js +67 -0
  206. package/dist/module/styles.js.map +1 -0
  207. package/dist/module/withNavigationFocus.js +30 -0
  208. package/dist/module/withNavigationFocus.js.map +1 -0
  209. package/package.json +1 -1
  210. package/src/components/CommentSection.js +8 -3
  211. package/src/components/PDFPopup.js +130 -35
@@ -0,0 +1,81 @@
1
+ const getScaledOffset = (sourceWidth, sourceHeight, targetWidth, targetHeight) => {
2
+ const sourceRatio = sourceWidth / sourceHeight;
3
+ const targetRatio = targetWidth / targetHeight;
4
+
5
+ // same ratio. no adjustment needed.
6
+ if (sourceRatio === targetRatio) {
7
+ return {
8
+ width: targetWidth,
9
+ height: targetHeight,
10
+ scaleFactor: targetWidth / sourceWidth,
11
+ offset: {
12
+ x: 0,
13
+ y: 0
14
+ },
15
+ bounds: {
16
+ start: {
17
+ x: 0,
18
+ y: 0
19
+ },
20
+ end: {
21
+ x: targetWidth,
22
+ y: targetHeight
23
+ }
24
+ }
25
+ };
26
+ }
27
+
28
+ // source is higher than target. height scaling and y offset required.
29
+ if (sourceRatio < targetRatio) {
30
+ const scaleFactor = targetWidth / sourceWidth;
31
+ const adjustedHeight = sourceHeight * scaleFactor;
32
+ const yOffset = (adjustedHeight - targetHeight) / 2;
33
+ return {
34
+ width: targetWidth,
35
+ height: adjustedHeight,
36
+ scaleFactor,
37
+ offset: {
38
+ x: 0,
39
+ y: -yOffset
40
+ },
41
+ bounds: {
42
+ start: {
43
+ x: 0,
44
+ y: yOffset
45
+ },
46
+ end: {
47
+ x: targetWidth,
48
+ y: yOffset + adjustedHeight
49
+ }
50
+ }
51
+ };
52
+ }
53
+
54
+ // source is wider than target. width scaling and x offset required.
55
+ if (sourceRatio > targetRatio) {
56
+ const scaleFactor = targetHeight / sourceHeight;
57
+ const adjustedWidth = sourceWidth * scaleFactor;
58
+ const xOffset = (adjustedWidth - targetWidth) / 2;
59
+ return {
60
+ width: adjustedWidth,
61
+ height: targetHeight,
62
+ scaleFactor,
63
+ offset: {
64
+ x: -xOffset,
65
+ y: 0
66
+ },
67
+ bounds: {
68
+ start: {
69
+ x: xOffset,
70
+ y: 0
71
+ },
72
+ end: {
73
+ x: xOffset + adjustedWidth,
74
+ y: targetHeight
75
+ }
76
+ }
77
+ };
78
+ }
79
+ };
80
+ export default getScaledOffset;
81
+ //# sourceMappingURL=getScaledOffset.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["getScaledOffset","sourceWidth","sourceHeight","targetWidth","targetHeight","sourceRatio","targetRatio","width","height","scaleFactor","offset","x","y","bounds","start","end","adjustedHeight","yOffset","adjustedWidth","xOffset"],"sources":["getScaledOffset.js"],"sourcesContent":["const getScaledOffset = (\n\tsourceWidth,\n\tsourceHeight,\n\ttargetWidth,\n\ttargetHeight,\n) => {\n\tconst sourceRatio = sourceWidth / sourceHeight;\n\tconst targetRatio = targetWidth / targetHeight;\n\n\t// same ratio. no adjustment needed.\n\tif (sourceRatio === targetRatio) {\n\t\treturn {\n\t\t\twidth: targetWidth,\n\t\t\theight: targetHeight,\n\t\t\tscaleFactor: targetWidth / sourceWidth,\n\t\t\toffset: {\n\t\t\t\tx: 0,\n\t\t\t\ty: 0,\n\t\t\t},\n\t\t\tbounds: {\n\t\t\t\tstart: {\n\t\t\t\t\tx: 0,\n\t\t\t\t\ty: 0,\n\t\t\t\t},\n\t\t\t\tend: {\n\t\t\t\t\tx: targetWidth,\n\t\t\t\t\ty: targetHeight,\n\t\t\t\t},\n\t\t\t},\n\t\t};\n\t}\n\n\t// source is higher than target. height scaling and y offset required.\n\tif (sourceRatio < targetRatio) {\n\t\tconst scaleFactor = targetWidth / sourceWidth;\n\t\tconst adjustedHeight = sourceHeight * scaleFactor;\n\t\tconst yOffset = (adjustedHeight - targetHeight) / 2;\n\n\t\treturn {\n\t\t\twidth: targetWidth,\n\t\t\theight: adjustedHeight,\n\t\t\tscaleFactor,\n\t\t\toffset: {\n\t\t\t\tx: 0,\n\t\t\t\ty: -yOffset,\n\t\t\t},\n\t\t\tbounds: {\n\t\t\t\tstart: {\n\t\t\t\t\tx: 0,\n\t\t\t\t\ty: yOffset,\n\t\t\t\t},\n\t\t\t\tend: {\n\t\t\t\t\tx: targetWidth,\n\t\t\t\t\ty: yOffset + adjustedHeight,\n\t\t\t\t},\n\t\t\t},\n\t\t};\n\t}\n\n\t// source is wider than target. width scaling and x offset required.\n\tif (sourceRatio > targetRatio) {\n\t\tconst scaleFactor = targetHeight / sourceHeight;\n\t\tconst adjustedWidth = sourceWidth * scaleFactor;\n\t\tconst xOffset = (adjustedWidth - targetWidth) / 2;\n\n\t\treturn {\n\t\t\twidth: adjustedWidth,\n\t\t\theight: targetHeight,\n\t\t\tscaleFactor,\n\t\t\toffset: {\n\t\t\t\tx: -xOffset,\n\t\t\t\ty: 0,\n\t\t\t},\n\t\t\tbounds: {\n\t\t\t\tstart: {\n\t\t\t\t\tx: xOffset,\n\t\t\t\t\ty: 0,\n\t\t\t\t},\n\t\t\t\tend: {\n\t\t\t\t\tx: xOffset + adjustedWidth,\n\t\t\t\t\ty: targetHeight,\n\t\t\t\t},\n\t\t\t},\n\t\t};\n\t}\n};\n\nexport default getScaledOffset;\n"],"mappings":"AAAA,MAAMA,eAAe,GAAGA,CACvBC,WAAW,EACXC,YAAY,EACZC,WAAW,EACXC,YAAY,KACR;EACJ,MAAMC,WAAW,GAAGJ,WAAW,GAAGC,YAAY;EAC9C,MAAMI,WAAW,GAAGH,WAAW,GAAGC,YAAY;;EAE9C;EACA,IAAIC,WAAW,KAAKC,WAAW,EAAE;IAChC,OAAO;MACNC,KAAK,EAAEJ,WAAW;MAClBK,MAAM,EAAEJ,YAAY;MACpBK,WAAW,EAAEN,WAAW,GAAGF,WAAW;MACtCS,MAAM,EAAE;QACPC,CAAC,EAAE,CAAC;QACJC,CAAC,EAAE;MACJ,CAAC;MACDC,MAAM,EAAE;QACPC,KAAK,EAAE;UACNH,CAAC,EAAE,CAAC;UACJC,CAAC,EAAE;QACJ,CAAC;QACDG,GAAG,EAAE;UACJJ,CAAC,EAAER,WAAW;UACdS,CAAC,EAAER;QACJ;MACD;IACD,CAAC;EACF;;EAEA;EACA,IAAIC,WAAW,GAAGC,WAAW,EAAE;IAC9B,MAAMG,WAAW,GAAGN,WAAW,GAAGF,WAAW;IAC7C,MAAMe,cAAc,GAAGd,YAAY,GAAGO,WAAW;IACjD,MAAMQ,OAAO,GAAG,CAACD,cAAc,GAAGZ,YAAY,IAAI,CAAC;IAEnD,OAAO;MACNG,KAAK,EAAEJ,WAAW;MAClBK,MAAM,EAAEQ,cAAc;MACtBP,WAAW;MACXC,MAAM,EAAE;QACPC,CAAC,EAAE,CAAC;QACJC,CAAC,EAAE,CAACK;MACL,CAAC;MACDJ,MAAM,EAAE;QACPC,KAAK,EAAE;UACNH,CAAC,EAAE,CAAC;UACJC,CAAC,EAAEK;QACJ,CAAC;QACDF,GAAG,EAAE;UACJJ,CAAC,EAAER,WAAW;UACdS,CAAC,EAAEK,OAAO,GAAGD;QACd;MACD;IACD,CAAC;EACF;;EAEA;EACA,IAAIX,WAAW,GAAGC,WAAW,EAAE;IAC9B,MAAMG,WAAW,GAAGL,YAAY,GAAGF,YAAY;IAC/C,MAAMgB,aAAa,GAAGjB,WAAW,GAAGQ,WAAW;IAC/C,MAAMU,OAAO,GAAG,CAACD,aAAa,GAAGf,WAAW,IAAI,CAAC;IAEjD,OAAO;MACNI,KAAK,EAAEW,aAAa;MACpBV,MAAM,EAAEJ,YAAY;MACpBK,WAAW;MACXC,MAAM,EAAE;QACPC,CAAC,EAAE,CAACQ,OAAO;QACXP,CAAC,EAAE;MACJ,CAAC;MACDC,MAAM,EAAE;QACPC,KAAK,EAAE;UACNH,CAAC,EAAEQ,OAAO;UACVP,CAAC,EAAE;QACJ,CAAC;QACDG,GAAG,EAAE;UACJJ,CAAC,EAAEQ,OAAO,GAAGD,aAAa;UAC1BN,CAAC,EAAER;QACJ;MACD;IACD,CAAC;EACF;AACD,CAAC;AAED,eAAeJ,eAAe","ignoreList":[]}
@@ -0,0 +1,29 @@
1
+ const getSiteLevelFromState = state => {
2
+ let siteType = "legacy";
3
+ if (state && state.user && state.user.siteInfo && state.user.siteInfo.Type) {
4
+ siteType = state.user.siteInfo.Type;
5
+ }
6
+ const siteConfig = {
7
+ type: siteType,
8
+ hasTV: true,
9
+ hasKiosk: false,
10
+ hasPayments: true,
11
+ hasPersonalNotes: true,
12
+ hasEmergencyContacts: true,
13
+ hasPersonalDocuments: true
14
+ };
15
+ switch (siteType) {
16
+ case "free":
17
+ siteConfig.hasTV = false;
18
+ siteConfig.hasPayments = false;
19
+ siteConfig.hasPersonalNotes = false;
20
+ siteConfig.hasEmergencyContacts = false;
21
+ siteConfig.hasPersonalDocuments = false;
22
+ break;
23
+ default:
24
+ break;
25
+ }
26
+ return siteConfig;
27
+ };
28
+ export default getSiteLevelFromState;
29
+ //# sourceMappingURL=getSiteLevelFromState.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["getSiteLevelFromState","state","siteType","user","siteInfo","Type","siteConfig","type","hasTV","hasKiosk","hasPayments","hasPersonalNotes","hasEmergencyContacts","hasPersonalDocuments"],"sources":["getSiteLevelFromState.js"],"sourcesContent":["const getSiteLevelFromState = (state) => {\n\tlet siteType = \"legacy\";\n\tif (state && state.user && state.user.siteInfo && state.user.siteInfo.Type) {\n\t\tsiteType = state.user.siteInfo.Type;\n\t}\n\tconst siteConfig = {\n\t\ttype: siteType,\n\t\thasTV: true,\n\t\thasKiosk: false,\n\t\thasPayments: true,\n\t\thasPersonalNotes: true,\n\t\thasEmergencyContacts: true,\n\t\thasPersonalDocuments: true,\n\t};\n\n\tswitch (siteType) {\n\t\tcase \"free\":\n\t\t\tsiteConfig.hasTV = false;\n\t\t\tsiteConfig.hasPayments = false;\n\t\t\tsiteConfig.hasPersonalNotes = false;\n\t\t\tsiteConfig.hasEmergencyContacts = false;\n\t\t\tsiteConfig.hasPersonalDocuments = false;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tbreak;\n\t}\n\treturn siteConfig;\n};\n\nexport default getSiteLevelFromState;\n"],"mappings":"AAAA,MAAMA,qBAAqB,GAAIC,KAAK,IAAK;EACxC,IAAIC,QAAQ,GAAG,QAAQ;EACvB,IAAID,KAAK,IAAIA,KAAK,CAACE,IAAI,IAAIF,KAAK,CAACE,IAAI,CAACC,QAAQ,IAAIH,KAAK,CAACE,IAAI,CAACC,QAAQ,CAACC,IAAI,EAAE;IAC3EH,QAAQ,GAAGD,KAAK,CAACE,IAAI,CAACC,QAAQ,CAACC,IAAI;EACpC;EACA,MAAMC,UAAU,GAAG;IAClBC,IAAI,EAAEL,QAAQ;IACdM,KAAK,EAAE,IAAI;IACXC,QAAQ,EAAE,KAAK;IACfC,WAAW,EAAE,IAAI;IACjBC,gBAAgB,EAAE,IAAI;IACtBC,oBAAoB,EAAE,IAAI;IAC1BC,oBAAoB,EAAE;EACvB,CAAC;EAED,QAAQX,QAAQ;IACf,KAAK,MAAM;MACVI,UAAU,CAACE,KAAK,GAAG,KAAK;MACxBF,UAAU,CAACI,WAAW,GAAG,KAAK;MAC9BJ,UAAU,CAACK,gBAAgB,GAAG,KAAK;MACnCL,UAAU,CAACM,oBAAoB,GAAG,KAAK;MACvCN,UAAU,CAACO,oBAAoB,GAAG,KAAK;MACvC;IACD;MACC;EACF;EACA,OAAOP,UAAU;AAClB,CAAC;AAED,eAAeN,qBAAqB","ignoreList":[]}
@@ -0,0 +1,10 @@
1
+ import _ from "lodash";
2
+ const isTVEnabled = (interfaces, feature) => {
3
+ return _.some(interfaces, t => {
4
+ return t.Type === "TV" && (!feature || _.some(t.Settings.widgets, f => {
5
+ return f.key === feature;
6
+ }));
7
+ });
8
+ };
9
+ export default isTVEnabled;
10
+ //# sourceMappingURL=isTVEnabled.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["_","isTVEnabled","interfaces","feature","some","t","Type","Settings","widgets","f","key"],"sources":["isTVEnabled.js"],"sourcesContent":["import _ from \"lodash\";\n\nconst isTVEnabled = (interfaces, feature) => {\n\treturn _.some(interfaces, (t) => {\n\t\treturn (\n\t\t\tt.Type === \"TV\" &&\n\t\t\t(!feature ||\n\t\t\t\t_.some(t.Settings.widgets, (f) => {\n\t\t\t\t\treturn f.key === feature;\n\t\t\t\t}))\n\t\t);\n\t});\n};\n\nexport default isTVEnabled;\n"],"mappings":"AAAA,OAAOA,CAAC,MAAM,QAAQ;AAEtB,MAAMC,WAAW,GAAGA,CAACC,UAAU,EAAEC,OAAO,KAAK;EAC5C,OAAOH,CAAC,CAACI,IAAI,CAACF,UAAU,EAAGG,CAAC,IAAK;IAChC,OACCA,CAAC,CAACC,IAAI,KAAK,IAAI,KACd,CAACH,OAAO,IACRH,CAAC,CAACI,IAAI,CAACC,CAAC,CAACE,QAAQ,CAACC,OAAO,EAAGC,CAAC,IAAK;MACjC,OAAOA,CAAC,CAACC,GAAG,KAAKP,OAAO;IACzB,CAAC,CAAC,CAAC;EAEN,CAAC,CAAC;AACH,CAAC;AAED,eAAeF,WAAW","ignoreList":[]}
@@ -0,0 +1,58 @@
1
+ import _ from "lodash";
2
+ import axios from "axios";
3
+ import { Auth } from "aws-amplify";
4
+ export const getSessionTokenAWS = async prefix => {
5
+ const data = await Auth.currentSession();
6
+ const token = data.accessToken.jwtToken;
7
+ if (_.isUndefined(prefix)) return token;
8
+ return `${prefix} ${token}`;
9
+ };
10
+
11
+ // export const getRefreshTokenAWS = async () => {
12
+ // const data = await Auth.currentSession();
13
+ // return data.getRefreshToken().token;
14
+ // };
15
+
16
+ export const getSessionUidAWS = () => {
17
+ return new Promise((resolve, reject) => {
18
+ Auth.currentSession().then(data => {
19
+ resolve(data.accessToken.payload.username);
20
+ }).catch(err => {
21
+ console.log("getSessionUidAWS error", err);
22
+ reject(err);
23
+ });
24
+ });
25
+ };
26
+ export const authedFunction = async request => {
27
+ const authkey = await getSessionTokenAWS();
28
+ if (!request.headers) request.headers = {};
29
+ request.headers.authkey = authkey;
30
+ return axios(request);
31
+ };
32
+
33
+ // export const LogoutAWS = () => {
34
+ // return new Promise((resolve, reject) => {
35
+ // Auth.signOut()
36
+ // .then(() => {
37
+ // resolve();
38
+ // })
39
+ // .catch(err => {
40
+ // reject(err);
41
+ // });
42
+ // });
43
+ // };
44
+
45
+ // export const isTheBest = auth => {
46
+ // return auth && auth.site === 'plussSpace' && auth.type === 'master';
47
+ // };
48
+
49
+ export const getApiError = error => {
50
+ if (!__DEV__) return error;
51
+ try {
52
+ const errorData = error.response.data;
53
+ return errorData || error;
54
+ } catch (e) {
55
+ return error;
56
+ }
57
+ };
58
+ //# sourceMappingURL=session.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["_","axios","Auth","getSessionTokenAWS","prefix","data","currentSession","token","accessToken","jwtToken","isUndefined","getSessionUidAWS","Promise","resolve","reject","then","payload","username","catch","err","console","log","authedFunction","request","authkey","headers","getApiError","error","__DEV__","errorData","response","e"],"sources":["session.js"],"sourcesContent":["import _ from \"lodash\";\nimport axios from \"axios\";\nimport { Auth } from \"aws-amplify\";\n\nexport const getSessionTokenAWS = async (prefix) => {\n\tconst data = await Auth.currentSession();\n\tconst token = data.accessToken.jwtToken;\n\tif (_.isUndefined(prefix)) return token;\n\treturn `${prefix} ${token}`;\n};\n\n// export const getRefreshTokenAWS = async () => {\n// const data = await Auth.currentSession();\n// return data.getRefreshToken().token;\n// };\n\nexport const getSessionUidAWS = () => {\n\treturn new Promise((resolve, reject) => {\n\t\tAuth.currentSession()\n\t\t\t.then((data) => {\n\t\t\t\tresolve(data.accessToken.payload.username);\n\t\t\t})\n\t\t\t.catch((err) => {\n\t\t\t\tconsole.log(\"getSessionUidAWS error\", err);\n\t\t\t\treject(err);\n\t\t\t});\n\t});\n};\n\nexport const authedFunction = async (request) => {\n\tconst authkey = await getSessionTokenAWS();\n\tif (!request.headers) request.headers = {};\n\trequest.headers.authkey = authkey;\n\n\treturn axios(request);\n};\n\n// export const LogoutAWS = () => {\n// return new Promise((resolve, reject) => {\n// Auth.signOut()\n// .then(() => {\n// resolve();\n// })\n// .catch(err => {\n// reject(err);\n// });\n// });\n// };\n\n// export const isTheBest = auth => {\n// return auth && auth.site === 'plussSpace' && auth.type === 'master';\n// };\n\nexport const getApiError = (error) => {\n\tif (!__DEV__) return error;\n\ttry {\n\t\tconst errorData = error.response.data;\n\t\treturn errorData || error;\n\t} catch (e) {\n\t\treturn error;\n\t}\n};\n"],"mappings":"AAAA,OAAOA,CAAC,MAAM,QAAQ;AACtB,OAAOC,KAAK,MAAM,OAAO;AACzB,SAASC,IAAI,QAAQ,aAAa;AAElC,OAAO,MAAMC,kBAAkB,GAAG,MAAOC,MAAM,IAAK;EACnD,MAAMC,IAAI,GAAG,MAAMH,IAAI,CAACI,cAAc,CAAC,CAAC;EACxC,MAAMC,KAAK,GAAGF,IAAI,CAACG,WAAW,CAACC,QAAQ;EACvC,IAAIT,CAAC,CAACU,WAAW,CAACN,MAAM,CAAC,EAAE,OAAOG,KAAK;EACvC,OAAO,GAAGH,MAAM,IAAIG,KAAK,EAAE;AAC5B,CAAC;;AAED;AACA;AACA;AACA;;AAEA,OAAO,MAAMI,gBAAgB,GAAGA,CAAA,KAAM;EACrC,OAAO,IAAIC,OAAO,CAAC,CAACC,OAAO,EAAEC,MAAM,KAAK;IACvCZ,IAAI,CAACI,cAAc,CAAC,CAAC,CACnBS,IAAI,CAAEV,IAAI,IAAK;MACfQ,OAAO,CAACR,IAAI,CAACG,WAAW,CAACQ,OAAO,CAACC,QAAQ,CAAC;IAC3C,CAAC,CAAC,CACDC,KAAK,CAAEC,GAAG,IAAK;MACfC,OAAO,CAACC,GAAG,CAAC,wBAAwB,EAAEF,GAAG,CAAC;MAC1CL,MAAM,CAACK,GAAG,CAAC;IACZ,CAAC,CAAC;EACJ,CAAC,CAAC;AACH,CAAC;AAED,OAAO,MAAMG,cAAc,GAAG,MAAOC,OAAO,IAAK;EAChD,MAAMC,OAAO,GAAG,MAAMrB,kBAAkB,CAAC,CAAC;EAC1C,IAAI,CAACoB,OAAO,CAACE,OAAO,EAAEF,OAAO,CAACE,OAAO,GAAG,CAAC,CAAC;EAC1CF,OAAO,CAACE,OAAO,CAACD,OAAO,GAAGA,OAAO;EAEjC,OAAOvB,KAAK,CAACsB,OAAO,CAAC;AACtB,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA,OAAO,MAAMG,WAAW,GAAIC,KAAK,IAAK;EACrC,IAAI,CAACC,OAAO,EAAE,OAAOD,KAAK;EAC1B,IAAI;IACH,MAAME,SAAS,GAAGF,KAAK,CAACG,QAAQ,CAACzB,IAAI;IACrC,OAAOwB,SAAS,IAAIF,KAAK;EAC1B,CAAC,CAAC,OAAOI,CAAC,EAAE;IACX,OAAOJ,KAAK;EACb;AACD,CAAC","ignoreList":[]}
@@ -0,0 +1,67 @@
1
+ import { StyleSheet } from "react-native";
2
+ import { COLOUR_GREEN } from "./colours";
3
+ export default StyleSheet.create({
4
+ notificationBell: {
5
+ height: 70,
6
+ width: 55,
7
+ alignItems: "center",
8
+ flexDirection: "row",
9
+ justifyContent: "space-between"
10
+ },
11
+ fill: {
12
+ flex: 1
13
+ },
14
+ genericPageContainer: {
15
+ flex: 1,
16
+ backgroundColor: "#fff"
17
+ },
18
+ addButton: {
19
+ position: "absolute",
20
+ bottom: 16,
21
+ right: 16,
22
+ height: 48,
23
+ width: 48,
24
+ borderRadius: 23,
25
+ justifyContent: "center",
26
+ zIndex: 200,
27
+ elevation: 2,
28
+ shadowColor: "#000",
29
+ shadowOffset: {
30
+ width: 0,
31
+ height: 2
32
+ },
33
+ shadowOpacity: 0.15,
34
+ shadowRadius: 6
35
+ },
36
+ addButtonIcon: {
37
+ color: "#fff",
38
+ fontSize: 16,
39
+ alignSelf: "center"
40
+ },
41
+ backButton: {
42
+ height: 32,
43
+ width: 32,
44
+ borderRadius: 15,
45
+ justifyContent: "center",
46
+ alignItems: "center"
47
+ },
48
+ backButtonIcon: {
49
+ color: "#fff",
50
+ fontSize: 18
51
+ },
52
+ tickBox: {
53
+ height: 20,
54
+ width: 20,
55
+ backgroundColor: COLOUR_GREEN,
56
+ borderRadius: 10,
57
+ justifyContent: "center",
58
+ alignItems: "center"
59
+ },
60
+ tickIcon: {
61
+ color: "#fff",
62
+ fontSize: 17,
63
+ paddingTop: 1,
64
+ paddingLeft: 1
65
+ }
66
+ });
67
+ //# sourceMappingURL=styles.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["StyleSheet","COLOUR_GREEN","create","notificationBell","height","width","alignItems","flexDirection","justifyContent","fill","flex","genericPageContainer","backgroundColor","addButton","position","bottom","right","borderRadius","zIndex","elevation","shadowColor","shadowOffset","shadowOpacity","shadowRadius","addButtonIcon","color","fontSize","alignSelf","backButton","backButtonIcon","tickBox","tickIcon","paddingTop","paddingLeft"],"sources":["styles.js"],"sourcesContent":["import { StyleSheet } from \"react-native\";\nimport { COLOUR_GREEN } from \"./colours\";\n\nexport default StyleSheet.create({\n\tnotificationBell: {\n\t\theight: 70,\n\t\twidth: 55,\n\t\talignItems: \"center\",\n\t\tflexDirection: \"row\",\n\t\tjustifyContent: \"space-between\",\n\t},\n\tfill: {\n\t\tflex: 1,\n\t},\n\tgenericPageContainer: {\n\t\tflex: 1,\n\t\tbackgroundColor: \"#fff\",\n\t},\n\taddButton: {\n\t\tposition: \"absolute\",\n\t\tbottom: 16,\n\t\tright: 16,\n\t\theight: 48,\n\t\twidth: 48,\n\t\tborderRadius: 23,\n\t\tjustifyContent: \"center\",\n\t\tzIndex: 200,\n\t\televation: 2,\n\t\tshadowColor: \"#000\",\n\t\tshadowOffset: { width: 0, height: 2 },\n\t\tshadowOpacity: 0.15,\n\t\tshadowRadius: 6,\n\t},\n\taddButtonIcon: {\n\t\tcolor: \"#fff\",\n\t\tfontSize: 16,\n\t\talignSelf: \"center\",\n\t},\n\tbackButton: {\n\t\theight: 32,\n\t\twidth: 32,\n\t\tborderRadius: 15,\n\t\tjustifyContent: \"center\",\n\t\talignItems: \"center\",\n\t},\n\tbackButtonIcon: {\n\t\tcolor: \"#fff\",\n\t\tfontSize: 18,\n\t},\n\ttickBox: {\n\t\theight: 20,\n\t\twidth: 20,\n\t\tbackgroundColor: COLOUR_GREEN,\n\t\tborderRadius: 10,\n\t\tjustifyContent: \"center\",\n\t\talignItems: \"center\",\n\t},\n\ttickIcon: {\n\t\tcolor: \"#fff\",\n\t\tfontSize: 17,\n\t\tpaddingTop: 1,\n\t\tpaddingLeft: 1,\n\t},\n});\n"],"mappings":"AAAA,SAASA,UAAU,QAAQ,cAAc;AACzC,SAASC,YAAY,QAAQ,WAAW;AAExC,eAAeD,UAAU,CAACE,MAAM,CAAC;EAChCC,gBAAgB,EAAE;IACjBC,MAAM,EAAE,EAAE;IACVC,KAAK,EAAE,EAAE;IACTC,UAAU,EAAE,QAAQ;IACpBC,aAAa,EAAE,KAAK;IACpBC,cAAc,EAAE;EACjB,CAAC;EACDC,IAAI,EAAE;IACLC,IAAI,EAAE;EACP,CAAC;EACDC,oBAAoB,EAAE;IACrBD,IAAI,EAAE,CAAC;IACPE,eAAe,EAAE;EAClB,CAAC;EACDC,SAAS,EAAE;IACVC,QAAQ,EAAE,UAAU;IACpBC,MAAM,EAAE,EAAE;IACVC,KAAK,EAAE,EAAE;IACTZ,MAAM,EAAE,EAAE;IACVC,KAAK,EAAE,EAAE;IACTY,YAAY,EAAE,EAAE;IAChBT,cAAc,EAAE,QAAQ;IACxBU,MAAM,EAAE,GAAG;IACXC,SAAS,EAAE,CAAC;IACZC,WAAW,EAAE,MAAM;IACnBC,YAAY,EAAE;MAAEhB,KAAK,EAAE,CAAC;MAAED,MAAM,EAAE;IAAE,CAAC;IACrCkB,aAAa,EAAE,IAAI;IACnBC,YAAY,EAAE;EACf,CAAC;EACDC,aAAa,EAAE;IACdC,KAAK,EAAE,MAAM;IACbC,QAAQ,EAAE,EAAE;IACZC,SAAS,EAAE;EACZ,CAAC;EACDC,UAAU,EAAE;IACXxB,MAAM,EAAE,EAAE;IACVC,KAAK,EAAE,EAAE;IACTY,YAAY,EAAE,EAAE;IAChBT,cAAc,EAAE,QAAQ;IACxBF,UAAU,EAAE;EACb,CAAC;EACDuB,cAAc,EAAE;IACfJ,KAAK,EAAE,MAAM;IACbC,QAAQ,EAAE;EACX,CAAC;EACDI,OAAO,EAAE;IACR1B,MAAM,EAAE,EAAE;IACVC,KAAK,EAAE,EAAE;IACTO,eAAe,EAAEX,YAAY;IAC7BgB,YAAY,EAAE,EAAE;IAChBT,cAAc,EAAE,QAAQ;IACxBF,UAAU,EAAE;EACb,CAAC;EACDyB,QAAQ,EAAE;IACTN,KAAK,EAAE,MAAM;IACbC,QAAQ,EAAE,EAAE;IACZM,UAAU,EAAE,CAAC;IACbC,WAAW,EAAE;EACd;AACD,CAAC,CAAC","ignoreList":[]}
@@ -0,0 +1,30 @@
1
+ function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
2
+ import React from "react";
3
+ import { useIsFocused } from "@react-navigation/native";
4
+
5
+ /**
6
+ * Compatibility wrapper for React Navigation v4's withNavigationFocus HOC
7
+ *
8
+ * In v4: withNavigationFocus provided an 'isFocused' prop to class components
9
+ * In v7: useIsFocused hook is the recommended approach for functional components
10
+ *
11
+ * This HOC bridges the gap, allowing class components to continue using
12
+ * the withNavigationFocus pattern while using the v7 useIsFocused hook internally.
13
+ *
14
+ * Usage (unchanged from v4):
15
+ * import { withNavigationFocus } from '@plusscommunities/pluss-core-app';
16
+ * export default withNavigationFocus(connect(mapStateToProps)(MyComponent));
17
+ *
18
+ * The wrapped component receives an 'isFocused' prop that is true when the
19
+ * screen is currently focused and false when not focused.
20
+ */
21
+ export function withNavigationFocus(Component) {
22
+ return function WithNavigationFocusWrapper(props) {
23
+ const isFocused = useIsFocused();
24
+ return /*#__PURE__*/React.createElement(Component, _extends({}, props, {
25
+ isFocused: isFocused
26
+ }));
27
+ };
28
+ }
29
+ export default withNavigationFocus;
30
+ //# sourceMappingURL=withNavigationFocus.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["React","useIsFocused","withNavigationFocus","Component","WithNavigationFocusWrapper","props","isFocused","createElement","_extends"],"sources":["withNavigationFocus.js"],"sourcesContent":["import React from \"react\";\nimport { useIsFocused } from \"@react-navigation/native\";\n\n/**\n * Compatibility wrapper for React Navigation v4's withNavigationFocus HOC\n *\n * In v4: withNavigationFocus provided an 'isFocused' prop to class components\n * In v7: useIsFocused hook is the recommended approach for functional components\n *\n * This HOC bridges the gap, allowing class components to continue using\n * the withNavigationFocus pattern while using the v7 useIsFocused hook internally.\n *\n * Usage (unchanged from v4):\n * import { withNavigationFocus } from '@plusscommunities/pluss-core-app';\n * export default withNavigationFocus(connect(mapStateToProps)(MyComponent));\n *\n * The wrapped component receives an 'isFocused' prop that is true when the\n * screen is currently focused and false when not focused.\n */\nexport function withNavigationFocus(Component) {\n\treturn function WithNavigationFocusWrapper(props) {\n\t\tconst isFocused = useIsFocused();\n\n\t\treturn <Component {...props} isFocused={isFocused} />;\n\t};\n}\n\nexport default withNavigationFocus;\n"],"mappings":";AAAA,OAAOA,KAAK,MAAM,OAAO;AACzB,SAASC,YAAY,QAAQ,0BAA0B;;AAEvD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,mBAAmBA,CAACC,SAAS,EAAE;EAC9C,OAAO,SAASC,0BAA0BA,CAACC,KAAK,EAAE;IACjD,MAAMC,SAAS,GAAGL,YAAY,CAAC,CAAC;IAEhC,oBAAOD,KAAA,CAAAO,aAAA,CAACJ,SAAS,EAAAK,QAAA,KAAKH,KAAK;MAAEC,SAAS,EAAEA;IAAU,EAAE,CAAC;EACtD,CAAC;AACF;AAEA,eAAeJ,mBAAmB","ignoreList":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@plusscommunities/pluss-core-app",
3
- "version": "8.0.29",
3
+ "version": "8.0.35",
4
4
  "description": "Core extension package for Pluss Communities platform",
5
5
  "exports": {
6
6
  ".": {
@@ -296,6 +296,11 @@ class CommentSection extends Component {
296
296
  this.loadComments();
297
297
  }, this.props.refreshFrequency || 2000);
298
298
  }
299
+ })
300
+ .catch((error) => {
301
+ console.error("loadComments error", error);
302
+ this.setState({ commentsLoading: false });
303
+ this.props.commentReply?.current?.loadingCompleted();
299
304
  });
300
305
  }
301
306
 
@@ -486,7 +491,7 @@ class CommentSection extends Component {
486
491
  key={c.Id}
487
492
  style={{ marginRight: -10 }}
488
493
  Diameter={20}
489
- ProfilePic={c.User.profilePic}
494
+ ProfilePic={c.User?.profilePic}
490
495
  />
491
496
  );
492
497
  })}
@@ -521,7 +526,7 @@ class CommentSection extends Component {
521
526
  <View style={styles.comment} key={c.Id}>
522
527
  <View style={styles.commentFlex}>
523
528
  <ProfilePic
524
- ProfilePic={isUserBlocked ? null : c.User.profilePic}
529
+ ProfilePic={isUserBlocked || !c.User ? null : c.User.profilePic}
525
530
  Diameter={40}
526
531
  style={styles.commentProfilePic}
527
532
  />
@@ -609,7 +614,7 @@ class CommentSection extends Component {
609
614
  { fontSize: this.getAdjustedSize(13) },
610
615
  ]}
611
616
  >
612
- {isUserBlocked ? "[blocked user]" : c.User.displayName}
617
+ {isUserBlocked ? "[blocked user]" : c.User?.displayName || "Unknown User"}
613
618
  </Text>
614
619
  </View>
615
620
  {!_.isEmpty(c.Comment) && (
@@ -1,28 +1,54 @@
1
- import React, { Component } from "react";
2
- import { View, TouchableOpacity, Modal, Dimensions, Alert } from "react-native";
3
- import { Text } from "./Text";
4
1
  import { Icon } from "@rneui/themed";
5
- import { WebView } from "react-native-webview";
6
2
  import { File, Paths } from "expo-file-system";
7
3
  import * as Sharing from "expo-sharing";
4
+ import { Component } from "react";
5
+ import { Alert, Dimensions, Modal, TouchableOpacity, View } from "react-native";
6
+ import { WebView } from "react-native-webview";
7
+ import { TEXT_DARK, TEXT_LIGHT } from "../colours";
8
+ import { getFileName, StatusBarHeight } from "../helper";
8
9
  import { FontAwesome } from "./Icon";
9
10
  import { Spinner } from "./Spinner";
10
- import { StatusBarHeight, getFileName } from "../helper";
11
+ import { Text } from "./Text";
11
12
 
12
13
  const SCREEN_HEIGHT = Dimensions.get("window").height;
13
14
 
14
15
  class PDFPopup extends Component {
15
16
  state = {
16
17
  loaded: false,
18
+ error: false,
17
19
  };
18
20
 
21
+ componentDidUpdate(prevProps) {
22
+ const sourceChanged = prevProps.source !== this.props.source;
23
+ const becameVisible = !prevProps.visible && this.props.visible;
24
+ if (sourceChanged || becameVisible) {
25
+ // Popup is reused across attachments — clear stale state so the
26
+ // spinner reappears and any prior error from a different PDF resets.
27
+ clearTimeout(this._loadTimeout);
28
+ this._loadTimeout = null;
29
+ this.setState({ loaded: false, error: false });
30
+ }
31
+ }
32
+
33
+ componentWillUnmount() {
34
+ clearTimeout(this._loadTimeout);
35
+ this._loadTimeout = null;
36
+ }
37
+
19
38
  onLoadStarted() {
20
39
  this.setState({
21
40
  loaded: false,
41
+ error: false,
22
42
  });
43
+ clearTimeout(this._loadTimeout);
44
+ this._loadTimeout = setTimeout(() => {
45
+ this.setState({ error: true });
46
+ }, 15000);
23
47
  }
24
48
 
25
49
  onLoadEnded() {
50
+ clearTimeout(this._loadTimeout);
51
+ this._loadTimeout = null;
26
52
  this.setState({
27
53
  loaded: true,
28
54
  });
@@ -33,9 +59,12 @@ class PDFPopup extends Component {
33
59
  }
34
60
 
35
61
  getUrl() {
62
+ if (!this.props.source) {
63
+ return "";
64
+ }
36
65
  const linkPrefix =
37
- "http://drive.google.com/viewerng/viewer?embedded=true&url=";
38
- return `${linkPrefix}${this.props.source}`;
66
+ "https://drive.google.com/viewerng/viewer?embedded=true&url=";
67
+ return `${linkPrefix}${encodeURIComponent(this.props.source)}`;
39
68
  }
40
69
 
41
70
  download = async () => {
@@ -132,35 +161,62 @@ class PDFPopup extends Component {
132
161
  </TouchableOpacity>
133
162
  </View>
134
163
  <View style={{ flex: 1, backgroundColor: "#fff" }}>
135
- {this.state.loaded ? null : (
136
- <Spinner
137
- style={{
138
- height: SCREEN_HEIGHT - StatusBarHeight(145),
139
- flex: 0,
140
- }}
141
- />
164
+ {this.state.error ? (
165
+ <View style={styles.errorContainer}>
166
+ <Text style={styles.errorTitle}>Unable to load this PDF.</Text>
167
+ <Text style={styles.errorSubtitle}>
168
+ Try downloading it instead.
169
+ </Text>
170
+ <TouchableOpacity
171
+ onPress={this.download}
172
+ activeOpacity={0.6}
173
+ style={styles.errorDownloadButton}
174
+ >
175
+ <Icon
176
+ type="font-awesome"
177
+ name="cloud-download"
178
+ iconStyle={styles.errorDownloadIcon}
179
+ />
180
+ <Text style={styles.errorDownloadText}>Download PDF</Text>
181
+ </TouchableOpacity>
182
+ </View>
183
+ ) : (
184
+ <>
185
+ {this.state.loaded ? null : (
186
+ <Spinner
187
+ style={{
188
+ height: SCREEN_HEIGHT - StatusBarHeight(145),
189
+ flex: 0,
190
+ }}
191
+ />
192
+ )}
193
+ <WebView
194
+ source={{
195
+ uri: this.getUrl(),
196
+ }}
197
+ javaScriptEnabled
198
+ domStorageEnabled
199
+ originWhitelist={["*"]}
200
+ renderError={() => {
201
+ // Surface error UI in the parent View rather than the
202
+ // default WebView error chrome. Defer setState to avoid
203
+ // triggering a state update during another render.
204
+ if (!this.state.error) {
205
+ setTimeout(() => this.setState({ error: true }), 0);
206
+ }
207
+ return null;
208
+ }}
209
+ style={[
210
+ {
211
+ flex: 1,
212
+ backgroundColor: "#fff",
213
+ },
214
+ ]}
215
+ onLoadStart={this.onLoadStarted.bind(this)}
216
+ onLoadEnd={this.onLoadEnded.bind(this)}
217
+ />
218
+ </>
142
219
  )}
143
- <WebView
144
- source={{
145
- uri: this.getUrl(),
146
- }}
147
- javaScriptEnabled
148
- domStorageEnabled
149
- originWhitelist={["*"]}
150
- mixedContentMode="always"
151
- renderError={(e) => {
152
- console.log("errored");
153
- console.log(e);
154
- }}
155
- style={[
156
- {
157
- flex: 1,
158
- backgroundColor: "#fff",
159
- },
160
- ]}
161
- onLoadStart={this.onLoadStarted.bind(this)}
162
- onLoadEnd={this.onLoadEnded.bind(this)}
163
- />
164
220
  </View>
165
221
  {this.renderFooter()}
166
222
  </View>
@@ -224,6 +280,45 @@ const styles = {
224
280
  width: 150,
225
281
  textAlign: "center",
226
282
  },
283
+ errorContainer: {
284
+ flex: 1,
285
+ alignItems: "center",
286
+ justifyContent: "center",
287
+ paddingHorizontal: 32,
288
+ paddingVertical: 24,
289
+ backgroundColor: "#fff",
290
+ },
291
+ errorTitle: {
292
+ fontFamily: "sf-semibold",
293
+ fontSize: 18,
294
+ color: TEXT_DARK,
295
+ textAlign: "center",
296
+ },
297
+ errorSubtitle: {
298
+ fontFamily: "sf-regular",
299
+ fontSize: 14,
300
+ color: TEXT_LIGHT,
301
+ textAlign: "center",
302
+ marginTop: 8,
303
+ },
304
+ errorDownloadButton: {
305
+ flexDirection: "row",
306
+ alignItems: "center",
307
+ justifyContent: "center",
308
+ marginTop: 24,
309
+ paddingHorizontal: 20,
310
+ paddingVertical: 12,
311
+ },
312
+ errorDownloadIcon: {
313
+ fontSize: 20,
314
+ color: TEXT_DARK,
315
+ marginRight: 8,
316
+ },
317
+ errorDownloadText: {
318
+ fontFamily: "sf-semibold",
319
+ fontSize: 16,
320
+ color: TEXT_DARK,
321
+ },
227
322
  };
228
323
 
229
324
  export { PDFPopup };