Merge branch 'develop' into rfac/transform

This commit is contained in:
Salvatore Giordano
2021-05-17 17:04:11 +02:00
34 changed files with 239 additions and 198 deletions
@@ -22,7 +22,7 @@ class Channel {
this._client,
this._type,
this._id, {
Map<String, Object> extraData = const {},
Map<String, Object?> extraData = const {},
}) : _cid = _id != null ? '$_type:$_id' : null,
_extraData = extraData {
_client.logger.info('New Channel instance not initialized created');
@@ -630,7 +630,7 @@ class Channel {
Future<SendReactionResponse> sendReaction(
Message message,
String type, {
Map<String, Object> extraData = const {},
Map<String, Object?> extraData = const {},
bool enforceUnique = false,
}) async {
_checkInitialized();
@@ -1099,7 +1099,7 @@ class Channel {
}) async {
final payload = <String, dynamic>{
'sort': sort,
'filter_conditions': filter,
'filter_conditions': filter ?? {},
'type': type,
};
+1 -1
View File
@@ -1194,7 +1194,7 @@ class StreamChatClient {
Channel channel(
String type, {
String? id,
Map<String, Object> extraData = const {},
Map<String, Object?> extraData = const {},
}) {
if (id != null && state.channels.containsKey('$type:$id')) {
return state.channels['$type:$id']!;
@@ -114,7 +114,7 @@ class Attachment extends Equatable {
includeIfNull: false,
defaultValue: {},
)
final Map<String, Object> extraData;
final Map<String, Object?> extraData;
/// The attachment ID.
///
@@ -183,7 +183,7 @@ class Attachment extends Equatable {
List<Action>? actions,
AttachmentFile? file,
UploadState? uploadState,
Map<String, Object>? extraData,
Map<String, Object?>? extraData,
}) =>
Attachment(
id: id ?? this.id,
@@ -30,10 +30,7 @@ Attachment _$AttachmentFromJson(Map<String, dynamic> json) {
?.map((e) => Action.fromJson(e as Map<String, dynamic>))
.toList() ??
[],
extraData: (json['extra_data'] as Map<String, dynamic>?)?.map(
(k, e) => MapEntry(k, e as Object),
) ??
{},
extraData: json['extra_data'] as Map<String, dynamic>? ?? {},
file: json['file'] == null
? null
: AttachmentFile.fromJson(json['file'] as Map<String, dynamic>),
@@ -132,9 +132,8 @@ class _$PreparingCopyWithImpl<$Res> extends _$UploadStateCopyWithImpl<$Res>
Preparing get _value => super._value as Preparing;
}
@JsonSerializable()
/// @nodoc
@JsonSerializable()
class _$Preparing implements Preparing {
const _$Preparing();
@@ -253,9 +252,8 @@ class _$InProgressCopyWithImpl<$Res> extends _$UploadStateCopyWithImpl<$Res>
}
}
@JsonSerializable()
/// @nodoc
@JsonSerializable()
class _$InProgress implements InProgress {
const _$InProgress({required this.uploaded, required this.total});
@@ -382,9 +380,8 @@ class _$SuccessCopyWithImpl<$Res> extends _$UploadStateCopyWithImpl<$Res>
Success get _value => super._value as Success;
}
@JsonSerializable()
/// @nodoc
@JsonSerializable()
class _$Success implements Success {
const _$Success();
@@ -497,9 +494,8 @@ class _$FailedCopyWithImpl<$Res> extends _$UploadStateCopyWithImpl<$Res>
}
}
@JsonSerializable()
/// @nodoc
@JsonSerializable()
class _$Failed implements Failed {
const _$Failed({required this.error});
@@ -8,10 +8,10 @@ part of 'attachment_file.dart';
AttachmentFile _$AttachmentFileFromJson(Map<String, dynamic> json) {
return AttachmentFile(
size: json['size'] as int?,
path: json['path'] as String?,
name: json['name'] as String?,
bytes: _fromString(json['bytes'] as String?),
size: json['size'] as int?,
);
}
@@ -87,7 +87,7 @@ class ChannelModel {
includeIfNull: false,
defaultValue: {},
)
final Map<String, Object> extraData;
final Map<String, Object?> extraData;
/// The team the channel belongs to
@JsonKey(includeIfNull: false, toJson: Serialization.readOnly)
@@ -132,7 +132,7 @@ class ChannelModel {
DateTime? updatedAt,
DateTime? deletedAt,
int? memberCount,
Map<String, Object>? extraData,
Map<String, Object?>? extraData,
String? team,
}) =>
ChannelModel(
@@ -31,10 +31,7 @@ ChannelModel _$ChannelModelFromJson(Map<String, dynamic> json) {
? null
: DateTime.parse(json['deleted_at'] as String),
memberCount: json['member_count'] as int? ?? 0,
extraData: (json['extra_data'] as Map<String, dynamic>?)?.map(
(k, e) => MapEntry(k, e as Object),
) ??
{},
extraData: json['extra_data'] as Map<String, dynamic>? ?? {},
team: json['team'] as String?,
);
}
@@ -93,7 +93,7 @@ class Event {
/// Map of custom channel extraData
@JsonKey(defaultValue: {})
final Map<String, Object> extraData;
final Map<String, Object?> extraData;
/// Known top level fields.
/// Useful for [Serialization] methods.
@@ -140,7 +140,7 @@ class Event {
int? unreadChannels,
bool? online,
String? parentId,
Map<String, Object>? extraData,
Map<String, Object?>? extraData,
}) =>
Event(
type: type ?? this.type,
@@ -180,7 +180,7 @@ class EventChannel extends ChannelModel {
required DateTime updatedAt,
DateTime? deletedAt,
required int memberCount,
Map<String, Object>? extraData,
Map<String, Object?>? extraData,
}) : super(
id: id,
type: type,
@@ -38,10 +38,7 @@ Event _$EventFromJson(Map<String, dynamic> json) {
channelId: json['channel_id'] as String?,
channelType: json['channel_type'] as String?,
parentId: json['parent_id'] as String?,
extraData: (json['extra_data'] as Map<String, dynamic>?)?.map(
(k, e) => MapEntry(k, e as Object),
) ??
{},
extraData: json['extra_data'] as Map<String, dynamic>? ?? {},
isLocal: json['is_local'] as bool? ?? false,
);
}
@@ -89,10 +86,7 @@ EventChannel _$EventChannelFromJson(Map<String, dynamic> json) {
? null
: DateTime.parse(json['deleted_at'] as String),
memberCount: json['member_count'] as int? ?? 0,
extraData: (json['extra_data'] as Map<String, dynamic>?)?.map(
(k, e) => MapEntry(k, e as Object),
) ??
{},
extraData: json['extra_data'] as Map<String, dynamic>? ?? {},
);
}
+24 -13
View File
@@ -87,8 +87,8 @@ extension FilterOperatorX on FilterOperator {
/// See <a href="https://getstream.io/chat/docs/query_channels/?language=dart" target="_top">Query Channels Documentation</a>
class Filter extends Equatable {
const Filter.__({
required this.operator,
required this.value,
this.operator,
this.key,
});
@@ -159,13 +159,26 @@ class Filter extends Equatable {
/// Creates a custom [Filter] if there isn't one already available.
const factory Filter.custom({
required String operator,
required Object value,
String? operator,
String? key,
}) = Filter.__;
/// Creates a custom [Filter] from a raw map value
///
/// ```dart
/// final filter = Filter.raw(
/// {
/// 'members': [user1.id, user2.id],
/// }
/// )
/// ```
const factory Filter.raw({
required Map<String, Object?> value,
}) = Filter.__;
/// An operator used for the filter. The operator string must start with `$`
final String operator;
final String? operator;
/// The "left-hand" side of the filter.
/// Specifies the name of the field the filter should match.
@@ -183,24 +196,22 @@ class Filter extends Equatable {
List<Object?> get props => [operator, key, value];
/// Serializes to json object
Map<String, Object> toJson() {
final json = <String, Object>{};
Map<String, Object?> toJson() {
final json = <String, Object?>{};
final groupOperators = _groupOperators.map((it) => it.rawValue);
assert(
groupOperators.contains(operator) || key != null,
'Filter must contain the `key` when the operator is not a '
'group operator.',
);
if (groupOperators.contains(operator)) {
// Filters with group operators are encoded in the following form:
// { $<operator>: [ <filter 1>, <filter 2> ] }
json[operator] = value;
} else {
json[operator!] = value;
} else if (operator != null) {
// Normal filters are encoded in the following form:
// { key: { $<operator>: <value> } }
json[key!] = {operator: value};
} else if (key != null) {
json[key!] = value;
} else {
return value as Map<String, Object?>;
}
return json;
@@ -208,7 +208,7 @@ class Message extends Equatable {
includeIfNull: false,
defaultValue: {},
)
final Map<String, Object> extraData;
final Map<String, Object?> extraData;
/// True if the message is a system info
bool get isSystem => type == 'system';
@@ -289,7 +289,7 @@ class Message extends Equatable {
DateTime? pinnedAt,
Object? pinExpires = _pinExpires,
User? pinnedBy,
Map<String, Object>? extraData,
Map<String, Object?>? extraData,
MessageSendingStatus? status,
bool? skipPush,
}) {
@@ -63,10 +63,7 @@ Message _$MessageFromJson(Map<String, dynamic> json) {
pinnedBy: json['pinned_by'] == null
? null
: User.fromJson(json['pinned_by'] as Map<String, dynamic>),
extraData: (json['extra_data'] as Map<String, dynamic>?)?.map(
(k, e) => MapEntry(k, e as Object),
) ??
{},
extraData: json['extra_data'] as Map<String, dynamic>? ?? {},
deletedAt: json['deleted_at'] == null
? null
: DateTime.parse(json['deleted_at'] as String),
@@ -23,7 +23,7 @@ class OwnUser extends User {
DateTime? updatedAt,
DateTime? lastActive,
bool online = false,
Map<String, Object> extraData = const {},
Map<String, Object?> extraData = const {},
bool banned = false,
}) : super(
id: id,
@@ -34,9 +34,7 @@ OwnUser _$OwnUserFromJson(Map<String, dynamic> json) {
? null
: DateTime.parse(json['last_active'] as String),
online: json['online'] as bool? ?? false,
extraData: (json['extra_data'] as Map<String, dynamic>).map(
(k, e) => MapEntry(k, e as Object),
),
extraData: json['extra_data'] as Map<String, dynamic>? ?? {},
banned: json['banned'] as bool? ?? false,
);
}
@@ -15,7 +15,7 @@ class Reaction {
this.user,
String? userId,
this.score = 0,
this.extraData,
this.extraData = const {},
}) : userId = userId ?? user?.id,
createdAt = createdAt ?? DateTime.now();
@@ -49,8 +49,11 @@ class Reaction {
final String? userId;
/// Reaction custom extraData
@JsonKey(includeIfNull: false)
final Map<String, Object>? extraData;
@JsonKey(
includeIfNull: false,
defaultValue: {},
)
final Map<String, Object?> extraData;
/// Map of custom user extraData
static const topLevelFields = [
@@ -75,7 +78,7 @@ class Reaction {
User? user,
String? userId,
int? score,
Map<String, Object>? extraData,
Map<String, Object?>? extraData,
}) =>
Reaction(
messageId: messageId ?? this.messageId,
@@ -18,9 +18,7 @@ Reaction _$ReactionFromJson(Map<String, dynamic> json) {
: User.fromJson(json['user'] as Map<String, dynamic>),
userId: json['user_id'] as String?,
score: json['score'] as int? ?? 0,
extraData: (json['extra_data'] as Map<String, dynamic>?)?.map(
(k, e) => MapEntry(k, e as Object),
),
extraData: json['extra_data'] as Map<String, dynamic>? ?? {},
);
}
@@ -40,6 +38,6 @@ Map<String, dynamic> _$ReactionToJson(Reaction instance) {
writeNotNull('user', readonly(instance.user));
val['score'] = instance.score;
writeNotNull('user_id', readonly(instance.userId));
writeNotNull('extra_data', instance.extraData);
val['extra_data'] = instance.extraData;
return val;
}
@@ -74,8 +74,11 @@ class User {
final bool banned;
/// Map of custom user extraData
@JsonKey(includeIfNull: false)
final Map<String, Object> extraData;
@JsonKey(
includeIfNull: false,
defaultValue: {},
)
final Map<String, Object?> extraData;
@override
int get hashCode => id.hashCode;
@@ -107,7 +110,7 @@ class User {
DateTime? updatedAt,
DateTime? lastActive,
bool? online,
Map<String, Object>? extraData,
Map<String, Object?>? extraData,
bool? banned,
List<String>? teams,
}) =>
@@ -20,9 +20,7 @@ User _$UserFromJson(Map<String, dynamic> json) {
? null
: DateTime.parse(json['last_active'] as String),
online: json['online'] as bool? ?? false,
extraData: (json['extra_data'] as Map<String, dynamic>).map(
(k, e) => MapEntry(k, e as Object),
),
extraData: json['extra_data'] as Map<String, dynamic>? ?? {},
banned: json['banned'] as bool? ?? false,
teams:
(json['teams'] as List<dynamic>?)?.map((e) => e as String).toList() ??
@@ -130,6 +130,14 @@ void main() {
expect(filter.operator, operator);
});
test('raw', () {
const value = {
'test': ['a', 'b'],
};
const filter = Filter.raw(value: value);
expect(filter.value, value);
});
group('groupedOperator', () {
final filter1 = Filter.equal('testKey', 'testValue');
final filter2 = Filter.in_('testKey', const ['testValue']);
@@ -180,6 +188,30 @@ void main() {
'{"$key":{"${FilterOperator.in_.rawValue}":${json.encode(values)}}}',
);
});
test('custom with no operator', () {
const key = 'testKey';
const values = ['testValue'];
final filter = Filter.custom(key: key, value: values);
final encoded = json.encode(filter);
expect(
encoded,
'{"$key":${json.encode(values)}}',
);
});
test('raw', () {
const value = {
'test': ['a', 'b'],
};
const filter = Filter.raw(value: value);
final encoded = json.encode(filter);
expect(
encoded,
json.encode(value),
);
});
});
test('groupedFilter', () {
@@ -12,12 +12,16 @@ class ImageGroup extends StatelessWidget {
required this.message,
required this.messageTheme,
required this.size,
this.onReturnAction,
this.onShowMessage,
}) : super(key: key);
/// List of attachments to show
final List<Attachment> images;
/// Callback when attachment is returned to from other screens
final ValueChanged<ReturnActionType>? onReturnAction;
/// Message which images are attached to
final Message message;
@@ -111,10 +115,10 @@ class ImageGroup extends StatelessWidget {
void _onTap(
BuildContext context,
int index,
) {
) async {
final channel = StreamChannel.of(context).channel;
Navigator.push(
final res = await Navigator.push(
context,
MaterialPageRoute(
builder: (context) => StreamChannel(
@@ -129,6 +133,7 @@ class ImageGroup extends StatelessWidget {
),
),
);
if (res != null) onReturnAction?.call(res);
}
Widget _buildImage(BuildContext context, int index) => ImageAttachment(
@@ -463,58 +463,57 @@ class MessageInputState extends State<MessageInput> {
);
}
Widget _buildExpandActionsButton() => Padding(
padding: const EdgeInsets.symmetric(horizontal: 8),
child: AnimatedCrossFade(
crossFadeState: _actionsShrunk
? CrossFadeState.showFirst
: CrossFadeState.showSecond,
firstChild: IconButton(
onPressed: () => setState(() => _actionsShrunk = false),
icon: Transform.rotate(
angle: (widget.actionsLocation == ActionsLocation.right ||
widget.actionsLocation == ActionsLocation.rightInside)
? pi
: 0,
child: StreamSvgIcon.emptyCircleLeft(
color: StreamChatTheme.of(context)
.messageInputTheme
.expandButtonColor,
),
Widget _buildExpandActionsButton() {
final channel = StreamChannel.of(context).channel;
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 8),
child: AnimatedCrossFade(
crossFadeState: _actionsShrunk
? CrossFadeState.showFirst
: CrossFadeState.showSecond,
firstChild: IconButton(
onPressed: () => setState(() => _actionsShrunk = false),
icon: Transform.rotate(
angle: (widget.actionsLocation == ActionsLocation.right ||
widget.actionsLocation == ActionsLocation.rightInside)
? pi
: 0,
child: StreamSvgIcon.emptyCircleLeft(
color: StreamChatTheme.of(context)
.messageInputTheme
.expandButtonColor,
),
padding: const EdgeInsets.all(0),
constraints: const BoxConstraints.tightFor(
height: 24,
width: 24,
),
splashRadius: 24,
),
secondChild: widget.disableAttachments &&
!widget.showCommandsButton &&
widget.actions?.isNotEmpty != true
? const Offstage()
: FittedBox(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
if (!widget.disableAttachments) _buildAttachmentButton(),
if (widget.showCommandsButton &&
widget.editMessage == null &&
StreamChannel.of(context)
.channel
.config
?.commands
.isNotEmpty ==
true)
_buildCommandButton(),
...widget.actions ?? [],
].insertBetween(const SizedBox(width: 8)),
),
),
duration: const Duration(milliseconds: 300),
alignment: Alignment.center,
padding: const EdgeInsets.all(0),
constraints: const BoxConstraints.tightFor(
height: 24,
width: 24,
),
splashRadius: 24,
),
);
secondChild: widget.disableAttachments &&
!widget.showCommandsButton &&
widget.actions?.isNotEmpty != true
? const Offstage()
: FittedBox(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
if (!widget.disableAttachments) _buildAttachmentButton(),
if (widget.showCommandsButton &&
widget.editMessage == null &&
channel.state != null &&
channel.config?.commands.isNotEmpty == true)
_buildCommandButton(),
...widget.actions ?? [],
].insertBetween(const SizedBox(width: 8)),
),
),
duration: const Duration(milliseconds: 300),
alignment: Alignment.center,
),
);
}
Expanded _buildTextInput(BuildContext context) {
final theme = StreamChatTheme.of(context);
@@ -270,7 +270,7 @@ class MessageListView extends StatefulWidget {
class _MessageListViewState extends State<MessageListView> {
ItemScrollController? _scrollController;
Function? _onThreadTap;
void Function(Message)? _onThreadTap;
bool _showScrollToBottom = false;
late final ItemPositionsListener _itemPositionListener;
int? _messageListLength;
@@ -814,7 +814,7 @@ class _MessageListViewState extends State<MessageListView> {
showUsername: !isMyMessage,
padding: const EdgeInsets.all(8),
showSendingIndicator: false,
onThreadTap: _onThreadTap as void Function(Message)?,
onThreadTap: _onThreadTap,
borderRadiusGeometry: const BorderRadius.only(
topLeft: Radius.circular(16),
bottomLeft: Radius.circular(2),
@@ -976,7 +976,7 @@ class _MessageListViewState extends State<MessageListView> {
showThreadReplyMessage: !isThreadMessage,
showFlagButton: !isMyMessage,
borderSide: borderSide,
onThreadTap: _onThreadTap as void Function(Message)?,
onThreadTap: _onThreadTap,
onReplyTap: widget.onReplyTap,
attachmentBorderRadiusGeometry: BorderRadius.only(
topLeft: Radius.circular(attachmentBorderRadius),
@@ -125,6 +125,7 @@ class MessageWidget extends StatefulWidget {
message: message,
messageTheme: messageTheme,
onShowMessage: onShowMessage,
onReturnAction: onReturnAction,
),
),
border,
@@ -159,11 +159,11 @@ class StreamChannelState extends State<StreamChannel> {
bool preferOffline = false,
}) async {
if (_topPaginationEnded ||
_queryTopMessagesController.value! ||
_queryTopMessagesController.value == true ||
channel.state == null) return;
_queryTopMessagesController.add(true);
late Message message;
Message? message;
if (channel.state!.threads.containsKey(parentId)) {
final thread = channel.state!.threads[parentId]!;
if (thread.isNotEmpty) {
@@ -175,7 +175,7 @@ class StreamChannelState extends State<StreamChannel> {
final response = await channel.getReplies(
parentId,
PaginationParams(
lessThan: message.id,
lessThan: message?.id,
limit: limit,
),
preferOffline: preferOffline,
@@ -57,7 +57,7 @@ class MoorChatDatabase extends _$MoorChatDatabase {
// you should bump this number whenever you change or add a table definition.
@override
int get schemaVersion => 2;
int get schemaVersion => 3;
@override
MigrationStrategy get migration => MigrationStrategy(
@@ -42,22 +42,20 @@ class ChannelEntity extends DataClass implements Insertable<ChannelEntity> {
final String? createdById;
/// Map of custom channel extraData
final Map<String, Object>? extraData;
ChannelEntity({
required this.id,
required this.type,
required this.cid,
required this.config,
required this.frozen,
this.lastMessageAt,
required this.createdAt,
required this.updatedAt,
this.deletedAt,
required this.memberCount,
this.createdById,
this.extraData,
});
final Map<String, Object?>? extraData;
ChannelEntity(
{required this.id,
required this.type,
required this.cid,
required this.config,
required this.frozen,
this.lastMessageAt,
required this.createdAt,
required this.updatedAt,
this.deletedAt,
required this.memberCount,
this.createdById,
this.extraData});
factory ChannelEntity.fromData(
Map<String, dynamic> data, GeneratedDatabase db,
{String? prefix}) {
@@ -135,7 +133,7 @@ class ChannelEntity extends DataClass implements Insertable<ChannelEntity> {
deletedAt: serializer.fromJson<DateTime?>(json['deletedAt']),
memberCount: serializer.fromJson<int>(json['memberCount']),
createdById: serializer.fromJson<String?>(json['createdById']),
extraData: serializer.fromJson<Map<String, Object>?>(json['extraData']),
extraData: serializer.fromJson<Map<String, Object?>?>(json['extraData']),
);
}
@override
@@ -153,7 +151,7 @@ class ChannelEntity extends DataClass implements Insertable<ChannelEntity> {
'deletedAt': serializer.toJson<DateTime?>(deletedAt),
'memberCount': serializer.toJson<int>(memberCount),
'createdById': serializer.toJson<String?>(createdById),
'extraData': serializer.toJson<Map<String, Object>?>(extraData),
'extraData': serializer.toJson<Map<String, Object?>?>(extraData),
};
}
@@ -169,7 +167,7 @@ class ChannelEntity extends DataClass implements Insertable<ChannelEntity> {
Value<DateTime?> deletedAt = const Value.absent(),
int? memberCount,
Value<String?> createdById = const Value.absent(),
Value<Map<String, Object>?> extraData = const Value.absent()}) =>
Value<Map<String, Object?>?> extraData = const Value.absent()}) =>
ChannelEntity(
id: id ?? this.id,
type: type ?? this.type,
@@ -257,7 +255,7 @@ class ChannelsCompanion extends UpdateCompanion<ChannelEntity> {
final Value<DateTime?> deletedAt;
final Value<int> memberCount;
final Value<String?> createdById;
final Value<Map<String, Object>?> extraData;
final Value<Map<String, Object?>?> extraData;
const ChannelsCompanion({
this.id = const Value.absent(),
this.type = const Value.absent(),
@@ -301,7 +299,7 @@ class ChannelsCompanion extends UpdateCompanion<ChannelEntity> {
Expression<DateTime?>? deletedAt,
Expression<int>? memberCount,
Expression<String?>? createdById,
Expression<Map<String, Object>?>? extraData,
Expression<Map<String, Object?>?>? extraData,
}) {
return RawValuesInsertable({
if (id != null) 'id': id,
@@ -331,7 +329,7 @@ class ChannelsCompanion extends UpdateCompanion<ChannelEntity> {
Value<DateTime?>? deletedAt,
Value<int>? memberCount,
Value<String?>? createdById,
Value<Map<String, Object>?>? extraData}) {
Value<Map<String, Object?>?>? extraData}) {
return ChannelsCompanion(
id: id ?? this.id,
type: type ?? this.type,
@@ -638,8 +636,8 @@ class $ChannelsTable extends Channels
static TypeConverter<Map<String, dynamic>, String> $converter0 =
MapConverter();
static TypeConverter<Map<String, Object>, String> $converter1 =
MapConverter<Object>();
static TypeConverter<Map<String, Object?>, String> $converter1 =
MapConverter<Object?>();
}
class MessageEntity extends DataClass implements Insertable<MessageEntity> {
@@ -714,7 +712,7 @@ class MessageEntity extends DataClass implements Insertable<MessageEntity> {
final String? channelCid;
/// Message custom extraData
final Map<String, Object>? extraData;
final Map<String, Object?>? extraData;
MessageEntity(
{required this.id,
this.messageText,
@@ -901,7 +899,7 @@ class MessageEntity extends DataClass implements Insertable<MessageEntity> {
pinExpires: serializer.fromJson<DateTime?>(json['pinExpires']),
pinnedByUserId: serializer.fromJson<String?>(json['pinnedByUserId']),
channelCid: serializer.fromJson<String?>(json['channelCid']),
extraData: serializer.fromJson<Map<String, Object>?>(json['extraData']),
extraData: serializer.fromJson<Map<String, Object?>?>(json['extraData']),
);
}
@override
@@ -931,7 +929,7 @@ class MessageEntity extends DataClass implements Insertable<MessageEntity> {
'pinExpires': serializer.toJson<DateTime?>(pinExpires),
'pinnedByUserId': serializer.toJson<String?>(pinnedByUserId),
'channelCid': serializer.toJson<String?>(channelCid),
'extraData': serializer.toJson<Map<String, Object>?>(extraData),
'extraData': serializer.toJson<Map<String, Object?>?>(extraData),
};
}
@@ -959,7 +957,7 @@ class MessageEntity extends DataClass implements Insertable<MessageEntity> {
Value<DateTime?> pinExpires = const Value.absent(),
Value<String?> pinnedByUserId = const Value.absent(),
Value<String?> channelCid = const Value.absent(),
Value<Map<String, Object>?> extraData = const Value.absent()}) =>
Value<Map<String, Object?>?> extraData = const Value.absent()}) =>
MessageEntity(
id: id ?? this.id,
messageText: messageText.present ? messageText.value : this.messageText,
@@ -1121,7 +1119,7 @@ class MessagesCompanion extends UpdateCompanion<MessageEntity> {
final Value<DateTime?> pinExpires;
final Value<String?> pinnedByUserId;
final Value<String?> channelCid;
final Value<Map<String, Object>?> extraData;
final Value<Map<String, Object?>?> extraData;
const MessagesCompanion({
this.id = const Value.absent(),
this.messageText = const Value.absent(),
@@ -1200,7 +1198,7 @@ class MessagesCompanion extends UpdateCompanion<MessageEntity> {
Expression<DateTime?>? pinExpires,
Expression<String?>? pinnedByUserId,
Expression<String?>? channelCid,
Expression<Map<String, Object>?>? extraData,
Expression<Map<String, Object?>?>? extraData,
}) {
return RawValuesInsertable({
if (id != null) 'id': id,
@@ -1254,7 +1252,7 @@ class MessagesCompanion extends UpdateCompanion<MessageEntity> {
Value<DateTime?>? pinExpires,
Value<String?>? pinnedByUserId,
Value<String?>? channelCid,
Value<Map<String, Object>?>? extraData}) {
Value<Map<String, Object?>?>? extraData}) {
return MessagesCompanion(
id: id ?? this.id,
messageText: messageText ?? this.messageText,
@@ -1818,8 +1816,8 @@ class $MessagesTable extends Messages
MapConverter<int>();
static TypeConverter<Map<String, int>, String> $converter4 =
MapConverter<int>();
static TypeConverter<Map<String, Object>, String> $converter5 =
MapConverter<Object>();
static TypeConverter<Map<String, Object?>, String> $converter5 =
MapConverter<Object?>();
}
class PinnedMessageEntity extends DataClass
@@ -1895,7 +1893,7 @@ class PinnedMessageEntity extends DataClass
final String? channelCid;
/// Message custom extraData
final Map<String, Object>? extraData;
final Map<String, Object?>? extraData;
PinnedMessageEntity(
{required this.id,
this.messageText,
@@ -2082,7 +2080,7 @@ class PinnedMessageEntity extends DataClass
pinExpires: serializer.fromJson<DateTime?>(json['pinExpires']),
pinnedByUserId: serializer.fromJson<String?>(json['pinnedByUserId']),
channelCid: serializer.fromJson<String?>(json['channelCid']),
extraData: serializer.fromJson<Map<String, Object>?>(json['extraData']),
extraData: serializer.fromJson<Map<String, Object?>?>(json['extraData']),
);
}
@override
@@ -2112,7 +2110,7 @@ class PinnedMessageEntity extends DataClass
'pinExpires': serializer.toJson<DateTime?>(pinExpires),
'pinnedByUserId': serializer.toJson<String?>(pinnedByUserId),
'channelCid': serializer.toJson<String?>(channelCid),
'extraData': serializer.toJson<Map<String, Object>?>(extraData),
'extraData': serializer.toJson<Map<String, Object?>?>(extraData),
};
}
@@ -2140,7 +2138,7 @@ class PinnedMessageEntity extends DataClass
Value<DateTime?> pinExpires = const Value.absent(),
Value<String?> pinnedByUserId = const Value.absent(),
Value<String?> channelCid = const Value.absent(),
Value<Map<String, Object>?> extraData = const Value.absent()}) =>
Value<Map<String, Object?>?> extraData = const Value.absent()}) =>
PinnedMessageEntity(
id: id ?? this.id,
messageText: messageText.present ? messageText.value : this.messageText,
@@ -2302,7 +2300,7 @@ class PinnedMessagesCompanion extends UpdateCompanion<PinnedMessageEntity> {
final Value<DateTime?> pinExpires;
final Value<String?> pinnedByUserId;
final Value<String?> channelCid;
final Value<Map<String, Object>?> extraData;
final Value<Map<String, Object?>?> extraData;
const PinnedMessagesCompanion({
this.id = const Value.absent(),
this.messageText = const Value.absent(),
@@ -2381,7 +2379,7 @@ class PinnedMessagesCompanion extends UpdateCompanion<PinnedMessageEntity> {
Expression<DateTime?>? pinExpires,
Expression<String?>? pinnedByUserId,
Expression<String?>? channelCid,
Expression<Map<String, Object>?>? extraData,
Expression<Map<String, Object?>?>? extraData,
}) {
return RawValuesInsertable({
if (id != null) 'id': id,
@@ -2435,7 +2433,7 @@ class PinnedMessagesCompanion extends UpdateCompanion<PinnedMessageEntity> {
Value<DateTime?>? pinExpires,
Value<String?>? pinnedByUserId,
Value<String?>? channelCid,
Value<Map<String, Object>?>? extraData}) {
Value<Map<String, Object?>?>? extraData}) {
return PinnedMessagesCompanion(
id: id ?? this.id,
messageText: messageText ?? this.messageText,
@@ -3000,8 +2998,8 @@ class $PinnedMessagesTable extends PinnedMessages
MapConverter<int>();
static TypeConverter<Map<String, int>, String> $converter4 =
MapConverter<int>();
static TypeConverter<Map<String, Object>, String> $converter5 =
MapConverter<Object>();
static TypeConverter<Map<String, Object?>, String> $converter5 =
MapConverter<Object?>();
}
class ReactionEntity extends DataClass implements Insertable<ReactionEntity> {
@@ -3021,7 +3019,7 @@ class ReactionEntity extends DataClass implements Insertable<ReactionEntity> {
final int score;
/// Reaction custom extraData
final Map<String, Object>? extraData;
final Map<String, Object?>? extraData;
ReactionEntity(
{required this.userId,
required this.messageId,
@@ -3073,7 +3071,7 @@ class ReactionEntity extends DataClass implements Insertable<ReactionEntity> {
type: serializer.fromJson<String>(json['type']),
createdAt: serializer.fromJson<DateTime>(json['createdAt']),
score: serializer.fromJson<int>(json['score']),
extraData: serializer.fromJson<Map<String, Object>?>(json['extraData']),
extraData: serializer.fromJson<Map<String, Object?>?>(json['extraData']),
);
}
@override
@@ -3085,7 +3083,7 @@ class ReactionEntity extends DataClass implements Insertable<ReactionEntity> {
'type': serializer.toJson<String>(type),
'createdAt': serializer.toJson<DateTime>(createdAt),
'score': serializer.toJson<int>(score),
'extraData': serializer.toJson<Map<String, Object>?>(extraData),
'extraData': serializer.toJson<Map<String, Object?>?>(extraData),
};
}
@@ -3095,7 +3093,7 @@ class ReactionEntity extends DataClass implements Insertable<ReactionEntity> {
String? type,
DateTime? createdAt,
int? score,
Value<Map<String, Object>?> extraData = const Value.absent()}) =>
Value<Map<String, Object?>?> extraData = const Value.absent()}) =>
ReactionEntity(
userId: userId ?? this.userId,
messageId: messageId ?? this.messageId,
@@ -3144,7 +3142,7 @@ class ReactionsCompanion extends UpdateCompanion<ReactionEntity> {
final Value<String> type;
final Value<DateTime> createdAt;
final Value<int> score;
final Value<Map<String, Object>?> extraData;
final Value<Map<String, Object?>?> extraData;
const ReactionsCompanion({
this.userId = const Value.absent(),
this.messageId = const Value.absent(),
@@ -3169,7 +3167,7 @@ class ReactionsCompanion extends UpdateCompanion<ReactionEntity> {
Expression<String>? type,
Expression<DateTime>? createdAt,
Expression<int>? score,
Expression<Map<String, Object>?>? extraData,
Expression<Map<String, Object?>?>? extraData,
}) {
return RawValuesInsertable({
if (userId != null) 'user_id': userId,
@@ -3187,7 +3185,7 @@ class ReactionsCompanion extends UpdateCompanion<ReactionEntity> {
Value<String>? type,
Value<DateTime>? createdAt,
Value<int>? score,
Value<Map<String, Object>?>? extraData}) {
Value<Map<String, Object?>?>? extraData}) {
return ReactionsCompanion(
userId: userId ?? this.userId,
messageId: messageId ?? this.messageId,
@@ -3357,8 +3355,8 @@ class $ReactionsTable extends Reactions
return $ReactionsTable(_db, alias);
}
static TypeConverter<Map<String, Object>, String> $converter0 =
MapConverter<Object>();
static TypeConverter<Map<String, Object?>, String> $converter0 =
MapConverter<Object?>();
}
class UserEntity extends DataClass implements Insertable<UserEntity> {
@@ -3384,7 +3382,7 @@ class UserEntity extends DataClass implements Insertable<UserEntity> {
final bool banned;
/// Map of custom user extraData
final Map<String, Object> extraData;
final Map<String, Object?> extraData;
UserEntity(
{required this.id,
this.role,
@@ -3449,7 +3447,7 @@ class UserEntity extends DataClass implements Insertable<UserEntity> {
lastActive: serializer.fromJson<DateTime?>(json['lastActive']),
online: serializer.fromJson<bool>(json['online']),
banned: serializer.fromJson<bool>(json['banned']),
extraData: serializer.fromJson<Map<String, Object>>(json['extraData']),
extraData: serializer.fromJson<Map<String, Object?>>(json['extraData']),
);
}
@override
@@ -3463,7 +3461,7 @@ class UserEntity extends DataClass implements Insertable<UserEntity> {
'lastActive': serializer.toJson<DateTime?>(lastActive),
'online': serializer.toJson<bool>(online),
'banned': serializer.toJson<bool>(banned),
'extraData': serializer.toJson<Map<String, Object>>(extraData),
'extraData': serializer.toJson<Map<String, Object?>>(extraData),
};
}
@@ -3475,7 +3473,7 @@ class UserEntity extends DataClass implements Insertable<UserEntity> {
Value<DateTime?> lastActive = const Value.absent(),
bool? online,
bool? banned,
Map<String, Object>? extraData}) =>
Map<String, Object?>? extraData}) =>
UserEntity(
id: id ?? this.id,
role: role.present ? role.value : this.role,
@@ -3536,7 +3534,7 @@ class UsersCompanion extends UpdateCompanion<UserEntity> {
final Value<DateTime?> lastActive;
final Value<bool> online;
final Value<bool> banned;
final Value<Map<String, Object>> extraData;
final Value<Map<String, Object?>> extraData;
const UsersCompanion({
this.id = const Value.absent(),
this.role = const Value.absent(),
@@ -3555,7 +3553,7 @@ class UsersCompanion extends UpdateCompanion<UserEntity> {
this.lastActive = const Value.absent(),
this.online = const Value.absent(),
this.banned = const Value.absent(),
required Map<String, Object> extraData,
required Map<String, Object?> extraData,
}) : id = Value(id),
extraData = Value(extraData);
static Insertable<UserEntity> custom({
@@ -3566,7 +3564,7 @@ class UsersCompanion extends UpdateCompanion<UserEntity> {
Expression<DateTime?>? lastActive,
Expression<bool>? online,
Expression<bool>? banned,
Expression<Map<String, Object>>? extraData,
Expression<Map<String, Object?>>? extraData,
}) {
return RawValuesInsertable({
if (id != null) 'id': id,
@@ -3588,7 +3586,7 @@ class UsersCompanion extends UpdateCompanion<UserEntity> {
Value<DateTime?>? lastActive,
Value<bool>? online,
Value<bool>? banned,
Value<Map<String, Object>>? extraData}) {
Value<Map<String, Object?>>? extraData}) {
return UsersCompanion(
id: id ?? this.id,
role: role ?? this.role,
@@ -3791,8 +3789,8 @@ class $UsersTable extends Users with TableInfo<$UsersTable, UserEntity> {
return $UsersTable(_db, alias);
}
static TypeConverter<Map<String, Object>, String> $converter0 =
MapConverter<Object>();
static TypeConverter<Map<String, Object?>, String> $converter0 =
MapConverter<Object?>();
}
class MemberEntity extends DataClass implements Insertable<MemberEntity> {
@@ -39,7 +39,7 @@ class Channels extends Table {
TextColumn get createdById => text().nullable()();
/// Map of custom channel extraData
TextColumn get extraData => text().nullable().map(MapConverter<Object>())();
TextColumn get extraData => text().nullable().map(MapConverter<Object?>())();
@override
Set<Column> get primaryKey => {cid};
@@ -81,7 +81,7 @@ class Messages extends Table {
'NULLABLE REFERENCES channels(cid) ON DELETE CASCADE')();
/// Message custom extraData
TextColumn get extraData => text().nullable().map(MapConverter<Object>())();
TextColumn get extraData => text().nullable().map(MapConverter<Object?>())();
@override
Set<Column> get primaryKey => {id};
@@ -22,7 +22,7 @@ class Reactions extends Table {
IntColumn get score => integer().withDefault(const Constant(0))();
/// Reaction custom extraData
TextColumn get extraData => text().nullable().map(MapConverter<Object>())();
TextColumn get extraData => text().nullable().map(MapConverter<Object?>())();
@override
Set<Column> get primaryKey => {
@@ -27,7 +27,7 @@ class Users extends Table {
BoolColumn get banned => boolean().withDefault(const Constant(false))();
/// Map of custom user extraData
TextColumn get extraData => text().map(MapConverter<Object>())();
TextColumn get extraData => text().map(MapConverter<Object?>())();
@override
Set<Column> get primaryKey => {id};
@@ -42,6 +42,8 @@ extension MessageEntityX on MessageEntity {
pinnedAt: pinnedAt,
pinExpires: pinExpires,
pinnedBy: pinnedBy,
mentionedUsers:
mentionedUsers.map((e) => User.fromJson(jsonDecode(e))).toList(),
);
}
@@ -5,7 +5,7 @@ import 'package:stream_chat_persistence/src/db/moor_chat_database.dart';
extension ReactionEntityX on ReactionEntity {
/// Maps a [ReactionEntity] into [Reaction]
Reaction toReaction({User? user}) => Reaction(
extraData: extraData,
extraData: extraData ?? {},
type: type,
createdAt: createdAt,
userId: userId,
@@ -48,7 +48,9 @@ void main() {
(prev, curr) =>
prev?..update(curr.type, (value) => value + 1, ifAbsent: () => 1),
),
mentionedUsers: const [],
mentionedUsers: [
jsonEncode(User(id: 'testuser')),
],
status: MessageSendingStatus.sent,
updatedAt: DateTime.now(),
extraData: {'extra_test_data': 'extraData'},
@@ -77,6 +79,11 @@ void main() {
expect(message.createdAt, isSameDateAs(entity.createdAt));
expect(message.shadowed, entity.shadowed);
expect(message.showInChannel, entity.showInChannel);
for (var i = 0; i < message.mentionedUsers.length; i++) {
final entityMentionedUser =
User.fromJson(jsonDecode(entity.mentionedUsers[i]));
expect(message.mentionedUsers[i].id, entityMentionedUser.id);
}
expect(message.replyCount, entity.replyCount);
expect(message.reactionScores, entity.reactionScores);
expect(message.reactionCounts, entity.reactionCounts);
@@ -135,6 +142,9 @@ void main() {
shadowed: math.Random().nextBool(),
showInChannel: math.Random().nextBool(),
replyCount: 33,
mentionedUsers: [
User(id: 'testuser'),
],
reactionScores: {for (final r in reactions) r.type: r.score},
reactionCounts: reactions.fold(
{},
@@ -163,6 +173,8 @@ void main() {
expect(entity.shadowed, message.shadowed);
expect(entity.showInChannel, message.showInChannel);
expect(entity.replyCount, message.replyCount);
expect(entity.mentionedUsers,
message.mentionedUsers.map((e) => jsonEncode(e)).toList());
expect(entity.reactionScores, message.reactionScores);
expect(entity.reactionCounts, message.reactionCounts);
expect(entity.status, message.status);