@stream-io/feeds-client 0.2.16 → 0.2.18
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/CHANGELOG.md +21 -0
- package/dist/cjs/index.js +1 -1
- package/dist/cjs/react-bindings.js +1 -1
- package/dist/es/index.mjs +2 -2
- package/dist/es/react-bindings.mjs +1 -1
- package/dist/{index-CaFrpjpl.js → index--koeDtxd.js} +310 -80
- package/dist/index--koeDtxd.js.map +1 -0
- package/dist/{index-J3MkoYPN.mjs → index-Zde8UE5f.mjs} +310 -80
- package/dist/index-Zde8UE5f.mjs.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/types/common/real-time/StableWSConnection.d.ts +3 -3
- package/dist/types/feed/event-handlers/activity/handle-activity-added.d.ts +4 -3
- package/dist/types/feed/event-handlers/activity/handle-activity-added.d.ts.map +1 -1
- package/dist/types/feed/event-handlers/activity/handle-activity-reaction-updated.d.ts +14 -0
- package/dist/types/feed/event-handlers/activity/handle-activity-reaction-updated.d.ts.map +1 -0
- package/dist/types/feed/event-handlers/activity/handle-activity-updated.d.ts.map +1 -1
- package/dist/types/feed/event-handlers/activity/index.d.ts +1 -0
- package/dist/types/feed/event-handlers/activity/index.d.ts.map +1 -1
- package/dist/types/feed/event-handlers/activity-updater.d.ts +44 -0
- package/dist/types/feed/event-handlers/activity-updater.d.ts.map +1 -0
- package/dist/types/feed/event-handlers/add-aggregated-activities-to-state.d.ts +6 -0
- package/dist/types/feed/event-handlers/add-aggregated-activities-to-state.d.ts.map +1 -0
- package/dist/types/feed/event-handlers/comment/handle-comment-reaction-added.d.ts.map +1 -1
- package/dist/types/feed/event-handlers/comment/handle-comment-reaction-updated.d.ts +6 -0
- package/dist/types/feed/event-handlers/comment/handle-comment-reaction-updated.d.ts.map +1 -0
- package/dist/types/feed/event-handlers/comment/index.d.ts +1 -0
- package/dist/types/feed/event-handlers/comment/index.d.ts.map +1 -1
- package/dist/types/feed/event-handlers/index.d.ts +3 -1
- package/dist/types/feed/event-handlers/index.d.ts.map +1 -1
- package/dist/types/feed/event-handlers/{aggregated-feed/handle-aggregated-feed-updated.d.ts → notification-feed/handle-notification-feed-updated.d.ts} +2 -11
- package/dist/types/feed/event-handlers/notification-feed/handle-notification-feed-updated.d.ts.map +1 -0
- package/dist/types/feed/event-handlers/notification-feed/index.d.ts +2 -0
- package/dist/types/feed/event-handlers/notification-feed/index.d.ts.map +1 -0
- package/dist/types/feed/event-handlers/story-feeds/handle-story-feeds-updated.d.ts +15 -0
- package/dist/types/feed/event-handlers/story-feeds/handle-story-feeds-updated.d.ts.map +1 -0
- package/dist/types/feed/event-handlers/story-feeds/index.d.ts +2 -0
- package/dist/types/feed/event-handlers/story-feeds/index.d.ts.map +1 -0
- package/dist/types/feed/feed.d.ts +9 -3
- package/dist/types/feed/feed.d.ts.map +1 -1
- package/dist/types/feeds-client/feeds-client.d.ts +5 -3
- package/dist/types/feeds-client/feeds-client.d.ts.map +1 -1
- package/dist/types/gen/feeds/FeedsApi.d.ts.map +1 -1
- package/dist/types/gen/models/index.d.ts +43 -452
- package/dist/types/gen/models/index.d.ts.map +1 -1
- package/dist/types/utils/state-update-queue.d.ts +5 -1
- package/dist/types/utils/state-update-queue.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/feed/event-handlers/activity/handle-activity-added.test.ts +16 -5
- package/src/feed/event-handlers/activity/handle-activity-added.ts +9 -11
- package/src/feed/event-handlers/activity/handle-activity-reaction-updated.test.ts +282 -0
- package/src/feed/event-handlers/activity/handle-activity-reaction-updated.ts +140 -0
- package/src/feed/event-handlers/activity/handle-activity-updated.ts +8 -16
- package/src/feed/event-handlers/activity/index.ts +1 -0
- package/src/feed/event-handlers/activity-updater.ts +15 -0
- package/src/feed/event-handlers/add-aggregated-activities-to-state.test.ts +510 -0
- package/src/feed/event-handlers/add-aggregated-activities-to-state.ts +72 -0
- package/src/feed/event-handlers/comment/handle-comment-reaction-added.ts +1 -2
- package/src/feed/event-handlers/comment/handle-comment-reaction-updated.test.ts +350 -0
- package/src/feed/event-handlers/comment/handle-comment-reaction-updated.ts +72 -0
- package/src/feed/event-handlers/comment/index.ts +1 -1
- package/src/feed/event-handlers/index.ts +3 -1
- package/src/feed/event-handlers/notification-feed/handle-notification-feed-updated.test.ts +182 -0
- package/src/feed/event-handlers/{aggregated-feed/handle-aggregated-feed-updated.ts → notification-feed/handle-notification-feed-updated.ts} +2 -94
- package/src/feed/event-handlers/notification-feed/index.ts +1 -0
- package/src/feed/event-handlers/story-feeds/handle-story-feeds-updated.test.ts +45 -0
- package/src/feed/event-handlers/story-feeds/handle-story-feeds-updated.ts +122 -0
- package/src/feed/event-handlers/story-feeds/index.ts +1 -0
- package/src/feed/feed.ts +16 -2
- package/src/feeds-client/feeds-client.ts +36 -6
- package/src/gen/feeds/FeedsApi.ts +5 -0
- package/src/gen/model-decoders/decoders.ts +10 -4
- package/src/gen/models/index.ts +76 -835
- package/src/test-utils/response-generators.ts +89 -1
- package/src/utils/state-update-queue.ts +14 -2
- package/dist/index-CaFrpjpl.js.map +0 -1
- package/dist/index-J3MkoYPN.mjs.map +0 -1
- package/dist/types/feed/event-handlers/aggregated-feed/handle-aggregated-feed-updated.d.ts.map +0 -1
- package/dist/types/feed/event-handlers/aggregated-feed/index.d.ts +0 -2
- package/dist/types/feed/event-handlers/aggregated-feed/index.d.ts.map +0 -1
- package/src/feed/event-handlers/activity/activity-utils.test.ts +0 -252
- package/src/feed/event-handlers/aggregated-feed/handle-aggregated-feed-updated.test.ts +0 -644
- package/src/feed/event-handlers/aggregated-feed/index.ts +0 -1
|
@@ -3,57 +3,9 @@ import type {
|
|
|
3
3
|
AggregatedActivityResponse,
|
|
4
4
|
NotificationFeedUpdatedEvent,
|
|
5
5
|
NotificationStatusResponse,
|
|
6
|
-
StoriesFeedUpdatedEvent,
|
|
7
6
|
} from '../../../gen/models';
|
|
8
7
|
import type { EventPayload, UpdateStateResult } from '../../../types-internal';
|
|
9
|
-
import {
|
|
10
|
-
|
|
11
|
-
export const addAggregatedActivitiesToState = (
|
|
12
|
-
newAggregatedActivities: AggregatedActivityResponse[],
|
|
13
|
-
aggregatedActivities: AggregatedActivityResponse[] | undefined,
|
|
14
|
-
position: 'start' | 'end' | 'replace',
|
|
15
|
-
) => {
|
|
16
|
-
let result: UpdateStateResult<{
|
|
17
|
-
aggregated_activities: AggregatedActivityResponse[];
|
|
18
|
-
}>;
|
|
19
|
-
if (newAggregatedActivities.length === 0) {
|
|
20
|
-
result = {
|
|
21
|
-
changed: false,
|
|
22
|
-
aggregated_activities: [],
|
|
23
|
-
};
|
|
24
|
-
} else {
|
|
25
|
-
result = {
|
|
26
|
-
changed: true,
|
|
27
|
-
aggregated_activities: [],
|
|
28
|
-
};
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
switch (position) {
|
|
32
|
-
case 'start':
|
|
33
|
-
result.aggregated_activities = uniqueArrayMerge(
|
|
34
|
-
newAggregatedActivities,
|
|
35
|
-
aggregatedActivities ?? [],
|
|
36
|
-
(a) => a.group,
|
|
37
|
-
);
|
|
38
|
-
break;
|
|
39
|
-
case 'end':
|
|
40
|
-
result.aggregated_activities = uniqueArrayMerge(
|
|
41
|
-
aggregatedActivities ?? [],
|
|
42
|
-
newAggregatedActivities,
|
|
43
|
-
(a) => a.group,
|
|
44
|
-
);
|
|
45
|
-
break;
|
|
46
|
-
case 'replace':
|
|
47
|
-
result.aggregated_activities = replaceUniqueArrayMerge(
|
|
48
|
-
aggregatedActivities ?? [],
|
|
49
|
-
newAggregatedActivities,
|
|
50
|
-
(a) => a.group,
|
|
51
|
-
);
|
|
52
|
-
break;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
return result;
|
|
56
|
-
};
|
|
8
|
+
import { addAggregatedActivitiesToState } from '../add-aggregated-activities-to-state';
|
|
57
9
|
|
|
58
10
|
export const updateNotificationStatus = (
|
|
59
11
|
newNotificationStatus?: NotificationStatusResponse,
|
|
@@ -94,7 +46,7 @@ export const updateNotificationFeedFromEvent = (
|
|
|
94
46
|
aggregated_activities?: AggregatedActivityResponse[];
|
|
95
47
|
} = {};
|
|
96
48
|
|
|
97
|
-
if (event.notification_status
|
|
49
|
+
if (event.notification_status) {
|
|
98
50
|
const notificationStatusResult = updateNotificationStatus(
|
|
99
51
|
event.notification_status,
|
|
100
52
|
currentNotificationStatus,
|
|
@@ -147,47 +99,3 @@ export function handleNotificationFeedUpdated(
|
|
|
147
99
|
});
|
|
148
100
|
}
|
|
149
101
|
}
|
|
150
|
-
|
|
151
|
-
export function updateStoriesFeedFromEvent(
|
|
152
|
-
aggregatedActivities: AggregatedActivityResponse[] | undefined,
|
|
153
|
-
event: StoriesFeedUpdatedEvent,
|
|
154
|
-
): UpdateStateResult<{
|
|
155
|
-
data?: {
|
|
156
|
-
aggregated_activities?: AggregatedActivityResponse[];
|
|
157
|
-
};
|
|
158
|
-
}> {
|
|
159
|
-
if (!aggregatedActivities) {
|
|
160
|
-
return {
|
|
161
|
-
changed: false,
|
|
162
|
-
};
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
if (event.aggregated_activities) {
|
|
166
|
-
const result = addAggregatedActivitiesToState(
|
|
167
|
-
event.aggregated_activities,
|
|
168
|
-
aggregatedActivities,
|
|
169
|
-
'replace',
|
|
170
|
-
);
|
|
171
|
-
|
|
172
|
-
return result;
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
return {
|
|
176
|
-
changed: false,
|
|
177
|
-
};
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
export function handleStoriesFeedUpdated(
|
|
181
|
-
this: Feed,
|
|
182
|
-
event: EventPayload<'feeds.stories_feed.updated'>,
|
|
183
|
-
) {
|
|
184
|
-
const result = updateStoriesFeedFromEvent(
|
|
185
|
-
this.currentState.aggregated_activities,
|
|
186
|
-
event,
|
|
187
|
-
);
|
|
188
|
-
if (result.changed) {
|
|
189
|
-
this.state.partialNext({
|
|
190
|
-
aggregated_activities: result.data?.aggregated_activities,
|
|
191
|
-
});
|
|
192
|
-
}
|
|
193
|
-
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './handle-notification-feed-updated';
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import {
|
|
2
|
+
generateActivityResponse,
|
|
3
|
+
generateFeedReactionResponse,
|
|
4
|
+
} from '../../../test-utils';
|
|
5
|
+
import { updateActivities } from './handle-story-feeds-updated';
|
|
6
|
+
import { describe, expect, it } from 'vitest';
|
|
7
|
+
|
|
8
|
+
describe('updateActivities', () => {
|
|
9
|
+
it('should return unchanged if new activities is empty', () => {
|
|
10
|
+
const currentActivities = [generateActivityResponse({ id: 'activity1' })];
|
|
11
|
+
const result = updateActivities([], currentActivities);
|
|
12
|
+
expect(result.changed).toBe(false);
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
it('should return unchanged if current activities is undefined', () => {
|
|
16
|
+
const newActivities = [generateActivityResponse({ id: 'activity1' })];
|
|
17
|
+
const result = updateActivities(newActivities, undefined);
|
|
18
|
+
expect(result.changed).toBe(false);
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
it('should update existing activities, ignore new ones', () => {
|
|
22
|
+
const newActivities = [
|
|
23
|
+
generateActivityResponse({ id: 'activity1', is_watched: true }),
|
|
24
|
+
generateActivityResponse({ id: 'activity3' }),
|
|
25
|
+
];
|
|
26
|
+
const currentActivities = [
|
|
27
|
+
generateActivityResponse({
|
|
28
|
+
id: 'activity1',
|
|
29
|
+
own_reactions: [generateFeedReactionResponse({ type: 'like' })],
|
|
30
|
+
}),
|
|
31
|
+
generateActivityResponse({
|
|
32
|
+
id: 'activity2',
|
|
33
|
+
}),
|
|
34
|
+
];
|
|
35
|
+
|
|
36
|
+
const result = updateActivities(newActivities, currentActivities);
|
|
37
|
+
|
|
38
|
+
expect(result.changed).toBe(true);
|
|
39
|
+
expect(result.activities).toHaveLength(2);
|
|
40
|
+
expect(result.activities[0].own_reactions).toHaveLength(1);
|
|
41
|
+
expect(result.activities[0].own_reactions[0].type).toBe('like');
|
|
42
|
+
expect(result.activities[0].is_watched).toBe(true);
|
|
43
|
+
expect(result.activities[1].id).toBe('activity2');
|
|
44
|
+
});
|
|
45
|
+
});
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
ActivityResponse,
|
|
3
|
+
AggregatedActivityResponse,
|
|
4
|
+
StoriesFeedUpdatedEvent,
|
|
5
|
+
} from '../../../gen/models';
|
|
6
|
+
import type { UpdateStateResult, EventPayload } from '../../../types-internal';
|
|
7
|
+
import type { Feed } from '../../feed';
|
|
8
|
+
import { updateActivity } from '../activity-updater';
|
|
9
|
+
import { addAggregatedActivitiesToState } from '../add-aggregated-activities-to-state';
|
|
10
|
+
|
|
11
|
+
export const updateActivities = (
|
|
12
|
+
activitiesToUpsert: ActivityResponse[],
|
|
13
|
+
currentActivities: ActivityResponse[] | undefined,
|
|
14
|
+
) => {
|
|
15
|
+
if (
|
|
16
|
+
!activitiesToUpsert ||
|
|
17
|
+
activitiesToUpsert.length === 0 ||
|
|
18
|
+
!currentActivities
|
|
19
|
+
) {
|
|
20
|
+
return {
|
|
21
|
+
changed: false,
|
|
22
|
+
activities: currentActivities ?? [],
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const result: ActivityResponse[] = [];
|
|
27
|
+
for (let i = 0; i < currentActivities.length; i++) {
|
|
28
|
+
const activity = currentActivities[i];
|
|
29
|
+
const updatedActivity = activitiesToUpsert.find(
|
|
30
|
+
(a) => a.id === activity.id,
|
|
31
|
+
);
|
|
32
|
+
if (updatedActivity) {
|
|
33
|
+
result.push(
|
|
34
|
+
updateActivity({
|
|
35
|
+
currentActivity: activity,
|
|
36
|
+
newActivtiy: updatedActivity,
|
|
37
|
+
}),
|
|
38
|
+
);
|
|
39
|
+
} else {
|
|
40
|
+
result.push(activity);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
return {
|
|
45
|
+
changed: true,
|
|
46
|
+
activities: result,
|
|
47
|
+
};
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
export function updateStoriesFeedFromEvent(
|
|
51
|
+
aggregatedActivities: AggregatedActivityResponse[] | undefined,
|
|
52
|
+
activities: ActivityResponse[] | undefined,
|
|
53
|
+
event: StoriesFeedUpdatedEvent,
|
|
54
|
+
): UpdateStateResult<{
|
|
55
|
+
data?: {
|
|
56
|
+
aggregated_activities?: AggregatedActivityResponse[];
|
|
57
|
+
activities?: ActivityResponse[];
|
|
58
|
+
};
|
|
59
|
+
}> {
|
|
60
|
+
if (
|
|
61
|
+
(!aggregatedActivities &&
|
|
62
|
+
event.aggregated_activities &&
|
|
63
|
+
event.aggregated_activities?.length > 0) ||
|
|
64
|
+
(!activities && event.activities && event.activities?.length > 0)
|
|
65
|
+
) {
|
|
66
|
+
return {
|
|
67
|
+
changed: false,
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const result = {
|
|
72
|
+
changed: true,
|
|
73
|
+
data: {
|
|
74
|
+
aggregated_activities: aggregatedActivities,
|
|
75
|
+
activities: activities,
|
|
76
|
+
},
|
|
77
|
+
};
|
|
78
|
+
if (event.aggregated_activities) {
|
|
79
|
+
const aggregatedActivitiesResult = addAggregatedActivitiesToState(
|
|
80
|
+
event.aggregated_activities,
|
|
81
|
+
aggregatedActivities,
|
|
82
|
+
'replace',
|
|
83
|
+
);
|
|
84
|
+
|
|
85
|
+
if (aggregatedActivitiesResult.changed) {
|
|
86
|
+
result.data.aggregated_activities =
|
|
87
|
+
aggregatedActivitiesResult.aggregated_activities;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
if (event.activities) {
|
|
92
|
+
const activitiesResult = updateActivities(event.activities, activities);
|
|
93
|
+
if (activitiesResult.changed) {
|
|
94
|
+
result.data.activities = activitiesResult.activities;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
if (event.aggregated_activities || event.activities) {
|
|
99
|
+
return result;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
return {
|
|
103
|
+
changed: false,
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
export function handleStoriesFeedUpdated(
|
|
108
|
+
this: Feed,
|
|
109
|
+
event: EventPayload<'feeds.stories_feed.updated'>,
|
|
110
|
+
) {
|
|
111
|
+
const result = updateStoriesFeedFromEvent(
|
|
112
|
+
this.currentState.aggregated_activities,
|
|
113
|
+
this.currentState.activities,
|
|
114
|
+
event,
|
|
115
|
+
);
|
|
116
|
+
if (result.changed) {
|
|
117
|
+
this.state.partialNext({
|
|
118
|
+
aggregated_activities: result.data?.aggregated_activities,
|
|
119
|
+
activities: result.data?.activities,
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './handle-story-feeds-updated';
|
package/src/feed/feed.ts
CHANGED
|
@@ -42,8 +42,10 @@ import {
|
|
|
42
42
|
handleActivityMarked,
|
|
43
43
|
handleActivityReactionAdded,
|
|
44
44
|
handleActivityReactionDeleted,
|
|
45
|
+
handleActivityReactionUpdated,
|
|
45
46
|
handleCommentReactionAdded,
|
|
46
47
|
handleCommentReactionDeleted,
|
|
48
|
+
handleCommentReactionUpdated,
|
|
47
49
|
addAggregatedActivitiesToState,
|
|
48
50
|
updateNotificationStatus,
|
|
49
51
|
handleStoriesFeedUpdated,
|
|
@@ -129,6 +131,12 @@ export type FeedState = Omit<
|
|
|
129
131
|
* `true` if the feed is receiving real-time updates via WebSocket
|
|
130
132
|
*/
|
|
131
133
|
watch: boolean;
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* When a new activity is received from a WebSocket event by default it's added to the start of the list. You can change this to `end` to add it to the end of the list.
|
|
137
|
+
* Useful for story feeds.
|
|
138
|
+
*/
|
|
139
|
+
addNewActivitiesTo: 'start' | 'end';
|
|
132
140
|
};
|
|
133
141
|
|
|
134
142
|
type EventHandlerByEventType = {
|
|
@@ -151,7 +159,7 @@ export class Feed extends FeedApi {
|
|
|
151
159
|
'feeds.activity.deleted': handleActivityDeleted.bind(this),
|
|
152
160
|
'feeds.activity.reaction.added': handleActivityReactionAdded.bind(this),
|
|
153
161
|
'feeds.activity.reaction.deleted': handleActivityReactionDeleted.bind(this),
|
|
154
|
-
'feeds.activity.reaction.updated':
|
|
162
|
+
'feeds.activity.reaction.updated': handleActivityReactionUpdated.bind(this),
|
|
155
163
|
'feeds.activity.removed_from_feed':
|
|
156
164
|
handleActivityRemovedFromFeed.bind(this),
|
|
157
165
|
'feeds.activity.updated': handleActivityUpdated.bind(this),
|
|
@@ -173,7 +181,7 @@ export class Feed extends FeedApi {
|
|
|
173
181
|
'feeds.follow.updated': handleFollowUpdated.bind(this),
|
|
174
182
|
'feeds.comment.reaction.added': handleCommentReactionAdded.bind(this),
|
|
175
183
|
'feeds.comment.reaction.deleted': handleCommentReactionDeleted.bind(this),
|
|
176
|
-
'feeds.comment.reaction.updated':
|
|
184
|
+
'feeds.comment.reaction.updated': handleCommentReactionUpdated.bind(this),
|
|
177
185
|
'feeds.feed_member.added': handleFeedMemberAdded.bind(this),
|
|
178
186
|
'feeds.feed_member.removed': handleFeedMemberRemoved.bind(this),
|
|
179
187
|
'feeds.feed_member.updated': handleFeedMemberUpdated.bind(this),
|
|
@@ -210,6 +218,7 @@ export class Feed extends FeedApi {
|
|
|
210
218
|
id: string,
|
|
211
219
|
data?: FeedResponse,
|
|
212
220
|
watch = false,
|
|
221
|
+
addNewActivitiesTo: 'start' | 'end' = 'start',
|
|
213
222
|
) {
|
|
214
223
|
super(client, groupId, id);
|
|
215
224
|
this.state = new StateStore<FeedState>({
|
|
@@ -221,6 +230,7 @@ export class Feed extends FeedApi {
|
|
|
221
230
|
is_loading_activities: false,
|
|
222
231
|
comments_by_entity_id: {},
|
|
223
232
|
watch,
|
|
233
|
+
addNewActivitiesTo,
|
|
224
234
|
});
|
|
225
235
|
this.client = client;
|
|
226
236
|
|
|
@@ -248,6 +258,10 @@ export class Feed extends FeedApi {
|
|
|
248
258
|
return this.state.getLatestValue();
|
|
249
259
|
}
|
|
250
260
|
|
|
261
|
+
set addNewActivitiesTo(value: 'start' | 'end') {
|
|
262
|
+
this.state.partialNext({ addNewActivitiesTo: value });
|
|
263
|
+
}
|
|
264
|
+
|
|
251
265
|
hasActivity(activityId: string) {
|
|
252
266
|
return this.indexedActivityIds.has(activityId);
|
|
253
267
|
}
|
|
@@ -51,6 +51,7 @@ import {
|
|
|
51
51
|
Feed,
|
|
52
52
|
handleActivityReactionAdded,
|
|
53
53
|
handleActivityReactionDeleted,
|
|
54
|
+
handleActivityReactionUpdated,
|
|
54
55
|
handleActivityUpdated,
|
|
55
56
|
handleCommentAdded,
|
|
56
57
|
handleCommentDeleted,
|
|
@@ -68,7 +69,8 @@ import { handleUserUpdated } from './event-handlers';
|
|
|
68
69
|
import type { SyncFailure } from '../common/real-time/event-models';
|
|
69
70
|
import { UnhandledErrorType } from '../common/real-time/event-models';
|
|
70
71
|
import { updateCommentCount } from '../feed/event-handlers/comment/utils';
|
|
71
|
-
import { configureLoggers } from '../utils
|
|
72
|
+
import { configureLoggers } from '../utils';
|
|
73
|
+
import { handleCommentReactionUpdated } from '../feed/event-handlers/comment/handle-comment-reaction-updated';
|
|
72
74
|
|
|
73
75
|
export type FeedsClientState = {
|
|
74
76
|
connected_user: OwnUser | undefined;
|
|
@@ -417,9 +419,14 @@ export class FeedsClient extends FeedsApi {
|
|
|
417
419
|
activity_id: string;
|
|
418
420
|
},
|
|
419
421
|
) => {
|
|
422
|
+
const shouldEnforceUnique = request.enforce_unique;
|
|
420
423
|
const response = await super.addActivityReaction(request);
|
|
421
424
|
for (const feed of Object.values(this.activeFeeds)) {
|
|
422
|
-
|
|
425
|
+
if (shouldEnforceUnique) {
|
|
426
|
+
handleActivityReactionUpdated.bind(feed)(response, false);
|
|
427
|
+
} else {
|
|
428
|
+
handleActivityReactionAdded.bind(feed)(response, false);
|
|
429
|
+
}
|
|
423
430
|
}
|
|
424
431
|
return response;
|
|
425
432
|
};
|
|
@@ -449,9 +456,14 @@ export class FeedsClient extends FeedsApi {
|
|
|
449
456
|
addCommentReaction = async (
|
|
450
457
|
request: AddCommentReactionRequest & { id: string },
|
|
451
458
|
): Promise<StreamResponse<AddCommentReactionResponse>> => {
|
|
459
|
+
const shouldEnforceUnique = request.enforce_unique;
|
|
452
460
|
const response = await super.addCommentReaction(request);
|
|
453
461
|
for (const feed of Object.values(this.activeFeeds)) {
|
|
454
|
-
|
|
462
|
+
if (shouldEnforceUnique) {
|
|
463
|
+
handleCommentReactionUpdated.bind(feed)(response, false);
|
|
464
|
+
} else {
|
|
465
|
+
handleCommentReactionAdded.bind(feed)(response, false);
|
|
466
|
+
}
|
|
455
467
|
}
|
|
456
468
|
return response;
|
|
457
469
|
};
|
|
@@ -513,8 +525,18 @@ export class FeedsClient extends FeedsApi {
|
|
|
513
525
|
on = this.eventDispatcher.on;
|
|
514
526
|
off = this.eventDispatcher.off;
|
|
515
527
|
|
|
516
|
-
feed = (
|
|
517
|
-
|
|
528
|
+
feed = (
|
|
529
|
+
groupId: string,
|
|
530
|
+
id: string,
|
|
531
|
+
options?: { addNewActivitiesTo?: 'start' | 'end' },
|
|
532
|
+
) => {
|
|
533
|
+
return this.getOrCreateActiveFeed(
|
|
534
|
+
groupId,
|
|
535
|
+
id,
|
|
536
|
+
undefined,
|
|
537
|
+
undefined,
|
|
538
|
+
options?.addNewActivitiesTo,
|
|
539
|
+
);
|
|
518
540
|
};
|
|
519
541
|
|
|
520
542
|
async queryFeeds(request?: QueryFeedsRequest) {
|
|
@@ -628,11 +650,19 @@ export class FeedsClient extends FeedsApi {
|
|
|
628
650
|
id: string,
|
|
629
651
|
data?: FeedResponse,
|
|
630
652
|
watch?: boolean,
|
|
653
|
+
addNewActivitiesTo?: 'start' | 'end',
|
|
631
654
|
) => {
|
|
632
655
|
const fid = `${group}:${id}`;
|
|
633
656
|
|
|
634
657
|
if (!this.activeFeeds[fid]) {
|
|
635
|
-
this.activeFeeds[fid] = new Feed(
|
|
658
|
+
this.activeFeeds[fid] = new Feed(
|
|
659
|
+
this,
|
|
660
|
+
group,
|
|
661
|
+
id,
|
|
662
|
+
data,
|
|
663
|
+
watch,
|
|
664
|
+
addNewActivitiesTo,
|
|
665
|
+
);
|
|
636
666
|
}
|
|
637
667
|
|
|
638
668
|
const feed = this.activeFeeds[fid];
|
|
@@ -170,6 +170,8 @@ export class FeedsApi {
|
|
|
170
170
|
const body = {
|
|
171
171
|
name: request?.name,
|
|
172
172
|
words: request?.words,
|
|
173
|
+
is_leet_check_enabled: request?.is_leet_check_enabled,
|
|
174
|
+
is_plural_check_enabled: request?.is_plural_check_enabled,
|
|
173
175
|
team: request?.team,
|
|
174
176
|
type: request?.type,
|
|
175
177
|
};
|
|
@@ -220,6 +222,8 @@ export class FeedsApi {
|
|
|
220
222
|
name: request?.name,
|
|
221
223
|
};
|
|
222
224
|
const body = {
|
|
225
|
+
is_leet_check_enabled: request?.is_leet_check_enabled,
|
|
226
|
+
is_plural_check_enabled: request?.is_plural_check_enabled,
|
|
223
227
|
team: request?.team,
|
|
224
228
|
words: request?.words,
|
|
225
229
|
};
|
|
@@ -499,6 +503,7 @@ export class FeedsApi {
|
|
|
499
503
|
reason: request?.reason,
|
|
500
504
|
report: request?.report,
|
|
501
505
|
show_less: request?.show_less,
|
|
506
|
+
show_more: request?.show_more,
|
|
502
507
|
};
|
|
503
508
|
|
|
504
509
|
const response = await this.apiClient.sendRequest<
|
|
@@ -1233,9 +1233,11 @@ decoders.ModerationCustomActionEvent = (input?: Record<string, any>) => {
|
|
|
1233
1233
|
const typeMappings: TypeMapping = {
|
|
1234
1234
|
created_at: { type: 'DatetimeType', isSingle: true },
|
|
1235
1235
|
|
|
1236
|
-
|
|
1236
|
+
review_queue_item: { type: 'ReviewQueueItemResponse', isSingle: true },
|
|
1237
1237
|
|
|
1238
|
-
|
|
1238
|
+
received_at: { type: 'DatetimeType', isSingle: true },
|
|
1239
|
+
|
|
1240
|
+
message: { type: 'MessageResponse', isSingle: true },
|
|
1239
1241
|
};
|
|
1240
1242
|
return decode(typeMappings, input);
|
|
1241
1243
|
};
|
|
@@ -1266,9 +1268,11 @@ decoders.ModerationMarkReviewedEvent = (input?: Record<string, any>) => {
|
|
|
1266
1268
|
const typeMappings: TypeMapping = {
|
|
1267
1269
|
created_at: { type: 'DatetimeType', isSingle: true },
|
|
1268
1270
|
|
|
1269
|
-
|
|
1271
|
+
item: { type: 'ReviewQueueItemResponse', isSingle: true },
|
|
1270
1272
|
|
|
1271
|
-
|
|
1273
|
+
received_at: { type: 'DatetimeType', isSingle: true },
|
|
1274
|
+
|
|
1275
|
+
message: { type: 'MessageResponse', isSingle: true },
|
|
1272
1276
|
};
|
|
1273
1277
|
return decode(typeMappings, input);
|
|
1274
1278
|
};
|
|
@@ -1745,6 +1749,8 @@ decoders.StoriesFeedUpdatedEvent = (input?: Record<string, any>) => {
|
|
|
1745
1749
|
|
|
1746
1750
|
received_at: { type: 'DatetimeType', isSingle: true },
|
|
1747
1751
|
|
|
1752
|
+
activities: { type: 'ActivityResponse', isSingle: false },
|
|
1753
|
+
|
|
1748
1754
|
aggregated_activities: {
|
|
1749
1755
|
type: 'AggregatedActivityResponse',
|
|
1750
1756
|
isSingle: false,
|