Skip to content

Commit

Permalink
Merge branch 'develop' into release/4.2.0
Browse files Browse the repository at this point in the history
  • Loading branch information
imtoori committed May 20, 2022
2 parents ae68226 + 1c333c6 commit 6d6e484
Show file tree
Hide file tree
Showing 9 changed files with 250 additions and 12 deletions.
6 changes: 6 additions & 0 deletions packages/stream_chat/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,19 @@
- Added `PaginationParams.createdAtBeforeOrEqual` for message pagination.
- Added `PaginationParams.createdAtBefore` for message pagination.
- Added `PaginationParams.createdAtAround` for message pagination.
- Added support for `channel.disabled`, `channel.hidden` and `channel.truncatedAt` in `Channel`.
- Added support for `channel.membership` and `channel.membershipStream` in `Channel`.
- `Channel` now listens for `member.updated` events and updates the `Channel.members` accordingly.

🔄 Changed

- Deprecated `PaginationParams.before` and `PaginationParams.after`. Use `PaginationParams.limit` instead.

🐞 Fixed

- [[#1147]](https://github.com/GetStream/stream-chat-flutter/issues/1147) `channel.unset` not updating the extra data
stream.

## 4.1.0

✅ Added
Expand Down
36 changes: 36 additions & 0 deletions packages/stream_chat/lib/src/client/channel.dart
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,42 @@ class Channel {
return state!.channelStateStream.map((cs) => cs.channel?.frozen == true);
}

/// Channel disabled status.
bool get disabled {
_checkInitialized();
return state!._channelState.channel?.disabled == true;
}

/// Channel disabled status as a stream.
Stream<bool> get disabledStream {
_checkInitialized();
return state!.channelStateStream.map((cs) => cs.channel?.disabled == true);
}

/// Channel hidden status.
bool get hidden {
_checkInitialized();
return state!._channelState.channel?.hidden == true;
}

/// Channel hidden status as a stream.
Stream<bool> get hiddenStream {
_checkInitialized();
return state!.channelStateStream.map((cs) => cs.channel?.hidden == true);
}

/// The last date at which the channel got truncated.
DateTime? get truncatedAt {
_checkInitialized();
return state!._channelState.channel?.truncatedAt;
}

/// The last date at which the channel got truncated as a stream.
Stream<DateTime?> get truncatedAtStream {
_checkInitialized();
return state!.channelStateStream.map((cs) => cs.channel?.truncatedAt);
}

/// Cooldown count
int get cooldown {
_checkInitialized();
Expand Down
50 changes: 47 additions & 3 deletions packages/stream_chat/lib/src/core/models/channel_model.dart
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,12 @@ class ChannelModel {
DateTime? updatedAt,
this.deletedAt,
this.memberCount = 0,
this.extraData = const {},
Map<String, Object?> extraData = const {},
this.team,
this.cooldown = 0,
bool? disabled,
bool? hidden,
DateTime? truncatedAt,
}) : assert(
(cid != null && cid.contains(':')) || (id != null && type != null),
'provide either a cid or an id and type',
Expand All @@ -34,7 +37,18 @@ class ChannelModel {
cid = cid ?? '$type:$id',
config = config ?? ChannelConfig(),
createdAt = createdAt ?? DateTime.now(),
updatedAt = updatedAt ?? DateTime.now();
updatedAt = updatedAt ?? DateTime.now(),

// TODO: Make them top-level fields in v5
// For backwards compatibility, set 'disabled', 'hidden'
// and 'truncated_at' in [extraData].
extraData = {
...extraData,
if (disabled != null) 'disabled': disabled,
if (hidden != null) 'hidden': hidden,
if (truncatedAt != null)
'truncated_at': truncatedAt.toIso8601String(),
};

/// Create a new instance from a json
factory ChannelModel.fromJson(Map<String, dynamic> json) =>
Expand Down Expand Up @@ -92,6 +106,22 @@ class ChannelModel {
@JsonKey(includeIfNull: false)
final int cooldown;

/// True if the channel is disabled
@JsonKey(ignore: true)
bool? get disabled => extraData['disabled'] as bool?;

/// True if the channel is hidden
@JsonKey(ignore: true)
bool? get hidden => extraData['hidden'] as bool?;

/// The date of the last time channel got truncated
@JsonKey(ignore: true)
DateTime? get truncatedAt {
final truncatedAt = extraData['truncated_at'] as String?;
if (truncatedAt == null) return null;
return DateTime.parse(truncatedAt);
}

/// Map of custom channel extraData
@JsonKey(includeIfNull: false)
final Map<String, Object?> extraData;
Expand Down Expand Up @@ -145,6 +175,9 @@ class ChannelModel {
Map<String, Object?>? extraData,
String? team,
int? cooldown,
bool? disabled,
bool? hidden,
DateTime? truncatedAt,
}) =>
ChannelModel(
id: id ?? this.id,
Expand All @@ -162,6 +195,14 @@ class ChannelModel {
extraData: extraData ?? this.extraData,
team: team ?? this.team,
cooldown: cooldown ?? this.cooldown,
disabled: disabled ?? extraData?['disabled'] as bool? ?? this.disabled,
hidden: hidden ?? extraData?['hidden'] as bool? ?? this.hidden,
truncatedAt: truncatedAt ??
(extraData?['truncated_at'] == null
? null
// ignore: cast_nullable_to_non_nullable
: DateTime.parse(extraData?['truncated_at'] as String)) ??
this.truncatedAt,
);

/// Returns a new [ChannelModel] that is a combination of this channelModel
Expand All @@ -181,9 +222,12 @@ class ChannelModel {
updatedAt: other.updatedAt,
deletedAt: other.deletedAt,
memberCount: other.memberCount,
extraData: {...extraData, ...other.extraData},
extraData: other.extraData,
team: other.team,
cooldown: other.cooldown,
disabled: other.disabled,
hidden: other.hidden,
truncatedAt: other.truncatedAt,
);
}
}
4 changes: 4 additions & 0 deletions packages/stream_chat/lib/src/core/models/event.dart
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,7 @@ class EventChannel extends ChannelModel {
super.id,
super.type,
required String super.cid,
super.ownCapabilities,
required ChannelConfig super.config,
super.createdBy,
super.frozen,
Expand All @@ -191,6 +192,9 @@ class EventChannel extends ChannelModel {
Map<String, Object?>? extraData,
super.cooldown,
super.team,
super.disabled,
super.hidden,
super.truncatedAt,
}) : super(extraData: extraData ?? {});

/// Create a new instance from a json
Expand Down
3 changes: 3 additions & 0 deletions packages/stream_chat/lib/src/core/models/event.g.dart

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

15 changes: 11 additions & 4 deletions packages/stream_chat/lib/src/core/models/own_user.dart
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ class OwnUser extends User {
factory OwnUser.fromUser(User user) => OwnUser(
id: user.id,
role: user.role,
// Using extraData value in order to not use id as name.
name: user.extraData['name'] as String?,
image: user.image,
createdAt: user.createdAt,
updatedAt: user.updatedAt,
lastActive: user.lastActive,
Expand Down Expand Up @@ -76,10 +79,11 @@ class OwnUser extends User {
OwnUser(
id: id ?? this.id,
role: role ?? this.role,
// if null, it will be retrieved from extraData['name']
name: name,
// if null, it will be retrieved from extraData['image']
image: image,
name: name ??
extraData?['name'] as String? ??
// Using extraData value in order to not use id as name.
this.extraData['name'] as String?,
image: image ?? extraData?['image'] as String? ?? this.image,
banned: banned ?? this.banned,
banExpires: banExpires ?? this.banExpires,
createdAt: createdAt ?? this.createdAt,
Expand All @@ -103,6 +107,9 @@ class OwnUser extends User {
return copyWith(
id: other.id,
role: other.role,
// Using extraData value in order to not use id as name.
name: other.extraData['name'] as String?,
image: other.image,
banned: other.banned,
channelMutes: other.channelMutes,
createdAt: other.createdAt,
Expand Down
10 changes: 6 additions & 4 deletions packages/stream_chat/lib/src/core/models/user.dart
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ class User extends Equatable {
this.language,
}) : createdAt = createdAt ?? DateTime.now(),
updatedAt = updatedAt ?? DateTime.now(),
// TODO: Make them top-level fields in v5
// For backwards compatibility, set 'name', 'image' in [extraData].
extraData = {
...extraData,
Expand Down Expand Up @@ -171,10 +172,11 @@ class User extends Equatable {
User(
id: id ?? this.id,
role: role ?? this.role,
// if null, it will be retrieved from extraData['name']
name: name,
// if null, it will be retrieved from extraData['image']
image: image,
name: name ??
extraData?['name'] as String? ??
// Using extraData value in order to not use id as name.
this.extraData['name'] as String?,
image: image ?? extraData?['image'] as String? ?? this.image,
createdAt: createdAt ?? this.createdAt,
updatedAt: updatedAt ?? this.updatedAt,
lastActive: lastActive ?? this.lastActive,
Expand Down
2 changes: 1 addition & 1 deletion packages/stream_chat/test/src/client/client_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2514,7 +2514,7 @@ void main() {
});

test(
'''setting the `currentUser` should also compute and update the unreadCounts''',
'setting the `currentUser` should also compute and update the unreadCounts',
() {
final state = client.state;
final initialUser = OwnUser.fromUser(user);
Expand Down
136 changes: 136 additions & 0 deletions packages/stream_chat/test/src/core/models/channel_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -55,4 +55,140 @@ void main() {
);
});
});

test('hidden property and extraData manipulation', () {
final channel = ChannelModel(cid: 'test:cid', hidden: false);

expect(channel.hidden, false);
expect(channel.extraData['hidden'], false);
print(channel.toJson());
expect(channel.toJson(), {
'id': 'cid',
'type': 'test',
'frozen': false,
'cooldown': 0,
'hidden': false,
});
expect(ChannelModel.fromJson(channel.toJson()).toJson(), {
'id': 'cid',
'type': 'test',
'frozen': false,
'cooldown': 0,
'hidden': false,
});

var newChannel = channel.copyWith(
extraData: {'hidden': true},
);

expect(newChannel.extraData['hidden'], true);
expect(newChannel.hidden, true);

newChannel = channel.copyWith(
hidden: false,
);

expect(newChannel.extraData['hidden'], false);
expect(newChannel.hidden, false);

newChannel = channel.copyWith(
hidden: true,
extraData: {'hidden': true},
);

expect(newChannel.extraData['hidden'], true);
expect(newChannel.hidden, true);
});

test('disabled property and extraData manipulation', () {
final channel = ChannelModel(cid: 'test:cid', disabled: false);

expect(channel.disabled, false);
expect(channel.extraData['disabled'], false);
print(channel.toJson());
expect(channel.toJson(), {
'id': 'cid',
'type': 'test',
'frozen': false,
'cooldown': 0,
'disabled': false,
});
expect(ChannelModel.fromJson(channel.toJson()).toJson(), {
'id': 'cid',
'type': 'test',
'frozen': false,
'cooldown': 0,
'disabled': false,
});

var newChannel = channel.copyWith(
extraData: {'disabled': true},
);

expect(newChannel.extraData['disabled'], true);
expect(newChannel.disabled, true);

newChannel = channel.copyWith(
hidden: false,
);

expect(newChannel.extraData['disabled'], false);
expect(newChannel.disabled, false);

newChannel = channel.copyWith(
hidden: true,
extraData: {'disabled': true},
);

expect(newChannel.extraData['disabled'], true);
expect(newChannel.disabled, true);
});

test('truncatedAt property and extraData manipulation', () {
final currentDate = DateTime.now();
final channel = ChannelModel(cid: 'test:cid', truncatedAt: currentDate);

expect(channel.truncatedAt, currentDate);
expect(channel.extraData['truncated_at'], currentDate.toIso8601String());
print(channel.toJson());
expect(channel.toJson(), {
'id': 'cid',
'type': 'test',
'frozen': false,
'cooldown': 0,
'truncated_at': currentDate.toIso8601String(),
});
expect(ChannelModel.fromJson(channel.toJson()).toJson(), {
'id': 'cid',
'type': 'test',
'frozen': false,
'cooldown': 0,
'truncated_at': currentDate.toIso8601String(),
});

final dateOne = DateTime.now();
var newChannel = channel.copyWith(
extraData: {'truncated_at': dateOne.toIso8601String()},
);

expect(newChannel.extraData['truncated_at'], dateOne.toIso8601String());
expect(newChannel.truncatedAt, dateOne);

final dateTwo = DateTime.now();
newChannel = channel.copyWith(
truncatedAt: dateTwo,
);

expect(newChannel.extraData['truncated_at'], dateTwo.toIso8601String());
expect(newChannel.truncatedAt, dateTwo);

final dateThree = DateTime.now();
newChannel = channel.copyWith(
truncatedAt: dateThree,
extraData: {'truncated_at': dateThree.toIso8601String()},
);

expect(newChannel.extraData['truncated_at'], dateThree.toIso8601String());
expect(newChannel.truncatedAt, dateThree);
});
}

0 comments on commit 6d6e484

Please sign in to comment.