@amityco/ts-sdk 7.7.0 → 7.7.1-99f7166.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 (142) hide show
  1. package/.env +26 -26
  2. package/dist/@types/core/events.d.ts +6 -1
  3. package/dist/@types/core/events.d.ts.map +1 -1
  4. package/dist/@types/core/payload.d.ts +25 -0
  5. package/dist/@types/core/payload.d.ts.map +1 -1
  6. package/dist/@types/domains/channel.d.ts +5 -0
  7. package/dist/@types/domains/channel.d.ts.map +1 -1
  8. package/dist/@types/domains/liveReaction.d.ts +20 -0
  9. package/dist/@types/domains/liveReaction.d.ts.map +1 -0
  10. package/dist/@types/domains/post.d.ts +3 -0
  11. package/dist/@types/domains/post.d.ts.map +1 -1
  12. package/dist/@types/domains/stream.d.ts +9 -1
  13. package/dist/@types/domains/stream.d.ts.map +1 -1
  14. package/dist/@types/index.d.ts +1 -0
  15. package/dist/@types/index.d.ts.map +1 -1
  16. package/dist/channelRepository/api/createChannel.d.ts +3 -1
  17. package/dist/channelRepository/api/createChannel.d.ts.map +1 -1
  18. package/dist/channelRepository/channelMembership/observers/getMembers/ChannelMemberLiveCollectionController.d.ts.map +1 -1
  19. package/dist/channelRepository/events/index.d.ts +1 -1
  20. package/dist/channelRepository/events/index.d.ts.map +1 -1
  21. package/dist/channelRepository/events/onChannelSetMuted.d.ts +2 -0
  22. package/dist/channelRepository/events/onChannelSetMuted.d.ts.map +1 -0
  23. package/dist/channelRepository/events/onChannelSetUserMuted.d.ts +2 -0
  24. package/dist/channelRepository/events/onChannelSetUserMuted.d.ts.map +1 -0
  25. package/dist/channelRepository/internalApi/getChannel.d.ts.map +1 -1
  26. package/dist/channelRepository/observers/getChannels/ChannelLiveCollectionController.d.ts.map +1 -1
  27. package/dist/client/api/login.d.ts.map +1 -1
  28. package/dist/core/events.d.ts +3 -3
  29. package/dist/core/events.d.ts.map +1 -1
  30. package/dist/core/subscription.d.ts +2 -1
  31. package/dist/core/subscription.d.ts.map +1 -1
  32. package/dist/index.cjs.js +6380 -5797
  33. package/dist/index.d.ts +1 -0
  34. package/dist/index.d.ts.map +1 -1
  35. package/dist/index.esm.js +6187 -5606
  36. package/dist/index.umd.js +3 -3
  37. package/dist/liveReactionRepository/api/createReaction.d.ts +20 -0
  38. package/dist/liveReactionRepository/api/createReaction.d.ts.map +1 -0
  39. package/dist/liveReactionRepository/api/index.d.ts +2 -0
  40. package/dist/liveReactionRepository/api/index.d.ts.map +1 -0
  41. package/dist/liveReactionRepository/events/index.d.ts +2 -0
  42. package/dist/liveReactionRepository/events/index.d.ts.map +1 -0
  43. package/dist/liveReactionRepository/events/onLiveReactionCreated.d.ts +17 -0
  44. package/dist/liveReactionRepository/events/onLiveReactionCreated.d.ts.map +1 -0
  45. package/dist/liveReactionRepository/events/onLiveReactionCreatedLocal.d.ts +17 -0
  46. package/dist/liveReactionRepository/events/onLiveReactionCreatedLocal.d.ts.map +1 -0
  47. package/dist/liveReactionRepository/index.d.ts +4 -0
  48. package/dist/liveReactionRepository/index.d.ts.map +1 -0
  49. package/dist/liveReactionRepository/internalApi/createLiveReaction.d.ts +20 -0
  50. package/dist/liveReactionRepository/internalApi/createLiveReaction.d.ts.map +1 -0
  51. package/dist/liveReactionRepository/observers/getReactions.d.ts +19 -0
  52. package/dist/liveReactionRepository/observers/getReactions.d.ts.map +1 -0
  53. package/dist/liveReactionRepository/observers/index.d.ts +2 -0
  54. package/dist/liveReactionRepository/observers/index.d.ts.map +1 -0
  55. package/dist/liveReactionRepository/service/ReactionSyncEngine.d.ts +26 -0
  56. package/dist/liveReactionRepository/service/ReactionSyncEngine.d.ts.map +1 -0
  57. package/dist/liveReactionRepository/utils/ReactionSyncEngineOnLoginHandler.d.ts +3 -0
  58. package/dist/liveReactionRepository/utils/ReactionSyncEngineOnLoginHandler.d.ts.map +1 -0
  59. package/dist/messagePreview/utils/getChannelMessagePreviewWithUser.d.ts +4 -0
  60. package/dist/messagePreview/utils/getChannelMessagePreviewWithUser.d.ts.map +1 -1
  61. package/dist/messageRepository/api/deleteMessage.d.ts.map +1 -1
  62. package/dist/messageRepository/observers/getMessage.d.ts.map +1 -1
  63. package/dist/messageRepository/observers/getMessages/MessageLiveCollectionController.d.ts.map +1 -1
  64. package/dist/messageRepository/observers/getMessages/MessageQueryStreamController.d.ts.map +1 -1
  65. package/dist/postRepository/api/createPost.d.ts.map +1 -1
  66. package/dist/postRepository/utils/payload.d.ts.map +1 -1
  67. package/dist/streamRepository/api/createStream.d.ts +1 -1
  68. package/dist/streamRepository/api/createStream.d.ts.map +1 -1
  69. package/dist/streamRepository/api/editStream.d.ts +18 -0
  70. package/dist/streamRepository/api/editStream.d.ts.map +1 -0
  71. package/dist/streamRepository/api/index.d.ts +1 -0
  72. package/dist/streamRepository/api/index.d.ts.map +1 -1
  73. package/dist/streamRepository/api/updateStream.d.ts +4 -1
  74. package/dist/streamRepository/api/updateStream.d.ts.map +1 -1
  75. package/dist/streamRepository/events/onStreamViewerBanned.d.ts +17 -0
  76. package/dist/streamRepository/events/onStreamViewerBanned.d.ts.map +1 -0
  77. package/dist/streamRepository/events/onStreamViewerUnbanned.d.ts +17 -0
  78. package/dist/streamRepository/events/onStreamViewerUnbanned.d.ts.map +1 -0
  79. package/dist/streamRepository/internalApi/getLiveChat.d.ts +16 -0
  80. package/dist/streamRepository/internalApi/getLiveChat.d.ts.map +1 -0
  81. package/dist/streamRepository/internalApi/getStream.d.ts +2 -2
  82. package/dist/streamRepository/internalApi/getStream.d.ts.map +1 -1
  83. package/dist/streamRepository/observers/getStreamById.d.ts.map +1 -1
  84. package/dist/streamRepository/observers/getStreams/GetStreamsLiveCollectionController.d.ts.map +1 -1
  85. package/dist/utils/linkedObject/postLinkedObject.d.ts.map +1 -1
  86. package/dist/utils/linkedObject/streamLinkedObject.d.ts.map +1 -1
  87. package/dist/utils/postTypePredicate.d.ts +2 -0
  88. package/dist/utils/postTypePredicate.d.ts.map +1 -1
  89. package/package.json +1 -1
  90. package/src/@types/core/events.ts +9 -1
  91. package/src/@types/core/payload.ts +32 -0
  92. package/src/@types/domains/channel.ts +6 -0
  93. package/src/@types/domains/liveReaction.ts +25 -0
  94. package/src/@types/domains/post.ts +3 -0
  95. package/src/@types/domains/stream.ts +12 -1
  96. package/src/@types/index.ts +1 -0
  97. package/src/channelRepository/api/createChannel.ts +12 -9
  98. package/src/channelRepository/channelMembership/observers/getMembers/ChannelMemberLiveCollectionController.ts +2 -0
  99. package/src/channelRepository/events/index.ts +1 -1
  100. package/src/channelRepository/events/onChannelSetMuted.ts +48 -0
  101. package/src/channelRepository/events/onChannelSetUserMuted.ts +67 -0
  102. package/src/channelRepository/internalApi/getChannel.ts +0 -1
  103. package/src/channelRepository/observers/getChannel.ts +2 -2
  104. package/src/channelRepository/observers/getChannels/ChannelLiveCollectionController.ts +2 -2
  105. package/src/channelRepository/utils/constructChannelObject.ts +2 -2
  106. package/src/client/api/login.ts +2 -0
  107. package/src/core/events.ts +1 -0
  108. package/src/core/subscription.ts +10 -6
  109. package/src/index.ts +2 -0
  110. package/src/liveReactionRepository/api/createReaction.ts +58 -0
  111. package/src/liveReactionRepository/api/index.ts +1 -0
  112. package/src/liveReactionRepository/events/index.ts +1 -0
  113. package/src/liveReactionRepository/events/onLiveReactionCreated.ts +37 -0
  114. package/src/liveReactionRepository/events/onLiveReactionCreatedLocal.ts +29 -0
  115. package/src/liveReactionRepository/index.ts +3 -0
  116. package/src/liveReactionRepository/internalApi/createLiveReaction.ts +42 -0
  117. package/src/liveReactionRepository/observers/getReactions.ts +59 -0
  118. package/src/liveReactionRepository/observers/index.ts +1 -0
  119. package/src/liveReactionRepository/service/ReactionSyncEngine.ts +138 -0
  120. package/src/liveReactionRepository/utils/ReactionSyncEngineOnLoginHandler.ts +19 -0
  121. package/src/messageRepository/api/deleteMessage.ts +16 -0
  122. package/src/messageRepository/observers/getMessage.ts +2 -0
  123. package/src/messageRepository/observers/getMessages/MessageLiveCollectionController.ts +2 -0
  124. package/src/messageRepository/observers/getMessages/MessageQueryStreamController.ts +13 -0
  125. package/src/postRepository/api/createPost.ts +3 -2
  126. package/src/postRepository/utils/payload.ts +37 -1
  127. package/src/streamRepository/api/createStream.ts +4 -1
  128. package/src/streamRepository/api/editStream.ts +51 -0
  129. package/src/streamRepository/api/index.ts +1 -0
  130. package/src/streamRepository/api/updateStream.ts +8 -1
  131. package/src/streamRepository/events/onStreamViewerBanned.ts +58 -0
  132. package/src/streamRepository/events/onStreamViewerUnbanned.ts +47 -0
  133. package/src/streamRepository/internalApi/getLiveChat.ts +59 -0
  134. package/src/streamRepository/internalApi/getStream.ts +3 -3
  135. package/src/streamRepository/observers/getStreamById.ts +2 -0
  136. package/src/streamRepository/observers/getStreams/GetStreamsLiveCollectionController.ts +5 -1
  137. package/src/utils/linkedObject/postLinkedObject.ts +28 -2
  138. package/src/utils/linkedObject/streamLinkedObject.ts +4 -0
  139. package/src/utils/postTypePredicate.ts +18 -0
  140. package/dist/channelRepository/events/onChannelMuted.d.ts +0 -2
  141. package/dist/channelRepository/events/onChannelMuted.d.ts.map +0 -1
  142. package/src/channelRepository/events/onChannelMuted.ts +0 -39
@@ -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
+ };
@@ -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);
@@ -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
+ };
@@ -0,0 +1,59 @@
1
+ import { getActiveClient } from '~/client/api/activeClient';
2
+ import { mergeInCache, pullFromCache } from '~/cache/api';
3
+ import { createChannel } from '~/channelRepository/api/createChannel';
4
+ import { channelLinkedObject } from '~/utils/linkedObject/channelLinkedObject';
5
+ import { getChannel } from '~/channelRepository/internalApi/getChannel';
6
+ import { constructChannelObject } from '~/channelRepository/utils/constructChannelObject';
7
+
8
+ /**
9
+ * ```js
10
+ * import { getStream } from '@amityco/ts-sdk'
11
+ * const stream = await getStream('foobar')
12
+ * ```
13
+ *
14
+ * Fetches a {@link Amity.Channel} object linked with a current stream
15
+ *
16
+ * @param stream {@link Amity.Stream} that has linked live channel
17
+ * @returns the associated {@link Amity.Channel<'live'>} object
18
+ *
19
+ * @category Stream API
20
+ * @async
21
+ */
22
+
23
+ export const getLiveChat = async (
24
+ stream: Amity.InternalStream,
25
+ ): Promise<Amity.Channel<'live'> | undefined> => {
26
+ const client = getActiveClient();
27
+ client.log('stream/getLiveChat', stream.streamId);
28
+
29
+ if (stream.channelId) {
30
+ const channel = pullFromCache<Amity.StaticInternalChannel>([
31
+ 'channel',
32
+ 'get',
33
+ stream.channelId,
34
+ ])?.data;
35
+
36
+ if (channel) return channelLinkedObject(constructChannelObject(channel));
37
+
38
+ const { data } = await getChannel(stream.channelId);
39
+ return channelLinkedObject(constructChannelObject(data));
40
+ }
41
+ // No Channel ID
42
+ // streamer: create a new live channel
43
+ if (stream.userId === client.userId) {
44
+ const { data: channel } = await createChannel({
45
+ type: 'live',
46
+ postId: stream.postId,
47
+ videoStreamId: stream.streamId,
48
+ });
49
+
50
+ // Update channelId to stream object in cache
51
+ mergeInCache(['stream', 'get', stream.streamId], {
52
+ channelId: channel.channelId,
53
+ });
54
+
55
+ return channel;
56
+ }
57
+ // watcher: return undefined
58
+ return undefined;
59
+ };
@@ -22,7 +22,7 @@ import { ingestInCache } from '~/cache/api/ingestInCache';
22
22
  */
23
23
  export const getStream = async (
24
24
  streamId: Amity.Stream['streamId'],
25
- ): Promise<Amity.Cached<Amity.Stream>> => {
25
+ ): Promise<Amity.Cached<Amity.InternalStream>> => {
26
26
  const client = getActiveClient();
27
27
  client.log('stream/getStream', streamId);
28
28
 
@@ -57,13 +57,13 @@ export const getStream = async (
57
57
  */
58
58
  getStream.locally = (
59
59
  streamId: Amity.Stream['streamId'],
60
- ): Amity.Cached<Amity.Stream> | undefined => {
60
+ ): Amity.Cached<Amity.InternalStream> | undefined => {
61
61
  const client = getActiveClient();
62
62
  client.log('stream/getStream', streamId);
63
63
 
64
64
  if (!client.cache) return;
65
65
 
66
- const cached = pullFromCache<Amity.Stream>(['stream', 'get', streamId]);
66
+ const cached = pullFromCache<Amity.InternalStream>(['stream', 'get', streamId]);
67
67
 
68
68
  if (!cached) return;
69
69
 
@@ -8,6 +8,7 @@ import { onStreamTerminated } from '~/streamRepository/events/onStreamTerminated
8
8
  import { LinkedObject } from '~/utils/linkedObject';
9
9
  import { getStream as _getStream } from '../internalApi/getStream';
10
10
  import { onStreamRecorded, onStreamStarted, onStreamStopped } from '../events';
11
+ import { onStreamViewerBanned } from '../events/onStreamViewerBanned';
11
12
 
12
13
  /* begin_public_function
13
14
  id: stream.get
@@ -45,6 +46,7 @@ export const getStreamById = (
45
46
  onStreamStopped,
46
47
  onStreamFlagged,
47
48
  onStreamTerminated,
49
+ onStreamViewerBanned,
48
50
  ]);
49
51
  };
50
52
  /* end_public_function */
@@ -12,6 +12,8 @@ import {
12
12
  } from '~/streamRepository/events';
13
13
  import { GetStreamsPageController } from '~/streamRepository/observers/getStreams/GetStreamsPageController';
14
14
  import { GetStreamsQueryStreamController } from '~/streamRepository/observers/getStreams/GetStreamsQueryStreamController';
15
+ import { onStreamViewerBanned } from '~/streamRepository/events/onStreamViewerBanned';
16
+ import { onStreamViewerUnbanned } from '~/streamRepository/events/onStreamViewerUnbanned';
15
17
 
16
18
  export class GetStreamsLiveCollectionController extends LiveCollectionController<
17
19
  'stream',
@@ -77,6 +79,8 @@ export class GetStreamsLiveCollectionController extends LiveCollectionController
77
79
  { fn: onStreamStopped, action: 'onStreamStopped' },
78
80
  { fn: onStreamFlagged, action: 'onStreamFlagged' },
79
81
  { fn: onStreamTerminated, action: 'onStreamTerminated' },
82
+ { fn: onStreamViewerBanned, action: 'onStreamViewerBanned' },
83
+ { fn: onStreamViewerUnbanned, action: 'onStreamViewerUnbanned' },
80
84
  ]);
81
85
  }
82
86
 
@@ -102,7 +106,7 @@ export class GetStreamsLiveCollectionController extends LiveCollectionController
102
106
  this.queryStreamController.appendToQueryStream(response, direction, refresh);
103
107
  }
104
108
 
105
- private applyFilter = (data: Amity.InternalStream[]): Amity.InternalStream[] => {
109
+ private applyFilter = (data: Amity.Stream[]): Amity.Stream[] => {
106
110
  let streams = filterByPropEquality(data, 'isDeleted', this.query.isDeleted);
107
111
 
108
112
  streams = streams.sort(