@amityco/ts-sdk 7.7.1-9d0f043.0 → 7.7.1-b56aa2f.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 (156) hide show
  1. package/dist/@types/core/events.d.ts +6 -1
  2. package/dist/@types/core/events.d.ts.map +1 -1
  3. package/dist/@types/core/payload.d.ts +25 -0
  4. package/dist/@types/core/payload.d.ts.map +1 -1
  5. package/dist/@types/domains/channel.d.ts +6 -0
  6. package/dist/@types/domains/channel.d.ts.map +1 -1
  7. package/dist/@types/domains/liveReaction.d.ts +20 -0
  8. package/dist/@types/domains/liveReaction.d.ts.map +1 -0
  9. package/dist/@types/domains/post.d.ts +3 -0
  10. package/dist/@types/domains/post.d.ts.map +1 -1
  11. package/dist/@types/domains/stream.d.ts +9 -1
  12. package/dist/@types/domains/stream.d.ts.map +1 -1
  13. package/dist/@types/index.d.ts +1 -0
  14. package/dist/@types/index.d.ts.map +1 -1
  15. package/dist/channelRepository/api/createChannel.d.ts +3 -1
  16. package/dist/channelRepository/api/createChannel.d.ts.map +1 -1
  17. package/dist/channelRepository/channelMembership/observers/getMembers/ChannelMemberLiveCollectionController.d.ts.map +1 -1
  18. package/dist/channelRepository/events/index.d.ts +1 -1
  19. package/dist/channelRepository/events/index.d.ts.map +1 -1
  20. package/dist/channelRepository/events/onChannelSetMuted.d.ts +2 -0
  21. package/dist/channelRepository/events/onChannelSetMuted.d.ts.map +1 -0
  22. package/dist/channelRepository/events/onChannelSetUserMuted.d.ts +2 -0
  23. package/dist/channelRepository/events/onChannelSetUserMuted.d.ts.map +1 -0
  24. package/dist/channelRepository/internalApi/getChannel.d.ts.map +1 -1
  25. package/dist/channelRepository/internalApi/getMyMembership.d.ts +11 -0
  26. package/dist/channelRepository/internalApi/getMyMembership.d.ts.map +1 -0
  27. package/dist/channelRepository/observers/getChannels/ChannelLiveCollectionController.d.ts.map +1 -1
  28. package/dist/channelRepository/observers/getMyMembership.d.ts +2 -0
  29. package/dist/channelRepository/observers/getMyMembership.d.ts.map +1 -0
  30. package/dist/client/api/login.d.ts.map +1 -1
  31. package/dist/core/events.d.ts +3 -3
  32. package/dist/core/events.d.ts.map +1 -1
  33. package/dist/core/subscription.d.ts +2 -1
  34. package/dist/core/subscription.d.ts.map +1 -1
  35. package/dist/index.cjs.js +6358 -5681
  36. package/dist/index.d.ts +1 -0
  37. package/dist/index.d.ts.map +1 -1
  38. package/dist/index.esm.js +6297 -5622
  39. package/dist/index.umd.js +3 -3
  40. package/dist/liveReactionRepository/api/createReaction.d.ts +20 -0
  41. package/dist/liveReactionRepository/api/createReaction.d.ts.map +1 -0
  42. package/dist/liveReactionRepository/api/index.d.ts +2 -0
  43. package/dist/liveReactionRepository/api/index.d.ts.map +1 -0
  44. package/dist/liveReactionRepository/events/index.d.ts +2 -0
  45. package/dist/liveReactionRepository/events/index.d.ts.map +1 -0
  46. package/dist/liveReactionRepository/events/onLiveReactionCreated.d.ts +17 -0
  47. package/dist/liveReactionRepository/events/onLiveReactionCreated.d.ts.map +1 -0
  48. package/dist/liveReactionRepository/events/onLiveReactionCreatedLocal.d.ts +17 -0
  49. package/dist/liveReactionRepository/events/onLiveReactionCreatedLocal.d.ts.map +1 -0
  50. package/dist/liveReactionRepository/index.d.ts +4 -0
  51. package/dist/liveReactionRepository/index.d.ts.map +1 -0
  52. package/dist/liveReactionRepository/internalApi/createLiveReaction.d.ts +20 -0
  53. package/dist/liveReactionRepository/internalApi/createLiveReaction.d.ts.map +1 -0
  54. package/dist/liveReactionRepository/observers/getReactions.d.ts +19 -0
  55. package/dist/liveReactionRepository/observers/getReactions.d.ts.map +1 -0
  56. package/dist/liveReactionRepository/observers/index.d.ts +2 -0
  57. package/dist/liveReactionRepository/observers/index.d.ts.map +1 -0
  58. package/dist/liveReactionRepository/service/ReactionSyncEngine.d.ts +26 -0
  59. package/dist/liveReactionRepository/service/ReactionSyncEngine.d.ts.map +1 -0
  60. package/dist/liveReactionRepository/utils/ReactionSyncEngineOnLoginHandler.d.ts +3 -0
  61. package/dist/liveReactionRepository/utils/ReactionSyncEngineOnLoginHandler.d.ts.map +1 -0
  62. package/dist/liveStreamPlayer/utils/eventRegister.d.ts +2 -1
  63. package/dist/liveStreamPlayer/utils/eventRegister.d.ts.map +1 -1
  64. package/dist/messagePreview/utils/getChannelMessagePreviewWithUser.d.ts +4 -0
  65. package/dist/messagePreview/utils/getChannelMessagePreviewWithUser.d.ts.map +1 -1
  66. package/dist/messageRepository/api/deleteMessage.d.ts.map +1 -1
  67. package/dist/messageRepository/observers/getMessage.d.ts.map +1 -1
  68. package/dist/messageRepository/observers/getMessages/MessageLiveCollectionController.d.ts.map +1 -1
  69. package/dist/messageRepository/observers/getMessages/MessageQueryStreamController.d.ts.map +1 -1
  70. package/dist/postRepository/api/createPost.d.ts.map +1 -1
  71. package/dist/postRepository/utils/payload.d.ts.map +1 -1
  72. package/dist/streamRepository/api/createStream.d.ts +1 -1
  73. package/dist/streamRepository/api/createStream.d.ts.map +1 -1
  74. package/dist/streamRepository/api/editStream.d.ts +18 -0
  75. package/dist/streamRepository/api/editStream.d.ts.map +1 -0
  76. package/dist/streamRepository/api/index.d.ts +1 -0
  77. package/dist/streamRepository/api/index.d.ts.map +1 -1
  78. package/dist/streamRepository/api/updateStream.d.ts +4 -1
  79. package/dist/streamRepository/api/updateStream.d.ts.map +1 -1
  80. package/dist/streamRepository/events/index.d.ts +2 -0
  81. package/dist/streamRepository/events/index.d.ts.map +1 -1
  82. package/dist/streamRepository/events/onStreamViewerBanned.d.ts +17 -0
  83. package/dist/streamRepository/events/onStreamViewerBanned.d.ts.map +1 -0
  84. package/dist/streamRepository/events/onStreamViewerUnbanned.d.ts +17 -0
  85. package/dist/streamRepository/events/onStreamViewerUnbanned.d.ts.map +1 -0
  86. package/dist/streamRepository/internalApi/getLiveChat.d.ts +16 -0
  87. package/dist/streamRepository/internalApi/getLiveChat.d.ts.map +1 -0
  88. package/dist/streamRepository/internalApi/getStream.d.ts +2 -2
  89. package/dist/streamRepository/internalApi/getStream.d.ts.map +1 -1
  90. package/dist/streamRepository/observers/getStreamById.d.ts.map +1 -1
  91. package/dist/streamRepository/observers/getStreams/GetStreamsLiveCollectionController.d.ts.map +1 -1
  92. package/dist/utils/linkedObject/channelLinkedObject.d.ts.map +1 -1
  93. package/dist/utils/linkedObject/postLinkedObject.d.ts.map +1 -1
  94. package/dist/utils/linkedObject/streamLinkedObject.d.ts.map +1 -1
  95. package/dist/utils/postTypePredicate.d.ts +2 -0
  96. package/dist/utils/postTypePredicate.d.ts.map +1 -1
  97. package/package.json +1 -1
  98. package/src/@types/core/events.ts +9 -1
  99. package/src/@types/core/payload.ts +32 -0
  100. package/src/@types/domains/channel.ts +9 -0
  101. package/src/@types/domains/liveReaction.ts +25 -0
  102. package/src/@types/domains/post.ts +3 -0
  103. package/src/@types/domains/stream.ts +12 -1
  104. package/src/@types/index.ts +1 -0
  105. package/src/channelRepository/api/createChannel.ts +11 -8
  106. package/src/channelRepository/channelMembership/observers/getMembers/ChannelMemberLiveCollectionController.ts +2 -0
  107. package/src/channelRepository/events/index.ts +1 -1
  108. package/src/channelRepository/events/onChannelSetMuted.ts +48 -0
  109. package/src/channelRepository/events/onChannelSetUserMuted.ts +65 -0
  110. package/src/channelRepository/internalApi/getChannel.ts +0 -1
  111. package/src/channelRepository/internalApi/getMyMembership.ts +37 -0
  112. package/src/channelRepository/observers/getChannel.ts +2 -2
  113. package/src/channelRepository/observers/getChannels/ChannelLiveCollectionController.ts +2 -2
  114. package/src/channelRepository/observers/getMyMembership.ts +98 -0
  115. package/src/channelRepository/utils/constructChannelObject.ts +2 -2
  116. package/src/client/api/login.ts +2 -0
  117. package/src/core/events.ts +4 -1
  118. package/src/core/subscription.ts +10 -6
  119. package/src/index.ts +2 -0
  120. package/src/liveReactionRepository/api/createReaction.ts +58 -0
  121. package/src/liveReactionRepository/api/index.ts +1 -0
  122. package/src/liveReactionRepository/events/index.ts +1 -0
  123. package/src/liveReactionRepository/events/onLiveReactionCreated.ts +37 -0
  124. package/src/liveReactionRepository/events/onLiveReactionCreatedLocal.ts +29 -0
  125. package/src/liveReactionRepository/index.ts +3 -0
  126. package/src/liveReactionRepository/internalApi/createLiveReaction.ts +42 -0
  127. package/src/liveReactionRepository/observers/getReactions.ts +59 -0
  128. package/src/liveReactionRepository/observers/index.ts +1 -0
  129. package/src/liveReactionRepository/service/ReactionSyncEngine.ts +138 -0
  130. package/src/liveReactionRepository/utils/ReactionSyncEngineOnLoginHandler.ts +19 -0
  131. package/src/liveStreamPlayer/api/getPlayer.ts +1 -1
  132. package/src/liveStreamPlayer/utils/eventRegister.ts +16 -1
  133. package/src/messageRepository/api/deleteMessage.ts +16 -0
  134. package/src/messageRepository/observers/getMessage.ts +2 -0
  135. package/src/messageRepository/observers/getMessages/MessageLiveCollectionController.ts +2 -0
  136. package/src/messageRepository/observers/getMessages/MessageQueryStreamController.ts +13 -0
  137. package/src/postRepository/api/createPost.ts +3 -2
  138. package/src/postRepository/utils/payload.ts +37 -1
  139. package/src/streamRepository/api/createStream.ts +4 -1
  140. package/src/streamRepository/api/editStream.ts +51 -0
  141. package/src/streamRepository/api/index.ts +1 -0
  142. package/src/streamRepository/api/updateStream.ts +8 -1
  143. package/src/streamRepository/events/index.ts +2 -0
  144. package/src/streamRepository/events/onStreamViewerBanned.ts +58 -0
  145. package/src/streamRepository/events/onStreamViewerUnbanned.ts +47 -0
  146. package/src/streamRepository/internalApi/getLiveChat.ts +59 -0
  147. package/src/streamRepository/internalApi/getStream.ts +3 -3
  148. package/src/streamRepository/observers/getStreamById.ts +2 -0
  149. package/src/streamRepository/observers/getStreams/GetStreamsLiveCollectionController.ts +5 -1
  150. package/src/utils/linkedObject/channelLinkedObject.ts +3 -0
  151. package/src/utils/linkedObject/postLinkedObject.ts +28 -2
  152. package/src/utils/linkedObject/streamLinkedObject.ts +4 -0
  153. package/src/utils/postTypePredicate.ts +18 -0
  154. package/dist/channelRepository/events/onChannelMuted.d.ts +0 -2
  155. package/dist/channelRepository/events/onChannelMuted.d.ts.map +0 -1
  156. package/src/channelRepository/events/onChannelMuted.ts +0 -39
@@ -0,0 +1,42 @@
1
+ import { getActiveClient } from '~/client/api/activeClient';
2
+ // TODO: confirm id
3
+ /* begin_public_function
4
+ id: live_reaction.create
5
+ */
6
+ /**
7
+ * ```js
8
+ * import { acceptInvitation } from '@amityco/ts-sdk'
9
+ * const isAccepted = await acceptInvitation(invitationId)
10
+ * ```
11
+ *
12
+ * Accepts array of {@link Amity.LiveReaction} object without userId
13
+ *
14
+ * @param reactions the array of {@link Amity.LiveReaction} to create
15
+ // TODO: confirm what is the ids in addedIds
16
+ * @returns An object addedIds contains array of reaction ID
17
+ *
18
+ * @category Live Reaction API
19
+ * @async
20
+ */
21
+ export const createLiveReaction = async ({
22
+ reactions,
23
+ liveStreamId,
24
+ }: {
25
+ reactions: Amity.CreateLiveReactionRequest[];
26
+ liveStreamId: string;
27
+ }): Promise<Amity.CreateLiveReactionResponse> => {
28
+ const client = getActiveClient();
29
+
30
+ client.log('live_reaction/addReaction', reactions);
31
+
32
+ const { data } = await client.http.post<Amity.CreateLiveReactionResponse>(
33
+ `/api/v1/reactions/live`,
34
+ {
35
+ liveStreamId,
36
+ reactions,
37
+ },
38
+ );
39
+
40
+ return data;
41
+ };
42
+ /* end_public_function */
@@ -0,0 +1,59 @@
1
+ import { ASCError } from '~/core/errors';
2
+ import { onLiveReactionCreated } from '../events';
3
+ import { getActiveClient, getActiveUser } from '~/client';
4
+ import { onLiveReactionCreatedLocal } from '../events/onLiveReactionCreatedLocal';
5
+
6
+ /**
7
+ *
8
+ * ```js
9
+ * import { getReactions } from '@amityco/ts-sdk';
10
+ *
11
+ * const unsubscribe = getReactions(response => {
12
+ * reactions = response.data
13
+ * });
14
+ * ```
15
+ *
16
+ * Observe live reactions {@link_Amity.LiveReaction} that have been created in a post linked with a stream
17
+ *
18
+ * @param callback the function to call when new data are available
19
+ * @returns An {@link Amity.Unsubscriber} function to run when willing to stop observing the events
20
+ *
21
+ * @category Live Reaction Observable
22
+ */
23
+ // TODO: confirm return type for this observable property
24
+ export const getReactions = (
25
+ postId: string,
26
+ callback: Amity.Listener<Amity.LiveReaction[]>,
27
+ ): Amity.Unsubscriber => {
28
+ const { _id: userId } = getActiveUser();
29
+
30
+ if (!userId)
31
+ throw new ASCError(
32
+ 'The _id has not been defined in ActiveUser',
33
+ Amity.ClientError.UNKNOWN_ERROR,
34
+ Amity.ErrorLevel.ERROR,
35
+ );
36
+
37
+ const { log } = getActiveClient();
38
+
39
+ const timestamp = Date.now();
40
+ log(`getReactions(tmpid: ${timestamp}) > listen`);
41
+
42
+ const disposers: Amity.Unsubscriber[] = [];
43
+
44
+ const dispatcher = (data: Amity.LiveReaction[]) => {
45
+ callback(data);
46
+ };
47
+
48
+ const realtimeRouter = (data: Amity.LiveReaction[]) => {
49
+ const relevantReactions = data.filter(({ referenceId }) => referenceId === postId);
50
+ dispatcher(relevantReactions);
51
+ };
52
+
53
+ disposers.push(onLiveReactionCreated(realtimeRouter));
54
+ disposers.push(onLiveReactionCreatedLocal(realtimeRouter));
55
+
56
+ return () => {
57
+ disposers.forEach(fn => fn());
58
+ };
59
+ };
@@ -0,0 +1 @@
1
+ export * from './getReactions';
@@ -0,0 +1,138 @@
1
+ import { onOffline } from '~/client/utils/onOffline';
2
+ import { onOnline } from '~/client/utils/onOnline';
3
+ import { SECOND } from '~/utils/constants';
4
+ import { createLiveReaction as _createLiveReaction } from '../internalApi/createLiveReaction';
5
+
6
+ class LiveReactionSyncEngine {
7
+ private readonly TIMER_INTERVAL_MS = 1 * SECOND;
8
+
9
+ private buffer: (Amity.CreateLiveReactionRequest & { streamId: string })[] = [];
10
+
11
+ private timer: NodeJS.Timer | undefined;
12
+
13
+ private isSyncing = false;
14
+
15
+ private connectionListener: (() => void)[] = [];
16
+
17
+ private isConnected = true;
18
+
19
+ constructor() {
20
+ this.addConnectionListener();
21
+ }
22
+
23
+ startReactionsSync() {
24
+ if (!this.timer) {
25
+ this.timer = setInterval(() => {
26
+ if (this.isConnected) this.syncLiveReactions();
27
+ }, this.TIMER_INTERVAL_MS);
28
+ }
29
+ }
30
+
31
+ stopReactionsSync() {
32
+ if (this.timer) {
33
+ clearInterval(this.timer);
34
+ this.timer = undefined;
35
+ }
36
+ }
37
+
38
+ createLiveReaction(liveReaction: Amity.CreateLiveReactionRequest & { streamId: string }) {
39
+ this.buffer.push(liveReaction);
40
+ }
41
+
42
+ private addConnectionListener() {
43
+ if (this.connectionListener.length > 0) return;
44
+ this.connectionListener.push(
45
+ onOnline(() => {
46
+ this.isConnected = true;
47
+ }),
48
+ );
49
+
50
+ this.connectionListener.push(
51
+ onOffline(() => {
52
+ this.isConnected = false;
53
+ }),
54
+ );
55
+ }
56
+
57
+ private removeConnectionListener() {
58
+ if (this.connectionListener.length > 0) {
59
+ this.connectionListener.forEach(listener => listener());
60
+ this.connectionListener = [];
61
+ }
62
+ }
63
+
64
+ private syncLiveReactions() {
65
+ if (this.isSyncing) {
66
+ return;
67
+ }
68
+
69
+ this.isSyncing = true;
70
+
71
+ const reactions = this.buffer;
72
+
73
+ // Clear buffer
74
+ this.clearBuffer();
75
+
76
+ const payloads: Record<string, Amity.CreateLiveReactionRequest[]> = reactions.reduce(
77
+ (prev: Record<string, Amity.CreateLiveReactionRequest[]>, curr) => {
78
+ const { streamId, ...rest } = curr;
79
+ if (!prev[streamId]) {
80
+ // eslint-disable-next-line no-param-reassign
81
+ prev[streamId] = [rest];
82
+ } else prev[streamId].push(rest);
83
+ return prev;
84
+ },
85
+ {} as Record<string, Amity.CreateLiveReactionRequest[]>,
86
+ );
87
+
88
+ // Call server api `POST /api/v1/reactions/live` to sync live reactions
89
+ Object.entries(payloads).forEach(([streamId, reactions]) => {
90
+ _createLiveReaction({
91
+ liveStreamId: streamId,
92
+ reactions,
93
+ });
94
+ });
95
+
96
+ // After sending request
97
+ this.isSyncing = false;
98
+ }
99
+
100
+ private clearBuffer() {
101
+ this.buffer = [];
102
+ }
103
+
104
+ // Session Management : SessionComponent
105
+ onSessionEstablished() {
106
+ this.startReactionsSync();
107
+ this.addConnectionListener();
108
+ }
109
+
110
+ onSessionDestroyed() {
111
+ // Stop timer
112
+ this.stopReactionsSync();
113
+
114
+ // Clear buffer
115
+ this.clearBuffer();
116
+
117
+ // Reset state
118
+ this.isSyncing = false;
119
+
120
+ // remove connection listener
121
+ this.removeConnectionListener();
122
+ }
123
+
124
+ onTokenExpired() {
125
+ this.stopReactionsSync();
126
+ }
127
+ }
128
+
129
+ let instance: LiveReactionSyncEngine;
130
+
131
+ export default {
132
+ getInstance: () => {
133
+ if (!instance) {
134
+ instance = new LiveReactionSyncEngine();
135
+ }
136
+ return instance;
137
+ },
138
+ };
@@ -0,0 +1,19 @@
1
+ import { onSessionStateChange } from '~/client/events/onSessionStateChange';
2
+ import ReactionSyncEngine from '../service/ReactionSyncEngine';
3
+
4
+ export default () => {
5
+ const reactionSynceEngine = ReactionSyncEngine.getInstance();
6
+ reactionSynceEngine.startReactionsSync();
7
+
8
+ onSessionStateChange(state => {
9
+ if (state === Amity.SessionStates.ESTABLISHED) {
10
+ reactionSynceEngine.onSessionEstablished();
11
+ } else if (state === Amity.SessionStates.TOKEN_EXPIRED) {
12
+ reactionSynceEngine.onTokenExpired();
13
+ } else reactionSynceEngine.onSessionDestroyed();
14
+ });
15
+
16
+ return () => {
17
+ reactionSynceEngine.onSessionDestroyed();
18
+ };
19
+ };
@@ -60,7 +60,7 @@ export const getPlayer = async (parameters: { streamId: string }): Promise<HTMLV
60
60
  video.src = recording.mp4.url;
61
61
  }
62
62
 
63
- new EventRegister(video, resolution).registerEvents();
63
+ new EventRegister(video, resolution, streamId).registerEvents();
64
64
 
65
65
  return video;
66
66
  };
@@ -1,5 +1,6 @@
1
1
  import uuid from 'react-native-uuid';
2
2
  import { getUsageCollector } from '../api/getUsageCollector';
3
+ import { onStreamViewerBanned } from '~/streamRepository/events';
3
4
 
4
5
  const SECOND = 1000;
5
6
  /*
@@ -32,7 +33,9 @@ export class EventRegister {
32
33
 
33
34
  _observer: MutationObserver;
34
35
 
35
- constructor(player: HTMLVideoElement, resolution: string) {
36
+ _SDKUnsubscribers: Amity.Unsubscriber[] = [];
37
+
38
+ constructor(player: HTMLVideoElement, resolution: string, streamId: string) {
36
39
  this.player = player;
37
40
  this.resolution = resolution;
38
41
  this._startTime = null;
@@ -53,10 +56,22 @@ export class EventRegister {
53
56
  mutation.removedNodes.forEach(node => {
54
57
  if (node === player) {
55
58
  this._unregisterEvents();
59
+ this._SDKUnsubscribers.forEach(fn => fn?.());
56
60
  }
57
61
  });
58
62
  });
59
63
  });
64
+
65
+ this._SDKUnsubscribers.push(
66
+ onStreamViewerBanned(stream => {
67
+ // if still has stream.watcherUrl, the current user has not banned.
68
+ if (stream.watcherUrl) return;
69
+ this.player.pause();
70
+ this.player.removeAttribute('src');
71
+ this.player.load();
72
+ this.player.remove();
73
+ }),
74
+ );
60
75
  }
61
76
 
62
77
  _resetStartTime() {
@@ -23,6 +23,22 @@ export const deleteMessage = async (
23
23
  const client = getActiveClient();
24
24
  client.log('message/deleteMessage', messageId);
25
25
 
26
+ if (messageId.includes('LOCAL_')) {
27
+ const message = pullFromCache<Amity.InternalMessage>(['message', 'get', messageId])?.data;
28
+ if (!message) throw Error('messageId not found');
29
+
30
+ const deletedMessage = {
31
+ ...message,
32
+ isDeleted: true,
33
+ };
34
+
35
+ fireEvent('local.message.deleted', {
36
+ messages: [deletedMessage],
37
+ });
38
+
39
+ return LinkedObject.message(deletedMessage);
40
+ }
41
+
26
42
  // API-FIX: This endpoint has not been implemented yet.
27
43
  const { data: deleted } = await client.http.delete<Amity.MessagePayload>(
28
44
  `/api/v5/messages/${encodeURIComponent(messageId)}`,
@@ -11,6 +11,7 @@ import {
11
11
  onMessageReactionAdded,
12
12
  onMessageReactionRemoved,
13
13
  } from '../events';
14
+ import { onStreamViewerBanned } from '~/streamRepository/events/onStreamViewerBanned';
14
15
  import { onMessageFetched } from '../events/onMessageFetched';
15
16
  import { LinkedObject } from '~/utils/linkedObject';
16
17
 
@@ -57,6 +58,7 @@ export const getMessage = (
57
58
  onMessageReactionRemoved,
58
59
  convertEventPayload(onMessageMarkerFetched, 'contentId', 'message'),
59
60
  convertEventPayload(onMessageMarked, 'contentId', 'message'),
61
+ convertEventPayload(onStreamViewerBanned, 'channelId', 'message'),
60
62
  ]);
61
63
  };
62
64
  /* end_public_function */
@@ -11,6 +11,7 @@ import {
11
11
  onMessageUnflagged,
12
12
  onMessageUpdated,
13
13
  } from '~/messageRepository/events';
14
+ import { onStreamViewerBanned } from '~/streamRepository/events/onStreamViewerBanned';
14
15
  import { convertEventPayload } from '~/utils/event';
15
16
  import { LiveCollectionController } from '~/core/liveCollection/LiveCollectionController';
16
17
  import { onMessageMarked, onMessageMarkerFetched } from '~/marker/events';
@@ -70,6 +71,7 @@ export class MessageLiveCollectionController extends LiveCollectionController<
70
71
  action: 'onUpdate',
71
72
  },
72
73
  { fn: convertEventPayload(onMessageMarked, 'contentId', 'message'), action: 'onUpdate' },
74
+ { fn: convertEventPayload(onStreamViewerBanned, 'channelId', 'message'), action: 'onUpdate' },
73
75
  ]);
74
76
  }
75
77
 
@@ -116,6 +116,19 @@ export class MessageQueryStreamController extends QueryStreamController<
116
116
  pushToCache(this.cacheKey, collection);
117
117
  }
118
118
 
119
+ if (action === 'onDelete' && payload.syncState === Amity.SyncState.Error) {
120
+ const collection = pullFromCache<Amity.MessageLiveCollectionCache>(this.cacheKey)?.data;
121
+ if (!collection) return;
122
+
123
+ if (collection.data.includes(payload.messageId)) {
124
+ const newCollectionData = collection.data.filter(
125
+ messageId => messageId !== payload.messageId,
126
+ );
127
+
128
+ pushToCache(this.cacheKey, { ...collection, data: newCollectionData });
129
+ }
130
+ }
131
+
119
132
  this.notifyChange({ origin: Amity.LiveDataOrigin.EVENT, loading: false });
120
133
  };
121
134
  }
@@ -2,8 +2,8 @@ import { getActiveClient } from '~/client/api';
2
2
 
3
3
  import { ingestInCache } from '~/cache/api/ingestInCache';
4
4
  import { fireEvent } from '~/core/events';
5
- import { prepareMembershipPayload } from '~/group/utils';
6
5
  import { LinkedObject } from '~/utils/linkedObject';
6
+ import { preparePostPayload } from '../utils/payload';
7
7
 
8
8
  /* begin_public_function
9
9
  id: post.create.text_post, post.create.image_post, post.create.file_post, post.create.video_post, post.create.poll_post, post.create.livestream_post, post.create.custom_post
@@ -46,7 +46,8 @@ export const createPost = async <T extends Amity.PostContentType | string>(
46
46
 
47
47
  fireEvent('post.created', payload);
48
48
 
49
- const data = prepareMembershipPayload(payload, 'communityUsers');
49
+ const data = preparePostPayload(payload);
50
+
50
51
  const cachedAt = client.cache && Date.now();
51
52
 
52
53
  if (client.cache) ingestInCache(data, { cachedAt });
@@ -1,8 +1,28 @@
1
1
  import { addPostSetting } from '~/communityRepository/utils';
2
2
  import { updateMembershipStatus } from '~/communityRepository/utils/communityWithMembership';
3
+ import { isAmityLivestreamPost } from '~/utils/postTypePredicate';
4
+
5
+ const updateStreamReferences = (
6
+ streams: Amity.RawStream[],
7
+ streamId: string | undefined,
8
+ postId: string,
9
+ ) => {
10
+ if (!streamId) return streams;
11
+
12
+ return streams.map(stream =>
13
+ stream.streamId === streamId
14
+ ? {
15
+ ...stream,
16
+ referenceType: 'post',
17
+ referenceId: postId,
18
+ postId,
19
+ }
20
+ : stream,
21
+ );
22
+ };
3
23
 
4
24
  export const preparePostPayload = (payload: Amity.PostPayload): Amity.ProcessedPostPayload => {
5
- const { posts: postsData, ...postPayload } = payload;
25
+ const { posts: postsData, postChildren, videoStreamings, ...postPayload } = payload;
6
26
 
7
27
  // Unpack community payload by mapping payload field to postSetting value.
8
28
  const communitiesWithPostSetting = addPostSetting({ communities: postPayload.communities });
@@ -24,18 +44,34 @@ export const preparePostPayload = (payload: Amity.PostPayload): Amity.ProcessedP
24
44
  mappedCommunityUsers,
25
45
  );
26
46
 
47
+ let mappedNewStream: Amity.RawStream[] = [];
48
+
27
49
  // feed type
28
50
  const posts = postsData.map(post => {
29
51
  const feedType = postPayload.feeds.find(feed => feed.feedId === post.feedId)?.feedType;
52
+ const childPosts = payload.postChildren.filter(
53
+ children => children.parentPostId === post.postId,
54
+ );
55
+
56
+ if (childPosts.length > 0 && isAmityLivestreamPost(childPosts[0])) {
57
+ mappedNewStream = updateStreamReferences(
58
+ videoStreamings,
59
+ childPosts[0].data?.streamId,
60
+ post.postId,
61
+ );
62
+ }
30
63
 
31
64
  return {
32
65
  ...post,
66
+ childPosts,
33
67
  feedType,
34
68
  };
35
69
  });
36
70
 
37
71
  return {
38
72
  ...postPayload,
73
+ postChildren,
74
+ videoStreamings: mappedNewStream,
39
75
  posts,
40
76
  communities: communityWithMembershipStatus,
41
77
  communityUsers: mappedCommunityUsers,
@@ -21,7 +21,10 @@ import { LinkedObject } from '~/utils/linkedObject';
21
21
  * @async
22
22
  */
23
23
  export const createStream = async (
24
- bundle: Pick<Amity.InternalStream, 'title' | 'thumbnailFileId' | 'description'> & {
24
+ bundle: Pick<
25
+ Amity.InternalStream,
26
+ 'title' | 'thumbnailFileId' | 'description' | 'channelEnabled'
27
+ > & {
25
28
  isSecure?: boolean;
26
29
  },
27
30
  ): Promise<Amity.Cached<Amity.Stream>> => {
@@ -0,0 +1,51 @@
1
+ import { getActiveClient } from '~/client/api';
2
+
3
+ import { ingestInCache } from '~/cache/api/ingestInCache';
4
+ import { LinkedObject } from '~/utils/linkedObject';
5
+
6
+ /* begin_public_function
7
+ id: stream.update
8
+ */
9
+ /**
10
+ *
11
+ * ```js
12
+ * import { StreamRepository } from '@amityco/ts-sdk'
13
+ * const updated = await StreamRepository.editStream(streamId, { title: 'foobar' })
14
+ * ```
15
+ *
16
+ * Updates an {@link Amity.Stream}
17
+ *
18
+ * @param streamId The ID of the {@link Amity.Stream} to edit
19
+ * @param patch The patch data to apply
20
+ * @returns the updated {@link Amity.Stream} object
21
+ *
22
+ * @category Stream API
23
+ * @async
24
+ */
25
+
26
+ export const editStream = async (
27
+ streamId: Amity.Stream['streamId'],
28
+ patch: Patch<
29
+ Amity.Stream,
30
+ 'title' | 'thumbnailFileId' | 'description' | 'metadata' | 'channelEnabled'
31
+ >,
32
+ ): Promise<Amity.Cached<Amity.Stream>> => {
33
+ const client = getActiveClient();
34
+ client.log('stream/updateStream', streamId, patch);
35
+
36
+ const { data } = await client.http.put<Amity.StreamPayload>(
37
+ `/api/v3/video-streaming/${streamId}`,
38
+ patch,
39
+ );
40
+
41
+ const cachedAt = client.cache && Date.now();
42
+ if (client.cache) ingestInCache(data, { cachedAt });
43
+
44
+ const { videoStreamings } = data;
45
+
46
+ return {
47
+ data: LinkedObject.stream(videoStreamings.find(stream => stream.streamId === streamId)!),
48
+ cachedAt,
49
+ };
50
+ };
51
+ /* end_public_function */
@@ -2,3 +2,4 @@ export * from './createStream';
2
2
  export * from './updateStream';
3
3
  export * from './deleteStream';
4
4
  export * from './disposeStream';
5
+ export * from './editStream';
@@ -7,6 +7,9 @@ import { LinkedObject } from '~/utils/linkedObject';
7
7
  id: stream.update
8
8
  */
9
9
  /**
10
+ * @deprecated this function is deprecated,
11
+ * please use {@link Amity.StreamRepository.editStream} instead.
12
+ *
10
13
  * ```js
11
14
  * import { updateStream } from '@amityco/ts-sdk'
12
15
  * const updated = await updateStream(streamId, { title: 'foobar' })
@@ -21,9 +24,13 @@ import { LinkedObject } from '~/utils/linkedObject';
21
24
  * @category Stream API
22
25
  * @async
23
26
  */
27
+
24
28
  export const updateStream = async (
25
29
  streamId: Amity.Stream['streamId'],
26
- patch: Patch<Amity.Stream, 'title' | 'thumbnailFileId' | 'description' | 'metadata'>,
30
+ patch: Patch<
31
+ Amity.Stream,
32
+ 'title' | 'thumbnailFileId' | 'description' | 'metadata' | 'channelEnabled'
33
+ >,
27
34
  ): Promise<Amity.Cached<Amity.Stream>> => {
28
35
  const client = getActiveClient();
29
36
  client.log('stream/updateStream', streamId, patch);
@@ -3,3 +3,5 @@ export { onStreamStopped } from './onStreamStopped';
3
3
  export { onStreamRecorded } from './onStreamRecorded';
4
4
  export { onStreamFlagged } from './onStreamFlagged';
5
5
  export { onStreamTerminated } from './onStreamTerminated';
6
+ export { onStreamViewerBanned } from './onStreamViewerBanned';
7
+ export { onStreamViewerUnbanned } from './onStreamViewerUnbanned';
@@ -0,0 +1,58 @@
1
+ import { getActiveClient } from '~/client/api';
2
+ import { createEventSubscriber } from '~/core/events';
3
+ import { mergeInCache, pullFromCache, queryCache } from '~/cache/api';
4
+
5
+ /**
6
+ * ```js
7
+ * import { onStreamViewerBanned } from '@amityco/ts-sdk'
8
+ * const dispose = onStreamViewerBanned(stream => {
9
+ * // ...
10
+ * })
11
+ * ```
12
+ *
13
+ * Fired when a user in channel linked to stream has been banned
14
+ *
15
+ * @param callback The function to call when the event was fired
16
+ * @returns an {@link Amity.Unsubscriber} function to stop listening
17
+ *
18
+ * @category Stream Events
19
+ */
20
+ export const onStreamViewerBanned = (
21
+ callback: Amity.Listener<Amity.InternalStream>,
22
+ ): Amity.Unsubscriber => {
23
+ const client = getActiveClient();
24
+
25
+ const filter = (payloads: Amity.StreamViewerBanPayload) => {
26
+ payloads.forEach(streamBanned => {
27
+ mergeInCache(['stream', 'get', streamBanned.streamId], { watcherUrl: null });
28
+
29
+ // Update isDeleted = true in banned user's messages
30
+ const messageCache = queryCache<Amity.InternalMessage>(['message', 'get'])?.filter(
31
+ // Check if creator id and user id are internal or external id
32
+ ({ data }) => data.creatorId === streamBanned.userId,
33
+ );
34
+
35
+ // Update isDeleted for each relavant messages
36
+ messageCache?.forEach(message => {
37
+ mergeInCache(message.key, { isDeleted: true });
38
+ });
39
+ });
40
+
41
+ const stream = pullFromCache<Amity.InternalStream>([
42
+ 'stream',
43
+ 'get',
44
+ payloads[0].streamId,
45
+ ])?.data;
46
+
47
+ if (!stream) return;
48
+
49
+ callback(stream);
50
+ };
51
+
52
+ return createEventSubscriber(
53
+ client,
54
+ 'stream/onStreamViewerDidBan',
55
+ 'video-streaming.viewerDidBan',
56
+ filter,
57
+ );
58
+ };
@@ -0,0 +1,47 @@
1
+ import { getActiveClient } from '~/client/api';
2
+ import { createEventSubscriber } from '~/core/events';
3
+ import { mergeInCache, pullFromCache } from '~/cache/api';
4
+ import { getStream } from '../internalApi/getStream';
5
+
6
+ /**
7
+ * ```js
8
+ * import { onStreamViewerUnbanned } from '@amityco/ts-sdk'
9
+ * const dispose = onStreamViewerBanned(stream => {
10
+ * // ...
11
+ * })
12
+ * ```
13
+ *
14
+ * Fired when a user in channel linked to stream has been unbanned
15
+ *
16
+ * @param callback The function to call when the event was fired
17
+ * @returns an {@link Amity.Unsubscriber} function to stop listening
18
+ *
19
+ * @category Stream Events
20
+ */
21
+ export const onStreamViewerUnbanned = (
22
+ callback: Amity.Listener<Amity.InternalStream>,
23
+ ): Amity.Unsubscriber => {
24
+ const client = getActiveClient();
25
+
26
+ const filter = async (payloads: Amity.StreamViewerUnbanPayload) => {
27
+ // Get new stream object to restore stream watcherUrl in cache
28
+ await Promise.all(payloads.map(({ streamId }) => getStream(streamId)));
29
+
30
+ const stream = pullFromCache<Amity.InternalStream>([
31
+ 'stream',
32
+ 'get',
33
+ payloads[0].streamId,
34
+ ])?.data;
35
+
36
+ if (!stream) return;
37
+
38
+ callback(stream);
39
+ };
40
+
41
+ return createEventSubscriber(
42
+ client,
43
+ 'stream/onStreamViewerDidUnban',
44
+ 'video-streaming.viewerDidUnban',
45
+ filter,
46
+ );
47
+ };