Skip to content
Open
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/code_snippets/03_02_querying_activities.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ late Feed feed;

Future<void> activitySearchAndQueries() async {
final query = ActivitiesQuery(
filter: Filter.equal(ActivitiesFilterField.type, 'post'),
filter: Filter.equal(ActivitiesFilterField.activityType, 'post'),
sort: [ActivitiesSort.desc(ActivitiesSortField.createdAt)],
limit: 10,
);
Expand Down
6 changes: 5 additions & 1 deletion melos.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,11 @@ command:
shared_preferences: ^2.5.3
state_notifier: ^1.0.0
stream_feeds: ^0.4.0
stream_core: ^0.3.1
stream_core:
git:
url: https://github.com/GetStream/stream-core-flutter
ref: feat/location-filtering
path: packages/stream_core
video_player: ^2.10.0
uuid: ^4.5.1

Expand Down
4 changes: 4 additions & 0 deletions packages/stream_feeds/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
## Upcoming
- [BREAKING] Unified `ThreadedCommentData` into `CommentData` to handle both flat and threaded comments.
- [BREAKING] Renamed `ActivitiesFilterField.type` to `ActivitiesFilterField.activityType`.
- [BREAKING] Changed `ActivityData.location` field type from `ActivityLocation?` to `LocationCoordinate?`.
- Add support for `enforceUnique` parameter while adding reactions.
- Add location filtering support for activities with `ActivitiesFilterField.near` and `ActivitiesFilterField.withinBounds` filter fields.
- Add new activity filter fields: `ActivitiesFilterField.feed` and `ActivitiesFilterField.interestTags`.

## 0.4.0
- [BREAKING] Change `queryFollowSuggestions` return type to `List<FeedSuggestionData>`.
Expand Down
2 changes: 1 addition & 1 deletion packages/stream_feeds/lib/src/feeds_client.dart
Original file line number Diff line number Diff line change
Expand Up @@ -319,7 +319,7 @@ abstract interface class StreamFeedsClient {
/// ```dart
/// final activityList = client.activityList(ActivitiesQuery(
/// filter: Filter.and([
/// Filter.equal(ActivitiesFilterField.type, 'post'),
/// Filter.equal(ActivitiesFilterField.activityType, 'post'),
/// Filter.greaterThan(ActivitiesFilterField.createdAt,
/// DateTime.now().subtract(Duration(days: 7))),
/// ]),
Expand Down
3 changes: 3 additions & 0 deletions packages/stream_feeds/lib/src/models.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
export 'package:stream_core/stream_core.dart'
show BoundingBox, CircularRegion, LocationCoordinate;

export 'models/activity_data.dart';
export 'models/aggregated_activity_data.dart';
export 'models/bookmark_data.dart';
Expand Down
9 changes: 7 additions & 2 deletions packages/stream_feeds/lib/src/models/activity_data.dart
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ class ActivityData with _$ActivityData {

/// Geographic location data associated with the activity, if any.
@override
final ActivityLocation? location;
final LocationCoordinate? location;

/// Users mentioned in the activity.
@override
Expand Down Expand Up @@ -277,7 +277,12 @@ extension ActivityResponseMapper on ActivityResponse {
interestTags: interestTags,
isWatched: isWatched,
latestReactions: [...latestReactions.map((r) => r.toModel())],
location: location,
location: location?.let(
(it) => LocationCoordinate(
latitude: it.lat,
longitude: it.lng,
),
),
mentionedUsers: [...mentionedUsers.map((u) => u.toModel())],
moderation: moderation?.toModel(),
notificationContext: notificationContext,
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

65 changes: 52 additions & 13 deletions packages/stream_feeds/lib/src/state/query/activities_query.dart
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ part 'activities_query.freezed.dart';
/// ## Example
/// ```dart
/// final query = ActivitiesQuery(
/// filter: Filter.equal(ActivitiesFilterField.type, "post"),
/// filter: Filter.equal(ActivitiesFilterField.activityType, "post"),
/// sort: [ActivitiesSort.desc(ActivitiesSortField.createdAt)],
/// limit: 20,
/// );
Expand Down Expand Up @@ -66,6 +66,14 @@ class ActivitiesFilterField extends FilterField<ActivityData> {
/// Creates a new activities filter field.
ActivitiesFilterField(super.remote, super.value);

/// Filter by the type of activity (e.g., "post", "comment", "reaction").
///
/// **Supported operators:** `.equal`, `.in`
static final activityType = ActivitiesFilterField(
'activity_type',
(data) => data.type,
);

/// Filter by the creation timestamp of the activity.
///
/// **Supported operators:** `.equal`, `.greaterThan`, `.lessThan`, `.greaterThanOrEqual`, `.lessThanOrEqual`
Expand All @@ -76,7 +84,8 @@ class ActivitiesFilterField extends FilterField<ActivityData> {

/// Filter by the expiration timestamp of the activity.
///
/// **Supported operators:** `.exists`
/// **Supported operators:** `.equal`, `.notEqual`, `.greaterThan`,
/// `.lessThan`, `.greaterThanOrEqual`, `.lessThanOrEqual`, `.exists`
static final expiresAt = ActivitiesFilterField(
'expires_at',
(data) => data.expiresAt,
Expand All @@ -90,14 +99,30 @@ class ActivitiesFilterField extends FilterField<ActivityData> {
(data) => data.id,
);

/// Filter by the feed ID(s) the activity belongs to.
///
/// **Supported operators:** `.equal`, `.in`
static final feed = ActivitiesFilterField(
'feed',
(data) => data.feeds,
);

/// Filter by the filter tags associated with the activity.
///
/// **Supported operators:** `.equal`, `.in`, `.customContains`
/// **Supported operators:** `.equal`, `.in`, `.contains`
static final filterTags = ActivitiesFilterField(
'filter_tags',
(data) => data.filterTags,
);

/// Filter by the interest tags associated with the activity.
///
/// **Supported operators:** `.equal`, `.in`, `.contains`
static final interestTags = ActivitiesFilterField(
'interest_tags',
(data) => data.interestTags,
);

/// Filter by the popularity score of the activity.
///
/// **Supported operators:** `.equal`, `.greaterThan`, `.lessThan`, `.greaterThanOrEqual`, `.lessThanOrEqual`
Expand All @@ -108,35 +133,49 @@ class ActivitiesFilterField extends FilterField<ActivityData> {

/// Filter by the search data content of the activity.
///
/// **Supported operators:** `.equal`, `.customQ`, `.customAutocomplete`
/// **Supported operators:** `.contains`, `.in`, `.pathExists`
static final searchData = ActivitiesFilterField(
'search_data',
(data) => data.searchData,
);

/// Filter by the text content of the activity.
///
/// **Supported operators:** `.equal`, `.customQ`, `.customAutocomplete`
/// **Supported operators:** `.equal`, `.q` (full-text search), `.autocomplete`
static final text = ActivitiesFilterField(
'text',
(data) => data.text,
);

/// Filter by the type of activity (e.g., "post", "comment", "reaction").
///
/// **Supported operators:** `.equal`, `.in`
static final type = ActivitiesFilterField(
'type',
(data) => data.type,
);

/// Filter by the user ID who created the activity.
///
/// **Supported operators:** `.equal`, `.in`
static final userId = ActivitiesFilterField(
'user_id',
(data) => data.user.id,
);

/// Filter by the proximity to a specific location.
///
/// Note: This requires an object with latitude ('lat'), longitude ('lng')
/// and distance in km ('distance).
///
/// **Supported operators:** `.equal`
static final near = ActivitiesFilterField(
'near',
(data) => data.location,
);

/// Filter by activities within specific geographical bounds.
///
/// Note: This requires an object with 'sw_lat', 'sw_lng' (southwest corner)
/// and 'ne_lat', 'ne_lng' (northeast) corner keys.
///
/// **Supported operators:** `.equal`
static final withinBounds = ActivitiesFilterField(
'within_bounds',
(data) => data.location,
);
}

// endregion
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ part 'feed_query.freezed.dart';
/// ```dart
/// final query = FeedQuery(
/// fid: FeedId(group: 'user', id: 'john'),
/// activityFilter: Filter.equal(ActivitiesFilterField.type, 'post'),
/// activityFilter: Filter.equal(ActivitiesFilterField.activityType, 'post'),
/// activityLimit: 25,
/// watch: true,
/// );
Expand Down
6 changes: 5 additions & 1 deletion packages/stream_feeds/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,11 @@ dependencies:
retrofit: ">=4.6.0 <=4.9.0"
rxdart: ^0.28.0
state_notifier: ^1.0.0
stream_core: ^0.3.1
stream_core:
git:
url: https://github.com/GetStream/stream-core-flutter
ref: feat/location-filtering
path: packages/stream_core
uuid: ^4.5.1

dev_dependencies:
Expand Down
16 changes: 8 additions & 8 deletions packages/stream_feeds/test/state/activity_list_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ void main() {
'ActivityUpdatedEvent - should remove activity when updated to non-matching type',
build: (client) => client.activityList(
ActivitiesQuery(
filter: Filter.equal(ActivitiesFilterField.type, 'post'),
filter: Filter.equal(ActivitiesFilterField.activityType, 'post'),
),
),
setUp: (tester) => tester.get(
Expand Down Expand Up @@ -54,7 +54,7 @@ void main() {
'ActivityReactionAddedEvent - should remove activity when reaction causes filter mismatch',
build: (client) => client.activityList(
ActivitiesQuery(
filter: Filter.equal(ActivitiesFilterField.type, 'post'),
filter: Filter.equal(ActivitiesFilterField.activityType, 'post'),
),
),
setUp: (tester) => tester.get(
Expand Down Expand Up @@ -91,7 +91,7 @@ void main() {
'ActivityReactionDeletedEvent - should remove activity when reaction deletion causes filter mismatch',
build: (client) => client.activityList(
ActivitiesQuery(
filter: Filter.equal(ActivitiesFilterField.type, 'post'),
filter: Filter.equal(ActivitiesFilterField.activityType, 'post'),
),
),
setUp: (tester) => tester.get(
Expand Down Expand Up @@ -128,7 +128,7 @@ void main() {
'BookmarkAddedEvent - should remove activity when bookmark causes filter mismatch',
build: (client) => client.activityList(
ActivitiesQuery(
filter: Filter.equal(ActivitiesFilterField.type, 'post'),
filter: Filter.equal(ActivitiesFilterField.activityType, 'post'),
),
),
setUp: (tester) => tester.get(
Expand Down Expand Up @@ -157,7 +157,7 @@ void main() {
'BookmarkDeletedEvent - should remove activity when bookmark deletion causes filter mismatch',
build: (client) => client.activityList(
ActivitiesQuery(
filter: Filter.equal(ActivitiesFilterField.type, 'post'),
filter: Filter.equal(ActivitiesFilterField.activityType, 'post'),
),
),
setUp: (tester) => tester.get(
Expand Down Expand Up @@ -186,7 +186,7 @@ void main() {
'CommentAddedEvent - should remove activity when comment causes filter mismatch',
build: (client) => client.activityList(
ActivitiesQuery(
filter: Filter.equal(ActivitiesFilterField.type, 'post'),
filter: Filter.equal(ActivitiesFilterField.activityType, 'post'),
),
),
setUp: (tester) => tester.get(
Expand Down Expand Up @@ -220,7 +220,7 @@ void main() {
build: (client) => client.activityList(
ActivitiesQuery(
filter: Filter.and([
Filter.equal(ActivitiesFilterField.type, 'post'),
Filter.equal(ActivitiesFilterField.activityType, 'post'),
Filter.equal(ActivitiesFilterField.filterTags, ['featured']),
]),
),
Expand Down Expand Up @@ -254,7 +254,7 @@ void main() {
build: (client) => client.activityList(
ActivitiesQuery(
filter: Filter.or([
Filter.equal(ActivitiesFilterField.type, 'post'),
Filter.equal(ActivitiesFilterField.activityType, 'post'),
Filter.equal(ActivitiesFilterField.filterTags, ['featured']),
]),
),
Expand Down
16 changes: 8 additions & 8 deletions packages/stream_feeds/test/state/feed_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -416,7 +416,7 @@ void main() {
build: (client) => client.feedFromQuery(
FeedQuery(
fid: feedId,
activityFilter: Filter.equal(ActivitiesFilterField.type, 'post'),
activityFilter: Filter.equal(ActivitiesFilterField.activityType, 'post'),
),
),
setUp: (tester) => tester.getOrCreate(
Expand Down Expand Up @@ -448,7 +448,7 @@ void main() {
build: (client) => client.feedFromQuery(
FeedQuery(
fid: feedId,
activityFilter: Filter.equal(ActivitiesFilterField.type, 'post'),
activityFilter: Filter.equal(ActivitiesFilterField.activityType, 'post'),
),
),
setUp: (tester) => tester.getOrCreate(
Expand Down Expand Up @@ -480,7 +480,7 @@ void main() {
build: (client) => client.feedFromQuery(
FeedQuery(
fid: feedId,
activityFilter: Filter.equal(ActivitiesFilterField.type, 'post'),
activityFilter: Filter.equal(ActivitiesFilterField.activityType, 'post'),
),
),
setUp: (tester) => tester.getOrCreate(
Expand Down Expand Up @@ -558,7 +558,7 @@ void main() {
build: (client) => client.feedFromQuery(
FeedQuery(
fid: feedId,
activityFilter: Filter.equal(ActivitiesFilterField.type, 'post'),
activityFilter: Filter.equal(ActivitiesFilterField.activityType, 'post'),
),
),
setUp: (tester) => tester.getOrCreate(
Expand Down Expand Up @@ -597,7 +597,7 @@ void main() {
build: (client) => client.feedFromQuery(
FeedQuery(
fid: feedId,
activityFilter: Filter.equal(ActivitiesFilterField.type, 'post'),
activityFilter: Filter.equal(ActivitiesFilterField.activityType, 'post'),
),
),
setUp: (tester) => tester.getOrCreate(
Expand Down Expand Up @@ -634,7 +634,7 @@ void main() {
build: (client) => client.feedFromQuery(
FeedQuery(
fid: feedId,
activityFilter: Filter.equal(ActivitiesFilterField.type, 'post'),
activityFilter: Filter.equal(ActivitiesFilterField.activityType, 'post'),
),
),
setUp: (tester) => tester.getOrCreate(
Expand Down Expand Up @@ -672,7 +672,7 @@ void main() {
FeedQuery(
fid: feedId,
activityFilter: Filter.and([
Filter.equal(ActivitiesFilterField.type, 'post'),
Filter.equal(ActivitiesFilterField.activityType, 'post'),
Filter.in_(ActivitiesFilterField.filterTags, ['featured']),
]),
),
Expand Down Expand Up @@ -711,7 +711,7 @@ void main() {
FeedQuery(
fid: feedId,
activityFilter: Filter.or([
Filter.equal(ActivitiesFilterField.type, 'post'),
Filter.equal(ActivitiesFilterField.activityType, 'post'),
Filter.in_(ActivitiesFilterField.filterTags, ['featured']),
]),
),
Expand Down
Loading