Skip to content

Commit 531dc49

Browse files
committed
feat: new aggregation format for notifications
1 parent bd1dc92 commit 531dc49

File tree

5 files changed

+61
-28
lines changed

5 files changed

+61
-28
lines changed

packages/feeds-client/__integration-tests__/aggregated-feed-pagination.test.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
import { describe, it, expect, beforeAll, afterAll } from 'vitest';
2-
import type { FeedsClient, UserRequest } from '../src';
2+
import type {
3+
FeedsClient,
4+
NotificationFeedUpdatedEvent,
5+
UserRequest,
6+
} from '../src';
37
import {
48
createTestClient,
59
createTestTokenGenerator,
@@ -58,14 +62,18 @@ describe('Aggregated Feed Pagination Integration Tests', () => {
5862
.aggregated_activities!.map((a) => a.group),
5963
});
6064

61-
await waitForEvent(feed, 'feeds.notification_feed.updated', {
65+
const event = await waitForEvent(feed, 'feeds.notification_feed.updated', {
6266
shouldReject: true,
6367
});
6468

6569
expect(feed.state.getLatestValue().notification_status?.unseen).toBe(1);
6670
expect(
6771
feed.state.getLatestValue().notification_status?.seen_activities?.length,
6872
).toBe(2);
73+
expect(
74+
(event as NotificationFeedUpdatedEvent)?.notification_status
75+
?.seen_activities?.length,
76+
).toBe(2);
6977
});
7078

7179
it('should fetch next page of notifications', async () => {

packages/feeds-client/__integration-tests__/utils.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ export const waitForEvent = (
7474
return new Promise((resolve, reject) => {
7575
// @ts-expect-error client expects WSEvents
7676
client.on(type, (e) => {
77-
resolve(undefined);
77+
resolve(e);
7878
clearTimeout(timeout);
7979
});
8080
const timeout = setTimeout(() => {

sample-apps/react-sample-app/app/components/NewActivity.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ export const NewActivity = ({ feed }: { feed: Feed }) => {
9191
<button
9292
type="submit"
9393
className="px-4 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700 focus:outline-none"
94-
disabled={isSending || activityText === ''}
94+
disabled={isSending || (activityText === '' && !files?.length)}
9595
>
9696
{isSending ? <LoadingIndicator /> : 'Post'}
9797
</button>

sample-apps/react-sample-app/app/components/Search/SearchResults/SearchResultItem.tsx

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,9 @@ export const FeedSearchResultItem = ({ item }: FeedSearchResultItemProps) => {
3434
);
3535

3636
const isFollowing =
37-
ownFollows.some((follow) => follow.source_feed.feed === ownTimeline?.feed) ??
38-
false;
37+
ownFollows.some(
38+
(follow) => follow.source_feed.feed === ownTimeline?.feed,
39+
) ?? false;
3940

4041
return (
4142
<div
@@ -52,7 +53,9 @@ export const FeedSearchResultItem = ({ item }: FeedSearchResultItemProps) => {
5253
if (isFollowing) {
5354
ownTimeline?.unfollow(item.feed);
5455
} else {
55-
ownTimeline?.follow(item.feed);
56+
ownTimeline?.follow(item.feed, {
57+
create_notification_activity: true,
58+
});
5659
}
5760
}}
5861
>

sample-apps/react-sample-app/app/components/notifications/Notification.tsx

Lines changed: 43 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -12,52 +12,74 @@ export const Notification = ({
1212
isSeen: boolean;
1313
onMarkRead: () => {};
1414
}) => {
15-
const notificationText = useMemo(() => {
15+
const notification = useMemo(() => {
1616
const verb = group.activities[0].type;
1717

18-
let text = '';
18+
const targetActivity = group.activities[0].notification_context?.target;
19+
const notification = {
20+
text: '',
21+
image: targetActivity?.text
22+
? undefined
23+
: targetActivity?.attachments?.[0]?.image_url,
24+
};
25+
26+
const targetActivityTruncatedText = targetActivity?.text
27+
? ` "${
28+
targetActivity.text.length > 20
29+
? targetActivity?.text?.slice(0, 20) + '...'
30+
: targetActivity?.text
31+
}"`
32+
: '';
33+
const previewCount = 5;
34+
const previewActors = Array.from(
35+
new Set(group.activities.map(({ user }) => user.name)),
36+
).slice(0, previewCount);
37+
notification.text = previewActors.join(', ');
38+
const remainingActors = group.user_count - previewActors.length;
39+
40+
if (remainingActors > 1) {
41+
notification.text += ` and ${remainingActors}${group.user_count_truncated ? '+' : ''} more people`;
42+
} else if (remainingActors === 1) {
43+
notification.text += ' and 1 more person';
44+
}
1945

2046
switch (verb) {
2147
case 'comment': {
22-
text += `${group.activity_count} new comments`;
48+
notification.text += ` commented on your post${targetActivityTruncatedText}`;
2349
break;
2450
}
2551
case 'reaction': {
26-
text += `${group.activity_count} likes`;
52+
notification.text += ` reacted to your post${targetActivityTruncatedText}`;
2753
break;
2854
}
2955
case 'follow': {
30-
const previewCount = 5;
31-
text = Array.from(
32-
new Set(group.activities.map(({ user }) => user.name)),
33-
)
34-
.slice(0, previewCount)
35-
.join(', ');
36-
const remainingActors = group.user_count - previewCount;
37-
if (remainingActors > 1) {
38-
text += ` and ${remainingActors}${group.user_count_truncated ? '+' : ''} more people`;
39-
} else if (remainingActors === 1) {
40-
text += ' and 1 more person';
41-
}
42-
text += ` started following you`;
56+
notification.text += ` started following you`;
4357
break;
4458
}
4559
case 'comment_reaction': {
46-
text += `${group.activity_count} new reactions to your comment`;
60+
notification.text += ` reacted to your comment on post${targetActivityTruncatedText}`;
4761
break;
4862
}
4963
default: {
50-
text += 'Unknown type';
64+
notification.text += 'Unknown type';
5165
break;
5266
}
5367
}
5468

55-
return text;
69+
return notification;
5670
}, [group]);
5771

5872
return (
5973
<div className="flex items-center justify-between gap-1">
60-
<div>{notificationText}</div>
74+
{notification.text && <div>{notification.text}</div>}
75+
{notification.image && (
76+
<img
77+
src={notification.image}
78+
alt="Notification image"
79+
width={40}
80+
height={40}
81+
/>
82+
)}
6183
<div className="flex items-center gap-1.5">
6284
{!isRead && (
6385
<button

0 commit comments

Comments
 (0)