From 46828764c1311d3b116e8b344c6934612abac68c Mon Sep 17 00:00:00 2001 From: Sahil Kumar Date: Thu, 5 Aug 2021 16:37:23 +0530 Subject: [PATCH] feat(ui): minor fixes, add support for `name` in user.dart Signed-off-by: xsahil03x --- .../lib/src/core/models/own_user.dart | 56 +++++---- .../lib/src/core/models/own_user.g.dart | 1 - .../stream_chat/lib/src/core/models/user.dart | 106 +++++++----------- .../lib/src/core/models/user.g.dart | 2 - .../test/src/core/models/user_test.dart | 40 ++++++- 5 files changed, 111 insertions(+), 94 deletions(-) diff --git a/packages/stream_chat/lib/src/core/models/own_user.dart b/packages/stream_chat/lib/src/core/models/own_user.dart index 5adc753c..ee81e909 100644 --- a/packages/stream_chat/lib/src/core/models/own_user.dart +++ b/packages/stream_chat/lib/src/core/models/own_user.dart @@ -20,6 +20,8 @@ class OwnUser extends User { this.channelMutes = const [], required String id, String? role, + String? name, + String? image, DateTime? createdAt, DateTime? updatedAt, DateTime? lastActive, @@ -28,10 +30,11 @@ class OwnUser extends User { bool banned = false, List teams = const [], String? language, - String? image, }) : super( id: id, role: role, + name: name, + image: image, createdAt: createdAt, updatedAt: updatedAt, lastActive: lastActive, @@ -40,7 +43,6 @@ class OwnUser extends User { banned: banned, teams: teams, language: language, - image: image, ); /// Create a new instance from a json @@ -51,6 +53,8 @@ class OwnUser extends User { factory OwnUser.fromUser(User user) => OwnUser( id: user.id, role: user.role, + name: user.name, + image: user.image, createdAt: user.createdAt, updatedAt: user.updatedAt, lastActive: user.lastActive, @@ -59,7 +63,6 @@ class OwnUser extends User { extraData: user.extraData, teams: user.teams, language: user.language, - image: user.image, ); /// Creates a copy of [OwnUser] with specified attributes overridden. @@ -67,6 +70,8 @@ class OwnUser extends User { OwnUser copyWith({ String? id, String? role, + String? name, + String? image, DateTime? createdAt, DateTime? updatedAt, DateTime? lastActive, @@ -80,48 +85,51 @@ class OwnUser extends User { int? totalUnreadCount, int? unreadChannels, String? language, - String? image, }) => OwnUser( - id: id ?? this.id, - banned: banned ?? this.banned, - role: role ?? this.role, - createdAt: createdAt ?? this.createdAt, - updatedAt: updatedAt ?? this.updatedAt, - lastActive: lastActive ?? this.lastActive, - online: online ?? this.online, - extraData: extraData ?? this.extraData, - teams: teams ?? this.teams, - channelMutes: channelMutes ?? this.channelMutes, - devices: devices ?? this.devices, - mutes: mutes ?? this.mutes, - totalUnreadCount: totalUnreadCount ?? this.totalUnreadCount, - unreadChannels: unreadChannels ?? this.unreadChannels, - language: language ?? this.language, - image: image // if null, it will be retrieved from extraData['image'] - ); + 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, + banned: banned ?? this.banned, + createdAt: createdAt ?? this.createdAt, + updatedAt: updatedAt ?? this.updatedAt, + lastActive: lastActive ?? this.lastActive, + online: online ?? this.online, + extraData: extraData ?? this.extraData, + teams: teams ?? this.teams, + channelMutes: channelMutes ?? this.channelMutes, + devices: devices ?? this.devices, + mutes: mutes ?? this.mutes, + totalUnreadCount: totalUnreadCount ?? this.totalUnreadCount, + unreadChannels: unreadChannels ?? this.unreadChannels, + language: language ?? this.language, + ); /// Returns a new [OwnUser] that is a combination of this ownUser /// and the given [other] ownUser. OwnUser merge(OwnUser? other) { if (other == null) return this; return copyWith( + id: other.id, + role: other.role, + name: other.name, + image: other.image, banned: other.banned, channelMutes: other.channelMutes, createdAt: other.createdAt, devices: other.devices, extraData: other.extraData, - id: other.id, lastActive: other.lastActive, mutes: other.mutes, online: other.online, - role: other.role, teams: other.teams, totalUnreadCount: other.totalUnreadCount, unreadChannels: other.unreadChannels, updatedAt: other.updatedAt, language: other.language, - image: other.image, ); } diff --git a/packages/stream_chat/lib/src/core/models/own_user.g.dart b/packages/stream_chat/lib/src/core/models/own_user.g.dart index cacb99c5..ca4acdea 100644 --- a/packages/stream_chat/lib/src/core/models/own_user.g.dart +++ b/packages/stream_chat/lib/src/core/models/own_user.g.dart @@ -40,6 +40,5 @@ OwnUser _$OwnUserFromJson(Map json) { (json['teams'] as List?)?.map((e) => e as String).toList() ?? [], language: json['language'] as String?, - image: json['image'] as String?, ); } diff --git a/packages/stream_chat/lib/src/core/models/user.dart b/packages/stream_chat/lib/src/core/models/user.dart index 9baaf049..5a5ef8e5 100644 --- a/packages/stream_chat/lib/src/core/models/user.dart +++ b/packages/stream_chat/lib/src/core/models/user.dart @@ -9,6 +9,18 @@ part 'user.g.dart'; class User extends Equatable { /// Creates a new user. /// + /// {@template name} + /// If an [name] is provided it will be set on [extraData] with a `key` + /// of 'name'. + /// + /// For example: + /// ```dart + /// final user = User(id: 'id', name: 'Sahil Kumar'); + /// print(user.name == user.extraData['name']); // true + /// ``` + /// {@endtemplate} + /// + /// {@template image} /// If an [image] is provided it will be set on [extraData] with a `key` /// of 'image'. /// @@ -17,9 +29,11 @@ class User extends Equatable { /// final user = User(id: 'id', image: 'https://getstream.io/image.png'); /// print(user.image == user.extraData['image']); // true /// ``` + /// {@endtemplate} User({ required this.id, this.role, + String? name, String? image, DateTime? createdAt, DateTime? updatedAt, @@ -29,13 +43,14 @@ class User extends Equatable { this.banned = false, this.teams = const [], this.language, - }) : _image = image, - createdAt = createdAt ?? DateTime.now(), + }) : createdAt = createdAt ?? DateTime.now(), updatedAt = updatedAt ?? DateTime.now(), - - // For backwards compatibalitity, set 'image' on [extraData]. - extraData = - (image != null) ? {...extraData, 'image': image} : extraData; + /*For backwards compatibility, set 'name', 'image' in [extraData].*/ + extraData = { + ...extraData, + if (name != null) 'name': name, + if (image != null) 'image': image, + }; /// Create a new instance from json. factory User.fromJson(Map json) => @@ -54,62 +69,32 @@ class User extends Equatable { 'banned', 'teams', 'language', - 'image', ]; /// User id. final String id; - /// User role. - @JsonKey(includeIfNull: false, toJson: Serializer.readOnly) - final String? role; - - /// Image for user. This is also set on `extraData['image']`. + /// Shortcut for user name. /// - /// {@template image} - /// There are a few ways to set an image. - /// - /// Setting an image by passing in an image argument: - /// ```dart - /// final user = User( - /// id: 'id', - /// image: 'https://getstream.io/image', - /// ); - /// ``` - /// - /// Or by directly setting it in [extraData], for example: - /// ```dart - /// final user = User( - /// id: 'id', - /// extraData: const {'image': 'https://getstream.io/image'}, - /// ); - /// - /// ``` - /// Parsing json with an 'image' key will automatically set the `image` - /// property and `extraData['image']` key/value. - /// - /// ```dart - /// final user = User.fromJson({ - /// id: 'id', - /// image: 'https://getstream.io/image', // key: image - /// }); - /// - /// print(user.image == user.extraData['image']); // true - /// ``` - /// {@endtemplate} - final String? _image; + /// {@macro name} + @JsonKey(ignore: true) + String get name { + if (extraData.containsKey('name')) { + final name = extraData['name']! as String; + if (name.isNotEmpty) return name; + } + return id; + } /// Shortcut for user image. /// /// {@macro image} + @JsonKey(ignore: true) + String? get image => extraData['image'] as String?; + + /// User role. @JsonKey(includeIfNull: false, toJson: Serializer.readOnly) - String? get image { - if (_image != null) { - return _image; - } else { - return extraData['image'] as String?; - } - } + final String? role; /// User teams @JsonKey( @@ -152,15 +137,6 @@ class User extends Equatable { @JsonKey(includeIfNull: false) final String? language; - /// Shortcut for user name. - String get name { - if (extraData.containsKey('name')) { - final name = extraData['name']! as String; - if (name.isNotEmpty) return name; - } - return id; - } - /// List of users to list of userIds. static List? toIds(List? users) => users?.map((u) => u.id).toList(); @@ -174,6 +150,8 @@ class User extends Equatable { User copyWith({ String? id, String? role, + String? name, + String? image, DateTime? createdAt, DateTime? updatedAt, DateTime? lastActive, @@ -182,11 +160,14 @@ class User extends Equatable { bool? banned, List? teams, String? language, - String? image, }) => 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, createdAt: createdAt ?? this.createdAt, updatedAt: updatedAt ?? this.updatedAt, lastActive: lastActive ?? this.lastActive, @@ -195,9 +176,8 @@ class User extends Equatable { banned: banned ?? this.banned, teams: teams ?? this.teams, language: language ?? this.language, - image: image, // if null, it will be retrieved from extraData['image'] ); @override - List get props => [id]; + List get props => [id, role]; } diff --git a/packages/stream_chat/lib/src/core/models/user.g.dart b/packages/stream_chat/lib/src/core/models/user.g.dart index c685cd57..ab2f04d5 100644 --- a/packages/stream_chat/lib/src/core/models/user.g.dart +++ b/packages/stream_chat/lib/src/core/models/user.g.dart @@ -10,7 +10,6 @@ User _$UserFromJson(Map json) { return User( id: json['id'] as String, role: json['role'] as String?, - image: json['image'] as String?, createdAt: json['created_at'] == null ? null : DateTime.parse(json['created_at'] as String), @@ -42,7 +41,6 @@ Map _$UserToJson(User instance) { } writeNotNull('role', readonly(instance.role)); - writeNotNull('image', readonly(instance.image)); writeNotNull('teams', readonly(instance.teams)); writeNotNull('created_at', readonly(instance.createdAt)); writeNotNull('updated_at', readonly(instance.updatedAt)); diff --git a/packages/stream_chat/test/src/core/models/user_test.dart b/packages/stream_chat/test/src/core/models/user_test.dart index 48306017..c8e04ede 100644 --- a/packages/stream_chat/test/src/core/models/user_test.dart +++ b/packages/stream_chat/test/src/core/models/user_test.dart @@ -45,9 +45,9 @@ void main() { final user = User( id: id, role: role, + name: name, image: image, extraData: const { - 'name': name, 'extraDataStringTest': extraDataStringTest, 'extraDataIntTest': extraDataIntTest, 'extraDataDoubleTest': extraDataDoubleTest, @@ -93,9 +93,7 @@ void main() { newUser = user.copyWith( id: 'test', role: 'test', - extraData: { - 'name': 'test', - }, + name: 'test', image: 'https://stream.io/new-image', online: false, banned: false, @@ -120,6 +118,40 @@ void main() { expect(newUser.language, 'it'); }); + test('name property and extraData manipulation', () { + final user = User(id: id, name: name); + + expect(user.name, name); + expect(user.extraData['name'], name); + expect(user.toJson(), {'id': id, 'name': name}); + expect(User.fromJson(user.toJson()).toJson(), {'id': id, 'name': name}); + + const nameOne = 'Name One'; + var newUser = user.copyWith( + extraData: {'name': nameOne}, + ); + + expect(newUser.extraData['name'], nameOne); + expect(newUser.name, nameOne); + + const nameTwo = 'Name Two'; + newUser = user.copyWith( + name: nameTwo, + ); + + expect(newUser.extraData['name'], nameTwo); + expect(newUser.name, nameTwo); + + const nameThree = 'Name Three'; + newUser = user.copyWith( + name: nameThree, + extraData: {'name': nameThree}, + ); + + expect(newUser.extraData['name'], nameThree); + expect(newUser.name, nameThree); + }); + test('image property and extraData manipulation', () { final user = User(id: id, image: image);