@plusscommunities/pluss-core-app 8.0.0 → 8.0.1-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 +116 -96
  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 +52 -39
  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 +94 -64
  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 +71 -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 +968 -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 +212 -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 +444 -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,791 +1,984 @@
1
- import React, { Component } from 'react';
2
- import { View, Text, TouchableOpacity, Image, StyleSheet } from 'react-native';
3
- import _ from 'lodash';
4
- import moment from 'moment';
5
- import { connect } from 'react-redux';
6
- import { Icon } from '@rneui/themed';
7
- import { getPluralS, getThumb300, get1400, getSiteSettingFromState, getFirstName, getPluralOptions } from '../helper';
8
- import { getMainBrandingColourFromState, TEXT_DARKEST, BG_GREY, TEXT_LIGHT, LINEGREY } from '../colours';
9
- import { reactionActions, notificationActions } from '../apis';
10
- import { blockUser, unblockUser } from '../actions';
11
- import { ConfirmPopup } from './ConfirmPopup';
12
- import { ProfilePic } from './ProfilePic';
13
- import { ImagePopup } from './ImagePopup';
14
- import { InlineButton } from './InlineButton';
15
- import { Spinner } from './Spinner';
16
- import { Services } from '../config';
1
+ import React, { Component } from "react";
2
+ import { View, TouchableOpacity, Image, StyleSheet } from "react-native";
3
+ import { Text } from "./Text";
4
+ import _ from "lodash";
5
+ import moment from "moment";
6
+ import { connect } from "react-redux";
7
+ import { Icon } from "@rneui/themed";
8
+ import {
9
+ getPluralS,
10
+ getThumb300,
11
+ get1400,
12
+ getSiteSettingFromState,
13
+ getFirstName,
14
+ getPluralOptions,
15
+ } from "../helper";
16
+ import {
17
+ getMainBrandingColourFromState,
18
+ TEXT_DARKEST,
19
+ BG_GREY,
20
+ TEXT_LIGHT,
21
+ LINEGREY,
22
+ } from "../colours";
23
+ import { reactionActions, notificationActions } from "../apis";
24
+ import { blockUser, unblockUser } from "../actions";
25
+ import { ConfirmPopup } from "./ConfirmPopup";
26
+ import { ProfilePic } from "./ProfilePic";
27
+ import { ImagePopup } from "./ImagePopup";
28
+ import { InlineButton } from "./InlineButton";
29
+ import { Spinner } from "./Spinner";
30
+ import { Services } from "../config";
17
31
 
18
32
  class CommentSection extends Component {
19
- constructor(props) {
20
- super(props);
21
- this.state = {
22
- commentsLoading: false,
23
- comments: [],
24
- addingComment: false,
25
- commentToDelete: null,
26
- commentToReport: null,
27
- commentReportedStatus: null,
28
- reportLoading: false,
29
- processing: false,
30
- muteExpiry: null,
31
- muteLoaded: false,
32
- };
33
- }
34
-
35
- componentDidMount() {
36
- this.getNotificationSate();
37
-
38
- if (!_.includes(this.props.user.hidden, 'viewComment')) {
39
- this.getComments();
40
- }
41
- }
42
-
43
- componentWillUnmount() {
44
- if (this.loadTimer) {
45
- clearTimeout(this.loadTimer);
46
- }
47
- }
48
-
49
- onPressDeleteComment = c => {
50
- this.setState({ commentToDelete: c });
51
- };
52
-
53
- onPressConfirmDelete = () => {
54
- reactionActions.removeComment(this.state.commentToDelete.Id).then(res => {
55
- console.log('deleted');
56
- });
57
- const newComments = _.filter(this.state.comments, c => {
58
- return c.Id !== this.state.commentToDelete.Id;
59
- });
60
- this.setState({
61
- comments: newComments,
62
- commentToDelete: null,
63
- });
64
- };
65
-
66
- onPressCancelDelete = () => {
67
- this.setState({ commentToDelete: null });
68
- };
69
-
70
- onPressReportComment = c => {
71
- this.setState({ commentToReport: c });
72
- };
73
-
74
- onPressBlockUser = c => {
75
- this.setState({ commentToBlock: c });
76
- };
77
-
78
- onPressConfirmBlock = () => {
79
- const userId = this.state.commentToBlock.UserId;
80
- this.props.blockUser(userId);
81
- this.setState({ commentToBlock: null });
82
- };
83
-
84
- onPressCancelBlock = () => {
85
- this.setState({ commentToBlock: null });
86
- };
87
-
88
- onPressUnblockUser = c => {
89
- this.setState({ commentToUnblock: c });
90
- };
91
-
92
- onPressConfirmUnblock = () => {
93
- const userId = this.state.commentToUnblock.UserId;
94
- this.props.unblockUser(userId);
95
- this.setState({ commentToUnblock: null });
96
- };
97
-
98
- onPressCancelUnblock = () => {
99
- this.setState({ commentToUnblock: null });
100
- };
101
-
102
- onPressConfirmReport = () => {
103
- const commentId = this.state.commentToReport.Id;
104
- this.setState({ reportLoading: true, commentToReport: null }, () => {
105
- reactionActions
106
- .reportComment(commentId)
107
- .then(res => {
108
- this.setState({ commentReportedStatus: 'success', reportLoading: false });
109
- })
110
- .catch(error => {
111
- console.log('reportComment', error);
112
- this.setState({ commentReportedStatus: 'fail', reportLoading: false });
113
- });
114
- });
115
- };
116
-
117
- onPressCancelReport = () => {
118
- this.setState({ commentToReport: null });
119
- };
120
-
121
- onPressConfirmReportStatus = () => {
122
- this.setState({ commentReportedStatus: null });
123
- };
124
-
125
- onPressCommentImage(image) {
126
- this.setState({
127
- imagePopupSource: [image],
128
- imagePopupOpen: true,
129
- });
130
- }
131
-
132
- onGoToAdd() {
133
- this.props.commentReply?.current?.focusInput();
134
- }
135
-
136
- onOpenThread = comment => {
137
- Services.navigation.navigate('thread', { ...this.props, threadId: comment.Id });
138
- };
139
-
140
- onMute = () => {
141
- const { entityType, entityId } = this.props;
142
- this.setState({ processing: true }, async () => {
143
- try {
144
- const { data } = await notificationActions.muteEntity(entityType, entityId);
145
- // console.log('onMute', data);
146
- const muteExpiry = moment(data.Expiry);
147
- this.setState({ muteExpiry, processing: false });
148
- } catch (error) {
149
- console.error('onMute', error);
150
- this.setState({ processing: false });
151
- }
152
- });
153
- };
154
-
155
- onUnmute = () => {
156
- const { entityType, entityId } = this.props;
157
- this.setState({ processing: true }, async () => {
158
- try {
159
- const { data } = await notificationActions.unmuteEntity(entityType, entityId);
160
- // console.log('onUnmute', data);
161
- this.setState({ muteExpiry: null, processing: false });
162
- } catch (error) {
163
- console.error('onUnmute', error);
164
- this.setState({ processing: false });
165
- }
166
- });
167
- };
168
-
169
- isMuted = () => {
170
- const { muteExpiry } = this.state;
171
- return muteExpiry && moment() <= muteExpiry;
172
- };
173
-
174
- getMuteRemaining = () => {
175
- const { muteExpiry } = this.state;
176
- const actual = muteExpiry ? moment.duration(muteExpiry.diff(moment())).asHours() : 0;
177
- return Math.abs(Math.ceil(actual));
178
- };
179
-
180
- getNotificationSate = () => {
181
- const { processing } = this.state;
182
- const { entityType, entityId, notificationsForComments } = this.props;
183
- if (processing || !notificationsForComments) return;
184
-
185
- this.setState({ processing: true }, async () => {
186
- try {
187
- const { data } = await notificationActions.getEntityNotificationSetting(entityType, entityId);
188
- // console.log('getNotificationSate', data);
189
- const muteExpiry = data ? moment(data.Expiry) : null;
190
- this.setState({ muteExpiry, muteLoaded: true, processing: false });
191
- } catch (error) {
192
- console.error('getNotificationSate', error);
193
- this.setState({ processing: false });
194
- }
195
- });
196
- };
197
-
198
- getAdjustedSize(size) {
199
- if (this.props.scaleFont) {
200
- return size + this.props.user.fontScale;
201
- }
202
- return size;
203
- }
204
-
205
- getComments() {
206
- if (!this.state.commentsLoadStarted) {
207
- this.setState({
208
- commentsLoadStarted: true,
209
- commentsLoading: true,
210
- });
211
- this.props.commentReply?.current?.loadingStarted();
212
-
213
- this.loadComments();
214
- }
215
- }
216
-
217
- isEmpty() {
218
- return _.isEmpty(this.state.comments);
219
- }
220
-
221
- loadComments() {
222
- const minTime = this.isEmpty()
223
- ? 0
224
- : _.maxBy(this.state.comments, c => {
225
- return c.Timestamp;
226
- }).Timestamp;
227
- reactionActions.getComments(this.props.entityId, this.props.entityType, minTime).then(res => {
228
- this.setState(
229
- {
230
- comments: _.sortBy(
231
- _.uniqBy(
232
- _.filter(_.concat(this.state.comments, res.data), c => {
233
- if (!this.props.threadId) {
234
- return true;
235
- }
236
- return c.Id === this.props.threadId || c.ParentId === this.props.threadId;
237
- }),
238
- c => {
239
- return c.Id;
240
- },
241
- ),
242
- 'Timestamp',
243
- ),
244
- commentsLoading: false,
245
- },
246
- () => {
247
- if (this.props.onCommentsLoaded) {
248
- this.props.onCommentsLoaded(this.state.comments.length);
249
- }
250
- },
251
- );
252
- //if (this.props.commentReply) {
253
- this.props.commentReply?.current?.loadingCompleted();
254
- //}
255
- if (this.props.live) {
256
- this.loadTimer = setTimeout(() => {
257
- this.loadComments();
258
- }, this.props.refreshFrequency || 2000);
259
- }
260
- });
261
- }
262
-
263
- isLoading = () => {
264
- return this.state.commentsLoading;
265
- };
266
-
267
- startedAddingComment() {
268
- this.setState({
269
- addingComment: true,
270
- });
271
- }
272
-
273
- commentAdded(comment) {
274
- const newComments = this.state.comments;
275
- newComments.push(comment);
276
- this.setState(
277
- {
278
- addingComment: false,
279
- comments: newComments,
280
- },
281
- () => {
282
- if (this.props.onCommentAdded) {
283
- this.props.onCommentAdded();
284
- }
285
- },
286
- );
287
- }
288
-
289
- isUserBlocked = c => {
290
- return _.includes(this.props.blockedUsers, c.UserId);
291
- };
292
-
293
- canBlockComment = c => {
294
- return this.props.user.uid !== c.UserId;
295
- };
296
-
297
- canRemoveComment(c) {
298
- if (this.props.user.uid === c.UserId) {
299
- return true;
300
- }
301
- return _.includes(this.props.user.permissions, this.props.adminPermission);
302
- }
303
-
304
- closeCommentGallery() {
305
- this.setState({
306
- imagePopupSource: [],
307
- imagePopupOpen: false,
308
- });
309
- }
310
-
311
- renderCommentDeleteConfirm() {
312
- return (
313
- <ConfirmPopup
314
- visible={!!this.state.commentToDelete}
315
- onConfirm={this.onPressConfirmDelete}
316
- onCancel={this.onPressCancelDelete}
317
- onClose={this.onPressCancelDelete}
318
- text="Are you sure you want to delete this comment?"
319
- />
320
- );
321
- }
322
-
323
- renderCommentReportConfirm() {
324
- return (
325
- <ConfirmPopup
326
- visible={!!this.state.commentToReport}
327
- onConfirm={this.onPressConfirmReport}
328
- onCancel={this.onPressCancelReport}
329
- onClose={this.onPressCancelReport}
330
- text="Are you sure you want to report this comment?"
331
- extraContent={<Text style={styles.commentReportText}>This comment will be reported to our team and considered for deletion</Text>}
332
- />
333
- );
334
- }
335
-
336
- renderCommentBlockConfirm() {
337
- return (
338
- <ConfirmPopup
339
- visible={!!this.state.commentToBlock}
340
- onConfirm={this.onPressConfirmBlock}
341
- onCancel={this.onPressCancelBlock}
342
- onClose={this.onPressCancelBlock}
343
- text="Are you sure you want to block this user?"
344
- extraContent={<Text style={styles.commentReportText}>You will no longer see comments made by this user</Text>}
345
- />
346
- );
347
- }
348
-
349
- renderCommentUnblockConfirm() {
350
- return (
351
- <ConfirmPopup
352
- visible={!!this.state.commentToUnblock}
353
- onConfirm={this.onPressConfirmUnblock}
354
- onCancel={this.onPressCancelUnblock}
355
- onClose={this.onPressCancelUnblock}
356
- text="Are you sure you want to unblock this user?"
357
- extraContent={<Text style={styles.commentReportText}>You will once again see comments made by this user</Text>}
358
- />
359
- );
360
- }
361
-
362
- renderCommentReportStatus() {
363
- const { commentReportedStatus } = this.state;
364
- const isSuccess = commentReportedStatus === 'success';
365
- return (
366
- <ConfirmPopup
367
- visible={!!commentReportedStatus}
368
- onConfirm={this.onPressConfirmReportStatus}
369
- text={isSuccess ? 'Thank you for reporting' : 'Unable to report'}
370
- extraContent={
371
- <Text style={styles.commentReportText}>
372
- {isSuccess ? 'We will review the comment within 24 hours' : 'There was a problem reporting the comment please try again later'}
373
- </Text>
374
- }
375
- hideNo
376
- yesText={'Done'}
377
- />
378
- );
379
- }
380
-
381
- renderCommentImage(c) {
382
- if (_.isEmpty(c.Image)) {
383
- return null;
384
- }
385
- return (
386
- <TouchableOpacity style={styles.commentImageContainer} onPress={this.onPressCommentImage.bind(this, get1400(c.Image))}>
387
- <Image style={styles.commentImage} source={{ uri: getThumb300(c.Image) }} />
388
- </TouchableOpacity>
389
- );
390
- }
391
-
392
- renderReplyText = (c, isUserBlocked) => {
393
- if (this.props.threadId || this.props.hideReplyButton) {
394
- return null;
395
- }
396
-
397
- const threadComments = _.filter(this.state.comments, innerC => {
398
- return innerC.ParentId === c.Id;
399
- });
400
-
401
- let content = null;
402
-
403
- if (_.isEmpty(threadComments)) {
404
- // no replies
405
- content = (
406
- <Text style={[styles.commentRepliesText, { color: this.props.colourBrandingMain }]}>{`Reply to ${getFirstName(
407
- !isUserBlocked && c.User ? c.User.displayName : 'comment',
408
- )}`}</Text>
409
- );
410
- } else {
411
- // existing replies
412
- const profilePics = _.take(
413
- _.uniqBy(threadComments, c => c.UserId),
414
- 3,
415
- );
416
- content = (
417
- <View style={styles.multiReplyContainer}>
418
- {profilePics.map((c, i) => {
419
- return <ProfilePic key={c.Id} style={{ marginRight: -10 }} Diameter={20} ProfilePic={c.User.profilePic} />;
420
- })}
421
- <Text style={[styles.commentRepliesText, { marginLeft: 20, color: this.props.colourBrandingMain }]}>{`${threadComments.length
422
- } repl${getPluralOptions(threadComments.length, 'y', 'ies')}`}</Text>
423
- </View>
424
- );
425
- }
426
-
427
- return (
428
- <View style={styles.commentReplies}>
429
- <TouchableOpacity
430
- onPress={() => {
431
- this.onOpenThread(c);
432
- }}
433
- >
434
- {content}
435
- </TouchableOpacity>
436
- </View>
437
- );
438
- };
439
-
440
- renderComment(c) {
441
- const isUserBlocked = this.isUserBlocked(c);
442
- return (
443
- <View style={styles.comment} key={c.Id}>
444
- <View style={styles.commentFlex}>
445
- <ProfilePic ProfilePic={isUserBlocked ? null : c.User.profilePic} Diameter={40} style={styles.commentProfilePic} />
446
- <View style={styles.commentBlock}>
447
- <View style={styles.commentTitleRow}>
448
- {this.canRemoveComment(c) ? (
449
- <TouchableOpacity onPress={this.onPressDeleteComment.bind(this, c)}>
450
- <View style={[styles.commentButtonContainer, { backgroundColor: this.props.colourBrandingMain }]}>
451
- <Icon name="trash" type="font-awesome" iconStyle={styles.commentButtonIcon} />
452
- </View>
453
- </TouchableOpacity>
454
- ) : (
455
- !this.props.disableFlag && (
456
- <TouchableOpacity onPress={this.onPressReportComment.bind(this, c)}>
457
- <View style={[styles.commentButtonContainer, { backgroundColor: this.props.colourBrandingMain }]}>
458
- <Icon name="flag" type="font-awesome" iconStyle={styles.commentButtonIcon} />
459
- </View>
460
- </TouchableOpacity>
461
- )
462
- )}
463
- {!this.props.disableFlag &&
464
- this.canBlockComment(c) &&
465
- (isUserBlocked ? (
466
- <TouchableOpacity style={{ marginRight: 8 }} onPress={this.onPressUnblockUser.bind(this, c)}>
467
- <View style={[styles.commentButtonContainer, { backgroundColor: this.props.colourBrandingMain }]}>
468
- <Icon name="user-plus" type="font-awesome" iconStyle={styles.commentButtonIcon} />
469
- </View>
470
- </TouchableOpacity>
471
- ) : (
472
- <TouchableOpacity style={{ marginRight: 8 }} onPress={this.onPressBlockUser.bind(this, c)}>
473
- <View style={[styles.commentButtonContainer, { backgroundColor: this.props.colourBrandingMain }]}>
474
- <Icon name="user-times" type="font-awesome" iconStyle={styles.commentButtonIcon} />
475
- </View>
476
- </TouchableOpacity>
477
- ))}
478
- <Text style={[styles.commentName, { fontSize: this.getAdjustedSize(13) }]}>
479
- {isUserBlocked ? '[blocked user]' : c.User.displayName}
480
- </Text>
481
- </View>
482
- {!_.isEmpty(c.Comment) && (
483
- <Text style={[styles.commentText, { fontSize: this.getAdjustedSize(13) }]}>{isUserBlocked ? '[hidden]' : c.Comment}</Text>
484
- )}
485
- {!isUserBlocked && this.renderCommentImage(c)}
486
- </View>
487
- </View>
488
- <View style={styles.commentBottom}>
489
- <Text style={[styles.commentTime, { fontSize: this.getAdjustedSize(13) }]}>
490
- {moment
491
- .utc(c.Timestamp)
492
- .local()
493
- .format('D MMM • h:mma')}
494
- </Text>
495
- {this.renderReplyText(c, isUserBlocked)}
496
- </View>
497
- </View>
498
- );
499
- }
500
-
501
- renderMute() {
502
- const { notificationsForComments } = this.props;
503
- const { muteLoaded, muteExpiry, processing } = this.state;
504
- if (!notificationsForComments || !muteLoaded) return null;
505
-
506
- if (processing)
507
- return (
508
- <View style={styles.muteSpinnerContainer}>
509
- <Spinner size={'small'} color={this.props.colourBrandingMain} />
510
- </View>
511
- );
512
-
513
- const isMuted = this.isMuted();
514
- const hours = this.getMuteRemaining();
515
- const mutedFor = `Muted for ${hours} hour${getPluralS(hours)}`;
516
- // console.log(muteExpiry.format('DD MMM YYYY hh:mm a'));
517
-
518
- return (
519
- <View style={styles.muteContainer}>
520
- {isMuted && muteExpiry ? <Text style={[{ color: this.props.colourBrandingMain }, styles.mutedForText]}>{mutedFor}</Text> : null}
521
- <InlineButton
522
- onPress={isMuted ? this.onUnmute : this.onMute}
523
- color="#fff"
524
- style={[{ borderColor: this.props.colourBrandingMain }, styles.muteButton]}
525
- disabled={processing}
526
- disabledOpacity
527
- noText
528
- >
529
- <View style={styles.muteButtonInner}>
530
- <Icon
531
- name={isMuted ? 'bell-o' : 'bell-slash-o'}
532
- type={'font-awesome'}
533
- iconStyle={[{ color: this.props.colourBrandingMain }, styles.muteButtonIcon]}
534
- />
535
- <Text style={[{ color: this.props.colourBrandingMain }, styles.muteButtonText]}>{isMuted ? 'Unmute' : 'Mute'}</Text>
536
- </View>
537
- </InlineButton>
538
- </View>
539
- );
540
- }
541
-
542
- renderComments() {
543
- if (this.state.commentsLoading) {
544
- return (
545
- <View style={styles.commentSection}>
546
- <Spinner color={this.props.colourBrandingMain} />
547
- </View>
548
- );
549
- }
550
- if (this.isEmpty() && !this.state.addingComment) {
551
- if (_.includes(this.props.user.hidden, 'addComment')) {
552
- return null;
553
- }
554
- if (!_.isNil(this.props.placeHolder) && _.isEmpty(this.props.placeHolder)) return null;
555
- return (
556
- <View style={styles.commentSection}>
557
- <Text style={[styles.commentsEmpty, { fontSize: this.getAdjustedSize(15) }]}>
558
- {_.isNil(this.props.placeHolder) ? 'Be the first to add a comment!' : this.props.placeHolder}
559
- </Text>
560
- </View>
561
- );
562
- }
563
- let source = [...this.state.comments];
564
- if (this.props.reverseOrder) {
565
- source = source.reverse();
566
- }
567
- if (!this.props.showReplies && !this.props.threadId) {
568
- source = _.filter(source, c => {
569
- return !c.ParentId;
570
- });
571
- }
572
- return (
573
- <View style={styles.commentSection}>
574
- {!this.isEmpty() && (
575
- <View style={styles.commentSectionTitleRow}>
576
- <View style={{ alignItems: 'flex-end' }}>
577
- {this.renderMute()}
578
- {!this.props.hideAddComment && this.state.comments.length > 2 && (
579
- <TouchableOpacity onPress={this.onGoToAdd.bind(this)}>
580
- <Text style={[styles.goToText, { color: this.props.colourBrandingMain }]}>Add a comment</Text>
581
- </TouchableOpacity>
582
- )}
583
- </View>
584
- <Text style={[styles.commentCount, { fontSize: this.getAdjustedSize(15) }]}>
585
- {this.state.comments.length}
586
- {` comment${getPluralS(this.state.comments.length)}`}
587
- </Text>
588
- </View>
589
- )}
590
- {this.props.reverseOrder && this.state.addingComment && <Spinner color={this.props.colourBrandingMain} />}
591
- {source.map(c => {
592
- return this.renderComment(c);
593
- })}
594
- {!this.props.reverseOrder && this.state.addingComment && <Spinner color={this.props.colourBrandingMain} />}
595
- </View>
596
- );
597
- }
598
-
599
- renderCommentImagePopup() {
600
- return (
601
- <ImagePopup
602
- visible={this.state.imagePopupOpen}
603
- images={this.state.imagePopupSource}
604
- onClose={this.closeCommentGallery.bind(this)}
605
- ref="commentImagePopup"
606
- />
607
- );
608
- }
609
-
610
- renderReportLoading() {
611
- if (!this.state.reportLoading) return null;
612
- return (
613
- <View style={styles.reportLoadingContainer}>
614
- <Spinner color={this.props.colourBrandingMain} />
615
- </View>
616
- );
617
- }
618
-
619
- render() {
620
- if (_.includes(this.props.user.hidden, 'viewComment')) {
621
- return null;
622
- }
623
- return (
624
- <View style={[styles.commentSectionOuter, this.props.style]}>
625
- {this.renderComments()}
626
- {this.renderReportLoading()}
627
- {this.renderCommentDeleteConfirm()}
628
- {this.renderCommentReportConfirm()}
629
- {this.renderCommentBlockConfirm()}
630
- {this.renderCommentUnblockConfirm()}
631
- {this.renderCommentReportStatus()}
632
- {this.renderCommentImagePopup()}
633
- </View>
634
- );
635
- }
33
+ constructor(props) {
34
+ super(props);
35
+ this.state = {
36
+ commentsLoading: false,
37
+ comments: [],
38
+ addingComment: false,
39
+ commentToDelete: null,
40
+ commentToReport: null,
41
+ commentReportedStatus: null,
42
+ reportLoading: false,
43
+ processing: false,
44
+ muteExpiry: null,
45
+ muteLoaded: false,
46
+ };
47
+ }
48
+
49
+ componentDidMount() {
50
+ this.getNotificationSate();
51
+
52
+ if (!_.includes(this.props.user.hidden, "viewComment")) {
53
+ this.getComments();
54
+ }
55
+ }
56
+
57
+ componentWillUnmount() {
58
+ if (this.loadTimer) {
59
+ clearTimeout(this.loadTimer);
60
+ }
61
+ }
62
+
63
+ onPressDeleteComment = (c) => {
64
+ this.setState({ commentToDelete: c });
65
+ };
66
+
67
+ onPressConfirmDelete = () => {
68
+ reactionActions.removeComment(this.state.commentToDelete.Id).then((res) => {
69
+ console.log("deleted");
70
+ });
71
+ const newComments = _.filter(this.state.comments, (c) => {
72
+ return c.Id !== this.state.commentToDelete.Id;
73
+ });
74
+ this.setState({
75
+ comments: newComments,
76
+ commentToDelete: null,
77
+ });
78
+ };
79
+
80
+ onPressCancelDelete = () => {
81
+ this.setState({ commentToDelete: null });
82
+ };
83
+
84
+ onPressReportComment = (c) => {
85
+ this.setState({ commentToReport: c });
86
+ };
87
+
88
+ onPressBlockUser = (c) => {
89
+ this.setState({ commentToBlock: c });
90
+ };
91
+
92
+ onPressConfirmBlock = () => {
93
+ const userId = this.state.commentToBlock.UserId;
94
+ this.props.blockUser(userId);
95
+ this.setState({ commentToBlock: null });
96
+ };
97
+
98
+ onPressCancelBlock = () => {
99
+ this.setState({ commentToBlock: null });
100
+ };
101
+
102
+ onPressUnblockUser = (c) => {
103
+ this.setState({ commentToUnblock: c });
104
+ };
105
+
106
+ onPressConfirmUnblock = () => {
107
+ const userId = this.state.commentToUnblock.UserId;
108
+ this.props.unblockUser(userId);
109
+ this.setState({ commentToUnblock: null });
110
+ };
111
+
112
+ onPressCancelUnblock = () => {
113
+ this.setState({ commentToUnblock: null });
114
+ };
115
+
116
+ onPressConfirmReport = () => {
117
+ const commentId = this.state.commentToReport.Id;
118
+ this.setState({ reportLoading: true, commentToReport: null }, () => {
119
+ reactionActions
120
+ .reportComment(commentId)
121
+ .then((res) => {
122
+ this.setState({
123
+ commentReportedStatus: "success",
124
+ reportLoading: false,
125
+ });
126
+ })
127
+ .catch((error) => {
128
+ console.log("reportComment", error);
129
+ this.setState({
130
+ commentReportedStatus: "fail",
131
+ reportLoading: false,
132
+ });
133
+ });
134
+ });
135
+ };
136
+
137
+ onPressCancelReport = () => {
138
+ this.setState({ commentToReport: null });
139
+ };
140
+
141
+ onPressConfirmReportStatus = () => {
142
+ this.setState({ commentReportedStatus: null });
143
+ };
144
+
145
+ onPressCommentImage(image) {
146
+ this.setState({
147
+ imagePopupSource: [image],
148
+ imagePopupOpen: true,
149
+ });
150
+ }
151
+
152
+ onGoToAdd() {
153
+ this.props.commentReply?.current?.focusInput();
154
+ }
155
+
156
+ onOpenThread = (comment) => {
157
+ Services.navigation.navigate("thread", {
158
+ ...this.props,
159
+ threadId: comment.Id,
160
+ });
161
+ };
162
+
163
+ onMute = () => {
164
+ const { entityType, entityId } = this.props;
165
+ this.setState({ processing: true }, async () => {
166
+ try {
167
+ const { data } = await notificationActions.muteEntity(
168
+ entityType,
169
+ entityId,
170
+ );
171
+ // console.log('onMute', data);
172
+ const muteExpiry = moment(data.Expiry);
173
+ this.setState({ muteExpiry, processing: false });
174
+ } catch (error) {
175
+ console.error("onMute", error);
176
+ this.setState({ processing: false });
177
+ }
178
+ });
179
+ };
180
+
181
+ onUnmute = () => {
182
+ const { entityType, entityId } = this.props;
183
+ this.setState({ processing: true }, async () => {
184
+ try {
185
+ const { data } = await notificationActions.unmuteEntity(
186
+ entityType,
187
+ entityId,
188
+ );
189
+ // console.log('onUnmute', data);
190
+ this.setState({ muteExpiry: null, processing: false });
191
+ } catch (error) {
192
+ console.error("onUnmute", error);
193
+ this.setState({ processing: false });
194
+ }
195
+ });
196
+ };
197
+
198
+ isMuted = () => {
199
+ const { muteExpiry } = this.state;
200
+ return muteExpiry && moment() <= muteExpiry;
201
+ };
202
+
203
+ getMuteRemaining = () => {
204
+ const { muteExpiry } = this.state;
205
+ const actual = muteExpiry
206
+ ? moment.duration(muteExpiry.diff(moment())).asHours()
207
+ : 0;
208
+ return Math.abs(Math.ceil(actual));
209
+ };
210
+
211
+ getNotificationSate = () => {
212
+ const { processing } = this.state;
213
+ const { entityType, entityId, notificationsForComments } = this.props;
214
+ if (processing || !notificationsForComments) return;
215
+
216
+ this.setState({ processing: true }, async () => {
217
+ try {
218
+ const { data } = await notificationActions.getEntityNotificationSetting(
219
+ entityType,
220
+ entityId,
221
+ );
222
+ // console.log('getNotificationSate', data);
223
+ const muteExpiry = data ? moment(data.Expiry) : null;
224
+ this.setState({ muteExpiry, muteLoaded: true, processing: false });
225
+ } catch (error) {
226
+ console.error("getNotificationSate", error);
227
+ this.setState({ processing: false });
228
+ }
229
+ });
230
+ };
231
+
232
+ getAdjustedSize(size) {
233
+ if (this.props.scaleFont) {
234
+ return size + this.props.user.fontScale;
235
+ }
236
+ return size;
237
+ }
238
+
239
+ getComments() {
240
+ if (!this.state.commentsLoadStarted) {
241
+ this.setState({
242
+ commentsLoadStarted: true,
243
+ commentsLoading: true,
244
+ });
245
+ this.props.commentReply?.current?.loadingStarted();
246
+
247
+ this.loadComments();
248
+ }
249
+ }
250
+
251
+ isEmpty() {
252
+ return _.isEmpty(this.state.comments);
253
+ }
254
+
255
+ loadComments() {
256
+ const minTime = this.isEmpty()
257
+ ? 0
258
+ : _.maxBy(this.state.comments, (c) => {
259
+ return c.Timestamp;
260
+ }).Timestamp;
261
+ reactionActions
262
+ .getComments(this.props.entityId, this.props.entityType, minTime)
263
+ .then((res) => {
264
+ this.setState(
265
+ {
266
+ comments: _.sortBy(
267
+ _.uniqBy(
268
+ _.filter(_.concat(this.state.comments, res.data), (c) => {
269
+ if (!this.props.threadId) {
270
+ return true;
271
+ }
272
+ return (
273
+ c.Id === this.props.threadId ||
274
+ c.ParentId === this.props.threadId
275
+ );
276
+ }),
277
+ (c) => {
278
+ return c.Id;
279
+ },
280
+ ),
281
+ "Timestamp",
282
+ ),
283
+ commentsLoading: false,
284
+ },
285
+ () => {
286
+ if (this.props.onCommentsLoaded) {
287
+ this.props.onCommentsLoaded(this.state.comments.length);
288
+ }
289
+ },
290
+ );
291
+ //if (this.props.commentReply) {
292
+ this.props.commentReply?.current?.loadingCompleted();
293
+ //}
294
+ if (this.props.live) {
295
+ this.loadTimer = setTimeout(() => {
296
+ this.loadComments();
297
+ }, this.props.refreshFrequency || 2000);
298
+ }
299
+ });
300
+ }
301
+
302
+ isLoading = () => {
303
+ return this.state.commentsLoading;
304
+ };
305
+
306
+ startedAddingComment() {
307
+ this.setState({
308
+ addingComment: true,
309
+ });
310
+ }
311
+
312
+ commentAdded(comment) {
313
+ const newComments = this.state.comments;
314
+ newComments.push(comment);
315
+ this.setState(
316
+ {
317
+ addingComment: false,
318
+ comments: newComments,
319
+ },
320
+ () => {
321
+ if (this.props.onCommentAdded) {
322
+ this.props.onCommentAdded();
323
+ }
324
+ },
325
+ );
326
+ }
327
+
328
+ isUserBlocked = (c) => {
329
+ return _.includes(this.props.blockedUsers, c.UserId);
330
+ };
331
+
332
+ canBlockComment = (c) => {
333
+ return this.props.user.uid !== c.UserId;
334
+ };
335
+
336
+ canRemoveComment(c) {
337
+ if (this.props.user.uid === c.UserId) {
338
+ return true;
339
+ }
340
+ return _.includes(this.props.user.permissions, this.props.adminPermission);
341
+ }
342
+
343
+ closeCommentGallery() {
344
+ this.setState({
345
+ imagePopupSource: [],
346
+ imagePopupOpen: false,
347
+ });
348
+ }
349
+
350
+ renderCommentDeleteConfirm() {
351
+ return (
352
+ <ConfirmPopup
353
+ visible={!!this.state.commentToDelete}
354
+ onConfirm={this.onPressConfirmDelete}
355
+ onCancel={this.onPressCancelDelete}
356
+ onClose={this.onPressCancelDelete}
357
+ text="Are you sure you want to delete this comment?"
358
+ />
359
+ );
360
+ }
361
+
362
+ renderCommentReportConfirm() {
363
+ return (
364
+ <ConfirmPopup
365
+ visible={!!this.state.commentToReport}
366
+ onConfirm={this.onPressConfirmReport}
367
+ onCancel={this.onPressCancelReport}
368
+ onClose={this.onPressCancelReport}
369
+ text="Are you sure you want to report this comment?"
370
+ extraContent={
371
+ <Text style={styles.commentReportText}>
372
+ This comment will be reported to our team and considered for
373
+ deletion
374
+ </Text>
375
+ }
376
+ />
377
+ );
378
+ }
379
+
380
+ renderCommentBlockConfirm() {
381
+ return (
382
+ <ConfirmPopup
383
+ visible={!!this.state.commentToBlock}
384
+ onConfirm={this.onPressConfirmBlock}
385
+ onCancel={this.onPressCancelBlock}
386
+ onClose={this.onPressCancelBlock}
387
+ text="Are you sure you want to block this user?"
388
+ extraContent={
389
+ <Text style={styles.commentReportText}>
390
+ You will no longer see comments made by this user
391
+ </Text>
392
+ }
393
+ />
394
+ );
395
+ }
396
+
397
+ renderCommentUnblockConfirm() {
398
+ return (
399
+ <ConfirmPopup
400
+ visible={!!this.state.commentToUnblock}
401
+ onConfirm={this.onPressConfirmUnblock}
402
+ onCancel={this.onPressCancelUnblock}
403
+ onClose={this.onPressCancelUnblock}
404
+ text="Are you sure you want to unblock this user?"
405
+ extraContent={
406
+ <Text style={styles.commentReportText}>
407
+ You will once again see comments made by this user
408
+ </Text>
409
+ }
410
+ />
411
+ );
412
+ }
413
+
414
+ renderCommentReportStatus() {
415
+ const { commentReportedStatus } = this.state;
416
+ const isSuccess = commentReportedStatus === "success";
417
+ return (
418
+ <ConfirmPopup
419
+ visible={!!commentReportedStatus}
420
+ onConfirm={this.onPressConfirmReportStatus}
421
+ text={isSuccess ? "Thank you for reporting" : "Unable to report"}
422
+ extraContent={
423
+ <Text style={styles.commentReportText}>
424
+ {isSuccess
425
+ ? "We will review the comment within 24 hours"
426
+ : "There was a problem reporting the comment please try again later"}
427
+ </Text>
428
+ }
429
+ hideNo
430
+ yesText={"Done"}
431
+ />
432
+ );
433
+ }
434
+
435
+ renderCommentImage(c) {
436
+ if (_.isEmpty(c.Image)) {
437
+ return null;
438
+ }
439
+ return (
440
+ <TouchableOpacity
441
+ style={styles.commentImageContainer}
442
+ onPress={this.onPressCommentImage.bind(this, get1400(c.Image))}
443
+ >
444
+ <Image
445
+ style={styles.commentImage}
446
+ source={{ uri: getThumb300(c.Image) }}
447
+ />
448
+ </TouchableOpacity>
449
+ );
450
+ }
451
+
452
+ renderReplyText = (c, isUserBlocked) => {
453
+ if (this.props.threadId || this.props.hideReplyButton) {
454
+ return null;
455
+ }
456
+
457
+ const threadComments = _.filter(this.state.comments, (innerC) => {
458
+ return innerC.ParentId === c.Id;
459
+ });
460
+
461
+ let content = null;
462
+
463
+ if (_.isEmpty(threadComments)) {
464
+ // no replies
465
+ content = (
466
+ <Text
467
+ style={[
468
+ styles.commentRepliesText,
469
+ { color: this.props.colourBrandingMain },
470
+ ]}
471
+ >{`Reply to ${getFirstName(
472
+ !isUserBlocked && c.User ? c.User.displayName : "comment",
473
+ )}`}</Text>
474
+ );
475
+ } else {
476
+ // existing replies
477
+ const profilePics = _.take(
478
+ _.uniqBy(threadComments, (c) => c.UserId),
479
+ 3,
480
+ );
481
+ content = (
482
+ <View style={styles.multiReplyContainer}>
483
+ {profilePics.map((c, i) => {
484
+ return (
485
+ <ProfilePic
486
+ key={c.Id}
487
+ style={{ marginRight: -10 }}
488
+ Diameter={20}
489
+ ProfilePic={c.User.profilePic}
490
+ />
491
+ );
492
+ })}
493
+ <Text
494
+ style={[
495
+ styles.commentRepliesText,
496
+ { marginLeft: 20, color: this.props.colourBrandingMain },
497
+ ]}
498
+ >{`${
499
+ threadComments.length
500
+ } repl${getPluralOptions(threadComments.length, "y", "ies")}`}</Text>
501
+ </View>
502
+ );
503
+ }
504
+
505
+ return (
506
+ <View style={styles.commentReplies}>
507
+ <TouchableOpacity
508
+ onPress={() => {
509
+ this.onOpenThread(c);
510
+ }}
511
+ >
512
+ {content}
513
+ </TouchableOpacity>
514
+ </View>
515
+ );
516
+ };
517
+
518
+ renderComment(c) {
519
+ const isUserBlocked = this.isUserBlocked(c);
520
+ return (
521
+ <View style={styles.comment} key={c.Id}>
522
+ <View style={styles.commentFlex}>
523
+ <ProfilePic
524
+ ProfilePic={isUserBlocked ? null : c.User.profilePic}
525
+ Diameter={40}
526
+ style={styles.commentProfilePic}
527
+ />
528
+ <View style={styles.commentBlock}>
529
+ <View style={styles.commentTitleRow}>
530
+ {this.canRemoveComment(c) ? (
531
+ <TouchableOpacity
532
+ onPress={this.onPressDeleteComment.bind(this, c)}
533
+ >
534
+ <View
535
+ style={[
536
+ styles.commentButtonContainer,
537
+ { backgroundColor: this.props.colourBrandingMain },
538
+ ]}
539
+ >
540
+ <Icon
541
+ name="trash"
542
+ type="font-awesome"
543
+ iconStyle={styles.commentButtonIcon}
544
+ />
545
+ </View>
546
+ </TouchableOpacity>
547
+ ) : (
548
+ !this.props.disableFlag && (
549
+ <TouchableOpacity
550
+ onPress={this.onPressReportComment.bind(this, c)}
551
+ >
552
+ <View
553
+ style={[
554
+ styles.commentButtonContainer,
555
+ { backgroundColor: this.props.colourBrandingMain },
556
+ ]}
557
+ >
558
+ <Icon
559
+ name="flag"
560
+ type="font-awesome"
561
+ iconStyle={styles.commentButtonIcon}
562
+ />
563
+ </View>
564
+ </TouchableOpacity>
565
+ )
566
+ )}
567
+ {!this.props.disableFlag &&
568
+ this.canBlockComment(c) &&
569
+ (isUserBlocked ? (
570
+ <TouchableOpacity
571
+ style={{ marginRight: 8 }}
572
+ onPress={this.onPressUnblockUser.bind(this, c)}
573
+ >
574
+ <View
575
+ style={[
576
+ styles.commentButtonContainer,
577
+ { backgroundColor: this.props.colourBrandingMain },
578
+ ]}
579
+ >
580
+ <Icon
581
+ name="user-plus"
582
+ type="font-awesome"
583
+ iconStyle={styles.commentButtonIcon}
584
+ />
585
+ </View>
586
+ </TouchableOpacity>
587
+ ) : (
588
+ <TouchableOpacity
589
+ style={{ marginRight: 8 }}
590
+ onPress={this.onPressBlockUser.bind(this, c)}
591
+ >
592
+ <View
593
+ style={[
594
+ styles.commentButtonContainer,
595
+ { backgroundColor: this.props.colourBrandingMain },
596
+ ]}
597
+ >
598
+ <Icon
599
+ name="user-times"
600
+ type="font-awesome"
601
+ iconStyle={styles.commentButtonIcon}
602
+ />
603
+ </View>
604
+ </TouchableOpacity>
605
+ ))}
606
+ <Text
607
+ style={[
608
+ styles.commentName,
609
+ { fontSize: this.getAdjustedSize(13) },
610
+ ]}
611
+ >
612
+ {isUserBlocked ? "[blocked user]" : c.User.displayName}
613
+ </Text>
614
+ </View>
615
+ {!_.isEmpty(c.Comment) && (
616
+ <Text
617
+ style={[
618
+ styles.commentText,
619
+ { fontSize: this.getAdjustedSize(13) },
620
+ ]}
621
+ >
622
+ {isUserBlocked ? "[hidden]" : c.Comment}
623
+ </Text>
624
+ )}
625
+ {!isUserBlocked && this.renderCommentImage(c)}
626
+ </View>
627
+ </View>
628
+ <View style={styles.commentBottom}>
629
+ <Text
630
+ style={[styles.commentTime, { fontSize: this.getAdjustedSize(13) }]}
631
+ >
632
+ {moment.utc(c.Timestamp).local().format("D MMM • h:mma")}
633
+ </Text>
634
+ {this.renderReplyText(c, isUserBlocked)}
635
+ </View>
636
+ </View>
637
+ );
638
+ }
639
+
640
+ renderMute() {
641
+ const { notificationsForComments } = this.props;
642
+ const { muteLoaded, muteExpiry, processing } = this.state;
643
+ if (!notificationsForComments || !muteLoaded) return null;
644
+
645
+ if (processing)
646
+ return (
647
+ <View style={styles.muteSpinnerContainer}>
648
+ <Spinner size={"small"} color={this.props.colourBrandingMain} />
649
+ </View>
650
+ );
651
+
652
+ const isMuted = this.isMuted();
653
+ const hours = this.getMuteRemaining();
654
+ const mutedFor = `Muted for ${hours} hour${getPluralS(hours)}`;
655
+ // console.log(muteExpiry.format('DD MMM YYYY hh:mm a'));
656
+
657
+ return (
658
+ <View style={styles.muteContainer}>
659
+ {isMuted && muteExpiry ? (
660
+ <Text
661
+ style={[
662
+ { color: this.props.colourBrandingMain },
663
+ styles.mutedForText,
664
+ ]}
665
+ >
666
+ {mutedFor}
667
+ </Text>
668
+ ) : null}
669
+ <InlineButton
670
+ onPress={isMuted ? this.onUnmute : this.onMute}
671
+ color="#fff"
672
+ style={[
673
+ { borderColor: this.props.colourBrandingMain },
674
+ styles.muteButton,
675
+ ]}
676
+ disabled={processing}
677
+ disabledOpacity
678
+ noText
679
+ >
680
+ <View style={styles.muteButtonInner}>
681
+ <Icon
682
+ name={isMuted ? "bell-o" : "bell-slash-o"}
683
+ type={"font-awesome"}
684
+ iconStyle={[
685
+ { color: this.props.colourBrandingMain },
686
+ styles.muteButtonIcon,
687
+ ]}
688
+ />
689
+ <Text
690
+ style={[
691
+ { color: this.props.colourBrandingMain },
692
+ styles.muteButtonText,
693
+ ]}
694
+ >
695
+ {isMuted ? "Unmute" : "Mute"}
696
+ </Text>
697
+ </View>
698
+ </InlineButton>
699
+ </View>
700
+ );
701
+ }
702
+
703
+ renderComments() {
704
+ if (this.state.commentsLoading) {
705
+ return (
706
+ <View style={styles.commentSection}>
707
+ <Spinner color={this.props.colourBrandingMain} />
708
+ </View>
709
+ );
710
+ }
711
+ if (this.isEmpty() && !this.state.addingComment) {
712
+ if (_.includes(this.props.user.hidden, "addComment")) {
713
+ return null;
714
+ }
715
+ if (!_.isNil(this.props.placeHolder) && _.isEmpty(this.props.placeHolder))
716
+ return null;
717
+ return (
718
+ <View style={styles.commentSection}>
719
+ <Text
720
+ style={[
721
+ styles.commentsEmpty,
722
+ { fontSize: this.getAdjustedSize(15) },
723
+ ]}
724
+ >
725
+ {_.isNil(this.props.placeHolder)
726
+ ? "Be the first to add a comment!"
727
+ : this.props.placeHolder}
728
+ </Text>
729
+ </View>
730
+ );
731
+ }
732
+ let source = [...this.state.comments];
733
+ if (this.props.reverseOrder) {
734
+ source = source.reverse();
735
+ }
736
+ if (!this.props.showReplies && !this.props.threadId) {
737
+ source = _.filter(source, (c) => {
738
+ return !c.ParentId;
739
+ });
740
+ }
741
+ return (
742
+ <View style={styles.commentSection}>
743
+ {!this.isEmpty() && (
744
+ <View style={styles.commentSectionTitleRow}>
745
+ <View style={{ alignItems: "flex-end" }}>
746
+ {this.renderMute()}
747
+ {!this.props.hideAddComment && this.state.comments.length > 2 && (
748
+ <TouchableOpacity onPress={this.onGoToAdd.bind(this)}>
749
+ <Text
750
+ style={[
751
+ styles.goToText,
752
+ { color: this.props.colourBrandingMain },
753
+ ]}
754
+ >
755
+ Add a comment
756
+ </Text>
757
+ </TouchableOpacity>
758
+ )}
759
+ </View>
760
+ <Text
761
+ style={[
762
+ styles.commentCount,
763
+ { fontSize: this.getAdjustedSize(15) },
764
+ ]}
765
+ >
766
+ {this.state.comments.length}
767
+ {` comment${getPluralS(this.state.comments.length)}`}
768
+ </Text>
769
+ </View>
770
+ )}
771
+ {this.props.reverseOrder && this.state.addingComment && (
772
+ <Spinner color={this.props.colourBrandingMain} />
773
+ )}
774
+ {source.map((c) => {
775
+ return this.renderComment(c);
776
+ })}
777
+ {!this.props.reverseOrder && this.state.addingComment && (
778
+ <Spinner color={this.props.colourBrandingMain} />
779
+ )}
780
+ </View>
781
+ );
782
+ }
783
+
784
+ renderCommentImagePopup() {
785
+ return (
786
+ <ImagePopup
787
+ visible={this.state.imagePopupOpen}
788
+ images={this.state.imagePopupSource}
789
+ onClose={this.closeCommentGallery.bind(this)}
790
+ />
791
+ );
792
+ }
793
+
794
+ renderReportLoading() {
795
+ if (!this.state.reportLoading) return null;
796
+ return (
797
+ <View style={styles.reportLoadingContainer}>
798
+ <Spinner color={this.props.colourBrandingMain} />
799
+ </View>
800
+ );
801
+ }
802
+
803
+ render() {
804
+ if (_.includes(this.props.user.hidden, "viewComment")) {
805
+ return null;
806
+ }
807
+ return (
808
+ <View style={[styles.commentSectionOuter, this.props.style]}>
809
+ {this.renderComments()}
810
+ {this.renderReportLoading()}
811
+ {this.renderCommentDeleteConfirm()}
812
+ {this.renderCommentReportConfirm()}
813
+ {this.renderCommentBlockConfirm()}
814
+ {this.renderCommentUnblockConfirm()}
815
+ {this.renderCommentReportStatus()}
816
+ {this.renderCommentImagePopup()}
817
+ </View>
818
+ );
819
+ }
636
820
  }
637
821
 
638
822
  const styles = StyleSheet.create({
639
- commentSectionOuter: {
640
- flex: 1,
641
- paddingHorizontal: 16,
642
- },
643
- commentSection: {
644
- flex: 1,
645
- paddingVertical: 12,
646
- borderTopColor: LINEGREY,
647
- borderTopWidth: 1,
648
- },
649
- commentCount: {
650
- fontFamily: 'sf-semibold',
651
- color: TEXT_DARKEST,
652
- flex: 1,
653
- marginTop: 4,
654
- },
655
- comment: {
656
- marginTop: 16,
657
- },
658
- commentFlex: {
659
- flexDirection: 'row',
660
- },
661
- commentProfilePic: {
662
- marginRight: 8,
663
- },
664
- commentBlock: {
665
- flex: 1,
666
- backgroundColor: BG_GREY,
667
- borderRadius: 5,
668
- padding: 8,
669
- },
670
- commentTitleRow: {
671
- flexDirection: 'row-reverse',
672
- alignItems: 'center',
673
- },
674
- commentButtonContainer: {
675
- width: 24,
676
- height: 24,
677
- borderRadius: 12,
678
- alignItems: 'center',
679
- justifyContent: 'center',
680
- },
681
- commentButtonIcon: {
682
- fontSize: 13,
683
- color: '#fff',
684
- },
685
- commentName: {
686
- fontFamily: 'sf-semibold',
687
- color: TEXT_DARKEST,
688
- flex: 1,
689
- },
690
- commentText: {
691
- marginTop: 8,
692
- fontFamily: 'sf-regular',
693
- color: TEXT_DARKEST,
694
- },
695
- commentBottom: {
696
- flexDirection: 'row-reverse',
697
- justifyContent: 'space-between',
698
- alignItems: 'center',
699
- },
700
- commentTime: {
701
- fontFamily: 'sf-regular',
702
- marginTop: 4,
703
- color: TEXT_LIGHT,
704
- textAlign: 'right',
705
- },
706
- commentReplies: {
707
- flex: 1,
708
- paddingLeft: 48,
709
- },
710
- commentRepliesText: {
711
- fontFamily: 'sf-semibold',
712
- fontSize: 15,
713
- },
714
- multiReplyContainer: {
715
- flexDirection: 'row',
716
- alignItems: 'center',
717
- paddingVertical: 4,
718
- },
719
- commentImageContainer: {
720
- marginTop: 8,
721
- width: 60,
722
- height: 60,
723
- },
724
- commentImage: {
725
- width: 60,
726
- height: 60,
727
- borderRadius: 2,
728
- },
729
- commentsEmpty: {
730
- fontFamily: 'sf-semibold',
731
- color: TEXT_DARKEST,
732
- },
733
- commentSectionTitleRow: {
734
- flexDirection: 'row-reverse',
735
- },
736
- commentReportText: {
737
- fontFamily: 'sf-regular',
738
- fontSize: 14,
739
- paddingHorizontal: 22,
740
- textAlign: 'center',
741
- },
742
- reportLoadingContainer: {
743
- paddingVertical: 10,
744
- },
745
- goToText: {
746
- marginTop: 4,
747
- },
748
- muteSpinnerContainer: {
749
- width: 100,
750
- marginBottom: 6,
751
- },
752
- muteContainer: {
753
- flexDirection: 'row',
754
- alignItems: 'center',
755
- justifyContent: 'flex-end',
756
- marginBottom: 6,
757
- },
758
- mutedForText: {
759
- fontFamily: 'sf-semibold',
760
- fontSize: 13,
761
- marginRight: 8,
762
- },
763
- muteButton: {
764
- borderWidth: 1,
765
- paddingHorizontal: 8,
766
- },
767
- muteButtonInner: {
768
- flexDirection: 'row',
769
- alignItems: 'center',
770
- },
771
- muteButtonIcon: {
772
- fontSize: 14,
773
- },
774
- muteButtonText: {
775
- fontFamily: 'sf-semibold',
776
- fontSize: 14,
777
- marginLeft: 6,
778
- },
823
+ commentSectionOuter: {
824
+ flex: 1,
825
+ paddingHorizontal: 16,
826
+ },
827
+ commentSection: {
828
+ flex: 1,
829
+ paddingVertical: 12,
830
+ borderTopColor: LINEGREY,
831
+ borderTopWidth: 1,
832
+ },
833
+ commentCount: {
834
+ fontFamily: "sf-semibold",
835
+ color: TEXT_DARKEST,
836
+ flex: 1,
837
+ marginTop: 4,
838
+ },
839
+ comment: {
840
+ marginTop: 16,
841
+ },
842
+ commentFlex: {
843
+ flexDirection: "row",
844
+ },
845
+ commentProfilePic: {
846
+ marginRight: 8,
847
+ },
848
+ commentBlock: {
849
+ flex: 1,
850
+ backgroundColor: BG_GREY,
851
+ borderRadius: 5,
852
+ padding: 8,
853
+ },
854
+ commentTitleRow: {
855
+ flexDirection: "row-reverse",
856
+ alignItems: "center",
857
+ },
858
+ commentButtonContainer: {
859
+ width: 24,
860
+ height: 24,
861
+ borderRadius: 12,
862
+ alignItems: "center",
863
+ justifyContent: "center",
864
+ },
865
+ commentButtonIcon: {
866
+ fontSize: 13,
867
+ color: "#fff",
868
+ },
869
+ commentName: {
870
+ fontFamily: "sf-semibold",
871
+ color: TEXT_DARKEST,
872
+ flex: 1,
873
+ },
874
+ commentText: {
875
+ marginTop: 8,
876
+ fontFamily: "sf-regular",
877
+ color: TEXT_DARKEST,
878
+ },
879
+ commentBottom: {
880
+ flexDirection: "row-reverse",
881
+ justifyContent: "space-between",
882
+ alignItems: "center",
883
+ },
884
+ commentTime: {
885
+ fontFamily: "sf-regular",
886
+ marginTop: 4,
887
+ color: TEXT_LIGHT,
888
+ textAlign: "right",
889
+ },
890
+ commentReplies: {
891
+ flex: 1,
892
+ paddingLeft: 48,
893
+ },
894
+ commentRepliesText: {
895
+ fontFamily: "sf-semibold",
896
+ fontSize: 15,
897
+ },
898
+ multiReplyContainer: {
899
+ flexDirection: "row",
900
+ alignItems: "center",
901
+ paddingVertical: 4,
902
+ },
903
+ commentImageContainer: {
904
+ marginTop: 8,
905
+ width: 60,
906
+ height: 60,
907
+ },
908
+ commentImage: {
909
+ width: 60,
910
+ height: 60,
911
+ borderRadius: 2,
912
+ },
913
+ commentsEmpty: {
914
+ fontFamily: "sf-semibold",
915
+ color: TEXT_DARKEST,
916
+ },
917
+ commentSectionTitleRow: {
918
+ flexDirection: "row-reverse",
919
+ },
920
+ commentReportText: {
921
+ fontFamily: "sf-regular",
922
+ fontSize: 14,
923
+ paddingHorizontal: 22,
924
+ textAlign: "center",
925
+ },
926
+ reportLoadingContainer: {
927
+ paddingVertical: 10,
928
+ },
929
+ goToText: {
930
+ marginTop: 4,
931
+ },
932
+ muteSpinnerContainer: {
933
+ width: 100,
934
+ marginBottom: 6,
935
+ },
936
+ muteContainer: {
937
+ flexDirection: "row",
938
+ alignItems: "center",
939
+ justifyContent: "flex-end",
940
+ marginBottom: 6,
941
+ },
942
+ mutedForText: {
943
+ fontFamily: "sf-semibold",
944
+ fontSize: 13,
945
+ marginRight: 8,
946
+ },
947
+ muteButton: {
948
+ borderWidth: 1,
949
+ paddingHorizontal: 8,
950
+ },
951
+ muteButtonInner: {
952
+ flexDirection: "row",
953
+ alignItems: "center",
954
+ },
955
+ muteButtonIcon: {
956
+ fontSize: 14,
957
+ },
958
+ muteButtonText: {
959
+ fontFamily: "sf-semibold",
960
+ fontSize: 14,
961
+ marginLeft: 6,
962
+ },
779
963
  });
780
964
 
781
- const mapStateToProps = state => {
782
- return {
783
- colourBrandingMain: getMainBrandingColourFromState(state),
784
- user: state.user,
785
- notificationsForComments: getSiteSettingFromState(state, 'NotificationsForComments', false),
786
- blockedUsers: state.userSettings.blockedUsers || [],
787
- };
965
+ const mapStateToProps = (state) => {
966
+ return {
967
+ colourBrandingMain: getMainBrandingColourFromState(state),
968
+ user: state.user,
969
+ notificationsForComments: getSiteSettingFromState(
970
+ state,
971
+ "NotificationsForComments",
972
+ false,
973
+ ),
974
+ blockedUsers: state.userSettings.blockedUsers || [],
975
+ };
788
976
  };
789
977
 
790
- const commentSection = connect(mapStateToProps, { blockUser, unblockUser }, null, { forwardRef: true })(CommentSection);
978
+ const commentSection = connect(
979
+ mapStateToProps,
980
+ { blockUser, unblockUser },
981
+ null,
982
+ { forwardRef: true },
983
+ )(CommentSection);
791
984
  export { commentSection as CommentSection };