Skip to content

Commit ef0ff2d

Browse files
committed
merge feed and activity event handlers
1 parent 11b075c commit ef0ff2d

File tree

7 files changed

+400
-139
lines changed

7 files changed

+400
-139
lines changed

packages/stream_feeds/lib/src/state/activity.dart

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,11 @@ class Activity with Disposable {
6868
);
6969

7070
// Attach event handlers for real-time updates
71-
final handler = ActivityEventHandler(fid: fid, state: _stateNotifier);
71+
final handler = ActivityEventHandler(
72+
fid: fid,
73+
state: _stateNotifier,
74+
capabilitiesRepository: capabilitiesRepository,
75+
);
7276
_eventsSubscription = eventsEmitter.listen(handler.handleEvent);
7377
}
7478

packages/stream_feeds/lib/src/state/activity_state.dart

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,24 @@ import 'package:state_notifier/state_notifier.dart';
33
import 'package:stream_core/stream_core.dart';
44

55
import '../models/activity_data.dart';
6+
import '../models/activity_pin_data.dart';
7+
import '../models/comment_data.dart';
8+
import '../models/feeds_reaction_data.dart';
9+
import '../models/mark_activity_data.dart';
610
import '../models/pagination_data.dart';
711
import '../models/poll_data.dart';
812
import '../models/poll_vote_data.dart';
913
import '../models/threaded_comment_data.dart';
1014
import 'activity_comment_list_state.dart';
15+
import 'event/partial_activity_event_handler.dart';
1116

1217
part 'activity_state.freezed.dart';
1318

1419
/// Manages the state of an activity and handles state updates.
1520
///
1621
/// Provides methods to update the activity state in response to data changes
1722
/// and real-time events from the Stream Feeds API.
18-
class ActivityStateNotifier extends StateNotifier<ActivityState> {
23+
class ActivityStateNotifier extends StateNotifier<ActivityState> implements StateWithUpdatableActivity {
1924
ActivityStateNotifier({
2025
required ActivityState initialState,
2126
required this.currentUserId,
@@ -167,6 +172,41 @@ class ActivityStateNotifier extends StateNotifier<ActivityState> {
167172
_removeCommentListListener?.call();
168173
super.dispose();
169174
}
175+
176+
@override
177+
void onActivityMarked(MarkActivityData activityMark) {
178+
// TODO: implement onActivityMarked
179+
}
180+
181+
@override
182+
void onActivityPinned(ActivityPinData activityPin) {
183+
// TODO: implement onActivityPinned
184+
}
185+
186+
@override
187+
void onActivityUnpinned(String activityId) {
188+
// TODO: implement onActivityUnpinned
189+
}
190+
191+
@override
192+
void onCommentAdded(CommentData comment) {
193+
// TODO: implement onCommentAdded
194+
}
195+
196+
@override
197+
void onCommentRemoved(CommentData comment) {
198+
// TODO: implement onCommentRemoved
199+
}
200+
201+
@override
202+
void onReactionAdded(FeedsReactionData reaction) {
203+
// TODO: implement onReactionAdded
204+
}
205+
206+
@override
207+
void onReactionRemoved(FeedsReactionData reaction) {
208+
// TODO: implement onReactionRemoved
209+
}
170210
}
171211

172212
/// An observable state object that manages the current state of an activity.

packages/stream_feeds/lib/src/state/event/activity_event_handler.dart

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,26 +4,38 @@ import '../../generated/api/models.dart' as api;
44
import '../../models/feed_id.dart';
55
import '../../models/poll_data.dart';
66
import '../../models/poll_vote_data.dart';
7+
import '../../repository/capabilities_repository.dart';
78
import '../../resolvers/poll/poll_answer_casted.dart';
89
import '../../resolvers/poll/poll_answer_removed.dart';
910
import '../activity_state.dart';
11+
import 'partial_activity_event_handler.dart';
1012
import 'state_event_handler.dart';
1113

1214
/// Event handler for activity real-time updates.
1315
///
1416
/// Processes WebSocket events related to polls and their associated voting
1517
/// and updates the activity state accordingly.
1618
class ActivityEventHandler implements StateEventHandler {
17-
const ActivityEventHandler({
19+
ActivityEventHandler({
1820
required this.fid,
1921
required this.state,
22+
required this.capabilitiesRepository,
2023
});
2124

2225
final FeedId fid;
2326
final ActivityStateNotifier state;
27+
final CapabilitiesRepository capabilitiesRepository;
28+
29+
late final PartialActivityEventHandler _partialActivityEventHandler =
30+
PartialActivityEventHandler(
31+
state: state,
32+
capabilitiesRepository: capabilitiesRepository,
33+
fid: fid,
34+
);
2435

2536
@override
26-
void handleEvent(WsEvent event) {
37+
Future<void> handleEvent(WsEvent event) async {
38+
if(await _partialActivityEventHandler.handleEvent(event)) return;
2739
if (event is api.PollClosedFeedEvent) {
2840
return state.onPollClosed(event.poll.toModel());
2941
}

packages/stream_feeds/lib/src/state/event/feed_event_handler.dart

Lines changed: 21 additions & 134 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,12 @@ import '../feed_state.dart';
1515

1616
import '../query/feed_query.dart';
1717
import 'feed_capabilities_mixin.dart';
18+
import 'partial_activity_event_handler.dart';
19+
import 'partial_activity_list_event_handler.dart';
1820
import 'state_event_handler.dart';
1921

2022
class FeedEventHandler with FeedCapabilitiesMixin implements StateEventHandler {
21-
const FeedEventHandler({
23+
FeedEventHandler({
2224
required this.query,
2325
required this.state,
2426
required this.capabilitiesRepository,
@@ -30,100 +32,27 @@ class FeedEventHandler with FeedCapabilitiesMixin implements StateEventHandler {
3032
@override
3133
final CapabilitiesRepository capabilitiesRepository;
3234

35+
late final PartialActivityListEventHandler _partialActivityListEventHandler =
36+
PartialActivityListEventHandler(
37+
state: state,
38+
capabilitiesRepository: capabilitiesRepository,
39+
fid: query.fid,
40+
activityFilter: query.activityFilter,
41+
);
42+
43+
late final PartialActivityEventHandler _partialActivityEventHandler =
44+
PartialActivityEventHandler(
45+
state: state,
46+
capabilitiesRepository: capabilitiesRepository,
47+
fid: query.fid,
48+
);
49+
3350
@override
3451
Future<void> handleEvent(WsEvent event) async {
35-
final fid = query.fid;
36-
37-
bool matchesQueryFilter(ActivityData activity) {
38-
final filter = query.activityFilter;
39-
if (filter == null) return true;
40-
return filter.matches(activity);
41-
}
42-
43-
if (event is api.ActivityAddedEvent) {
44-
if (event.fid != fid.rawValue) return;
45-
46-
final activity = event.activity.toModel();
47-
if (!matchesQueryFilter(activity)) return;
48-
49-
state.onActivityAdded(activity);
50-
51-
final updatedActivity = await withUpdatedFeedCapabilities(activity);
52-
if (updatedActivity != null) state.onActivityUpdated(updatedActivity);
53-
54-
return;
55-
}
56-
57-
if (event is api.ActivityUpdatedEvent) {
58-
if (event.fid != fid.rawValue) return;
59-
60-
final activity = event.activity.toModel();
61-
if (!matchesQueryFilter(activity)) {
62-
// If the updated activity no longer matches the filter, remove it
63-
return state.onActivityRemoved(activity);
64-
}
65-
66-
final updatedActivity = await withUpdatedFeedCapabilities(activity);
67-
return state.onActivityUpdated(updatedActivity ?? activity);
68-
}
69-
70-
if (event is api.ActivityDeletedEvent) {
71-
if (event.fid != fid.rawValue) return;
72-
return state.onActivityRemoved(event.activity.toModel());
73-
}
74-
75-
if (event is api.ActivityReactionAddedEvent) {
76-
if (event.fid != fid.rawValue) return;
77-
78-
final activity = event.activity.toModel();
79-
if (!matchesQueryFilter(activity)) {
80-
// If the reaction's activity no longer matches the filter, remove it
81-
return state.onActivityRemoved(activity);
82-
}
83-
84-
return state.onReactionAdded(event.reaction.toModel());
85-
}
86-
87-
if (event is api.ActivityReactionDeletedEvent) {
88-
if (event.fid != fid.rawValue) return;
89-
90-
final activity = event.activity.toModel();
91-
if (!matchesQueryFilter(activity)) {
92-
// If the reaction's activity no longer matches the filter, remove it
93-
return state.onActivityRemoved(activity);
94-
}
95-
96-
return state.onReactionRemoved(event.reaction.toModel());
97-
}
52+
if (await _partialActivityListEventHandler.handleEvent(event)) return;
53+
if (await _partialActivityEventHandler.handleEvent(event)) return;
9854

99-
if (event is api.ActivityPinnedEvent) {
100-
if (event.fid != fid.rawValue) return;
101-
102-
final activity = event.pinnedActivity.activity.toModel();
103-
if (!matchesQueryFilter(activity)) {
104-
// If the pinned activity no longer matches the filter, remove it
105-
return state.onActivityRemoved(activity);
106-
}
107-
108-
return state.onActivityPinned(event.pinnedActivity.toModel());
109-
}
110-
111-
if (event is api.ActivityUnpinnedEvent) {
112-
if (event.fid != fid.rawValue) return;
113-
114-
final activity = event.pinnedActivity.activity.toModel();
115-
if (!matchesQueryFilter(activity)) {
116-
// If the unpinned activity no longer matches the filter, remove it
117-
return state.onActivityRemoved(activity);
118-
}
119-
120-
return state.onActivityUnpinned(event.pinnedActivity.activity.id);
121-
}
122-
123-
if (event is api.ActivityMarkEvent) {
124-
if (event.fid != fid.rawValue) return;
125-
return state.onActivityMarked(event.toModel());
126-
}
55+
final fid = query.fid;
12756

12857
if (event is api.NotificationFeedUpdatedEvent) {
12958
if (event.fid != fid.rawValue) return;
@@ -133,48 +62,6 @@ class FeedEventHandler with FeedCapabilitiesMixin implements StateEventHandler {
13362
);
13463
}
13564

136-
if (event is api.BookmarkAddedEvent) {
137-
final activity = event.bookmark.activity.toModel();
138-
if (!activity.feeds.contains(fid.rawValue)) return;
139-
140-
if (!matchesQueryFilter(activity)) {
141-
// If the bookmark's activity no longer matches the filter, remove it
142-
return state.onActivityRemoved(activity);
143-
}
144-
145-
return state.onBookmarkAdded(event.bookmark.toModel());
146-
}
147-
148-
if (event is api.BookmarkDeletedEvent) {
149-
final activity = event.bookmark.activity.toModel();
150-
if (!activity.feeds.contains(fid.rawValue)) return;
151-
152-
if (!matchesQueryFilter(activity)) {
153-
// If the bookmark's activity no longer matches the filter, remove it
154-
return state.onActivityRemoved(activity);
155-
}
156-
157-
return state.onBookmarkRemoved(event.bookmark.toModel());
158-
}
159-
160-
if (event is api.CommentAddedEvent) {
161-
if (event.fid != fid.rawValue) return;
162-
163-
final activity = event.activity.toModel();
164-
if (!matchesQueryFilter(activity)) {
165-
// If the comment's activity no longer matches the filter, remove it
166-
return state.onActivityRemoved(activity);
167-
}
168-
169-
return state.onCommentAdded(event.comment.toModel());
170-
}
171-
172-
if (event is api.CommentDeletedEvent) {
173-
if (event.fid != fid.rawValue) return;
174-
// TODO: Match event activity against filter once available in the event
175-
return state.onCommentRemoved(event.comment.toModel());
176-
}
177-
17865
if (event is api.FeedDeletedEvent) {
17966
if (event.fid != fid.rawValue) return;
18067
return state.onFeedDeleted();

0 commit comments

Comments
 (0)