@amityco/react-native-social-uikit 4.0.0 → 4.0.1-00d805a4.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 (196) hide show
  1. package/lib/commonjs/core/assets/icons/index.js +8 -0
  2. package/lib/commonjs/core/assets/icons/index.js.map +1 -1
  3. package/lib/commonjs/core/assets/icons/visitorLimit.js +26 -0
  4. package/lib/commonjs/core/assets/icons/visitorLimit.js.map +1 -0
  5. package/lib/commonjs/core/constants/index.js +11 -1
  6. package/lib/commonjs/core/constants/index.js.map +1 -1
  7. package/lib/commonjs/core/hooks/useAuth.js +6 -2
  8. package/lib/commonjs/core/hooks/useAuth.js.map +1 -1
  9. package/lib/commonjs/core/providers/AmityUIKitProvider.js.map +1 -1
  10. package/lib/commonjs/core/providers/AuthProvider.js +44 -16
  11. package/lib/commonjs/core/providers/AuthProvider.js.map +1 -1
  12. package/lib/commonjs/core/routes/AmityUIKitNavigator.js +28 -1
  13. package/lib/commonjs/core/routes/AmityUIKitNavigator.js.map +1 -1
  14. package/lib/commonjs/index.js +6 -0
  15. package/lib/commonjs/index.js.map +1 -1
  16. package/lib/commonjs/social/components/Social/CommentList/CommentList.js +7 -1
  17. package/lib/commonjs/social/components/Social/CommentList/CommentList.js.map +1 -1
  18. package/lib/commonjs/social/components/Social/CommentListItem/CommentListItem.js +16 -3
  19. package/lib/commonjs/social/components/Social/CommentListItem/CommentListItem.js.map +1 -1
  20. package/lib/commonjs/social/components/legacy/Social/ReplyCommentList/index.js +12 -2
  21. package/lib/commonjs/social/components/legacy/Social/ReplyCommentList/index.js.map +1 -1
  22. package/lib/commonjs/social/elements/CommunityJoinButtonElement/CommunityJoinButtonElement.js +6 -1
  23. package/lib/commonjs/social/elements/CommunityJoinButtonElement/CommunityJoinButtonElement.js.map +1 -1
  24. package/lib/commonjs/social/features/comment/components/PostComment/CommentListItem/CommentListItem.js +15 -3
  25. package/lib/commonjs/social/features/comment/components/PostComment/CommentListItem/CommentListItem.js.map +1 -1
  26. package/lib/commonjs/social/features/comment/components/PostComment/ReplyCommentList/index.js +12 -2
  27. package/lib/commonjs/social/features/comment/components/PostComment/ReplyCommentList/index.js.map +1 -1
  28. package/lib/commonjs/social/features/feed/components/TopNavigation/TopNavigation.js +5 -1
  29. package/lib/commonjs/social/features/feed/components/TopNavigation/TopNavigation.js.map +1 -1
  30. package/lib/commonjs/social/features/post/Detail/index.js +8 -2
  31. package/lib/commonjs/social/features/post/Detail/index.js.map +1 -1
  32. package/lib/commonjs/social/features/post/components/Content/Content.js +5 -1
  33. package/lib/commonjs/social/features/post/components/Content/Content.js.map +1 -1
  34. package/lib/commonjs/social/features/post/components/EngagementActions/Components/DetailStyle.js +9 -1
  35. package/lib/commonjs/social/features/post/components/EngagementActions/Components/DetailStyle.js.map +1 -1
  36. package/lib/commonjs/social/features/post/components/EngagementActions/Components/FeedStyle.js +9 -1
  37. package/lib/commonjs/social/features/post/components/EngagementActions/Components/FeedStyle.js.map +1 -1
  38. package/lib/commonjs/social/features/user/Profile/components/Header/hooks/useHeader.js +6 -1
  39. package/lib/commonjs/social/features/user/Profile/components/Header/hooks/useHeader.js.map +1 -1
  40. package/lib/commonjs/social/hooks/index.js +11 -0
  41. package/lib/commonjs/social/hooks/index.js.map +1 -1
  42. package/lib/commonjs/social/hooks/useGlobalBehavior.js +53 -0
  43. package/lib/commonjs/social/hooks/useGlobalBehavior.js.map +1 -0
  44. package/lib/commonjs/social/hooks/usePostPermission.js +4 -2
  45. package/lib/commonjs/social/hooks/usePostPermission.js.map +1 -1
  46. package/lib/commonjs/social/hooks/useStoryPermission.js +3 -2
  47. package/lib/commonjs/social/hooks/useStoryPermission.js.map +1 -1
  48. package/lib/commonjs/social/index.js +7 -0
  49. package/lib/commonjs/social/index.js.map +1 -1
  50. package/lib/commonjs/social/providers/BehaviourProvider.js +1 -0
  51. package/lib/commonjs/social/providers/BehaviourProvider.js.map +1 -1
  52. package/lib/commonjs/social/screens/SocialHomePage/index.js +15 -5
  53. package/lib/commonjs/social/screens/SocialHomePage/index.js.map +1 -1
  54. package/lib/commonjs/social/screens/VisitorUsageLimit/VisitorUsageLimit.js +81 -0
  55. package/lib/commonjs/social/screens/VisitorUsageLimit/VisitorUsageLimit.js.map +1 -0
  56. package/lib/commonjs/social/screens/VisitorUsageLimit/index.js +13 -0
  57. package/lib/commonjs/social/screens/VisitorUsageLimit/index.js.map +1 -0
  58. package/lib/commonjs/social/screens/VisitorUsageLimit/styles.js +52 -0
  59. package/lib/commonjs/social/screens/VisitorUsageLimit/styles.js.map +1 -0
  60. package/lib/module/core/assets/icons/index.js +1 -0
  61. package/lib/module/core/assets/icons/index.js.map +1 -1
  62. package/lib/module/core/assets/icons/visitorLimit.js +19 -0
  63. package/lib/module/core/assets/icons/visitorLimit.js.map +1 -0
  64. package/lib/module/core/constants/index.js +10 -0
  65. package/lib/module/core/constants/index.js.map +1 -1
  66. package/lib/module/core/hooks/useAuth.js +6 -2
  67. package/lib/module/core/hooks/useAuth.js.map +1 -1
  68. package/lib/module/core/providers/AmityUIKitProvider.js.map +1 -1
  69. package/lib/module/core/providers/AuthProvider.js +44 -16
  70. package/lib/module/core/providers/AuthProvider.js.map +1 -1
  71. package/lib/module/core/routes/AmityUIKitNavigator.js +28 -1
  72. package/lib/module/core/routes/AmityUIKitNavigator.js.map +1 -1
  73. package/lib/module/index.js +2 -2
  74. package/lib/module/index.js.map +1 -1
  75. package/lib/module/social/components/Social/CommentList/CommentList.js +7 -1
  76. package/lib/module/social/components/Social/CommentList/CommentList.js.map +1 -1
  77. package/lib/module/social/components/Social/CommentListItem/CommentListItem.js +16 -3
  78. package/lib/module/social/components/Social/CommentListItem/CommentListItem.js.map +1 -1
  79. package/lib/module/social/components/legacy/Social/ReplyCommentList/index.js +12 -2
  80. package/lib/module/social/components/legacy/Social/ReplyCommentList/index.js.map +1 -1
  81. package/lib/module/social/elements/CommunityJoinButtonElement/CommunityJoinButtonElement.js +7 -2
  82. package/lib/module/social/elements/CommunityJoinButtonElement/CommunityJoinButtonElement.js.map +1 -1
  83. package/lib/module/social/features/comment/components/PostComment/CommentListItem/CommentListItem.js +16 -4
  84. package/lib/module/social/features/comment/components/PostComment/CommentListItem/CommentListItem.js.map +1 -1
  85. package/lib/module/social/features/comment/components/PostComment/ReplyCommentList/index.js +12 -2
  86. package/lib/module/social/features/comment/components/PostComment/ReplyCommentList/index.js.map +1 -1
  87. package/lib/module/social/features/feed/components/TopNavigation/TopNavigation.js +5 -1
  88. package/lib/module/social/features/feed/components/TopNavigation/TopNavigation.js.map +1 -1
  89. package/lib/module/social/features/post/Detail/index.js +8 -2
  90. package/lib/module/social/features/post/Detail/index.js.map +1 -1
  91. package/lib/module/social/features/post/components/Content/Content.js +5 -1
  92. package/lib/module/social/features/post/components/Content/Content.js.map +1 -1
  93. package/lib/module/social/features/post/components/EngagementActions/Components/DetailStyle.js +10 -2
  94. package/lib/module/social/features/post/components/EngagementActions/Components/DetailStyle.js.map +1 -1
  95. package/lib/module/social/features/post/components/EngagementActions/Components/FeedStyle.js +10 -2
  96. package/lib/module/social/features/post/components/EngagementActions/Components/FeedStyle.js.map +1 -1
  97. package/lib/module/social/features/user/Profile/components/Header/hooks/useHeader.js +7 -2
  98. package/lib/module/social/features/user/Profile/components/Header/hooks/useHeader.js.map +1 -1
  99. package/lib/module/social/hooks/index.js +1 -0
  100. package/lib/module/social/hooks/index.js.map +1 -1
  101. package/lib/module/social/hooks/useGlobalBehavior.js +45 -0
  102. package/lib/module/social/hooks/useGlobalBehavior.js.map +1 -0
  103. package/lib/module/social/hooks/usePostPermission.js +4 -2
  104. package/lib/module/social/hooks/usePostPermission.js.map +1 -1
  105. package/lib/module/social/hooks/useStoryPermission.js +3 -2
  106. package/lib/module/social/hooks/useStoryPermission.js.map +1 -1
  107. package/lib/module/social/index.js +1 -0
  108. package/lib/module/social/index.js.map +1 -1
  109. package/lib/module/social/providers/BehaviourProvider.js +1 -0
  110. package/lib/module/social/providers/BehaviourProvider.js.map +1 -1
  111. package/lib/module/social/screens/SocialHomePage/index.js +16 -6
  112. package/lib/module/social/screens/SocialHomePage/index.js.map +1 -1
  113. package/lib/module/social/screens/VisitorUsageLimit/VisitorUsageLimit.js +75 -0
  114. package/lib/module/social/screens/VisitorUsageLimit/VisitorUsageLimit.js.map +1 -0
  115. package/lib/module/social/screens/VisitorUsageLimit/index.js +2 -0
  116. package/lib/module/social/screens/VisitorUsageLimit/index.js.map +1 -0
  117. package/lib/module/social/screens/VisitorUsageLimit/styles.js +45 -0
  118. package/lib/module/social/screens/VisitorUsageLimit/styles.js.map +1 -0
  119. package/lib/typescript/core/assets/icons/index.d.ts +1 -0
  120. package/lib/typescript/core/assets/icons/index.d.ts.map +1 -1
  121. package/lib/typescript/core/assets/icons/visitorLimit.d.ts +3 -0
  122. package/lib/typescript/core/assets/icons/visitorLimit.d.ts.map +1 -0
  123. package/lib/typescript/core/constants/index.d.ts +8 -0
  124. package/lib/typescript/core/constants/index.d.ts.map +1 -1
  125. package/lib/typescript/core/hooks/useAuth.d.ts.map +1 -1
  126. package/lib/typescript/core/providers/AmityUIKitProvider.d.ts +2 -1
  127. package/lib/typescript/core/providers/AmityUIKitProvider.d.ts.map +1 -1
  128. package/lib/typescript/core/providers/AuthProvider.d.ts.map +1 -1
  129. package/lib/typescript/core/routes/AmityUIKitNavigator.d.ts.map +1 -1
  130. package/lib/typescript/core/types/auth.d.ts +2 -0
  131. package/lib/typescript/core/types/auth.d.ts.map +1 -1
  132. package/lib/typescript/core/types/behaviour.d.ts +18 -0
  133. package/lib/typescript/core/types/behaviour.d.ts.map +1 -1
  134. package/lib/typescript/index.d.ts +2 -2
  135. package/lib/typescript/index.d.ts.map +1 -1
  136. package/lib/typescript/social/components/Social/CommentList/CommentList.d.ts.map +1 -1
  137. package/lib/typescript/social/components/Social/CommentListItem/CommentListItem.d.ts.map +1 -1
  138. package/lib/typescript/social/components/legacy/Social/ReplyCommentList/index.d.ts.map +1 -1
  139. package/lib/typescript/social/elements/CommunityJoinButtonElement/CommunityJoinButtonElement.d.ts.map +1 -1
  140. package/lib/typescript/social/features/comment/components/PostComment/CommentListItem/CommentListItem.d.ts.map +1 -1
  141. package/lib/typescript/social/features/comment/components/PostComment/ReplyCommentList/index.d.ts.map +1 -1
  142. package/lib/typescript/social/features/feed/components/TopNavigation/TopNavigation.d.ts.map +1 -1
  143. package/lib/typescript/social/features/post/Detail/index.d.ts.map +1 -1
  144. package/lib/typescript/social/features/post/components/Content/Content.d.ts.map +1 -1
  145. package/lib/typescript/social/features/post/components/EngagementActions/Components/DetailStyle.d.ts.map +1 -1
  146. package/lib/typescript/social/features/post/components/EngagementActions/Components/FeedStyle.d.ts.map +1 -1
  147. package/lib/typescript/social/features/user/Profile/components/Header/hooks/useHeader.d.ts.map +1 -1
  148. package/lib/typescript/social/hooks/index.d.ts +1 -0
  149. package/lib/typescript/social/hooks/index.d.ts.map +1 -1
  150. package/lib/typescript/social/hooks/useGlobalBehavior.d.ts +23 -0
  151. package/lib/typescript/social/hooks/useGlobalBehavior.d.ts.map +1 -0
  152. package/lib/typescript/social/hooks/usePostPermission.d.ts.map +1 -1
  153. package/lib/typescript/social/hooks/useStoryPermission.d.ts.map +1 -1
  154. package/lib/typescript/social/index.d.ts +1 -0
  155. package/lib/typescript/social/index.d.ts.map +1 -1
  156. package/lib/typescript/social/providers/BehaviourProvider.d.ts.map +1 -1
  157. package/lib/typescript/social/screens/SocialHomePage/index.d.ts.map +1 -1
  158. package/lib/typescript/social/screens/VisitorUsageLimit/VisitorUsageLimit.d.ts +2 -0
  159. package/lib/typescript/social/screens/VisitorUsageLimit/VisitorUsageLimit.d.ts.map +1 -0
  160. package/lib/typescript/social/screens/VisitorUsageLimit/index.d.ts +2 -0
  161. package/lib/typescript/social/screens/VisitorUsageLimit/index.d.ts.map +1 -0
  162. package/lib/typescript/social/screens/VisitorUsageLimit/styles.d.ts +40 -0
  163. package/lib/typescript/social/screens/VisitorUsageLimit/styles.d.ts.map +1 -0
  164. package/package.json +3 -3
  165. package/src/core/assets/icons/index.ts +1 -0
  166. package/src/core/assets/icons/visitorLimit.tsx +19 -0
  167. package/src/core/constants/index.ts +12 -0
  168. package/src/core/hooks/useAuth.ts +4 -0
  169. package/src/core/providers/AmityUIKitProvider.tsx +2 -1
  170. package/src/core/providers/AuthProvider.tsx +38 -12
  171. package/src/core/routes/AmityUIKitNavigator.tsx +28 -1
  172. package/src/core/types/auth.ts +2 -0
  173. package/src/core/types/behaviour.ts +18 -0
  174. package/src/index.tsx +2 -0
  175. package/src/social/components/Social/CommentList/CommentList.tsx +5 -1
  176. package/src/social/components/Social/CommentListItem/CommentListItem.tsx +19 -12
  177. package/src/social/components/legacy/Social/ReplyCommentList/index.tsx +17 -11
  178. package/src/social/elements/CommunityJoinButtonElement/CommunityJoinButtonElement.tsx +10 -2
  179. package/src/social/features/comment/components/PostComment/CommentListItem/CommentListItem.tsx +22 -16
  180. package/src/social/features/comment/components/PostComment/ReplyCommentList/index.tsx +17 -11
  181. package/src/social/features/feed/components/TopNavigation/TopNavigation.tsx +3 -1
  182. package/src/social/features/post/Detail/index.tsx +6 -2
  183. package/src/social/features/post/components/Content/Content.tsx +7 -4
  184. package/src/social/features/post/components/EngagementActions/Components/DetailStyle.tsx +7 -2
  185. package/src/social/features/post/components/EngagementActions/Components/FeedStyle.tsx +7 -2
  186. package/src/social/features/user/Profile/components/Header/hooks/useHeader.ts +5 -2
  187. package/src/social/hooks/index.ts +1 -0
  188. package/src/social/hooks/useGlobalBehavior.ts +39 -0
  189. package/src/social/hooks/usePostPermission.ts +3 -1
  190. package/src/social/hooks/useStoryPermission.ts +8 -6
  191. package/src/social/index.tsx +1 -0
  192. package/src/social/providers/BehaviourProvider.tsx +1 -0
  193. package/src/social/screens/SocialHomePage/index.tsx +26 -11
  194. package/src/social/screens/VisitorUsageLimit/VisitorUsageLimit.tsx +81 -0
  195. package/src/social/screens/VisitorUsageLimit/index.ts +1 -0
  196. package/src/social/screens/VisitorUsageLimit/styles.ts +45 -0
@@ -15,6 +15,7 @@ import AmityCreatePostMenuComponent from '../CreatePostMenu';
15
15
  import TextKeyElement from '../../../../elements/TextKeyElement/TextKeyElement';
16
16
  import { usePopup } from '../../../../hooks/usePopup';
17
17
  import Popup from '../../../../components/PopupMenu/PopupMenu';
18
+ import useAuth from '../../../../../core/hooks/useAuth';
18
19
 
19
20
  type AmitySocialHomeTopNavigationComponentType = {
20
21
  activeTab: string;
@@ -29,6 +30,7 @@ const AmitySocialHomeTopNavigationComponent: FC<
29
30
  const theme = componentConfig.themeStyles;
30
31
  const { AmitySocialHomeTopNavigationComponentBehaviour } = useBehaviour();
31
32
  const { isOpen, setIsOpen, toggle } = usePopup();
33
+ const { isVisitorOrBot } = useAuth();
32
34
 
33
35
  const [myCommunitiesTab] = useUiKitConfig({
34
36
  page: PageID.social_home_page,
@@ -169,7 +171,7 @@ const AmitySocialHomeTopNavigationComponent: FC<
169
171
  >
170
172
  <Image source={searchIcon} style={styles.icon} />
171
173
  </TouchableOpacity>
172
- {activeTab !== exploreTab && (
174
+ {!isVisitorOrBot && activeTab !== exploreTab && (
173
175
  <TouchableOpacity
174
176
  style={styles.iconBtn}
175
177
  onPress={onPressCreate}
@@ -43,6 +43,7 @@ import NetInfo from '@react-native-community/netinfo';
43
43
  import { useToast } from '../../../../core/stores/slices/toastSlice';
44
44
  import MyAvatar from '../../../components/MyAvatar/MyAvatar';
45
45
  import { MAX_MENTION_USERS } from '../../../../core/constants';
46
+ import useAuth from '../../../../core/hooks/useAuth';
46
47
 
47
48
  import { SafeAreaView } from 'react-native-safe-area-context';
48
49
  import ErrorComponent from '../../../components/ErrorComponent/ErrorComponent';
@@ -73,6 +74,9 @@ const AmityPostDetailPage: FC<AmityPostDetailPageType> = ({
73
74
  }) => {
74
75
  const pageId = PageID.post_detail_page;
75
76
  const componentId = ComponentID.WildCardComponent;
77
+ // Web parity (CommentTray.canShowComposer): visitors never see the
78
+ // composer; comment rows stay visible and their actions toast on tap.
79
+ const { isVisitorOrBot } = useAuth();
76
80
  const disabledInteraction = false;
77
81
  const navigation =
78
82
  useNavigation<NativeStackNavigationProp<RootStackParamList>>();
@@ -285,7 +289,7 @@ const AmityPostDetailPage: FC<AmityPostDetailPageType> = ({
285
289
  </TouchableOpacity>
286
290
  </View>
287
291
  )}
288
- {!disabledInteraction && (
292
+ {!disabledInteraction && !isVisitorOrBot && (
289
293
  <View style={styles.InputWrap}>
290
294
  <MyAvatar style={styles.myAvatar} />
291
295
  <View style={styles.inputContainer}>
@@ -398,7 +402,7 @@ const AmityPostDetailPage: FC<AmityPostDetailPageType> = ({
398
402
  postData?.targetType === 'community' && postData?.targetId
399
403
  }
400
404
  postType="post"
401
- disabledInteraction={false}
405
+ disabledInteraction={disabledInteraction}
402
406
  ListHeaderComponent={
403
407
  postData && (
404
408
  <AmityPostContentComponent
@@ -35,6 +35,7 @@ import { PostMenu } from '../../../../components/PostMenu';
35
35
  import PinBadge from '../../../../elements/PinBadge';
36
36
  import AnnouncementBadge from '../../../../elements/AnnouncementBadge';
37
37
  import { Typography } from '../../../../../core/components/Typography/Typography';
38
+ import useAuth from '../../../../../core/hooks/useAuth';
38
39
 
39
40
  type AmityPostContentComponentProps = {
40
41
  post: Amity.Post;
@@ -74,6 +75,7 @@ const AmityPostContentComponent: FC<AmityPostContentComponentProps> = ({
74
75
  componentId: componentId,
75
76
  });
76
77
  const styles = useStyles(themeStyles);
78
+ const { isVisitorOrBot } = useAuth();
77
79
  const [textPost, setTextPost] = useState<string>('');
78
80
  const [communityData, setCommunityData] = useState<Amity.Community>(null);
79
81
  const navigation =
@@ -292,10 +294,11 @@ const AmityPostContentComponent: FC<AmityPostContentComponentProps> = ({
292
294
  category === AmityPostCategory.PIN_AND_ANNOUNCEMENT) && (
293
295
  <PinBadge componentId={ComponentID.post_content} />
294
296
  )}
295
- {AmityPostContentComponentStyle ===
296
- AmityPostContentComponentStyleEnum.feed && (
297
- <PostMenu post={post} pageId={pageId} componentId={componentId} />
298
- )}
297
+ {!isVisitorOrBot &&
298
+ AmityPostContentComponentStyle ===
299
+ AmityPostContentComponentStyleEnum.feed && (
300
+ <PostMenu post={post} pageId={pageId} componentId={componentId} />
301
+ )}
299
302
  </Pressable>
300
303
  <View>
301
304
  <View style={styles.bodySection}>
@@ -8,7 +8,7 @@ import {
8
8
  } from '@amityco/ts-sdk-react-native';
9
9
  import { AmityPostEngagementActionsSubComponentType } from './type';
10
10
  import { useStyles } from './styles';
11
- import { useAmityComponent } from '../../../../../hooks';
11
+ import { useAmityComponent, useGlobalBehavior } from '../../../../../hooks';
12
12
  import { PageID, ComponentID } from '../../../../../enums';
13
13
  import { SvgXml } from 'react-native-svg';
14
14
  import { likeReaction } from '../../../../../../core/assets/icons/xml';
@@ -34,6 +34,7 @@ const DetailStyle: FC<AmityPostEngagementActionsSubComponentType> = ({
34
34
  componentId: ComponentID.post_content,
35
35
  });
36
36
  const styles = useStyles(themeStyles);
37
+ const { handleGlobalBehavior } = useGlobalBehavior();
37
38
  const [postData, setPostData] = useState<Amity.Post>(null);
38
39
 
39
40
  const { shareLink, handleSharePress } = usePostShareAction({
@@ -95,6 +96,10 @@ const DetailStyle: FC<AmityPostEngagementActionsSubComponentType> = ({
95
96
  }
96
97
  }, [isLike, postId]);
97
98
 
99
+ const onPressReaction = useCallback(() => {
100
+ handleGlobalBehavior({ defaultBehavior: addReactionToPost });
101
+ }, [addReactionToPost, handleGlobalBehavior]);
102
+
98
103
  const onClickReactions = useCallback(() => {
99
104
  setIsReactionListVisible(true);
100
105
  }, []);
@@ -136,7 +141,7 @@ const DetailStyle: FC<AmityPostEngagementActionsSubComponentType> = ({
136
141
  </View>
137
142
  <View style={[styles.actionSection, styles.detailActionSection]}>
138
143
  <View style={styles.row}>
139
- <TouchableOpacity onPress={addReactionToPost} style={styles.likeBtn}>
144
+ <TouchableOpacity onPress={onPressReaction} style={styles.likeBtn}>
140
145
  {isLike ? (
141
146
  <SvgXml
142
147
  xml={likeReaction(themeStyles.colors.background)}
@@ -8,7 +8,7 @@ import {
8
8
  subscribeTopic,
9
9
  } from '@amityco/ts-sdk-react-native';
10
10
  import { useStyles } from './styles';
11
- import { useAmityComponent } from '../../../../../hooks';
11
+ import { useAmityComponent, useGlobalBehavior } from '../../../../../hooks';
12
12
  import { PageID, ComponentID } from '../../../../../enums';
13
13
  import { SvgXml } from 'react-native-svg';
14
14
  import { likeReaction } from '../../../../../../core/assets/icons/xml';
@@ -38,6 +38,7 @@ const FeedStyle: FC<AmityPostEngagementActionsSubComponentType> = ({
38
38
  });
39
39
  const styles = useStyles(themeStyles);
40
40
  const { AmityGlobalFeedComponentBehavior } = useBehaviour();
41
+ const { handleGlobalBehavior } = useGlobalBehavior();
41
42
  const navigation =
42
43
  useNavigation<NativeStackNavigationProp<RootStackParamList>>();
43
44
  const [postData, setPostData] = useState<Amity.Post>(null);
@@ -81,6 +82,10 @@ const FeedStyle: FC<AmityPostEngagementActionsSubComponentType> = ({
81
82
  }
82
83
  }, [isLike, postData, postId]);
83
84
 
85
+ const onPressReaction = useCallback(() => {
86
+ handleGlobalBehavior({ defaultBehavior: addReactionToPost });
87
+ }, [addReactionToPost, handleGlobalBehavior]);
88
+
84
89
  const onPressComment = useCallback(() => {
85
90
  if (AmityGlobalFeedComponentBehavior.goToPostDetailPage) {
86
91
  return AmityGlobalFeedComponentBehavior.goToPostDetailPage();
@@ -103,7 +108,7 @@ const FeedStyle: FC<AmityPostEngagementActionsSubComponentType> = ({
103
108
  return (
104
109
  <Pressable onPress={onPressComment} style={styles.actionSection}>
105
110
  <View style={styles.row}>
106
- <TouchableOpacity onPress={addReactionToPost} style={styles.likeBtn}>
111
+ <TouchableOpacity onPress={onPressReaction} style={styles.likeBtn}>
107
112
  {isLike ? (
108
113
  <SvgXml
109
114
  xml={likeReaction(themeStyles.colors.background)}
@@ -8,7 +8,7 @@ import { NativeStackNavigationProp } from '@react-navigation/native-stack';
8
8
  import { RootStackParamList } from '../../../../../../../core/routes/RouteParamList';
9
9
  import { UserRelationshipTab } from '../../../../../../types';
10
10
  import { useBehaviour } from '../../../../../../providers/BehaviourProvider';
11
- import { useBlockUser } from '../../../../../../hooks';
11
+ import { useBlockUser, useGlobalBehavior } from '../../../../../../hooks';
12
12
  import useAuth from '../../../../../../../core/hooks/useAuth';
13
13
  import { useFollowUser } from '../../../../../../hooks/queries/useFollowUser';
14
14
  import useSocialSettings from '../../../../../../../core/hooks/useSocialSettings';
@@ -31,6 +31,7 @@ export function useHeader(user?: Amity.User) {
31
31
  const { openBottomSheet, closeBottomSheet, bottomSheetHeight } =
32
32
  useBottomSheet();
33
33
  const { showToast } = useToast();
34
+ const { handleGlobalBehavior } = useGlobalBehavior();
34
35
  const {
35
36
  followUser,
36
37
  unfollowUser,
@@ -56,7 +57,9 @@ export function useHeader(user?: Amity.User) {
56
57
 
57
58
  const handleFollow = () => {
58
59
  if (!user?.userId) return;
59
- followUser(user.userId);
60
+ handleGlobalBehavior({
61
+ defaultBehavior: () => followUser(user.userId),
62
+ });
60
63
  };
61
64
 
62
65
  const handleUnfollow = () => {
@@ -35,3 +35,4 @@ export * from './usePostSubscription';
35
35
  export * from './useRoomSubscription';
36
36
  export * from './queries/useFlagPost';
37
37
  export * from './queries/useClosePoll';
38
+ export * from './useGlobalBehavior';
@@ -0,0 +1,39 @@
1
+ import { useCallback } from 'react';
2
+ import useAuth from '../../core/hooks/useAuth';
3
+ import { useBehaviour } from '../providers/BehaviourProvider';
4
+ import { useToast } from '../../core/stores/slices/toastSlice';
5
+ import { VISITOR_USER_ACTION_TOAST } from '../../core/constants';
6
+
7
+ const TOAST_DURATION = 3000;
8
+
9
+ /**
10
+ * Mirrors the Web UIKit's useGlobalBehavior: gate a restricted action behind
11
+ * the visitor/bot check. For signed-in users the default behaviour runs; for
12
+ * visitors the AmityGlobalBehaviour.handleVisitorUserAction override is
13
+ * called when provided, otherwise a "create an account or sign in" toast is
14
+ * shown.
15
+ */
16
+ export const useGlobalBehavior = () => {
17
+ const { isVisitorOrBot } = useAuth();
18
+ const { AmityGlobalBehaviour } = useBehaviour();
19
+ const { showToast } = useToast();
20
+
21
+ const handleGlobalBehavior = useCallback(
22
+ ({ defaultBehavior }: { defaultBehavior?: () => void }) => {
23
+ if (isVisitorOrBot) {
24
+ if (AmityGlobalBehaviour?.handleVisitorUserAction) {
25
+ return AmityGlobalBehaviour.handleVisitorUserAction();
26
+ }
27
+ return showToast({
28
+ message: VISITOR_USER_ACTION_TOAST,
29
+ type: 'informative',
30
+ duration: TOAST_DURATION,
31
+ });
32
+ }
33
+ return defaultBehavior?.();
34
+ },
35
+ [isVisitorOrBot, AmityGlobalBehaviour, showToast]
36
+ );
37
+
38
+ return { handleGlobalBehavior, isVisitorOrBot };
39
+ };
@@ -12,13 +12,14 @@ type UsePostPermissionParams = {
12
12
  };
13
13
 
14
14
  export function usePostPermission({ community }: UsePostPermissionParams) {
15
- const { client } = useAuth();
15
+ const { client, isVisitorOrBot } = useAuth();
16
16
  const [hasPostPermission, setHasPostPermission] = useState(false);
17
17
 
18
18
  const isOnlyAdminCanPost =
19
19
  community?.postSetting === CommunityPostSettings.ONLY_ADMIN_CAN_POST;
20
20
 
21
21
  useEffect(() => {
22
+ if (isVisitorOrBot) return;
22
23
  if (!community?.communityId || !client?.userId) return;
23
24
 
24
25
  CommunityRepository.Membership.getMembers(
@@ -41,6 +42,7 @@ export function usePostPermission({ community }: UsePostPermissionParams) {
41
42
  client?.userId,
42
43
  isOnlyAdminCanPost,
43
44
  community?.isJoined,
45
+ isVisitorOrBot,
44
46
  ]);
45
47
 
46
48
  return hasPostPermission;
@@ -4,17 +4,19 @@ import useSocialSettings from '../../core/hooks/useSocialSettings';
4
4
  import { checkStoryPermission, isAdmin } from '../utils/permissions';
5
5
 
6
6
  export function useStoryPermission(communityId?: string) {
7
- const { client } = useAuth();
7
+ const { client, isVisitorOrBot } = useAuth();
8
8
  const { socialSettings } = useSocialSettings();
9
9
  const user = useUser(client?.userId || '');
10
10
 
11
11
  const isGlobalAdmin = isAdmin(user?.roles);
12
12
 
13
- const hasStoryPermission = !communityId
14
- ? socialSettings?.story?.allowAllUserToCreateStory
15
- : socialSettings?.story?.allowAllUserToCreateStory ||
16
- isGlobalAdmin ||
17
- checkStoryPermission(client, communityId);
13
+ const hasStoryPermission =
14
+ !isVisitorOrBot &&
15
+ (!communityId
16
+ ? socialSettings?.story?.allowAllUserToCreateStory
17
+ : socialSettings?.story?.allowAllUserToCreateStory ||
18
+ isGlobalAdmin ||
19
+ checkStoryPermission(client, communityId));
18
20
 
19
21
  return { hasStoryPermission };
20
22
  }
@@ -2,6 +2,7 @@ export { default as AmityCreateStoryPage } from './features/story/Create';
2
2
  export { default as AmityDraftStoryPage } from './features/story/Draft/Draft';
3
3
  export { default as AmityViewStoryPage } from './features/story/View/View';
4
4
  export { default as AmitySocialHomePage } from './screens/SocialHomePage';
5
+ export { VisitorUsageLimit } from './screens/VisitorUsageLimit';
5
6
  export { default as AmitySocialGlobalSearchPage } from './screens/SocialGlobalSearch';
6
7
  export { default as AmityPostDetailPage } from './features/post/Detail';
7
8
  export { default as AmityPostTargetSelectionPage } from './features/post/TargetSelection';
@@ -14,6 +14,7 @@ export const BehaviourProvider = ({
14
14
  }: IBehavioudProviderProps) => {
15
15
  const defaultBehaviour = useMemo(
16
16
  () => ({
17
+ AmityGlobalBehaviour: {},
17
18
  AmitySocialHomePageBehaviour: {},
18
19
  AmityGlobalFeedComponentBehavior: {},
19
20
  AmityPostContentComponentBehavior: {},
@@ -1,5 +1,5 @@
1
1
  import * as React from 'react';
2
- import { useCallback, useRef, useState } from 'react';
2
+ import { useCallback, useEffect, useRef, useState } from 'react';
3
3
  import { StyleSheet, View } from 'react-native';
4
4
  import CustomSocialTab from '../../components/CustomSocialTab/CustomSocialTab';
5
5
  import { useUiKitConfig } from '../../hooks';
@@ -20,7 +20,7 @@ const PROFILE_TAB = 'Profile';
20
20
 
21
21
  const AmitySocialHomePage = () => {
22
22
  const theme = useTheme() as MyMD3Theme;
23
- const { client } = useAuth();
23
+ const { client, isVisitorOrBot } = useAuth();
24
24
 
25
25
  const styles = StyleSheet.create({
26
26
  container: {
@@ -55,6 +55,15 @@ const AmitySocialHomePage = () => {
55
55
  const [activeTab, setActiveTab] = useState<string>(newsFeedTab);
56
56
  const visitedTabs = useRef<Set<string>>(new Set([newsFeedTab]));
57
57
 
58
+ // Web parity (SocialHomePage): visitors land on the community browsing tab
59
+ // and never see Newsfeed / My Communities / Profile.
60
+ useEffect(() => {
61
+ if (isVisitorOrBot) {
62
+ visitedTabs.current.add(exploreTab);
63
+ setActiveTab(exploreTab);
64
+ }
65
+ }, [isVisitorOrBot, exploreTab]);
66
+
58
67
  const onTabChange = useCallback(
59
68
  (tabName: string) => {
60
69
  if (AmitySocialHomePageBehaviour?.onChooseTab)
@@ -85,21 +94,27 @@ const AmitySocialHomePage = () => {
85
94
  <CustomSocialTab
86
95
  activeTab={activeTab}
87
96
  onTabChange={onTabChange}
88
- tabNames={[newsFeedTab, exploreTab, myCommunitiesTab, PROFILE_TAB]}
97
+ tabNames={
98
+ isVisitorOrBot
99
+ ? [exploreTab]
100
+ : [newsFeedTab, exploreTab, myCommunitiesTab, PROFILE_TAB]
101
+ }
89
102
  />
90
103
  <Divider />
91
- <View style={tabStyle(newsFeedTab)}>
92
- <AmityNewsFeedComponent
93
- pageId={PageID.social_home_page}
94
- onPressExploreCommunity={onPressExploreCommunity}
95
- />
96
- </View>
104
+ {!isVisitorOrBot && (
105
+ <View style={tabStyle(newsFeedTab)}>
106
+ <AmityNewsFeedComponent
107
+ pageId={PageID.social_home_page}
108
+ onPressExploreCommunity={onPressExploreCommunity}
109
+ />
110
+ </View>
111
+ )}
97
112
  {visitedTabs.current.has(exploreTab) && (
98
113
  <View style={tabStyle(exploreTab)}>
99
114
  <AmityExploreComponent pageId={PageID.social_home_page} />
100
115
  </View>
101
116
  )}
102
- {visitedTabs.current.has(myCommunitiesTab) && (
117
+ {!isVisitorOrBot && visitedTabs.current.has(myCommunitiesTab) && (
103
118
  <View style={tabStyle(myCommunitiesTab)}>
104
119
  <AmityMyCommunitiesComponent
105
120
  pageId={PageID.social_home_page}
@@ -107,7 +122,7 @@ const AmitySocialHomePage = () => {
107
122
  />
108
123
  </View>
109
124
  )}
110
- {visitedTabs.current.has(PROFILE_TAB) && (
125
+ {!isVisitorOrBot && visitedTabs.current.has(PROFILE_TAB) && (
111
126
  <View style={tabStyle(PROFILE_TAB)}>
112
127
  <UserProfile inline stickyTab={false} userId={client?.userId ?? ''} />
113
128
  </View>
@@ -0,0 +1,81 @@
1
+ import { useCallback, useEffect } from 'react';
2
+ import { BackHandler, TouchableOpacity, View } from 'react-native';
3
+ import { SafeAreaView } from 'react-native-safe-area-context';
4
+ import { SvgXml } from 'react-native-svg';
5
+ import { useStyles } from './styles';
6
+ import { Typography } from '../../../core/components/Typography/Typography';
7
+ import { visitorLimit } from '../../../core/assets/icons';
8
+ import { useToast } from '../../../core/stores/slices/toastSlice';
9
+ import { useBehaviour } from '../../providers/BehaviourProvider';
10
+ import { VISITOR_USAGE_LIMIT_MESSAGE } from '../../../core/constants';
11
+
12
+ const TOAST_DURATION = 3000;
13
+
14
+ export function VisitorUsageLimit() {
15
+ const { styles, theme } = useStyles();
16
+ const { showToast } = useToast();
17
+ const { AmityGlobalBehaviour } = useBehaviour();
18
+
19
+ const showSignInToast = useCallback(() => {
20
+ showToast({
21
+ message: VISITOR_USAGE_LIMIT_MESSAGE.TOAST,
22
+ type: 'informative',
23
+ duration: TOAST_DURATION,
24
+ });
25
+ }, []);
26
+
27
+ // Toast appears on the initial usage-limit trigger only; a dismissed
28
+ // sign-in flow returning to this page must not re-show it.
29
+ useEffect(() => {
30
+ showSignInToast();
31
+ }, [showSignInToast]);
32
+
33
+ // Dead-end page: swallow the Android hardware back press so the user
34
+ // cannot navigate away from the error state.
35
+ useEffect(() => {
36
+ const subscription = BackHandler.addEventListener(
37
+ 'hardwareBackPress',
38
+ () => true
39
+ );
40
+ return () => subscription.remove();
41
+ }, []);
42
+
43
+ const onPressSignIn = () => {
44
+ if (AmityGlobalBehaviour?.handleVisitorUsageLimitSignIn) {
45
+ return AmityGlobalBehaviour.handleVisitorUsageLimitSignIn();
46
+ }
47
+ showSignInToast();
48
+ };
49
+
50
+ return (
51
+ <SafeAreaView style={styles.container} edges={['top', 'left']}>
52
+ <View style={styles.contentContainer}>
53
+ <SvgXml
54
+ accessible
55
+ accessibilityLabel="Usage limit reached"
56
+ width={60}
57
+ height={40}
58
+ style={styles.icon}
59
+ xml={visitorLimit()}
60
+ color={theme.colors.secondaryShade4}
61
+ />
62
+ <Typography.TitleBold style={styles.title}>
63
+ {VISITOR_USAGE_LIMIT_MESSAGE.TITLE}
64
+ </Typography.TitleBold>
65
+ <Typography.Caption style={styles.subtitle}>
66
+ {VISITOR_USAGE_LIMIT_MESSAGE.SUBTITLE}
67
+ </Typography.Caption>
68
+ <TouchableOpacity
69
+ style={styles.signInButton}
70
+ onPress={onPressSignIn}
71
+ accessibilityRole="button"
72
+ accessibilityLabel={VISITOR_USAGE_LIMIT_MESSAGE.SIGN_IN}
73
+ >
74
+ <Typography.BodyBold style={styles.signInText}>
75
+ {VISITOR_USAGE_LIMIT_MESSAGE.SIGN_IN}
76
+ </Typography.BodyBold>
77
+ </TouchableOpacity>
78
+ </View>
79
+ </SafeAreaView>
80
+ );
81
+ }
@@ -0,0 +1 @@
1
+ export { VisitorUsageLimit } from './VisitorUsageLimit';
@@ -0,0 +1,45 @@
1
+ import { StyleSheet } from 'react-native';
2
+ import { useTheme } from 'react-native-paper';
3
+ import type { MyMD3Theme } from '../../../core/providers/AmityUIKitProvider';
4
+
5
+ export const useStyles = () => {
6
+ const theme = useTheme<MyMD3Theme>();
7
+
8
+ const styles = StyleSheet.create({
9
+ container: {
10
+ flex: 1,
11
+ backgroundColor: theme.colors.background,
12
+ },
13
+ contentContainer: {
14
+ flex: 1,
15
+ alignItems: 'center',
16
+ paddingHorizontal: 32,
17
+ flexDirection: 'column',
18
+ justifyContent: 'center',
19
+ },
20
+ icon: {
21
+ marginBottom: 16,
22
+ },
23
+ title: {
24
+ maxWidth: 252,
25
+ textAlign: 'center',
26
+ color: theme.colors.baseShade3,
27
+ },
28
+ subtitle: {
29
+ maxWidth: 252,
30
+ textAlign: 'center',
31
+ color: theme.colors.baseShade3,
32
+ },
33
+ signInButton: {
34
+ marginTop: 16,
35
+ borderRadius: 8,
36
+ paddingVertical: 10,
37
+ paddingHorizontal: 16,
38
+ },
39
+ signInText: {
40
+ color: theme.colors.primary,
41
+ },
42
+ });
43
+
44
+ return { styles, theme };
45
+ };