@amityco/ts-sdk 7.7.0 → 7.7.1-4e97d71.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.
- package/.env +26 -26
- package/dist/@types/core/events.d.ts +6 -1
- package/dist/@types/core/events.d.ts.map +1 -1
- package/dist/@types/core/payload.d.ts +25 -0
- package/dist/@types/core/payload.d.ts.map +1 -1
- package/dist/@types/domains/channel.d.ts +6 -0
- package/dist/@types/domains/channel.d.ts.map +1 -1
- package/dist/@types/domains/liveReaction.d.ts +20 -0
- package/dist/@types/domains/liveReaction.d.ts.map +1 -0
- package/dist/@types/domains/post.d.ts +3 -0
- package/dist/@types/domains/post.d.ts.map +1 -1
- package/dist/@types/domains/stream.d.ts +9 -1
- package/dist/@types/domains/stream.d.ts.map +1 -1
- package/dist/@types/index.d.ts +1 -0
- package/dist/@types/index.d.ts.map +1 -1
- package/dist/channelRepository/api/createChannel.d.ts +3 -1
- package/dist/channelRepository/api/createChannel.d.ts.map +1 -1
- package/dist/channelRepository/channelMembership/observers/getMembers/ChannelMemberLiveCollectionController.d.ts.map +1 -1
- package/dist/channelRepository/events/index.d.ts +1 -1
- package/dist/channelRepository/events/index.d.ts.map +1 -1
- package/dist/channelRepository/events/onChannelSetMuted.d.ts +2 -0
- package/dist/channelRepository/events/onChannelSetMuted.d.ts.map +1 -0
- package/dist/channelRepository/events/onChannelSetUserMuted.d.ts +2 -0
- package/dist/channelRepository/events/onChannelSetUserMuted.d.ts.map +1 -0
- package/dist/channelRepository/internalApi/getChannel.d.ts.map +1 -1
- package/dist/channelRepository/internalApi/getMyMembership.d.ts +11 -0
- package/dist/channelRepository/internalApi/getMyMembership.d.ts.map +1 -0
- package/dist/channelRepository/observers/getChannels/ChannelLiveCollectionController.d.ts.map +1 -1
- package/dist/channelRepository/observers/getMyMembership.d.ts +2 -0
- package/dist/channelRepository/observers/getMyMembership.d.ts.map +1 -0
- package/dist/client/api/login.d.ts.map +1 -1
- package/dist/core/events.d.ts +3 -3
- package/dist/core/events.d.ts.map +1 -1
- package/dist/core/subscription.d.ts +2 -1
- package/dist/core/subscription.d.ts.map +1 -1
- package/dist/index.cjs.js +6359 -5682
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.esm.js +6298 -5623
- package/dist/index.umd.js +3 -3
- package/dist/liveReactionRepository/api/createReaction.d.ts +20 -0
- package/dist/liveReactionRepository/api/createReaction.d.ts.map +1 -0
- package/dist/liveReactionRepository/api/index.d.ts +2 -0
- package/dist/liveReactionRepository/api/index.d.ts.map +1 -0
- package/dist/liveReactionRepository/events/index.d.ts +2 -0
- package/dist/liveReactionRepository/events/index.d.ts.map +1 -0
- package/dist/liveReactionRepository/events/onLiveReactionCreated.d.ts +17 -0
- package/dist/liveReactionRepository/events/onLiveReactionCreated.d.ts.map +1 -0
- package/dist/liveReactionRepository/events/onLiveReactionCreatedLocal.d.ts +17 -0
- package/dist/liveReactionRepository/events/onLiveReactionCreatedLocal.d.ts.map +1 -0
- package/dist/liveReactionRepository/index.d.ts +4 -0
- package/dist/liveReactionRepository/index.d.ts.map +1 -0
- package/dist/liveReactionRepository/internalApi/createLiveReaction.d.ts +20 -0
- package/dist/liveReactionRepository/internalApi/createLiveReaction.d.ts.map +1 -0
- package/dist/liveReactionRepository/observers/getReactions.d.ts +19 -0
- package/dist/liveReactionRepository/observers/getReactions.d.ts.map +1 -0
- package/dist/liveReactionRepository/observers/index.d.ts +2 -0
- package/dist/liveReactionRepository/observers/index.d.ts.map +1 -0
- package/dist/liveReactionRepository/service/ReactionSyncEngine.d.ts +26 -0
- package/dist/liveReactionRepository/service/ReactionSyncEngine.d.ts.map +1 -0
- package/dist/liveReactionRepository/utils/ReactionSyncEngineOnLoginHandler.d.ts +3 -0
- package/dist/liveReactionRepository/utils/ReactionSyncEngineOnLoginHandler.d.ts.map +1 -0
- package/dist/liveStreamPlayer/utils/eventRegister.d.ts +2 -1
- package/dist/liveStreamPlayer/utils/eventRegister.d.ts.map +1 -1
- package/dist/messagePreview/utils/getChannelMessagePreviewWithUser.d.ts +4 -0
- package/dist/messagePreview/utils/getChannelMessagePreviewWithUser.d.ts.map +1 -1
- package/dist/messageRepository/api/deleteMessage.d.ts.map +1 -1
- package/dist/messageRepository/observers/getMessage.d.ts.map +1 -1
- package/dist/messageRepository/observers/getMessages/MessageLiveCollectionController.d.ts.map +1 -1
- package/dist/messageRepository/observers/getMessages/MessageQueryStreamController.d.ts.map +1 -1
- package/dist/postRepository/api/createPost.d.ts.map +1 -1
- package/dist/postRepository/utils/payload.d.ts.map +1 -1
- package/dist/streamRepository/api/createStream.d.ts +1 -1
- package/dist/streamRepository/api/createStream.d.ts.map +1 -1
- package/dist/streamRepository/api/editStream.d.ts +18 -0
- package/dist/streamRepository/api/editStream.d.ts.map +1 -0
- package/dist/streamRepository/api/index.d.ts +1 -0
- package/dist/streamRepository/api/index.d.ts.map +1 -1
- package/dist/streamRepository/api/updateStream.d.ts +4 -1
- package/dist/streamRepository/api/updateStream.d.ts.map +1 -1
- package/dist/streamRepository/events/index.d.ts +2 -0
- package/dist/streamRepository/events/index.d.ts.map +1 -1
- package/dist/streamRepository/events/onStreamViewerBanned.d.ts +17 -0
- package/dist/streamRepository/events/onStreamViewerBanned.d.ts.map +1 -0
- package/dist/streamRepository/events/onStreamViewerUnbanned.d.ts +17 -0
- package/dist/streamRepository/events/onStreamViewerUnbanned.d.ts.map +1 -0
- package/dist/streamRepository/internalApi/getLiveChat.d.ts +16 -0
- package/dist/streamRepository/internalApi/getLiveChat.d.ts.map +1 -0
- package/dist/streamRepository/internalApi/getStream.d.ts +2 -2
- package/dist/streamRepository/internalApi/getStream.d.ts.map +1 -1
- package/dist/streamRepository/observers/getStreamById.d.ts.map +1 -1
- package/dist/streamRepository/observers/getStreams/GetStreamsLiveCollectionController.d.ts.map +1 -1
- package/dist/utils/linkedObject/channelLinkedObject.d.ts.map +1 -1
- package/dist/utils/linkedObject/postLinkedObject.d.ts.map +1 -1
- package/dist/utils/linkedObject/streamLinkedObject.d.ts.map +1 -1
- package/dist/utils/postTypePredicate.d.ts +2 -0
- package/dist/utils/postTypePredicate.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/@types/core/events.ts +9 -1
- package/src/@types/core/payload.ts +32 -0
- package/src/@types/domains/channel.ts +9 -0
- package/src/@types/domains/liveReaction.ts +25 -0
- package/src/@types/domains/post.ts +3 -0
- package/src/@types/domains/stream.ts +12 -1
- package/src/@types/index.ts +1 -0
- package/src/channelRepository/api/createChannel.ts +11 -8
- package/src/channelRepository/channelMembership/observers/getMembers/ChannelMemberLiveCollectionController.ts +2 -0
- package/src/channelRepository/events/index.ts +1 -1
- package/src/channelRepository/events/onChannelSetMuted.ts +48 -0
- package/src/channelRepository/events/onChannelSetUserMuted.ts +65 -0
- package/src/channelRepository/internalApi/getChannel.ts +0 -1
- package/src/channelRepository/internalApi/getMyMembership.ts +37 -0
- package/src/channelRepository/observers/getChannel.ts +2 -2
- package/src/channelRepository/observers/getChannels/ChannelLiveCollectionController.ts +2 -2
- package/src/channelRepository/observers/getMyMembership.ts +98 -0
- package/src/channelRepository/utils/constructChannelObject.ts +2 -2
- package/src/client/api/login.ts +2 -0
- package/src/core/events.ts +4 -1
- package/src/core/subscription.ts +10 -6
- package/src/index.ts +2 -0
- package/src/liveReactionRepository/api/createReaction.ts +58 -0
- package/src/liveReactionRepository/api/index.ts +1 -0
- package/src/liveReactionRepository/events/index.ts +1 -0
- package/src/liveReactionRepository/events/onLiveReactionCreated.ts +37 -0
- package/src/liveReactionRepository/events/onLiveReactionCreatedLocal.ts +29 -0
- package/src/liveReactionRepository/index.ts +3 -0
- package/src/liveReactionRepository/internalApi/createLiveReaction.ts +42 -0
- package/src/liveReactionRepository/observers/getReactions.ts +59 -0
- package/src/liveReactionRepository/observers/index.ts +1 -0
- package/src/liveReactionRepository/service/ReactionSyncEngine.ts +138 -0
- package/src/liveReactionRepository/utils/ReactionSyncEngineOnLoginHandler.ts +19 -0
- package/src/liveStreamPlayer/api/getPlayer.ts +1 -1
- package/src/liveStreamPlayer/utils/eventRegister.ts +16 -1
- package/src/messageRepository/api/deleteMessage.ts +16 -0
- package/src/messageRepository/observers/getMessage.ts +2 -0
- package/src/messageRepository/observers/getMessages/MessageLiveCollectionController.ts +2 -0
- package/src/messageRepository/observers/getMessages/MessageQueryStreamController.ts +13 -0
- package/src/postRepository/api/createPost.ts +3 -2
- package/src/postRepository/utils/payload.ts +37 -1
- package/src/streamRepository/api/createStream.ts +4 -1
- package/src/streamRepository/api/editStream.ts +51 -0
- package/src/streamRepository/api/index.ts +1 -0
- package/src/streamRepository/api/updateStream.ts +8 -1
- package/src/streamRepository/events/index.ts +2 -0
- package/src/streamRepository/events/onStreamViewerBanned.ts +58 -0
- package/src/streamRepository/events/onStreamViewerUnbanned.ts +47 -0
- package/src/streamRepository/internalApi/getLiveChat.ts +59 -0
- package/src/streamRepository/internalApi/getStream.ts +3 -3
- package/src/streamRepository/observers/getStreamById.ts +2 -0
- package/src/streamRepository/observers/getStreams/GetStreamsLiveCollectionController.ts +5 -1
- package/src/utils/linkedObject/channelLinkedObject.ts +3 -0
- package/src/utils/linkedObject/postLinkedObject.ts +28 -2
- package/src/utils/linkedObject/streamLinkedObject.ts +4 -0
- package/src/utils/postTypePredicate.ts +18 -0
- package/dist/channelRepository/events/onChannelMuted.d.ts +0 -2
- package/dist/channelRepository/events/onChannelMuted.d.ts.map +0 -1
- 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
|
-
|
|
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 =
|
|
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<
|
|
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 */
|
|
@@ -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<
|
|
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
|
+
};
|