@amityco/ts-sdk 7.5.4-ec2fdd4.0 → 7.6.1-09fb578a.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 (159) 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/group.d.ts +2 -0
  8. package/dist/@types/domains/group.d.ts.map +1 -1
  9. package/dist/@types/domains/liveReaction.d.ts +20 -0
  10. package/dist/@types/domains/liveReaction.d.ts.map +1 -0
  11. package/dist/@types/domains/post.d.ts +3 -0
  12. package/dist/@types/domains/post.d.ts.map +1 -1
  13. package/dist/@types/domains/stream.d.ts +9 -1
  14. package/dist/@types/domains/stream.d.ts.map +1 -1
  15. package/dist/@types/index.d.ts +1 -0
  16. package/dist/@types/index.d.ts.map +1 -1
  17. package/dist/channelRepository/api/createChannel.d.ts +3 -1
  18. package/dist/channelRepository/api/createChannel.d.ts.map +1 -1
  19. package/dist/channelRepository/channelMembership/observers/getMembers/ChannelMemberLiveCollectionController.d.ts.map +1 -1
  20. package/dist/channelRepository/channelMembership/observers/searchMembers/SearchChannelMemberLiveCollectionController.d.ts.map +1 -1
  21. package/dist/channelRepository/channelMembership/observers/searchMembers/SearchChannelMemberQueryStreamController.d.ts +2 -2
  22. package/dist/channelRepository/channelMembership/observers/searchMembers/SearchChannelMemberQueryStreamController.d.ts.map +1 -1
  23. package/dist/channelRepository/events/index.d.ts +1 -1
  24. package/dist/channelRepository/events/index.d.ts.map +1 -1
  25. package/dist/channelRepository/events/onChannelSetMuted.d.ts +2 -0
  26. package/dist/channelRepository/events/onChannelSetMuted.d.ts.map +1 -0
  27. package/dist/channelRepository/events/onChannelSetUserMuted.d.ts +2 -0
  28. package/dist/channelRepository/events/onChannelSetUserMuted.d.ts.map +1 -0
  29. package/dist/channelRepository/internalApi/getChannel.d.ts.map +1 -1
  30. package/dist/channelRepository/observers/getChannels/ChannelLiveCollectionController.d.ts.map +1 -1
  31. package/dist/client/api/login.d.ts.map +1 -1
  32. package/dist/core/events.d.ts +3 -3
  33. package/dist/core/events.d.ts.map +1 -1
  34. package/dist/core/subscription.d.ts +2 -1
  35. package/dist/core/subscription.d.ts.map +1 -1
  36. package/dist/index.cjs.js +6267 -5651
  37. package/dist/index.d.ts +1 -0
  38. package/dist/index.d.ts.map +1 -1
  39. package/dist/index.esm.js +6191 -5577
  40. package/dist/index.umd.js +3 -3
  41. package/dist/liveReactionRepository/api/createReaction.d.ts +20 -0
  42. package/dist/liveReactionRepository/api/createReaction.d.ts.map +1 -0
  43. package/dist/liveReactionRepository/api/index.d.ts +2 -0
  44. package/dist/liveReactionRepository/api/index.d.ts.map +1 -0
  45. package/dist/liveReactionRepository/events/index.d.ts +2 -0
  46. package/dist/liveReactionRepository/events/index.d.ts.map +1 -0
  47. package/dist/liveReactionRepository/events/onLiveReactionCreated.d.ts +17 -0
  48. package/dist/liveReactionRepository/events/onLiveReactionCreated.d.ts.map +1 -0
  49. package/dist/liveReactionRepository/events/onLiveReactionCreatedLocal.d.ts +17 -0
  50. package/dist/liveReactionRepository/events/onLiveReactionCreatedLocal.d.ts.map +1 -0
  51. package/dist/liveReactionRepository/index.d.ts +4 -0
  52. package/dist/liveReactionRepository/index.d.ts.map +1 -0
  53. package/dist/liveReactionRepository/internalApi/createLiveReaction.d.ts +20 -0
  54. package/dist/liveReactionRepository/internalApi/createLiveReaction.d.ts.map +1 -0
  55. package/dist/liveReactionRepository/observers/getReactions.d.ts +19 -0
  56. package/dist/liveReactionRepository/observers/getReactions.d.ts.map +1 -0
  57. package/dist/liveReactionRepository/observers/index.d.ts +2 -0
  58. package/dist/liveReactionRepository/observers/index.d.ts.map +1 -0
  59. package/dist/liveReactionRepository/service/ReactionSyncEngine.d.ts +26 -0
  60. package/dist/liveReactionRepository/service/ReactionSyncEngine.d.ts.map +1 -0
  61. package/dist/liveReactionRepository/utils/ReactionSyncEngineOnLoginHandler.d.ts +3 -0
  62. package/dist/liveReactionRepository/utils/ReactionSyncEngineOnLoginHandler.d.ts.map +1 -0
  63. package/dist/messagePreview/utils/getChannelMessagePreviewWithUser.d.ts +4 -0
  64. package/dist/messagePreview/utils/getChannelMessagePreviewWithUser.d.ts.map +1 -1
  65. package/dist/messageRepository/api/deleteMessage.d.ts.map +1 -1
  66. package/dist/messageRepository/observers/getMessage.d.ts.map +1 -1
  67. package/dist/messageRepository/observers/getMessages/MessageLiveCollectionController.d.ts.map +1 -1
  68. package/dist/messageRepository/observers/getMessages/MessageQueryStreamController.d.ts.map +1 -1
  69. package/dist/postRepository/api/createPost.d.ts.map +1 -1
  70. package/dist/postRepository/utils/payload.d.ts.map +1 -1
  71. package/dist/streamRepository/api/createStream.d.ts +1 -1
  72. package/dist/streamRepository/api/createStream.d.ts.map +1 -1
  73. package/dist/streamRepository/api/editStream.d.ts +18 -0
  74. package/dist/streamRepository/api/editStream.d.ts.map +1 -0
  75. package/dist/streamRepository/api/index.d.ts +1 -0
  76. package/dist/streamRepository/api/index.d.ts.map +1 -1
  77. package/dist/streamRepository/api/updateStream.d.ts +4 -1
  78. package/dist/streamRepository/api/updateStream.d.ts.map +1 -1
  79. package/dist/streamRepository/events/onStreamViewerBanned.d.ts +17 -0
  80. package/dist/streamRepository/events/onStreamViewerBanned.d.ts.map +1 -0
  81. package/dist/streamRepository/events/onStreamViewerUnbanned.d.ts +17 -0
  82. package/dist/streamRepository/events/onStreamViewerUnbanned.d.ts.map +1 -0
  83. package/dist/streamRepository/internalApi/getLiveChat.d.ts +16 -0
  84. package/dist/streamRepository/internalApi/getLiveChat.d.ts.map +1 -0
  85. package/dist/streamRepository/internalApi/getStream.d.ts +2 -2
  86. package/dist/streamRepository/internalApi/getStream.d.ts.map +1 -1
  87. package/dist/streamRepository/observers/getStreamById.d.ts.map +1 -1
  88. package/dist/streamRepository/observers/getStreams/GetStreamsLiveCollectionController.d.ts.map +1 -1
  89. package/dist/utils/linkedObject/channelLinkedObject.d.ts.map +1 -1
  90. package/dist/utils/linkedObject/channelMemberLinkedObject.d.ts +2 -0
  91. package/dist/utils/linkedObject/channelMemberLinkedObject.d.ts.map +1 -0
  92. package/dist/utils/linkedObject/index.d.ts +1 -0
  93. package/dist/utils/linkedObject/index.d.ts.map +1 -1
  94. package/dist/utils/linkedObject/postLinkedObject.d.ts.map +1 -1
  95. package/dist/utils/linkedObject/streamLinkedObject.d.ts.map +1 -1
  96. package/dist/utils/postTypePredicate.d.ts +5 -3
  97. package/dist/utils/postTypePredicate.d.ts.map +1 -1
  98. package/dist/utils/tests/dummy/community.d.ts +2 -0
  99. package/dist/utils/tests/dummy/community.d.ts.map +1 -1
  100. package/package.json +1 -1
  101. package/src/@types/core/events.ts +9 -1
  102. package/src/@types/core/payload.ts +32 -0
  103. package/src/@types/domains/channel.ts +7 -0
  104. package/src/@types/domains/group.ts +2 -0
  105. package/src/@types/domains/liveReaction.ts +25 -0
  106. package/src/@types/domains/post.ts +3 -0
  107. package/src/@types/domains/stream.ts +12 -1
  108. package/src/@types/index.ts +1 -0
  109. package/src/channelRepository/api/createChannel.ts +12 -9
  110. package/src/channelRepository/channelMembership/observers/getMembers/ChannelMemberLiveCollectionController.ts +5 -1
  111. package/src/channelRepository/channelMembership/observers/searchMembers/SearchChannelMemberLiveCollectionController.ts +2 -1
  112. package/src/channelRepository/channelMembership/observers/searchMembers/SearchChannelMemberQueryStreamController.ts +2 -2
  113. package/src/channelRepository/events/index.ts +1 -1
  114. package/src/channelRepository/events/onChannelSetMuted.ts +48 -0
  115. package/src/channelRepository/events/onChannelSetUserMuted.ts +67 -0
  116. package/src/channelRepository/internalApi/getChannel.ts +0 -1
  117. package/src/channelRepository/observers/getChannel.ts +2 -2
  118. package/src/channelRepository/observers/getChannels/ChannelLiveCollectionController.ts +2 -2
  119. package/src/channelRepository/utils/constructChannelObject.ts +2 -2
  120. package/src/client/api/login.ts +2 -0
  121. package/src/core/events.ts +1 -0
  122. package/src/core/subscription.ts +10 -6
  123. package/src/index.ts +2 -0
  124. package/src/liveReactionRepository/api/createReaction.ts +58 -0
  125. package/src/liveReactionRepository/api/index.ts +1 -0
  126. package/src/liveReactionRepository/events/index.ts +1 -0
  127. package/src/liveReactionRepository/events/onLiveReactionCreated.ts +37 -0
  128. package/src/liveReactionRepository/events/onLiveReactionCreatedLocal.ts +29 -0
  129. package/src/liveReactionRepository/index.ts +3 -0
  130. package/src/liveReactionRepository/internalApi/createLiveReaction.ts +42 -0
  131. package/src/liveReactionRepository/observers/getReactions.ts +59 -0
  132. package/src/liveReactionRepository/observers/index.ts +1 -0
  133. package/src/liveReactionRepository/service/ReactionSyncEngine.ts +138 -0
  134. package/src/liveReactionRepository/utils/ReactionSyncEngineOnLoginHandler.ts +19 -0
  135. package/src/messageRepository/api/deleteMessage.ts +16 -0
  136. package/src/messageRepository/observers/getMessage.ts +2 -0
  137. package/src/messageRepository/observers/getMessages/MessageLiveCollectionController.ts +2 -0
  138. package/src/messageRepository/observers/getMessages/MessageQueryStreamController.ts +13 -0
  139. package/src/postRepository/api/createPost.ts +3 -2
  140. package/src/postRepository/utils/payload.ts +37 -1
  141. package/src/streamRepository/api/createStream.ts +4 -1
  142. package/src/streamRepository/api/editStream.ts +51 -0
  143. package/src/streamRepository/api/index.ts +1 -0
  144. package/src/streamRepository/api/updateStream.ts +8 -1
  145. package/src/streamRepository/events/onStreamViewerBanned.ts +58 -0
  146. package/src/streamRepository/events/onStreamViewerUnbanned.ts +47 -0
  147. package/src/streamRepository/internalApi/getLiveChat.ts +59 -0
  148. package/src/streamRepository/internalApi/getStream.ts +3 -3
  149. package/src/streamRepository/observers/getStreamById.ts +2 -0
  150. package/src/streamRepository/observers/getStreams/GetStreamsLiveCollectionController.ts +5 -1
  151. package/src/utils/linkedObject/channelLinkedObject.ts +19 -0
  152. package/src/utils/linkedObject/channelMemberLinkedObject.ts +20 -0
  153. package/src/utils/linkedObject/index.ts +2 -0
  154. package/src/utils/linkedObject/postLinkedObject.ts +32 -2
  155. package/src/utils/linkedObject/streamLinkedObject.ts +4 -0
  156. package/src/utils/postTypePredicate.ts +26 -3
  157. package/dist/channelRepository/events/onChannelMuted.d.ts +0 -2
  158. package/dist/channelRepository/events/onChannelMuted.d.ts.map +0 -1
  159. package/src/channelRepository/events/onChannelMuted.ts +0 -39
@@ -15,6 +15,8 @@ declare global {
15
15
 
16
16
  type Member<T extends Amity.GroupType> = {
17
17
  userId: Amity.InternalUser['userId'];
18
+ userInternalId: Amity.InternalUser['userInternalId'];
19
+ userPublicId: Amity.InternalUser['userPublicId'];
18
20
  } & (T extends 'channel'
19
21
  ? {
20
22
  channelId: Amity.Channel['channelId'];
@@ -0,0 +1,25 @@
1
+ export {};
2
+
3
+ declare global {
4
+ namespace Amity {
5
+ type RawLiveReaction = {
6
+ userId: string; // user's public ID
7
+ referenceId: string; // post's internal ID
8
+ referencePublicId: string; // post's public ID
9
+ referenceType: string; // 'post'
10
+ reactionName: string; // 'love
11
+ // date string in ISO format
12
+ occurredAt: string;
13
+ };
14
+
15
+ type InternalLiveReaction = RawLiveReaction;
16
+
17
+ type LiveReaction = InternalLiveReaction;
18
+
19
+ type CreateLiveReactionRequest = Omit<RawLiveReaction, 'userId' | 'referenceId' | 'occurredAt'>;
20
+
21
+ type CreateLiveReactionResponse = {
22
+ addedIds: string[];
23
+ };
24
+ }
25
+ }
@@ -73,6 +73,7 @@ declare global {
73
73
  };
74
74
 
75
75
  type PostLinkObject = {
76
+ childrenPosts: Amity.Post[];
76
77
  latestComments: (Amity.Comment | null)[];
77
78
  creator: Amity.User | undefined;
78
79
  analytics: {
@@ -82,6 +83,8 @@ declare global {
82
83
  getVideoInfo: () => Amity.File<'video'> | undefined;
83
84
  getVideoThumbnailInfo: () => Amity.File<'image'> | undefined;
84
85
  getFileInfo: () => Amity.File<'file'> | undefined;
86
+ getPollInfo: () => Amity.Poll | undefined;
87
+ getLivestreamInfo: () => Amity.Stream | undefined;
85
88
  };
86
89
 
87
90
  type Post<T extends PostContentType = any> = Amity.InternalPost<T> & Amity.PostLinkObject;
@@ -73,6 +73,12 @@ declare global {
73
73
  */
74
74
  targetId?: string; // communityId, userId, etc..
75
75
  targetType?: string; // 'community', 'user', etc..
76
+ /*
77
+ * when stream linked with a post and a live channel.
78
+ */
79
+ postId?: string;
80
+ channelId?: string;
81
+ channelEnabled?: boolean;
76
82
  } & Amity.Metadata &
77
83
  Amity.Timestamps &
78
84
  Amity.SoftDelete;
@@ -81,9 +87,14 @@ declare global {
81
87
 
82
88
  type StreamLinkedObject = {
83
89
  moderation?: Amity.StreamModeration;
90
+ post?: Amity.InternalPost;
91
+ getLiveChat: () => Promise<Amity.Channel<'live'> | undefined>;
84
92
  };
85
93
 
86
- type Stream = Amity.InternalStream & Amity.StreamLinkedObject;
94
+ type Stream = Omit<Amity.InternalStream & Amity.StreamLinkedObject, 'watcherUrl'> & {
95
+ isBanned: boolean;
96
+ watcherUrl: null;
97
+ };
87
98
 
88
99
  type QueryStreams = {
89
100
  isLive?: boolean;
@@ -43,3 +43,4 @@ export * from './domains/invitation';
43
43
  export * from './domains/joinRequest';
44
44
  export * from './domains/pin';
45
45
  export * from './domains/pinnedPost';
46
+ export * from './domains/liveReaction';
@@ -1,9 +1,9 @@
1
- import { getActiveClient } from '~/client/api';
1
+ import { getActiveClient } from '~/client/api/activeClient';
2
2
 
3
3
  import { ingestInCache } from '~/cache/api/ingestInCache';
4
4
 
5
- import { prepareChannelPayload } from '../utils';
6
- import { constructChannelDynamicValue } from '../utils/constructChannelDynamicValue';
5
+ import { prepareChannelPayload } from '../utils/prepareChannelPayload';
6
+ import { constructChannelObject } from '../utils/constructChannelObject';
7
7
 
8
8
  /* begin_public_function
9
9
  id: channel.create
@@ -23,11 +23,14 @@ import { constructChannelDynamicValue } from '../utils/constructChannelDynamicVa
23
23
  * @async
24
24
  */
25
25
  export const createChannel = async <T extends Amity.ChannelType>(
26
- bundle: { type: T; userIds?: Amity.InternalUser['userId'][] } & Pick<
27
- Amity.Channel<T>,
28
- 'displayName' | 'avatarFileId' | 'tags' | 'metadata' | 'isPublic'
29
- >,
30
- ): Promise<Amity.Cached<Amity.InternalChannel>> => {
26
+ bundle: {
27
+ type: T;
28
+ userIds?: Amity.InternalUser['userId'][];
29
+ // For live channel linked with a livestream post
30
+ videoStreamId?: string;
31
+ postId?: string;
32
+ } & Pick<Amity.Channel<T>, 'displayName' | 'avatarFileId' | 'tags' | 'metadata' | 'isPublic'>,
33
+ ): Promise<Amity.Cached<Amity.Channel<T>>> => {
31
34
  const client = getActiveClient();
32
35
  client.log('user/createChannel', bundle);
33
36
 
@@ -53,7 +56,7 @@ export const createChannel = async <T extends Amity.ChannelType>(
53
56
 
54
57
  const { channels } = data;
55
58
  return {
56
- data: constructChannelDynamicValue(channels[0]),
59
+ data: constructChannelObject(channels[0]),
57
60
  cachedAt,
58
61
  };
59
62
  };
@@ -23,6 +23,8 @@ import {
23
23
  } from '~/core/query';
24
24
  import { prepareChannelPayload } from '~/channelRepository/utils';
25
25
  import { onUserDeleted } from '~/channelRepository/events/onUserDeleted';
26
+ import { LinkedObject } from '~/utils/linkedObject';
27
+ import { onChannelSetUserMuted } from '~/channelRepository/events/onChannelSetUserMuted';
26
28
 
27
29
  export class ChannelMemberLiveCollectionController extends LiveCollectionController<
28
30
  'channelUser',
@@ -88,6 +90,7 @@ export class ChannelMemberLiveCollectionController extends LiveCollectionControl
88
90
  { fn: onChannelMemberUnbanned, action: 'onChannelMemberUnbanned' },
89
91
  { fn: onChannelMemberRoleAdded, action: 'onChannelMemberRoleAdded' },
90
92
  { fn: onChannelMemberRoleRemoved, action: 'onChannelMemberRoleRemoved' },
93
+ { fn: onChannelSetUserMuted, action: 'onChannelSetUserMuted' },
91
94
  { fn: onUserDeleted(this.query.channelId), action: 'onChannelMemberChanged' },
92
95
  ]);
93
96
  }
@@ -100,7 +103,8 @@ export class ChannelMemberLiveCollectionController extends LiveCollectionControl
100
103
  collection.data
101
104
  .map(id => pullFromCache<Amity.Membership<'channel'>>(['channelUsers', 'get', id])!)
102
105
  .filter(Boolean)
103
- .map(({ data }) => data) ?? [],
106
+ .map(({ data }) => data)
107
+ .map(LinkedObject.channelMember) ?? [],
104
108
  );
105
109
 
106
110
  if (!this.shouldNotify(data) && origin === 'event') return;
@@ -17,6 +17,7 @@ import {
17
17
  import { filterByPropIntersection, filterBySearchTerm } from '~/core/query';
18
18
  import { prepareChannelPayload } from '~/channelRepository/utils';
19
19
  import { onUserDeleted } from '~/channelRepository/events/onUserDeleted';
20
+ import { LinkedObject } from '~/utils/linkedObject';
20
21
 
21
22
  export class SearchChannelMemberLiveCollectionController extends LiveCollectionController<
22
23
  'channelUser',
@@ -94,7 +95,7 @@ export class SearchChannelMemberLiveCollectionController extends LiveCollectionC
94
95
  collection.data
95
96
  .map(id => pullFromCache<Amity.Membership<'channel'>>(['channelUsers', 'get', id])!)
96
97
  .filter(Boolean)
97
- .map(({ data }) => data) ?? [],
98
+ .map(({ data }) => LinkedObject.channelMember(data) ?? []),
98
99
  );
99
100
 
100
101
  if (!this.shouldNotify(data) && origin === 'event') return;
@@ -72,7 +72,7 @@ export class SearchChannelMemberQueryStreamController extends QueryStreamControl
72
72
  }
73
73
 
74
74
  reactor(action: string) {
75
- return (channel: Amity.InternalChannel, channelMember: Amity.Membership<'channel'>) => {
75
+ return (channel: Amity.StaticInternalChannel, channelMember: Amity.Membership<'channel'>) => {
76
76
  if (this.query.channelId !== channelMember.channelId) return;
77
77
 
78
78
  const collection = pullFromCache<Amity.ChannelMembersLiveCollectionCache>(
@@ -100,7 +100,7 @@ export class SearchChannelMemberQueryStreamController extends QueryStreamControl
100
100
  createSubscriber: {
101
101
  fn: (
102
102
  reactor: (
103
- channel: Amity.InternalChannel,
103
+ channel: Amity.StaticInternalChannel,
104
104
  channelMember: Amity.Membership<'channel'>,
105
105
  ) => void,
106
106
  ) => Amity.Unsubscriber;
@@ -4,7 +4,7 @@ export * from './onChannelDeleted';
4
4
 
5
5
  export * from './onChannelJoined';
6
6
  export * from './onChannelLeft';
7
- export * from './onChannelMuted';
7
+ export * from './onChannelSetMuted';
8
8
 
9
9
  export * from './onChannelMemberAdded';
10
10
  export * from './onChannelMemberRemoved';
@@ -0,0 +1,48 @@
1
+ import { getActiveClient } from '~/client/api/activeClient';
2
+ import { createEventSubscriber } from '~/core/events';
3
+ import { pullFromCache, upsertInCache } from '~/cache/api';
4
+
5
+ type CallbackFn = Amity.Listener<Amity.StaticInternalChannel>;
6
+ const callbacks: CallbackFn[] = [];
7
+ let mainDisposer: (() => void) | null = null;
8
+
9
+ const dispose = (cb: CallbackFn) => {
10
+ const index = callbacks.indexOf(cb);
11
+ if (index > -1) {
12
+ callbacks.splice(index, 1);
13
+ }
14
+ if (callbacks.length === 0) {
15
+ mainDisposer?.();
16
+ }
17
+ };
18
+
19
+ export const onChannelSetMuted = (callback: Amity.Listener<Amity.StaticInternalChannel>) => {
20
+ if (callbacks.length === 0) {
21
+ const client = getActiveClient();
22
+
23
+ const filter = async (payloads: Amity.ChannelSetMutedPayload) => {
24
+ payloads.forEach(payload => {
25
+ upsertInCache(['channel', 'get', payload.channelId], {
26
+ // If muteTimeout > now => user is muted
27
+ // Otherwise => user is unmuted
28
+ isMuted: Date.parse(payload.muteTimeout) > Date.now(),
29
+ });
30
+ });
31
+
32
+ const channel = pullFromCache<Amity.StaticInternalChannel>([
33
+ 'channel',
34
+ 'get',
35
+ payloads[0].channelId,
36
+ ])?.data;
37
+
38
+ if (channel) {
39
+ callbacks.forEach(cb => cb(channel));
40
+ }
41
+ };
42
+
43
+ mainDisposer = createEventSubscriber(client, 'onChannelMute', 'channel.setMuted', filter);
44
+ }
45
+
46
+ callbacks.push(callback);
47
+ return () => dispose(callback);
48
+ };
@@ -0,0 +1,67 @@
1
+ import { getActiveClient } from '~/client/api/activeClient';
2
+ import { createEventSubscriber } from '~/core/events';
3
+
4
+ import { pullFromCache, upsertInCache } from '~/cache/api';
5
+
6
+ type CallbackFn = (
7
+ channel: Amity.StaticInternalChannel,
8
+ member: Amity.Membership<'channel'>,
9
+ ) => void;
10
+ const callbacks: CallbackFn[] = [];
11
+ let mainDisposer: (() => void) | null = null;
12
+
13
+ const dispose = (cb: CallbackFn) => {
14
+ const index = callbacks.indexOf(cb);
15
+ if (index > -1) {
16
+ callbacks.splice(index, 1);
17
+ }
18
+ if (callbacks.length === 0) {
19
+ mainDisposer?.();
20
+ }
21
+ };
22
+
23
+ export const onChannelSetUserMuted = (
24
+ callback: (channel: Amity.StaticInternalChannel, member: Amity.Membership<'channel'>) => void,
25
+ ): Amity.Unsubscriber => {
26
+ if (callbacks.length === 0) {
27
+ const client = getActiveClient();
28
+
29
+ const filter = async (payloads: Amity.ChannelSetUserMutedPayload) => {
30
+ payloads.forEach(payload => {
31
+ payload.userIds.forEach(userId =>
32
+ // If muteTimeout > now => user is muted
33
+ // Otherwise => user is unmuted
34
+ upsertInCache(['channelUsers', 'get', `${payload.channelId}#${userId}`], {
35
+ isMuted: Date.parse(payload.muteTimeout) > Date.now(),
36
+ }),
37
+ );
38
+ });
39
+
40
+ const channel = pullFromCache<Amity.StaticInternalChannel>([
41
+ 'channel',
42
+ 'get',
43
+ payloads[0].channelId,
44
+ ])?.data;
45
+
46
+ const channelUser = pullFromCache<Amity.Membership<'channel'>>([
47
+ 'channelUsers',
48
+ 'get',
49
+ `${payloads[0].channelId}#${payloads[0].userIds[0]}`,
50
+ ])?.data;
51
+
52
+ if (channel && channelUser) {
53
+ callbacks.forEach(cb => cb(channel, channelUser));
54
+ }
55
+ };
56
+
57
+ mainDisposer = createEventSubscriber(
58
+ client,
59
+ 'onChannelUserMute',
60
+ 'channel.setUserMuted',
61
+ filter,
62
+ );
63
+ }
64
+
65
+ callbacks.push(callback);
66
+ return () => dispose(callback);
67
+ };
@@ -9,7 +9,6 @@ import { pushToTombstone } from '~/cache/api/pushToTombstone';
9
9
 
10
10
  import { prepareChannelPayload } from '../utils';
11
11
  import { prepareUnreadCountInfo } from '../utils/prepareUnreadCountInfo';
12
- import { constructChannelDynamicValue } from '../utils/constructChannelDynamicValue';
13
12
 
14
13
  /**
15
14
  * ```js
@@ -10,7 +10,7 @@ import {
10
10
  onChannelMemberBanned,
11
11
  onChannelMemberRemoved,
12
12
  onChannelMemberUnbanned,
13
- onChannelMuted,
13
+ onChannelSetMuted,
14
14
  onChannelUpdated,
15
15
  } from '../events';
16
16
  import { dropFromCache, pullFromCache } from '~/cache/api';
@@ -104,7 +104,7 @@ export const getChannel = (
104
104
  onChannelMemberRemoved,
105
105
  onChannelMemberBanned,
106
106
  onChannelMemberUnbanned,
107
- onChannelMuted,
107
+ onChannelSetMuted,
108
108
  convertEventPayload(onChannelMarkerFetched, 'entityId', 'channel'),
109
109
  convertEventPayload(onChannelMarkerUpdated, 'entityId', 'channel'),
110
110
  convertEventPayload(
@@ -11,7 +11,6 @@ import {
11
11
  onChannelLeft,
12
12
  onChannelMemberAdded,
13
13
  onChannelMemberRemoved,
14
- onChannelMuted,
15
14
  onChannelUpdated,
16
15
  } from '~/channelRepository/events';
17
16
  import {
@@ -58,6 +57,7 @@ import { onUserMessageFeedMarkerResolved } from '~/marker/events/onUserMessageFe
58
57
  import { onChannelUnreadInfoUpdatedLocal } from '~/marker/events/onChannelUnreadInfoUpdatedLocal';
59
58
  import { constructChannelObject } from '~/channelRepository/utils/constructChannelObject';
60
59
  import { onChannelUnreadUpdatedLocal } from '~/channelRepository/events/onChannelUnreadUpdatedLocal';
60
+ import { onChannelSetMuted } from '~/channelRepository/events/onChannelSetMuted';
61
61
 
62
62
  export class ChannelLiveCollectionController extends LiveCollectionController<
63
63
  'channel',
@@ -313,7 +313,7 @@ export class ChannelLiveCollectionController extends LiveCollectionController<
313
313
  },
314
314
  { fn: onChannelDeleted, action: Amity.ChannelActionType.OnDelete },
315
315
  { fn: onChannelUpdated, action: Amity.ChannelActionType.OnUpdate },
316
- { fn: onChannelMuted, action: Amity.ChannelActionType.OnMute },
316
+ { fn: onChannelSetMuted, action: Amity.ChannelActionType.OnMute },
317
317
  {
318
318
  fn: (callback: Amity.Listener<Amity.StaticInternalChannel>) => {
319
319
  return onChannelJoined(channel => {
@@ -1,6 +1,6 @@
1
1
  import { getChannelMessagePreviewWithUser } from '~/messagePreview/utils';
2
2
  import { constructChannelDynamicValue } from './constructChannelDynamicValue';
3
- import { LinkedObject } from '~/utils/linkedObject';
3
+ import { channelLinkedObject } from '~/utils/linkedObject/channelLinkedObject';
4
4
 
5
5
  export const constructChannelObject = (channel: Amity.StaticInternalChannel): Amity.Channel => {
6
6
  /**
@@ -10,7 +10,7 @@ export const constructChannelObject = (channel: Amity.StaticInternalChannel): Am
10
10
  * 3. [LinkedObject.channel] add markAsRead >> Amity.InternalChannel -> Amity.Channel
11
11
  */
12
12
 
13
- return LinkedObject.channel(
13
+ return channelLinkedObject(
14
14
  constructChannelDynamicValue(getChannelMessagePreviewWithUser(channel)),
15
15
  );
16
16
  };
@@ -13,6 +13,7 @@ import analyticsEngineOnLoginHandler from '~/analytic/utils/analyticsEngineOnLog
13
13
  import readReceiptSyncEngineOnLoginHandler from '~/client/utils/ReadReceiptSync/readReceiptSyncEngineOnLoginHandler';
14
14
  import legacyReadReceiptSyncEngineOnLoginHandler from '~/client/utils/ReadReceiptSync/legacyReadReceiptSyncEngineOnLoginHandler';
15
15
  import objectResolverEngineOnLoginHandler from '~/client/utils/ObjectResolver/objectResolverEngineOnLoginHandler';
16
+ import reactionSyncEngineOnLoginHandler from '~/liveReactionRepository/utils/ReactionSyncEngineOnLoginHandler';
16
17
  import { logout } from './logout';
17
18
 
18
19
  import { getActiveClient } from './activeClient';
@@ -201,6 +202,7 @@ export const login = async (
201
202
  markReadEngineOnLoginHandler(),
202
203
  analyticsEngineOnLoginHandler(),
203
204
  objectResolverEngineOnLoginHandler(),
205
+ reactionSyncEngineOnLoginHandler(),
204
206
  );
205
207
 
206
208
  if (client.useLegacyUnreadCount) {
@@ -33,6 +33,7 @@ const MQTT_EVENTS = [
33
33
  'video-streaming.didTerminate',
34
34
 
35
35
  // 'user.didGlobalBan' remove due to message event,
36
+ 'liveReaction.created',
36
37
  ] as const;
37
38
 
38
39
  /** @hidden */
@@ -154,6 +154,16 @@ export const getSmartFeedMessageTopic = (): string => {
154
154
  return `${getNetworkId(user)}/smartfeed/${user._id}/messages`;
155
155
  };
156
156
 
157
+ export const getLiveStreamTopic = (): string => {
158
+ const user = getActiveUser();
159
+
160
+ return `${getNetworkId(user)}/videostreaming`;
161
+ };
162
+
163
+ export const getLiveReactionTopic = (post: Amity.Post) => {
164
+ return `${post.path}/liveReaction`;
165
+ };
166
+
157
167
  let mqttAccessToken: string;
158
168
  let mqttUserId: string;
159
169
 
@@ -168,9 +178,3 @@ export function subscribeTopic(
168
178
 
169
179
  return mqtt.subscribe(topic, callback);
170
180
  }
171
-
172
- export const getLiveStreamTopic = (): string => {
173
- const user = getActiveUser();
174
-
175
- return `${getNetworkId(user)}/videostreaming`;
176
- };
package/src/index.ts CHANGED
@@ -53,3 +53,5 @@ export * from './external/api';
53
53
  export * as notificationTray from './notificationTray';
54
54
 
55
55
  export * as InvitationRepository from './invitationRepository';
56
+
57
+ export * as LiveReactionRepository from './liveReactionRepository';
@@ -0,0 +1,58 @@
1
+ import { fireEvent } from '~/core/events';
2
+ import ReactionSyncEngine from '../service/ReactionSyncEngine';
3
+
4
+ import { getActiveClient } from '~/client/api/activeClient';
5
+ // TODO: confirm id
6
+ /* begin_public_function
7
+ id: live_reaction.create
8
+ */
9
+ /**
10
+ * ```js
11
+ * import { acceptInvitation } from '@amityco/ts-sdk'
12
+ * const isAccepted = await acceptInvitation(invitationId)
13
+ * ```
14
+ *
15
+ *
16
+ * @param referenceId that is target post's ID linked with a livestream
17
+ * @param reactionName that is the reaction name
18
+ * @param streamId stream id
19
+ * @returns a success boolean if the reaction was added
20
+ *
21
+ * @category Live Reaction API
22
+ * @async
23
+ */
24
+ export const createReaction = async ({
25
+ referenceId,
26
+ referenceType,
27
+ reactionName,
28
+ streamId,
29
+ }: Pick<Amity.CreateLiveReactionRequest, 'referenceType' | 'reactionName'> & {
30
+ referenceId: string;
31
+ streamId: string;
32
+ }): Promise<boolean> => {
33
+ const client = getActiveClient();
34
+
35
+ client.log('live_reaction/createReaction', {
36
+ referenceId,
37
+ referenceType,
38
+ reactionName,
39
+ });
40
+
41
+ const reactionSynceEngine = ReactionSyncEngine.getInstance();
42
+
43
+ const reaction = {
44
+ reactionName,
45
+ referencePublicId: referenceId,
46
+ referenceType,
47
+ streamId,
48
+ occurredAt: new Date().toISOString(),
49
+ };
50
+
51
+
52
+ reactionSynceEngine.createLiveReaction(reaction);
53
+
54
+ fireEvent('local.liveReaction.created', [{ ...reaction, userId: client.userId!, referenceId }]);
55
+
56
+ return true;
57
+ };
58
+ /* end_public_function */
@@ -0,0 +1 @@
1
+ export * from './createReaction';
@@ -0,0 +1 @@
1
+ export * from './onLiveReactionCreated';
@@ -0,0 +1,37 @@
1
+ import { getActiveClient } from '~/client/api';
2
+ import { createEventSubscriber } from '~/core/events';
3
+ /**
4
+ * ```js
5
+ * import { onLiveReactionCreated } from '@amityco/ts-sdk'
6
+ * const dispose = onLiveReactionCreated(reactions => {
7
+ * // ...
8
+ * })
9
+ * ```
10
+ *
11
+ * Fired when a batch of {@link Amity.LiveReaction} has been created
12
+ *
13
+ * @param callback The function to call when the event was fired
14
+ * @returns an {@link Amity.Unsubscriber} function to stop listening
15
+ *
16
+ * @category Live Reaction Events
17
+ */
18
+ export const onLiveReactionCreated = (
19
+ callback: Amity.Listener<Amity.LiveReaction[]>,
20
+ ): Amity.Unsubscriber => {
21
+ const client = getActiveClient();
22
+
23
+ const filter = (rawPayload: Amity.LiveReactionPayload) => {
24
+ if (rawPayload.reactions.length > 0) {
25
+ // TODO: check with BE if user id is internal or pulbic id
26
+ const filteredPayload = rawPayload.reactions.filter(({ userId }) => userId !== client.userId);
27
+ callback(filteredPayload);
28
+ }
29
+ };
30
+
31
+ return createEventSubscriber(
32
+ client,
33
+ 'live_reaction/onLiveReactionCreated',
34
+ 'liveReaction.created',
35
+ filter,
36
+ );
37
+ };
@@ -0,0 +1,29 @@
1
+ import { getActiveClient } from '~/client/api';
2
+ import { createEventSubscriber } from '~/core/events';
3
+ /**
4
+ * ```js
5
+ * import { onLiveReactionCreatedLocal } from '@amityco/ts-sdk'
6
+ * const dispose = onLiveReactionCreatedLocal(reactions => {
7
+ * // ...
8
+ * })
9
+ * ```
10
+ *
11
+ * Fired when a batch of {@link Amity.LiveReaction} has been created
12
+ *
13
+ * @param callback The function to call when the event was fired
14
+ * @returns an {@link Amity.Unsubscriber} function to stop listening
15
+ *
16
+ * @category Live Reaction Events
17
+ */
18
+ export const onLiveReactionCreatedLocal = (
19
+ callback: Amity.Listener<Amity.LiveReaction[]>,
20
+ ): Amity.Unsubscriber => {
21
+ const client = getActiveClient();
22
+
23
+ return createEventSubscriber(
24
+ client,
25
+ 'live_reaction/onLiveReactionCreated',
26
+ 'local.liveReaction.created',
27
+ callback,
28
+ );
29
+ };
@@ -0,0 +1,3 @@
1
+ export * from './api';
2
+ export * from './events';
3
+ export * from './observers';
@@ -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 */