@amityco/react-native-social-uikit 4.0.0-b295c41.0 → 4.0.0-c2327e7.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 (204) hide show
  1. package/lib/commonjs/components/CreatePostChooseTargetModal/CreatePostChooseTargetModal.js +1 -1
  2. package/lib/commonjs/components/CreatePostChooseTargetModal/CreatePostChooseTargetModal.js.map +1 -1
  3. package/lib/commonjs/components/MediaSection/index.js +3 -3
  4. package/lib/commonjs/components/MediaSection/index.js.map +1 -1
  5. package/lib/commonjs/components/PostTypeChoiceModal/PostTypeChoiceModal.js +14 -5
  6. package/lib/commonjs/components/PostTypeChoiceModal/PostTypeChoiceModal.js.map +1 -1
  7. package/lib/commonjs/components/PostTypeChoiceModal/style.js +1 -2
  8. package/lib/commonjs/components/PostTypeChoiceModal/style.js.map +1 -1
  9. package/lib/commonjs/components/Social/PostList/index.js +1 -3
  10. package/lib/commonjs/components/Social/PostList/index.js.map +1 -1
  11. package/lib/commonjs/index.js +6 -0
  12. package/lib/commonjs/index.js.map +1 -1
  13. package/lib/commonjs/screens/CreateLivestream/CreateLivestream.js +16 -16
  14. package/lib/commonjs/screens/CreateLivestream/CreateLivestream.js.map +1 -1
  15. package/lib/commonjs/screens/LivestreamPlayer/index.js +3 -6
  16. package/lib/commonjs/screens/LivestreamPlayer/index.js.map +1 -1
  17. package/lib/commonjs/svg/svg-xml-list.js +1 -1
  18. package/lib/commonjs/util/postTypeChecker.js.map +1 -1
  19. package/lib/commonjs/v4/PublicApi/Components/AmityCreatePostMenuComponent/AmityCreatePostMenuComponent.js +11 -9
  20. package/lib/commonjs/v4/PublicApi/Components/AmityCreatePostMenuComponent/AmityCreatePostMenuComponent.js.map +1 -1
  21. package/lib/commonjs/v4/PublicApi/Elements/ButtonWithIconElement/styles.js +3 -2
  22. package/lib/commonjs/v4/PublicApi/Elements/ButtonWithIconElement/styles.js.map +1 -1
  23. package/lib/commonjs/v4/PublicApi/Pages/AmityCommunityProfilePage/AmityCommunityProfilePage.js +28 -25
  24. package/lib/commonjs/v4/PublicApi/Pages/AmityCommunityProfilePage/AmityCommunityProfilePage.js.map +1 -1
  25. package/lib/commonjs/v4/PublicApi/Pages/AmityCommunityProfilePage/styles.js +2 -2
  26. package/lib/commonjs/v4/PublicApi/Pages/AmityCommunityProfilePage/styles.js.map +1 -1
  27. package/lib/commonjs/v4/PublicApi/Pages/AmityCreateLivestreamPage/AmityCreateLivestreamPage.js +206 -68
  28. package/lib/commonjs/v4/PublicApi/Pages/AmityCreateLivestreamPage/AmityCreateLivestreamPage.js.map +1 -1
  29. package/lib/commonjs/v4/PublicApi/Pages/AmityCreateLivestreamPage/RoomView.js +50 -0
  30. package/lib/commonjs/v4/PublicApi/Pages/AmityCreateLivestreamPage/RoomView.js.map +1 -0
  31. package/lib/commonjs/v4/PublicApi/Pages/AmityCreateLivestreamPage/styles.js +71 -3
  32. package/lib/commonjs/v4/PublicApi/Pages/AmityCreateLivestreamPage/styles.js.map +1 -1
  33. package/lib/commonjs/v4/PublicApi/Pages/AmityLivestreamPlayerPage/AmityLivestreamPlayerPage.js +120 -117
  34. package/lib/commonjs/v4/PublicApi/Pages/AmityLivestreamPlayerPage/AmityLivestreamPlayerPage.js.map +1 -1
  35. package/lib/commonjs/v4/PublicApi/Pages/AmityLivestreamPlayerPage/styles.js.map +1 -1
  36. package/lib/commonjs/v4/component/LivestreamContent/index.js +12 -12
  37. package/lib/commonjs/v4/component/LivestreamContent/index.js.map +1 -1
  38. package/lib/commonjs/v4/component/PostContent/index.js +4 -4
  39. package/lib/commonjs/v4/component/PostContent/index.js.map +1 -1
  40. package/lib/commonjs/v4/component/PostMenu/index.js +2 -2
  41. package/lib/commonjs/v4/component/PostMenu/index.js.map +1 -1
  42. package/lib/commonjs/v4/component/Toast/index.js +4 -4
  43. package/lib/commonjs/v4/component/Toast/index.js.map +1 -1
  44. package/lib/commonjs/v4/component/Toast/styles.js +2 -2
  45. package/lib/commonjs/v4/component/Toast/styles.js.map +1 -1
  46. package/lib/commonjs/v4/enum/roomStatus.js +14 -0
  47. package/lib/commonjs/v4/enum/roomStatus.js.map +1 -0
  48. package/lib/commonjs/v4/hook/index.js +22 -0
  49. package/lib/commonjs/v4/hook/index.js.map +1 -1
  50. package/lib/commonjs/v4/hook/useCustomRankingGlobalFeed.js +1 -3
  51. package/lib/commonjs/v4/hook/useCustomRankingGlobalFeed.js.map +1 -1
  52. package/lib/commonjs/v4/hook/usePostSubscription.js +38 -0
  53. package/lib/commonjs/v4/hook/usePostSubscription.js.map +1 -0
  54. package/lib/commonjs/v4/hook/useRoomSubscription.js +22 -0
  55. package/lib/commonjs/v4/hook/useRoomSubscription.js.map +1 -0
  56. package/lib/commonjs/v4/index.js +7 -0
  57. package/lib/commonjs/v4/index.js.map +1 -1
  58. package/lib/commonjs/v4/stores/slices/toast.js +4 -1
  59. package/lib/commonjs/v4/stores/slices/toast.js.map +1 -1
  60. package/lib/module/components/CreatePostChooseTargetModal/CreatePostChooseTargetModal.js +1 -1
  61. package/lib/module/components/CreatePostChooseTargetModal/CreatePostChooseTargetModal.js.map +1 -1
  62. package/lib/module/components/MediaSection/index.js +3 -3
  63. package/lib/module/components/MediaSection/index.js.map +1 -1
  64. package/lib/module/components/PostTypeChoiceModal/PostTypeChoiceModal.js +15 -8
  65. package/lib/module/components/PostTypeChoiceModal/PostTypeChoiceModal.js.map +1 -1
  66. package/lib/module/components/PostTypeChoiceModal/style.js +1 -2
  67. package/lib/module/components/PostTypeChoiceModal/style.js.map +1 -1
  68. package/lib/module/components/Social/PostList/index.js +1 -3
  69. package/lib/module/components/Social/PostList/index.js.map +1 -1
  70. package/lib/module/index.js +2 -6
  71. package/lib/module/index.js.map +1 -1
  72. package/lib/module/screens/CreateLivestream/CreateLivestream.js +17 -17
  73. package/lib/module/screens/CreateLivestream/CreateLivestream.js.map +1 -1
  74. package/lib/module/screens/LivestreamPlayer/index.js +4 -8
  75. package/lib/module/screens/LivestreamPlayer/index.js.map +1 -1
  76. package/lib/module/svg/svg-xml-list.js +1 -1
  77. package/lib/module/util/postTypeChecker.js.map +1 -1
  78. package/lib/module/v4/PublicApi/Components/AmityCreatePostMenuComponent/AmityCreatePostMenuComponent.js +11 -9
  79. package/lib/module/v4/PublicApi/Components/AmityCreatePostMenuComponent/AmityCreatePostMenuComponent.js.map +1 -1
  80. package/lib/module/v4/PublicApi/Elements/ButtonWithIconElement/styles.js +3 -2
  81. package/lib/module/v4/PublicApi/Elements/ButtonWithIconElement/styles.js.map +1 -1
  82. package/lib/module/v4/PublicApi/Pages/AmityCommunityProfilePage/AmityCommunityProfilePage.js +29 -26
  83. package/lib/module/v4/PublicApi/Pages/AmityCommunityProfilePage/AmityCommunityProfilePage.js.map +1 -1
  84. package/lib/module/v4/PublicApi/Pages/AmityCommunityProfilePage/styles.js +2 -2
  85. package/lib/module/v4/PublicApi/Pages/AmityCommunityProfilePage/styles.js.map +1 -1
  86. package/lib/module/v4/PublicApi/Pages/AmityCreateLivestreamPage/AmityCreateLivestreamPage.js +211 -72
  87. package/lib/module/v4/PublicApi/Pages/AmityCreateLivestreamPage/AmityCreateLivestreamPage.js.map +1 -1
  88. package/lib/module/v4/PublicApi/Pages/AmityCreateLivestreamPage/RoomView.js +42 -0
  89. package/lib/module/v4/PublicApi/Pages/AmityCreateLivestreamPage/RoomView.js.map +1 -0
  90. package/lib/module/v4/PublicApi/Pages/AmityCreateLivestreamPage/styles.js +71 -3
  91. package/lib/module/v4/PublicApi/Pages/AmityCreateLivestreamPage/styles.js.map +1 -1
  92. package/lib/module/v4/PublicApi/Pages/AmityLivestreamPlayerPage/AmityLivestreamPlayerPage.js +123 -120
  93. package/lib/module/v4/PublicApi/Pages/AmityLivestreamPlayerPage/AmityLivestreamPlayerPage.js.map +1 -1
  94. package/lib/module/v4/PublicApi/Pages/AmityLivestreamPlayerPage/styles.js.map +1 -1
  95. package/lib/module/v4/component/LivestreamContent/index.js +13 -13
  96. package/lib/module/v4/component/LivestreamContent/index.js.map +1 -1
  97. package/lib/module/v4/component/PostContent/index.js +4 -4
  98. package/lib/module/v4/component/PostContent/index.js.map +1 -1
  99. package/lib/module/v4/component/PostMenu/index.js +2 -2
  100. package/lib/module/v4/component/PostMenu/index.js.map +1 -1
  101. package/lib/module/v4/component/Toast/index.js +4 -4
  102. package/lib/module/v4/component/Toast/index.js.map +1 -1
  103. package/lib/module/v4/component/Toast/styles.js +2 -2
  104. package/lib/module/v4/component/Toast/styles.js.map +1 -1
  105. package/lib/module/v4/enum/roomStatus.js +8 -0
  106. package/lib/module/v4/enum/roomStatus.js.map +1 -0
  107. package/lib/module/v4/hook/index.js +2 -0
  108. package/lib/module/v4/hook/index.js.map +1 -1
  109. package/lib/module/v4/hook/useCustomRankingGlobalFeed.js +1 -3
  110. package/lib/module/v4/hook/useCustomRankingGlobalFeed.js.map +1 -1
  111. package/lib/module/v4/hook/usePostSubscription.js +31 -0
  112. package/lib/module/v4/hook/usePostSubscription.js.map +1 -0
  113. package/lib/module/v4/hook/useRoomSubscription.js +15 -0
  114. package/lib/module/v4/hook/useRoomSubscription.js.map +1 -0
  115. package/lib/module/v4/index.js +1 -1
  116. package/lib/module/v4/index.js.map +1 -1
  117. package/lib/module/v4/stores/slices/toast.js +4 -1
  118. package/lib/module/v4/stores/slices/toast.js.map +1 -1
  119. package/lib/typescript/src/components/MediaSection/index.d.ts.map +1 -1
  120. package/lib/typescript/src/components/PostTypeChoiceModal/style.d.ts +1 -2
  121. package/lib/typescript/src/components/PostTypeChoiceModal/style.d.ts.map +1 -1
  122. package/lib/typescript/src/components/Social/PostList/index.d.ts +1 -3
  123. package/lib/typescript/src/components/Social/PostList/index.d.ts.map +1 -1
  124. package/lib/typescript/src/index.d.ts +2 -2
  125. package/lib/typescript/src/index.d.ts.map +1 -1
  126. package/lib/typescript/src/screens/LivestreamPlayer/index.d.ts.map +1 -1
  127. package/lib/typescript/src/util/postTypeChecker.d.ts +1 -1
  128. package/lib/typescript/src/util/postTypeChecker.d.ts.map +1 -1
  129. package/lib/typescript/src/v4/PublicApi/Components/AmityPostContentComponent/AmityPostContentComponent.d.ts +1 -3
  130. package/lib/typescript/src/v4/PublicApi/Components/AmityPostContentComponent/AmityPostContentComponent.d.ts.map +1 -1
  131. package/lib/typescript/src/v4/PublicApi/Elements/ButtonWithIconElement/styles.d.ts +1 -0
  132. package/lib/typescript/src/v4/PublicApi/Elements/ButtonWithIconElement/styles.d.ts.map +1 -1
  133. package/lib/typescript/src/v4/PublicApi/Pages/AmityCommunityProfilePage/AmityCommunityProfilePage.d.ts.map +1 -1
  134. package/lib/typescript/src/v4/PublicApi/Pages/AmityCommunityProfilePage/styles.d.ts +1 -1
  135. package/lib/typescript/src/v4/PublicApi/Pages/AmityCreateLivestreamPage/AmityCreateLivestreamPage.d.ts.map +1 -1
  136. package/lib/typescript/src/v4/PublicApi/Pages/AmityCreateLivestreamPage/RoomView.d.ts +8 -0
  137. package/lib/typescript/src/v4/PublicApi/Pages/AmityCreateLivestreamPage/RoomView.d.ts.map +1 -0
  138. package/lib/typescript/src/v4/PublicApi/Pages/AmityCreateLivestreamPage/styles.d.ts +70 -2
  139. package/lib/typescript/src/v4/PublicApi/Pages/AmityCreateLivestreamPage/styles.d.ts.map +1 -1
  140. package/lib/typescript/src/v4/PublicApi/Pages/AmityLivestreamPlayerPage/AmityLivestreamPlayerPage.d.ts.map +1 -1
  141. package/lib/typescript/src/v4/PublicApi/Pages/AmityLivestreamPlayerPage/styles.d.ts.map +1 -1
  142. package/lib/typescript/src/v4/component/LivestreamContent/index.d.ts +1 -1
  143. package/lib/typescript/src/v4/component/LivestreamContent/index.d.ts.map +1 -1
  144. package/lib/typescript/src/v4/component/PostContent/index.d.ts.map +1 -1
  145. package/lib/typescript/src/v4/component/Toast/styles.d.ts +1 -1
  146. package/lib/typescript/src/v4/component/Toast/styles.d.ts.map +1 -1
  147. package/lib/typescript/src/v4/enum/roomStatus.d.ts +8 -0
  148. package/lib/typescript/src/v4/enum/roomStatus.d.ts.map +1 -0
  149. package/lib/typescript/src/v4/hook/index.d.ts +2 -0
  150. package/lib/typescript/src/v4/hook/index.d.ts.map +1 -1
  151. package/lib/typescript/src/v4/hook/usePendingPostQuery.d.ts +3 -0
  152. package/lib/typescript/src/v4/hook/usePendingPostQuery.d.ts.map +1 -1
  153. package/lib/typescript/src/v4/hook/usePostSubscription.d.ts +4 -0
  154. package/lib/typescript/src/v4/hook/usePostSubscription.d.ts.map +1 -0
  155. package/lib/typescript/src/v4/hook/useRoomSubscription.d.ts +4 -0
  156. package/lib/typescript/src/v4/hook/useRoomSubscription.d.ts.map +1 -0
  157. package/lib/typescript/src/v4/index.d.ts +1 -0
  158. package/lib/typescript/src/v4/index.d.ts.map +1 -1
  159. package/lib/typescript/src/v4/routes/RouteParamList.d.ts +1 -1
  160. package/lib/typescript/src/v4/routes/RouteParamList.d.ts.map +1 -1
  161. package/lib/typescript/src/v4/stores/slices/toast.d.ts +1 -0
  162. package/lib/typescript/src/v4/stores/slices/toast.d.ts.map +1 -1
  163. package/package.json +6 -3
  164. package/src/components/CreatePostChooseTargetModal/CreatePostChooseTargetModal.tsx +1 -1
  165. package/src/components/MediaSection/index.tsx +4 -6
  166. package/src/components/PostTypeChoiceModal/PostTypeChoiceModal.tsx +15 -15
  167. package/src/components/PostTypeChoiceModal/style.ts +1 -2
  168. package/src/components/Social/PostList/index.tsx +1 -4
  169. package/src/index.tsx +2 -2
  170. package/src/screens/CreateLivestream/CreateLivestream.tsx +17 -17
  171. package/src/screens/LivestreamPlayer/index.tsx +9 -15
  172. package/src/svg/svg-xml-list.ts +1 -1
  173. package/src/util/postTypeChecker.ts +1 -1
  174. package/src/v4/PublicApi/Components/AmityCreatePostMenuComponent/AmityCreatePostMenuComponent.tsx +10 -10
  175. package/src/v4/PublicApi/Components/AmityPostContentComponent/AmityPostContentComponent.tsx +1 -1
  176. package/src/v4/PublicApi/Elements/ButtonWithIconElement/styles.ts +3 -2
  177. package/src/v4/PublicApi/Pages/AmityCommunityProfilePage/AmityCommunityProfilePage.tsx +24 -25
  178. package/src/v4/PublicApi/Pages/AmityCommunityProfilePage/styles.ts +2 -2
  179. package/src/v4/PublicApi/Pages/AmityCreateLivestreamPage/AmityCreateLivestreamPage.tsx +241 -89
  180. package/src/v4/PublicApi/Pages/AmityCreateLivestreamPage/RoomView.tsx +48 -0
  181. package/src/v4/PublicApi/Pages/AmityCreateLivestreamPage/styles.ts +72 -3
  182. package/src/v4/PublicApi/Pages/AmityLivestreamPlayerPage/AmityLivestreamPlayerPage.tsx +135 -148
  183. package/src/v4/PublicApi/Pages/AmityLivestreamPlayerPage/styles.ts +1 -0
  184. package/src/v4/component/LivestreamContent/index.tsx +21 -22
  185. package/src/v4/component/PostContent/index.tsx +6 -8
  186. package/src/v4/component/PostMenu/index.tsx +2 -2
  187. package/src/v4/component/Toast/index.tsx +1 -1
  188. package/src/v4/component/Toast/styles.ts +2 -2
  189. package/src/v4/enum/roomStatus.ts +7 -0
  190. package/src/v4/hook/index.ts +2 -0
  191. package/src/v4/hook/useCustomRankingGlobalFeed.ts +1 -1
  192. package/src/v4/hook/usePostSubscription.ts +34 -0
  193. package/src/v4/hook/useRoomSubscription.ts +19 -0
  194. package/src/v4/index.tsx +1 -1
  195. package/src/v4/routes/RouteParamList.tsx +1 -1
  196. package/src/v4/stores/slices/toast.ts +5 -0
  197. package/uikit.config.json +1 -1
  198. package/lib/commonjs/v4/enum/livestreamStatus.js +0 -13
  199. package/lib/commonjs/v4/enum/livestreamStatus.js.map +0 -1
  200. package/lib/module/v4/enum/livestreamStatus.js +0 -7
  201. package/lib/module/v4/enum/livestreamStatus.js.map +0 -1
  202. package/lib/typescript/src/v4/enum/livestreamStatus.d.ts +0 -7
  203. package/lib/typescript/src/v4/enum/livestreamStatus.d.ts.map +0 -1
  204. package/src/v4/enum/livestreamStatus.ts +0 -6
@@ -1,131 +1,75 @@
1
- import React, { useEffect, useRef, useState } from 'react';
2
- import {
3
- View,
4
- TouchableOpacity,
5
- TouchableWithoutFeedback,
6
- useAnimatedValue,
7
- } from 'react-native';
1
+ import React, { useEffect, useState, useRef } from 'react';
2
+ import { View, TouchableOpacity } from 'react-native';
8
3
  import { useStyles } from './styles';
9
- // @ts-ignore
10
- // import { AmityStreamPlayer } from '@amityco/video-player-react-native';
11
4
  import LiveStreamEndThumbnail from '../../../component/LivestreamContent/LivestreamEndedThumbnail';
12
- import { Animated } from 'react-native';
13
5
  import { SvgXml } from 'react-native-svg';
14
- import {
15
- getPostTopic,
16
- PostRepository,
17
- StreamRepository,
18
- subscribeTopic,
19
- } from '@amityco/ts-sdk-react-native';
20
- import { close, pause, resume } from '../../../assets/icons';
6
+ import { RoomRepository } from '@amityco/ts-sdk-react-native';
7
+ import { close } from '../../../assets/icons';
21
8
  import { RouteProp, useNavigation, useRoute } from '@react-navigation/native';
22
9
  import { NativeStackNavigationProp } from '@react-navigation/native-stack';
23
10
  import { RootStackParamList } from '../../../routes/RouteParamList';
24
- import { LivestreamStatus } from '../../../enum/livestreamStatus';
11
+ import { RoomStatus } from '../../../enum/roomStatus';
25
12
  import LiveStreamIdleThumbnail from '../../../component/LivestreamContent/LivestreamIdleThumbnail';
26
13
  import { Typography } from '../../../component/Typography/Typography';
27
14
  import { SafeAreaView } from 'react-native-safe-area-context';
28
15
  import NetInfo from '@react-native-community/netinfo';
29
16
  import { CircularProgressIndicator } from '../../../component/CircularProgressIndicator';
30
- const usePostSubscription = (postId: string) => {
31
- const [subscribedPost, setSubscribedPost] = useState<Amity.Post>(null);
32
-
33
- useEffect(() => {
34
- let unsubscribe: () => void;
35
- if (postId) {
36
- unsubscribe = PostRepository.getPost(postId, ({ data }) => {
37
- setSubscribedPost(data);
38
- });
39
- }
40
- return () => {
41
- unsubscribe && unsubscribe();
42
- };
43
- }, [postId]);
44
-
45
- useEffect(() => {
46
- let unsubscribe: () => void;
47
- if (subscribedPost) {
48
- unsubscribe = subscribeTopic(getPostTopic(subscribedPost));
49
- }
50
- return () => {
51
- unsubscribe && unsubscribe();
52
- };
53
- }, [subscribedPost]);
54
-
55
- return { subscribedPost };
56
- };
17
+ import Video from 'react-native-video';
18
+ import useAuth from '../../../../hooks/useAuth';
19
+ import {
20
+ usePostSubscription,
21
+ useRoomSubscription,
22
+ } from '../../../../v4/hook/index';
57
23
 
58
24
  function AmityLiveStreamPlayerPage() {
59
- const ref = useRef<any>(null);
60
25
  const { styles, theme } = useStyles();
61
- const controlOpacity = useAnimatedValue(0);
62
26
  const navigation =
63
27
  useNavigation<NativeStackNavigationProp<RootStackParamList>>();
64
28
  const route = useRoute<RouteProp<RootStackParamList, 'LivestreamPlayer'>>();
65
29
 
66
- const [error, setError] = useState<any>(null);
67
- const [isPlaying, setIsPlaying] = useState(true);
68
30
  const [reconnecting, setReconnecting] = useState(false);
69
- const [livestream, setLivestream] = useState<Amity.Stream>();
70
-
71
- const { streamId, post } = route.params;
31
+ const [room, setRoom] = useState<Amity.Room | null>(null);
32
+ const [error, setError] = useState<Error | null>(null);
33
+ const [wasLive, setWasLive] = useState(false);
34
+ const [showEndThumbnail, setShowEndThumbnail] = useState(false);
35
+ const { roomId, post } = route.params;
36
+ const { client } = useAuth();
37
+ const videoRef = useRef<any>(null);
38
+ const isProgrammaticDismiss = useRef(false);
72
39
 
73
40
  const { subscribedPost } = usePostSubscription(post?.postId);
74
41
 
75
- const onStopPlayer = () => {
76
- ref.current && ref.current.pause();
77
- setIsPlaying(false);
78
- };
79
-
80
- const onStartPlayer = () => {
81
- ref.current && ref.current.play();
82
- setIsPlaying(true);
83
- };
84
-
85
- const onPressControlButton = () => {
86
- isPlaying ? onStopPlayer() : onStartPlayer();
87
- };
88
-
89
- const onToggleControl = () => {
90
- controlOpacity.stopAnimation((currentValue) => {
91
- Animated.timing(controlOpacity, {
92
- toValue: currentValue === 0 ? 1 : 0,
93
- duration: 300,
94
- useNativeDriver: false,
95
- }).start();
96
- });
97
- };
42
+ useRoomSubscription({ room });
98
43
 
99
44
  useEffect(() => {
100
- const unsubscribe = StreamRepository.getStreamById(
101
- streamId,
45
+ const unsubscribe = RoomRepository.getRoom(
46
+ roomId,
102
47
  ({ data, loading, error: streamError }) => {
103
48
  if (streamError) setError(streamError);
104
- if (!loading && data) setLivestream({ ...data });
49
+ if (!loading && data) setRoom({ ...data });
105
50
  }
106
51
  );
107
52
 
108
53
  return () => unsubscribe();
109
- }, [streamId]);
54
+ }, [roomId]);
110
55
 
111
56
  useEffect(() => {
112
- if (livestream?.isDeleted || subscribedPost?.isDeleted) {
57
+ if (room?.isDeleted || subscribedPost?.isDeleted) {
113
58
  navigation.replace('PostDetail', { postId: subscribedPost?.postId });
114
59
  }
115
- }, [livestream?.isDeleted, subscribedPost, navigation]);
60
+ }, [room?.isDeleted, subscribedPost, navigation]);
116
61
 
117
62
  useEffect(() => {
118
63
  const isTerminated =
119
- livestream?.moderation?.terminateLabels &&
120
- livestream?.moderation?.terminateLabels?.length > 0;
64
+ room?.moderation?.terminateLabels &&
65
+ room?.moderation?.terminateLabels?.length > 0;
121
66
  const isLiveOrEnded =
122
- livestream?.status === LivestreamStatus.live ||
123
- livestream?.status === LivestreamStatus.ended;
67
+ room?.status === RoomStatus.live || room?.status === RoomStatus.ended;
124
68
 
125
69
  if (isLiveOrEnded && isTerminated) {
126
70
  navigation.replace('LivestreamTerminated', { type: 'viewer' });
127
71
  }
128
- }, [livestream?.moderation?.terminateLabels, livestream?.status, navigation]);
72
+ }, [room?.moderation?.terminateLabels, room?.status, navigation]);
129
73
 
130
74
  useEffect(() => {
131
75
  const unsubscribe = NetInfo.addEventListener((state) => {
@@ -134,24 +78,77 @@ function AmityLiveStreamPlayerPage() {
134
78
  return () => unsubscribe();
135
79
  }, []);
136
80
 
137
- if (!livestream || error)
81
+ // Track if user was watching live
82
+ useEffect(() => {
83
+ if (room?.status === RoomStatus.live) {
84
+ setWasLive(true);
85
+ }
86
+ }, [room?.status]);
87
+
88
+ // Dismiss fullscreen player when stream ends
89
+ useEffect(() => {
90
+ const shouldShowEndThumbnail =
91
+ room?.status === RoomStatus.ended ||
92
+ (room?.status === RoomStatus.recorded && wasLive);
93
+
94
+ console.log('shouldShowEndThumbnail =>', shouldShowEndThumbnail);
95
+ console.log('videoRef.current', videoRef.current);
96
+
97
+ if (shouldShowEndThumbnail && videoRef.current) {
98
+ console.log('Dismissing fullscreen player');
99
+ isProgrammaticDismiss.current = true;
100
+ videoRef.current?.dismissFullscreenPlayer();
101
+ // Delay showing end thumbnail to allow fullscreen dismiss to complete
102
+ setTimeout(() => {
103
+ setShowEndThumbnail(true);
104
+ }, 300);
105
+ } else if (shouldShowEndThumbnail && !videoRef.current) {
106
+ // If video ref is already null, show end thumbnail immediately
107
+ setShowEndThumbnail(true);
108
+ } else if (!shouldShowEndThumbnail) {
109
+ setShowEndThumbnail(false);
110
+ }
111
+ }, [room?.status, wasLive]);
112
+
113
+ // Start in fullscreen mode on iOS
114
+ useEffect(() => {
115
+ if (videoRef.current && room && room.status !== RoomStatus.ended) {
116
+ const timer = setTimeout(() => {
117
+ videoRef.current?.presentFullscreenPlayer();
118
+ }, 100);
119
+ return () => clearTimeout(timer);
120
+ }
121
+ return undefined;
122
+ }, [room]);
123
+
124
+ if (!room || error) {
138
125
  return (
139
126
  <SafeAreaView style={styles.container}>
140
127
  <LiveStreamIdleThumbnail />
141
128
  </SafeAreaView>
142
129
  );
130
+ }
131
+
132
+ const closePlayer = () => {
133
+ navigation.goBack();
134
+ };
135
+
136
+ const handleFullscreenDismiss = () => {
137
+ // Only navigate back if user manually dismissed, not programmatically
138
+ if (!isProgrammaticDismiss.current) {
139
+ closePlayer();
140
+ }
141
+ isProgrammaticDismiss.current = false;
142
+ };
143
143
 
144
144
  return (
145
145
  <SafeAreaView style={styles.container}>
146
- {livestream.status === LivestreamStatus.ended ? (
146
+ {showEndThumbnail ? (
147
147
  <>
148
148
  <View style={styles.steamEndContainer}>
149
149
  <LiveStreamEndThumbnail />
150
150
  </View>
151
- <TouchableOpacity
152
- style={styles.closeButton}
153
- onPress={navigation.goBack}
154
- >
151
+ <TouchableOpacity style={styles.closeButton} onPress={closePlayer}>
155
152
  <SvgXml
156
153
  xml={close()}
157
154
  width="28"
@@ -160,14 +157,52 @@ function AmityLiveStreamPlayerPage() {
160
157
  />
161
158
  </TouchableOpacity>
162
159
  </>
163
- ) : // <AmityStreamPlayer
164
- // ref={ref}
165
- // stream={livestream}
166
- // onBack={navigation.goBack}
167
- // status={livestream.status === 'live' ? 'live' : 'recorded'}
168
- // />
169
- null}
170
- {livestream.status === LivestreamStatus.live && reconnecting && (
160
+ ) : (
161
+ <View style={styles.container}>
162
+ {(room.status === RoomStatus.live ||
163
+ room.status === RoomStatus.waiting_reconnect) && (
164
+ <View style={styles.indicator}>
165
+ <View style={styles.status}>
166
+ <Typography.CaptionBold style={styles.live}>
167
+ LIVE
168
+ </Typography.CaptionBold>
169
+ </View>
170
+ </View>
171
+ )}
172
+ <Video
173
+ ref={videoRef}
174
+ source={{
175
+ uri:
176
+ room.status === RoomStatus.recorded
177
+ ? room.recordedPlaybackInfos[0]?.url
178
+ : room.livePlaybackUrl,
179
+ headers: {
180
+ Authorization: `Bearer ${client.token.accessToken}`,
181
+ },
182
+
183
+ type: 'm3u8',
184
+ }}
185
+ style={styles.container}
186
+ resizeMode="contain"
187
+ controls={room.status === RoomStatus.recorded}
188
+ fullscreen={true}
189
+ fullscreenOrientation="landscape"
190
+ paused={false}
191
+ muted={false}
192
+ volume={1.0}
193
+ audioOutput="speaker"
194
+ playInBackground={false}
195
+ playWhenInactive={false}
196
+ onError={(e) => {
197
+ console.log('Video Player Error: ', e);
198
+ }}
199
+ onFullscreenPlayerDidDismiss={handleFullscreenDismiss}
200
+ />
201
+ </View>
202
+ )}
203
+
204
+ {((room.status === RoomStatus.live && reconnecting) ||
205
+ room.status === RoomStatus.waiting_reconnect) && (
171
206
  <View style={styles.connecting}>
172
207
  <CircularProgressIndicator size={40} strokeWidth={2} />
173
208
  <Typography.TitleBold style={styles.text}>
@@ -179,54 +214,6 @@ function AmityLiveStreamPlayerPage() {
179
214
  </Typography.Caption>
180
215
  </View>
181
216
  )}
182
- {livestream.status === LivestreamStatus.live && (
183
- <>
184
- <View style={styles.indicator}>
185
- <View style={styles.status}>
186
- <Typography.CaptionBold style={styles.live}>
187
- LIVE
188
- </Typography.CaptionBold>
189
- </View>
190
- </View>
191
- <TouchableWithoutFeedback onPress={onToggleControl}>
192
- <Animated.View
193
- style={[styles.control, { opacity: controlOpacity }]}
194
- >
195
- <TouchableOpacity
196
- style={styles.closeButton}
197
- onPress={navigation.goBack}
198
- >
199
- <SvgXml
200
- xml={close()}
201
- width="28"
202
- height="28"
203
- color={theme.colors.background}
204
- />
205
- </TouchableOpacity>
206
-
207
- <View style={styles.controller}>
208
- <TouchableOpacity onPress={onPressControlButton}>
209
- {isPlaying ? (
210
- <SvgXml
211
- width={32}
212
- height={32}
213
- xml={pause()}
214
- color={theme.colors.background}
215
- />
216
- ) : (
217
- <SvgXml
218
- width={32}
219
- height={32}
220
- xml={resume()}
221
- color={theme.colors.background}
222
- />
223
- )}
224
- </TouchableOpacity>
225
- </View>
226
- </Animated.View>
227
- </TouchableWithoutFeedback>
228
- </>
229
- )}
230
217
  </SafeAreaView>
231
218
  );
232
219
  }
@@ -13,6 +13,7 @@ export const useStyles = () => {
13
13
  position: 'relative',
14
14
  backgroundColor: '#000000',
15
15
  },
16
+
16
17
  steamEndContainer: {
17
18
  flex: 1,
18
19
  justifyContent: 'center',
@@ -7,14 +7,14 @@ import {
7
7
  ImageStyle,
8
8
  } from 'react-native';
9
9
  import React, { useEffect, useState, useCallback, Fragment } from 'react';
10
- import { FileRepository, StreamRepository } from '@amityco/ts-sdk-react-native';
10
+ import { FileRepository, RoomRepository } from '@amityco/ts-sdk-react-native';
11
11
  import { useStyles } from './styles';
12
12
  import { useNavigation } from '@react-navigation/native';
13
13
  import { SvgXml } from 'react-native-svg';
14
14
  import type { NativeStackNavigationProp } from '@react-navigation/native-stack';
15
15
  import { play } from '../../assets/icons';
16
16
  import { Typography } from '../Typography/Typography';
17
- import { LivestreamStatus } from '../../enum/livestreamStatus';
17
+ import { RoomStatus } from '../../enum/roomStatus';
18
18
  import LiveStreamEndThumbnail from './LivestreamEndedThumbnail';
19
19
  import LiveStreamIdleThumbnail from './LivestreamIdleThumbnail';
20
20
  import RenderTextWithMention from '../RenderTextWithMention/RenderTextWithMention';
@@ -22,14 +22,14 @@ import { RootStackParamList } from '../../routes/RouteParamList';
22
22
  import LiveStreamTerminatedThumbnail from './LivestreamTerminatedThumbnail';
23
23
 
24
24
  interface ILivestreamContent {
25
- streamId: Amity.Stream['streamId'];
25
+ roomId: Amity.Room['roomId'];
26
26
  onPressPost: () => void;
27
27
  post: Amity.Post;
28
28
  }
29
29
 
30
30
  const LivestreamContent: React.FC<ILivestreamContent> = ({
31
31
  post,
32
- streamId,
32
+ roomId,
33
33
  onPressPost,
34
34
  }) => {
35
35
  const { styles, theme } = useStyles();
@@ -39,18 +39,18 @@ const LivestreamContent: React.FC<ILivestreamContent> = ({
39
39
  >();
40
40
 
41
41
  const [error, setError] = useState<boolean>(false);
42
- const [livestream, setLivestream] = useState<Amity.Stream>();
42
+ const [livestream, setLivestream] = useState<Amity.Room>();
43
43
  const [thumbnailUrl, setThumbnailUrl] = useState<ImageSourcePropType>();
44
44
  const [isUpcoming, setIsUpcoming] = useState<boolean>(false);
45
45
 
46
46
  const onPlayLivestream = useCallback(() => {
47
47
  navigation.navigate('LivestreamPlayer', {
48
48
  post,
49
- streamId: livestream.streamId,
49
+ roomId: livestream.roomId,
50
50
  });
51
51
  }, [livestream, navigation, post]);
52
52
 
53
- const getLivestreamThumbnail = async (currentStream: Amity.Stream) => {
53
+ const getLivestreamThumbnail = async (currentStream: Amity.Room) => {
54
54
  const defaultThumbnail = require('../../assets/images/livestream.png');
55
55
 
56
56
  if (currentStream.thumbnailFileId) {
@@ -71,8 +71,8 @@ const LivestreamContent: React.FC<ILivestreamContent> = ({
71
71
 
72
72
  useEffect(() => {
73
73
  setIsUpcoming(true);
74
- const unsubscribe = StreamRepository.getStreamById(
75
- streamId,
74
+ const unsubscribe = RoomRepository.getRoom(
75
+ roomId,
76
76
  ({ data, loading, error: streamError }) => {
77
77
  if (streamError) setError(!!streamError);
78
78
  if (!loading && data) {
@@ -86,13 +86,13 @@ const LivestreamContent: React.FC<ILivestreamContent> = ({
86
86
  return () => {
87
87
  unsubscribe();
88
88
  };
89
- }, [streamId]);
89
+ }, [roomId]);
90
90
 
91
91
  if (!livestream) return null;
92
92
 
93
93
  if (error || livestream?.isDeleted) {
94
94
  return (
95
- <View key={livestream.streamId} style={styles.container}>
95
+ <View key={livestream.roomId} style={styles.container}>
96
96
  <LiveStreamIdleThumbnail />
97
97
  </View>
98
98
  );
@@ -102,12 +102,12 @@ const LivestreamContent: React.FC<ILivestreamContent> = ({
102
102
  livestream?.moderation?.terminateLabels &&
103
103
  livestream?.moderation?.terminateLabels?.length > 0;
104
104
  const isLiveOrEnded =
105
- livestream?.status === LivestreamStatus.live ||
106
- livestream?.status === LivestreamStatus.ended;
105
+ livestream?.status === RoomStatus.live ||
106
+ livestream?.status === RoomStatus.ended;
107
107
 
108
108
  if (isTerminated && isLiveOrEnded) {
109
109
  return (
110
- <View key={livestream.streamId} style={styles.container}>
110
+ <View key={livestream.roomId} style={styles.container}>
111
111
  <LiveStreamTerminatedThumbnail />
112
112
  </View>
113
113
  );
@@ -129,7 +129,7 @@ const LivestreamContent: React.FC<ILivestreamContent> = ({
129
129
  )}
130
130
  </Pressable>
131
131
  <View style={styles.container}>
132
- {(livestream.status === LivestreamStatus.idle || isUpcoming) &&
132
+ {(livestream.status === RoomStatus.idle || isUpcoming) &&
133
133
  thumbnailUrl && (
134
134
  <View style={styles.content}>
135
135
  <Image
@@ -144,12 +144,10 @@ const LivestreamContent: React.FC<ILivestreamContent> = ({
144
144
  </View>
145
145
  )}
146
146
 
147
- {livestream.status === LivestreamStatus.ended && (
148
- <LiveStreamEndThumbnail />
149
- )}
147
+ {livestream.status === RoomStatus.ended && <LiveStreamEndThumbnail />}
150
148
 
151
- {(livestream.status === LivestreamStatus.live ||
152
- livestream.status === LivestreamStatus.recorded) &&
149
+ {(livestream.status === RoomStatus.live ||
150
+ livestream.status === RoomStatus.recorded) &&
153
151
  thumbnailUrl &&
154
152
  !isUpcoming && (
155
153
  <View style={styles.content}>
@@ -157,14 +155,15 @@ const LivestreamContent: React.FC<ILivestreamContent> = ({
157
155
  source={thumbnailUrl}
158
156
  style={styles.streamImageCover as ImageStyle}
159
157
  />
160
- {livestream.status === LivestreamStatus.live && (
158
+ {(livestream.status === RoomStatus.live ||
159
+ livestream.status === RoomStatus.waiting_reconnect) && (
161
160
  <View style={styles.streamStatusLive}>
162
161
  <Typography.CaptionBold style={styles.streamStatusText}>
163
162
  LIVE
164
163
  </Typography.CaptionBold>
165
164
  </View>
166
165
  )}
167
- {livestream.status === LivestreamStatus.recorded && (
166
+ {livestream.status === RoomStatus.recorded && (
168
167
  <View style={styles.streamStatusRecorded}>
169
168
  <Typography.CaptionBold style={styles.streamStatusText}>
170
169
  RECORDED
@@ -43,9 +43,7 @@ const PostContent: React.FC<IPostContent> = ({
43
43
  const [imagePosts, setImagePosts] = useState<string[]>([]);
44
44
  const [videoPosts, setVideoPosts] = useState<IVideoPost[]>([]);
45
45
  const [pollIds, setPollIds] = useState<{ pollId: string }[]>([]);
46
- const [livestreamId, setLivestreamId] = useState<Amity.Stream['streamId'][]>(
47
- []
48
- );
46
+ const [livestreamId, setLivestreamId] = useState<Amity.Room['roomId'][]>([]);
49
47
 
50
48
  const [imagePostsFullSize, setImagePostsFullSize] = useState<MediaUri[]>([]);
51
49
  const [videoPostsFullSize, setVideoPostsFullSize] = useState<MediaUri[]>([]);
@@ -96,7 +94,7 @@ const PostContent: React.FC<IPostContent> = ({
96
94
  const images: string[] = [];
97
95
  const videos: IVideoPost[] = [];
98
96
  const polls: { pollId: string }[] = [];
99
- const livestreams: Amity.Stream['streamId'][] = [];
97
+ const livestreams: Amity.Room['roomId'][] = [];
100
98
 
101
99
  response.forEach((item) => {
102
100
  if (item?.dataType === 'image' && item?.data?.fileId) {
@@ -119,9 +117,9 @@ const PostContent: React.FC<IPostContent> = ({
119
117
  if (!polls.some((poll) => poll.pollId === item.data.pollId)) {
120
118
  polls.push(item.data);
121
119
  }
122
- } else if (item?.dataType === 'liveStream') {
123
- if (!livestreams.includes(item.data.streamId)) {
124
- livestreams.push(item.data.streamId);
120
+ } else if (item?.dataType === 'room') {
121
+ if (!livestreams.includes(item.data.roomId)) {
122
+ livestreams.push(item.data.roomId);
125
123
  }
126
124
  }
127
125
  });
@@ -344,7 +342,7 @@ const PostContent: React.FC<IPostContent> = ({
344
342
  <LivestreamContent
345
343
  post={post}
346
344
  onPressPost={onPressPost}
347
- streamId={livestreamId[0]}
345
+ roomId={livestreamId[0]}
348
346
  />
349
347
  ) : (
350
348
  renderMediaPosts()
@@ -255,7 +255,7 @@ export function PostMenu({ pageId, componentId, post }: PostMenuProps) {
255
255
  ],
256
256
  },
257
257
  (post?.creator?.userId === myId || isIAmModerator) &&
258
- ((childrenPost?.dataType !== 'liveStream' &&
258
+ ((childrenPost?.dataType !== 'room' &&
259
259
  childrenPost?.dataType !== 'poll') ||
260
260
  (childrenPost?.dataType === 'poll' &&
261
261
  pollData?.status === 'open')) &&
@@ -280,7 +280,7 @@ export function PostMenu({ pageId, componentId, post }: PostMenuProps) {
280
280
  </TouchableOpacity>
281
281
  )}
282
282
  {post?.creator?.userId === myId &&
283
- childrenPost?.dataType !== 'liveStream' &&
283
+ childrenPost?.dataType !== 'room' &&
284
284
  childrenPost?.dataType !== 'poll' && (
285
285
  <TouchableOpacity
286
286
  onPress={goToEditPost}
@@ -8,8 +8,8 @@ import { informative, failed, success } from '../../assets/icons';
8
8
  import { CircularProgressIndicator } from '../CircularProgressIndicator';
9
9
 
10
10
  const Toast = () => {
11
- const { styles, theme } = useStyles();
12
11
  const { hideToast, toast } = useToast();
12
+ const { styles, theme } = useStyles(toast.bottomPosition);
13
13
  const timeoutRef = useRef<number | null>(null);
14
14
  const fadeIn = useRef(new Animated.Value(0)).current;
15
15
 
@@ -3,7 +3,7 @@ import { useTheme } from 'react-native-paper';
3
3
  import type { MyMD3Theme } from '../../../providers/amity-ui-kit-provider';
4
4
  import { useSafeAreaInsets } from 'react-native-safe-area-context';
5
5
 
6
- export const useStyles = () => {
6
+ export const useStyles = (bottomPosition: number = 16) => {
7
7
  const theme = useTheme<MyMD3Theme>();
8
8
  const { bottom } = useSafeAreaInsets();
9
9
 
@@ -13,7 +13,7 @@ export const useStyles = () => {
13
13
  zIndex: 999,
14
14
  width: '90%',
15
15
  borderRadius: 8,
16
- bottom: bottom + 16,
16
+ bottom: bottom + bottomPosition,
17
17
  paddingVertical: 16,
18
18
  alignSelf: 'center',
19
19
  flexDirection: 'row',
@@ -0,0 +1,7 @@
1
+ export const RoomStatus = {
2
+ idle: 'idle' as Amity.RoomStatus,
3
+ live: 'live' as Amity.RoomStatus,
4
+ recorded: 'recorded' as Amity.RoomStatus,
5
+ ended: 'ended' as Amity.RoomStatus,
6
+ waiting_reconnect: 'waiting_reconnect' as Amity.RoomStatus,
7
+ };
@@ -30,3 +30,5 @@ export * from './usePendingPostQuery';
30
30
  export * from './useMembersQuery';
31
31
  export * from './useRolesQuery';
32
32
  export * from './useFlagUserQuery';
33
+ export * from './usePostSubscription';
34
+ export * from './useRoomSubscription';
@@ -51,7 +51,7 @@ export const useCustomRankingGlobalFeed = () => {
51
51
  if (
52
52
  data?.dataType === 'image' ||
53
53
  data?.dataType === 'video' ||
54
- // data?.dataType === 'liveStream' ||
54
+ data?.dataType === 'room' ||
55
55
  data?.dataType === 'poll'
56
56
  ) {
57
57
  resolve(post);
@@ -0,0 +1,34 @@
1
+ import { useEffect, useState } from 'react';
2
+ import {
3
+ getPostTopic,
4
+ PostRepository,
5
+ subscribeTopic,
6
+ } from '@amityco/ts-sdk-react-native';
7
+
8
+ export const usePostSubscription = (postId: string) => {
9
+ const [subscribedPost, setSubscribedPost] = useState<Amity.Post>(null);
10
+
11
+ useEffect(() => {
12
+ let unsubscribe: () => void;
13
+ if (postId) {
14
+ unsubscribe = PostRepository.getPost(postId, ({ data }) => {
15
+ setSubscribedPost(data);
16
+ });
17
+ }
18
+ return () => {
19
+ unsubscribe && unsubscribe();
20
+ };
21
+ }, [postId]);
22
+
23
+ useEffect(() => {
24
+ let unsubscribe: () => void;
25
+ if (subscribedPost) {
26
+ unsubscribe = subscribeTopic(getPostTopic(subscribedPost));
27
+ }
28
+ return () => {
29
+ unsubscribe && unsubscribe();
30
+ };
31
+ }, [subscribedPost]);
32
+
33
+ return { subscribedPost };
34
+ };