Release/1.4.0 beta (#318)
* fix: fixed long system messages overflowing * fix: fixed long system messages overflowing * [UI-Kit] Refactor, add support for downloading attachments. Signed-off-by: Sahil Kumar <[email protected]> * fix: header casing * [UI-Kit] Disable attachment download dialog pop using back button Signed-off-by: Sahil Kumar <[email protected]> * stream_chat_flutter fix svg on web * [UI-Kit] Pop attachment download dialog in case of any error. Signed-off-by: Sahil Kumar <[email protected]> * restore svg * feat: add pr title linter * fix test * fix client headers * update system message design * update gh token env var * add scopes * expose systemMessageBuilder in messagelistview * fix(ui): fix button size * add dispatch workflow * add dispatch workflow * update dispatch acton * add runson * fix ref * fix ref * update secret * specify repo * fix: list scroll keyboard behaviour (#304) * fix: Keyboard now closes by clicking on space or scrolling. * fix: Exposed system and normal message tap builders * fmt: dartfmt * feat: Add support for messages filter in `MessageListView` and `MessageListCore` (#303) * [MessageListView, MessageListCore] Add support for message filter Signed-off-by: Sahil Kumar <[email protected]> * [UI-Kit -> Pubspec] Remove `stream_chat_flutter_core` relative import Signed-off-by: Sahil Kumar <[email protected]> * add relative import * add relative import * remove svg for web * remove badge logic on web * style: Update for team lint (#297) * Update for team lint * fix tests * remove pedantic and sort deps * remove jiffy from system message Co-authored-by: Salvatore Giordano <[email protected]> * add section highlighting sample app repo (#307) Co-authored-by: Salvatore Giordano <[email protected]> * add null check to debounce * fix messagelistview loading errors * remove core relative import * fix: fixes message newline issue (#308) * fix: minor * fix: generate image thumbnails and use transparent image as placeholder for cached network images (#310) * update cdn handling * fix image attachment with new cdn * fix(ui): Fix message input permission request crash (#311) Signed-off-by: Sahil Kumar <[email protected]> * fix(llc): update member presence and add skip_push to message (#314) * update member presence * add skip_push to message * fix tests * fix: Fixed shimmer overflow (#316) * fix dialogs * fix(llc): Fix attachment upload state uneven progress. (#315) * feat(llc): Add rate limiter functions. fix(llc): Fix attachment upload state uneven progress. Signed-off-by: Sahil Kumar <[email protected]> * feat(llc): Export `async.dart` and `rate_limit.dart` Signed-off-by: Sahil Kumar <[email protected]> * refactor(llc): Replace our `rate_limit` implementation with the dart port of js `lodash` to better handlw `cancel` and `flush` functions. Signed-off-by: Sahil Kumar <[email protected]> * fix(UI-Kit): Make android example run on real devices Signed-off-by: Sahil Kumar <[email protected]> * fix offline behaviour Co-authored-by: Salvatore Giordano <[email protected]> * feat: Introduce onAttachmentTap on messages attachment (#309) * introdce onAttachmentTap on message * correct indent * sdfsd Co-authored-by: Salvatore Giordano <[email protected]> * feat: added customization options in main widgets (#312) * polish channelpreview customization options * polish channelheader customization options * polish messageinput customization options * polish threadheader customization options * polish channellistheader customization options * show the parent message if no messages in thread * fix edit message * fix channelinfo textstyle * fix review * fix useravatar * add ontitle tap to thread header * add custom message actions * add borderradius and button builder * add ontap to messageinput custom send button * fix bottom sheet * add doc * use placeholder image * add doc * fix listtile density * remove subtitle from ChannelListHeaderTheme.copyWith * add InputDecoration.merge extension * fix: use shimmer in images * fix: remove notification badge logic from the sdk and move it to sample app * fix import * fix: Method being called during build (#317) * method call bug fix * dartfmt * fix: show error messages as system and keep them in the message input (#319) * fix: pre release (#324) * use share_plus plugin * bump dependency versions * fix ui for web * unfocus messageinput only on commands * fix default error for messagesearchlistview * fix thumbnail animation * fix lint * ignore example in linter * update changelogs * fix lint * fix lint * update stream_chat pana min * add doc Co-authored-by: Sahil Kumar <[email protected]> Co-authored-by: Deven Joshi <[email protected]> Co-authored-by: Neevash Ramdial (Nash) <[email protected]> Co-authored-by: Nelson Nunes <[email protected]>
This commit is contained in:
co-authored by
Sahil Kumar
Deven Joshi
Neevash Ramdial
Nelson Nunes
parent
3332a48a0e
commit
4488fa6c3a
@@ -5,6 +5,12 @@ part 'action.g.dart';
|
||||
/// The class that contains the information about an action
|
||||
@JsonSerializable()
|
||||
class Action {
|
||||
/// Constructor used for json serialization
|
||||
Action({this.name, this.style, this.text, this.type, this.value});
|
||||
|
||||
/// Create a new instance from a json
|
||||
factory Action.fromJson(Map<String, dynamic> json) => _$ActionFromJson(json);
|
||||
|
||||
/// The name of the action
|
||||
final String name;
|
||||
|
||||
@@ -20,12 +26,6 @@ class Action {
|
||||
/// The value of the action
|
||||
final String value;
|
||||
|
||||
/// Constructor used for json serialization
|
||||
Action({this.name, this.style, this.text, this.type, this.value});
|
||||
|
||||
/// Create a new instance from a json
|
||||
factory Action.fromJson(Map<String, dynamic> json) => _$ActionFromJson(json);
|
||||
|
||||
/// Serialize to json
|
||||
Map<String, dynamic> toJson() => _$ActionToJson(this);
|
||||
}
|
||||
|
||||
@@ -1,18 +1,61 @@
|
||||
// ignore_for_file: public_member_api_docs
|
||||
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
import 'package:stream_chat/src/models/action.dart';
|
||||
import 'package:stream_chat/src/models/attachment_file.dart';
|
||||
import 'package:stream_chat/src/models/serialization.dart';
|
||||
import 'package:uuid/uuid.dart';
|
||||
|
||||
import 'action.dart';
|
||||
import 'serialization.dart';
|
||||
|
||||
part 'attachment.g.dart';
|
||||
|
||||
/// The class that contains the information about an attachment
|
||||
@JsonSerializable(includeIfNull: false)
|
||||
class Attachment {
|
||||
///The attachment type based on the URL resource. This can be: audio, image or video
|
||||
/// Constructor used for json serialization
|
||||
Attachment({
|
||||
String id,
|
||||
this.type,
|
||||
this.titleLink,
|
||||
String title,
|
||||
this.thumbUrl,
|
||||
this.text,
|
||||
this.pretext,
|
||||
this.ogScrapeUrl,
|
||||
this.imageUrl,
|
||||
this.footerIcon,
|
||||
this.footer,
|
||||
this.fields,
|
||||
this.fallback,
|
||||
this.color,
|
||||
this.authorName,
|
||||
this.authorLink,
|
||||
this.authorIcon,
|
||||
this.assetUrl,
|
||||
this.actions,
|
||||
this.extraData,
|
||||
this.file,
|
||||
UploadState uploadState,
|
||||
}) : id = id ?? Uuid().v4(),
|
||||
title = title ?? file?.name,
|
||||
localUri = file?.path != null ? Uri.parse(file.path) : null {
|
||||
this.uploadState = uploadState ??
|
||||
((assetUrl != null || imageUrl != null)
|
||||
? const UploadState.success()
|
||||
: const UploadState.preparing());
|
||||
}
|
||||
|
||||
/// Create a new instance from a json
|
||||
factory Attachment.fromJson(Map<String, dynamic> json) =>
|
||||
_$AttachmentFromJson(
|
||||
Serialization.moveToExtraDataFromRoot(json, topLevelFields));
|
||||
|
||||
/// Create a new instance from a db data
|
||||
factory Attachment.fromData(Map<String, dynamic> json) =>
|
||||
_$AttachmentFromJson(Serialization.moveToExtraDataFromRoot(
|
||||
json, topLevelFields + dbSpecificTopLevelFields));
|
||||
|
||||
///The attachment type based on the URL resource. This can be: audio,
|
||||
///image or video
|
||||
final String type;
|
||||
|
||||
///The link to which the attachment message points to.
|
||||
@@ -21,10 +64,12 @@ class Attachment {
|
||||
/// The attachment title
|
||||
final String title;
|
||||
|
||||
/// The URL to the attached file thumbnail. You can use this to represent the attached link.
|
||||
/// The URL to the attached file thumbnail. You can use this to represent the
|
||||
/// attached link.
|
||||
final String thumbUrl;
|
||||
|
||||
/// The attachment text. It will be displayed in the channel next to the original message.
|
||||
/// The attachment text. It will be displayed in the channel next to the
|
||||
/// original message.
|
||||
final String text;
|
||||
|
||||
/// Optional text that appears above the attachment block
|
||||
@@ -33,7 +78,8 @@ class Attachment {
|
||||
/// The original URL that was used to scrape this attachment.
|
||||
final String ogScrapeUrl;
|
||||
|
||||
/// The URL to the attached image. This is present for URL pointing to an image article (eg. Unsplash)
|
||||
/// The URL to the attached image. This is present for URL pointing to an
|
||||
/// image article (eg. Unsplash)
|
||||
final String imageUrl;
|
||||
final String footerIcon;
|
||||
final String footer;
|
||||
@@ -100,56 +146,11 @@ class Attachment {
|
||||
'file',
|
||||
];
|
||||
|
||||
/// Constructor used for json serialization
|
||||
Attachment({
|
||||
String id,
|
||||
this.type,
|
||||
this.titleLink,
|
||||
String title,
|
||||
this.thumbUrl,
|
||||
this.text,
|
||||
this.pretext,
|
||||
this.ogScrapeUrl,
|
||||
this.imageUrl,
|
||||
this.footerIcon,
|
||||
this.footer,
|
||||
this.fields,
|
||||
this.fallback,
|
||||
this.color,
|
||||
this.authorName,
|
||||
this.authorLink,
|
||||
this.authorIcon,
|
||||
this.assetUrl,
|
||||
this.actions,
|
||||
this.extraData,
|
||||
this.file,
|
||||
UploadState uploadState,
|
||||
}) : id = id ?? Uuid().v4(),
|
||||
title = title ?? file?.name,
|
||||
localUri = file?.path != null ? Uri.parse(file.path) : null {
|
||||
this.uploadState = uploadState ??
|
||||
((assetUrl != null || imageUrl != null)
|
||||
? UploadState.success()
|
||||
: UploadState.preparing());
|
||||
}
|
||||
|
||||
/// Create a new instance from a json
|
||||
factory Attachment.fromJson(Map<String, dynamic> json) {
|
||||
return _$AttachmentFromJson(
|
||||
Serialization.moveToExtraDataFromRoot(json, topLevelFields));
|
||||
}
|
||||
|
||||
/// Serialize to json
|
||||
Map<String, dynamic> toJson() => Serialization.moveFromExtraDataToRoot(
|
||||
_$AttachmentToJson(this), topLevelFields)
|
||||
..removeWhere((key, value) => dbSpecificTopLevelFields.contains(key));
|
||||
|
||||
/// Create a new instance from a db data
|
||||
factory Attachment.fromData(Map<String, dynamic> json) {
|
||||
return _$AttachmentFromJson(Serialization.moveToExtraDataFromRoot(
|
||||
json, topLevelFields + dbSpecificTopLevelFields));
|
||||
}
|
||||
|
||||
/// Serialize to db data
|
||||
Map<String, dynamic> toData() => Serialization.moveFromExtraDataToRoot(
|
||||
_$AttachmentToJson(this), topLevelFields + dbSpecificTopLevelFields);
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'package:meta/meta.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
import 'package:meta/meta.dart';
|
||||
|
||||
part 'attachment_file.freezed.dart';
|
||||
|
||||
part 'attachment_file.g.dart';
|
||||
|
||||
/// Union class to hold various [UploadState] of a attachment.
|
||||
@@ -57,8 +56,12 @@ class AttachmentFile {
|
||||
this.size,
|
||||
});
|
||||
|
||||
/// The absolute path for a cached copy of this file. It can be used to create a
|
||||
/// file instance with a descriptor for the given path.
|
||||
/// Create a new instance from a json
|
||||
factory AttachmentFile.fromJson(Map<String, dynamic> json) =>
|
||||
_$AttachmentFileFromJson(json);
|
||||
|
||||
/// The absolute path for a cached copy of this file. It can be used to
|
||||
/// create a file instance with a descriptor for the given path.
|
||||
/// ```
|
||||
/// final File myFile = File(platformFile.path);
|
||||
/// ```
|
||||
@@ -67,8 +70,8 @@ class AttachmentFile {
|
||||
/// File name including its extension.
|
||||
final String name;
|
||||
|
||||
/// Byte data for this file. Particularly useful if you want to manipulate its data
|
||||
/// or easily upload to somewhere else.
|
||||
/// Byte data for this file. Particularly useful if you want to manipulate
|
||||
/// its data or easily upload to somewhere else.
|
||||
@JsonKey(toJson: _toString, fromJson: _fromString)
|
||||
final Uint8List bytes;
|
||||
|
||||
@@ -78,11 +81,6 @@ class AttachmentFile {
|
||||
/// File extension for this file.
|
||||
String get extension => name?.split('.')?.last;
|
||||
|
||||
/// Create a new instance from a json
|
||||
factory AttachmentFile.fromJson(Map<String, dynamic> json) {
|
||||
return _$AttachmentFileFromJson(json);
|
||||
}
|
||||
|
||||
/// Serialize to json
|
||||
Map<String, dynamic> toJson() => _$AttachmentFileToJson(this);
|
||||
}
|
||||
|
||||
@@ -1,12 +1,34 @@
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
|
||||
import 'command.dart';
|
||||
|
||||
import 'package:stream_chat/src/models/command.dart';
|
||||
part 'channel_config.g.dart';
|
||||
|
||||
/// The class that contains the information about the configuration of a channel
|
||||
@JsonSerializable()
|
||||
class ChannelConfig {
|
||||
/// Constructor used for json serialization
|
||||
ChannelConfig({
|
||||
this.automod,
|
||||
this.commands,
|
||||
this.connectEvents,
|
||||
this.createdAt,
|
||||
this.updatedAt,
|
||||
this.maxMessageLength,
|
||||
this.messageRetention,
|
||||
this.mutes,
|
||||
this.name,
|
||||
this.reactions,
|
||||
this.readEvents,
|
||||
this.replies,
|
||||
this.search,
|
||||
this.typingEvents,
|
||||
this.uploads,
|
||||
this.urlEnrichment,
|
||||
});
|
||||
|
||||
/// Create a new instance from a json
|
||||
factory ChannelConfig.fromJson(Map<String, dynamic> json) =>
|
||||
_$ChannelConfigFromJson(json);
|
||||
|
||||
/// Moderation configuration
|
||||
final String automod;
|
||||
|
||||
@@ -55,30 +77,6 @@ class ChannelConfig {
|
||||
/// True if urls appears as attachments
|
||||
final bool urlEnrichment;
|
||||
|
||||
/// Constructor used for json serialization
|
||||
ChannelConfig({
|
||||
this.automod,
|
||||
this.commands,
|
||||
this.connectEvents,
|
||||
this.createdAt,
|
||||
this.updatedAt,
|
||||
this.maxMessageLength,
|
||||
this.messageRetention,
|
||||
this.mutes,
|
||||
this.name,
|
||||
this.reactions,
|
||||
this.readEvents,
|
||||
this.replies,
|
||||
this.search,
|
||||
this.typingEvents,
|
||||
this.uploads,
|
||||
this.urlEnrichment,
|
||||
});
|
||||
|
||||
/// Create a new instance from a json
|
||||
factory ChannelConfig.fromJson(Map<String, dynamic> json) =>
|
||||
_$ChannelConfigFromJson(json);
|
||||
|
||||
/// Serialize to json
|
||||
Map<String, dynamic> toJson() => _$ChannelConfigToJson(this);
|
||||
}
|
||||
|
||||
@@ -1,14 +1,35 @@
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
|
||||
import 'channel_config.dart';
|
||||
import 'serialization.dart';
|
||||
import 'user.dart';
|
||||
import 'package:stream_chat/src/models/channel_config.dart';
|
||||
import 'package:stream_chat/src/models/serialization.dart';
|
||||
import 'package:stream_chat/src/models/user.dart';
|
||||
|
||||
part 'channel_model.g.dart';
|
||||
|
||||
/// The class that contains the information about a channel
|
||||
@JsonSerializable()
|
||||
class ChannelModel {
|
||||
/// Constructor used for json serialization
|
||||
ChannelModel({
|
||||
this.id,
|
||||
this.type,
|
||||
this.cid,
|
||||
this.config,
|
||||
this.createdBy,
|
||||
this.frozen,
|
||||
this.lastMessageAt,
|
||||
this.createdAt,
|
||||
this.updatedAt,
|
||||
this.deletedAt,
|
||||
this.memberCount,
|
||||
this.extraData,
|
||||
this.team,
|
||||
});
|
||||
|
||||
/// Create a new instance from a json
|
||||
factory ChannelModel.fromJson(Map<String, dynamic> json) =>
|
||||
_$ChannelModelFromJson(
|
||||
Serialization.moveToExtraDataFromRoot(json, topLevelFields));
|
||||
|
||||
/// The id of this channel
|
||||
final String id;
|
||||
|
||||
@@ -76,40 +97,15 @@ class ChannelModel {
|
||||
'team',
|
||||
];
|
||||
|
||||
/// Constructor used for json serialization
|
||||
ChannelModel({
|
||||
this.id,
|
||||
this.type,
|
||||
this.cid,
|
||||
this.config,
|
||||
this.createdBy,
|
||||
this.frozen,
|
||||
this.lastMessageAt,
|
||||
this.createdAt,
|
||||
this.updatedAt,
|
||||
this.deletedAt,
|
||||
this.memberCount,
|
||||
this.extraData,
|
||||
this.team,
|
||||
});
|
||||
|
||||
/// Shortcut for channel name
|
||||
String get name =>
|
||||
extraData?.containsKey('name') == true ? extraData['name'] : cid;
|
||||
|
||||
/// Create a new instance from a json
|
||||
factory ChannelModel.fromJson(Map<String, dynamic> json) {
|
||||
return _$ChannelModelFromJson(
|
||||
Serialization.moveToExtraDataFromRoot(json, topLevelFields));
|
||||
}
|
||||
|
||||
/// Serialize to json
|
||||
Map<String, dynamic> toJson() {
|
||||
return Serialization.moveFromExtraDataToRoot(
|
||||
_$ChannelModelToJson(this),
|
||||
topLevelFields,
|
||||
);
|
||||
}
|
||||
Map<String, dynamic> toJson() => Serialization.moveFromExtraDataToRoot(
|
||||
_$ChannelModelToJson(this),
|
||||
topLevelFields,
|
||||
);
|
||||
|
||||
/// Creates a copy of [ChannelModel] with specified attributes overridden.
|
||||
ChannelModel copyWith({
|
||||
@@ -143,8 +139,8 @@ class ChannelModel {
|
||||
team: team ?? this.team,
|
||||
);
|
||||
|
||||
/// Returns a new [ChannelModel] that is a combination of this channelModel and the given
|
||||
/// [other] channelModel.
|
||||
/// Returns a new [ChannelModel] that is a combination of this channelModel
|
||||
/// and the given [other] channelModel.
|
||||
ChannelModel merge(ChannelModel other) {
|
||||
if (other == null) return this;
|
||||
return copyWith(
|
||||
|
||||
@@ -1,16 +1,26 @@
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
|
||||
import '../models/read.dart';
|
||||
import '../models/user.dart';
|
||||
import 'channel_model.dart';
|
||||
import 'member.dart';
|
||||
import 'message.dart';
|
||||
import 'package:stream_chat/src/models/channel_model.dart';
|
||||
import 'package:stream_chat/src/models/member.dart';
|
||||
import 'package:stream_chat/src/models/message.dart';
|
||||
import 'package:stream_chat/src/models/read.dart';
|
||||
import 'package:stream_chat/src/models/user.dart';
|
||||
|
||||
part 'channel_state.g.dart';
|
||||
|
||||
/// The class that contains the information about a channel
|
||||
@JsonSerializable()
|
||||
class ChannelState {
|
||||
/// Constructor used for json serialization
|
||||
ChannelState({
|
||||
this.channel,
|
||||
this.messages = const [],
|
||||
this.members = const [],
|
||||
this.pinnedMessages = const [],
|
||||
this.watcherCount,
|
||||
this.watchers = const [],
|
||||
this.read = const [],
|
||||
});
|
||||
|
||||
/// The channel to which this state belongs
|
||||
final ChannelModel channel;
|
||||
|
||||
@@ -32,17 +42,6 @@ class ChannelState {
|
||||
/// The list of channel reads
|
||||
final List<Read> read;
|
||||
|
||||
/// Constructor used for json serialization
|
||||
ChannelState({
|
||||
this.channel,
|
||||
this.messages = const [],
|
||||
this.members = const [],
|
||||
this.pinnedMessages = const [],
|
||||
this.watcherCount,
|
||||
this.watchers = const [],
|
||||
this.read = const [],
|
||||
});
|
||||
|
||||
/// Create a new instance from a json
|
||||
static ChannelState fromJson(Map<String, dynamic> json) =>
|
||||
_$ChannelStateFromJson(json);
|
||||
|
||||
@@ -5,15 +5,6 @@ part 'command.g.dart';
|
||||
/// The class that contains the information about a command
|
||||
@JsonSerializable()
|
||||
class Command {
|
||||
/// The name of the command
|
||||
final String name;
|
||||
|
||||
/// The description explaining the command
|
||||
final String description;
|
||||
|
||||
/// The arguments of the command
|
||||
final String args;
|
||||
|
||||
/// Constructor used for json serialization
|
||||
Command({
|
||||
this.name,
|
||||
@@ -25,6 +16,15 @@ class Command {
|
||||
factory Command.fromJson(Map<String, dynamic> json) =>
|
||||
_$CommandFromJson(json);
|
||||
|
||||
/// The name of the command
|
||||
final String name;
|
||||
|
||||
/// The description explaining the command
|
||||
final String description;
|
||||
|
||||
/// The arguments of the command
|
||||
final String args;
|
||||
|
||||
/// Serialize to json
|
||||
Map<String, dynamic> toJson() => _$CommandToJson(this);
|
||||
}
|
||||
|
||||
@@ -5,12 +5,6 @@ part 'device.g.dart';
|
||||
/// The class that contains the information about a device
|
||||
@JsonSerializable()
|
||||
class Device {
|
||||
/// The id of the device
|
||||
final String id;
|
||||
|
||||
/// The notification push provider
|
||||
final String pushProvider;
|
||||
|
||||
/// Constructor used for json serialization
|
||||
Device({
|
||||
this.id,
|
||||
@@ -20,6 +14,12 @@ class Device {
|
||||
/// Create a new instance from a json
|
||||
factory Device.fromJson(Map<String, dynamic> json) => _$DeviceFromJson(json);
|
||||
|
||||
/// The id of the device
|
||||
final String id;
|
||||
|
||||
/// The notification push provider
|
||||
final String pushProvider;
|
||||
|
||||
/// Serialize to json
|
||||
Map<String, dynamic> toJson() => _$DeviceToJson(this);
|
||||
}
|
||||
|
||||
@@ -4,17 +4,40 @@ import 'package:stream_chat/src/models/message.dart';
|
||||
import 'package:stream_chat/src/models/serialization.dart';
|
||||
import 'package:stream_chat/stream_chat.dart';
|
||||
|
||||
import '../event_type.dart';
|
||||
import 'member.dart';
|
||||
import 'own_user.dart';
|
||||
import 'reaction.dart';
|
||||
import 'user.dart';
|
||||
|
||||
part 'event.g.dart';
|
||||
|
||||
/// The class that contains the information about an event
|
||||
@JsonSerializable()
|
||||
class Event {
|
||||
/// Constructor used for json serialization
|
||||
Event({
|
||||
this.type,
|
||||
this.cid,
|
||||
this.connectionId,
|
||||
this.createdAt,
|
||||
this.me,
|
||||
this.user,
|
||||
this.message,
|
||||
this.totalUnreadCount,
|
||||
this.unreadChannels,
|
||||
this.reaction,
|
||||
this.online,
|
||||
this.channel,
|
||||
this.member,
|
||||
this.channelId,
|
||||
this.channelType,
|
||||
this.parentId,
|
||||
this.extraData,
|
||||
}) : isLocal = true;
|
||||
|
||||
/// Create a new instance from a json
|
||||
factory Event.fromJson(Map<String, dynamic> json) =>
|
||||
_$EventFromJson(Serialization.moveToExtraDataFromRoot(
|
||||
json,
|
||||
topLevelFields,
|
||||
))
|
||||
..isLocal = false;
|
||||
|
||||
/// The type of the event
|
||||
/// [EventType] contains some predefined constant types
|
||||
final String type;
|
||||
@@ -71,27 +94,6 @@ class Event {
|
||||
@JsonKey(includeIfNull: false)
|
||||
final Map<String, dynamic> extraData;
|
||||
|
||||
/// Constructor used for json serialization
|
||||
Event({
|
||||
this.type,
|
||||
this.cid,
|
||||
this.connectionId,
|
||||
this.createdAt,
|
||||
this.me,
|
||||
this.user,
|
||||
this.message,
|
||||
this.totalUnreadCount,
|
||||
this.unreadChannels,
|
||||
this.reaction,
|
||||
this.online,
|
||||
this.channel,
|
||||
this.member,
|
||||
this.channelId,
|
||||
this.channelType,
|
||||
this.parentId,
|
||||
this.extraData,
|
||||
}) : isLocal = true;
|
||||
|
||||
/// Known top level fields.
|
||||
/// Useful for [Serialization] methods.
|
||||
static final topLevelFields = [
|
||||
@@ -114,15 +116,6 @@ class Event {
|
||||
'is_local',
|
||||
];
|
||||
|
||||
/// Create a new instance from a json
|
||||
factory Event.fromJson(Map<String, dynamic> json) {
|
||||
return _$EventFromJson(Serialization.moveToExtraDataFromRoot(
|
||||
json,
|
||||
topLevelFields,
|
||||
))
|
||||
..isLocal = false;
|
||||
}
|
||||
|
||||
/// Serialize to json
|
||||
Map<String, dynamic> toJson() => Serialization.moveFromExtraDataToRoot(
|
||||
_$EventToJson(this),
|
||||
@@ -133,16 +126,6 @@ class Event {
|
||||
/// The channel embedded in the event object
|
||||
@JsonSerializable()
|
||||
class EventChannel extends ChannelModel {
|
||||
/// A paginated list of channel members
|
||||
final List<Member> members;
|
||||
|
||||
/// Known top level fields.
|
||||
/// Useful for [Serialization] methods.
|
||||
static final topLevelFields = [
|
||||
'members',
|
||||
...ChannelModel.topLevelFields,
|
||||
];
|
||||
|
||||
/// Constructor used for json serialization
|
||||
EventChannel({
|
||||
this.members,
|
||||
@@ -174,12 +157,21 @@ class EventChannel extends ChannelModel {
|
||||
);
|
||||
|
||||
/// Create a new instance from a json
|
||||
factory EventChannel.fromJson(Map<String, dynamic> json) {
|
||||
return _$EventChannelFromJson(Serialization.moveToExtraDataFromRoot(
|
||||
json,
|
||||
topLevelFields,
|
||||
));
|
||||
}
|
||||
factory EventChannel.fromJson(Map<String, dynamic> json) =>
|
||||
_$EventChannelFromJson(Serialization.moveToExtraDataFromRoot(
|
||||
json,
|
||||
topLevelFields,
|
||||
));
|
||||
|
||||
/// A paginated list of channel members
|
||||
final List<Member> members;
|
||||
|
||||
/// Known top level fields.
|
||||
/// Useful for [Serialization] methods.
|
||||
static final topLevelFields = [
|
||||
'members',
|
||||
...ChannelModel.topLevelFields,
|
||||
];
|
||||
|
||||
/// Serialize to json
|
||||
@override
|
||||
|
||||
@@ -1,12 +1,35 @@
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
|
||||
import '../models/user.dart';
|
||||
import 'package:stream_chat/src/models/user.dart';
|
||||
|
||||
part 'member.g.dart';
|
||||
|
||||
/// The class that contains the information about the user membership in a channel
|
||||
/// The class that contains the information about the user membership
|
||||
/// in a channel
|
||||
@JsonSerializable()
|
||||
class Member {
|
||||
/// Constructor used for json serialization
|
||||
Member({
|
||||
this.user,
|
||||
this.inviteAcceptedAt,
|
||||
this.inviteRejectedAt,
|
||||
this.invited,
|
||||
this.role,
|
||||
this.userId,
|
||||
this.isModerator,
|
||||
this.createdAt,
|
||||
this.updatedAt,
|
||||
this.banned,
|
||||
this.shadowBanned,
|
||||
});
|
||||
|
||||
/// Create a new instance from a json
|
||||
factory Member.fromJson(Map<String, dynamic> json) {
|
||||
final member = _$MemberFromJson(json);
|
||||
return member.copyWith(
|
||||
userId: member.user?.id,
|
||||
);
|
||||
}
|
||||
|
||||
/// The interested user
|
||||
final User user;
|
||||
|
||||
@@ -40,29 +63,6 @@ class Member {
|
||||
/// The last date of update
|
||||
final DateTime updatedAt;
|
||||
|
||||
/// Constructor used for json serialization
|
||||
Member({
|
||||
this.user,
|
||||
this.inviteAcceptedAt,
|
||||
this.inviteRejectedAt,
|
||||
this.invited,
|
||||
this.role,
|
||||
this.userId,
|
||||
this.isModerator,
|
||||
this.createdAt,
|
||||
this.updatedAt,
|
||||
this.banned,
|
||||
this.shadowBanned,
|
||||
});
|
||||
|
||||
/// Create a new instance from a json
|
||||
factory Member.fromJson(Map<String, dynamic> json) {
|
||||
final member = _$MemberFromJson(json);
|
||||
return member.copyWith(
|
||||
userId: member.user?.id,
|
||||
);
|
||||
}
|
||||
|
||||
/// Creates a copy of [Member] with specified attributes overridden.
|
||||
Member copyWith({
|
||||
User user,
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
import 'package:stream_chat/src/models/attachment.dart';
|
||||
import 'package:stream_chat/src/models/reaction.dart';
|
||||
import 'package:stream_chat/src/models/serialization.dart';
|
||||
import 'package:stream_chat/src/models/user.dart';
|
||||
import 'package:uuid/uuid.dart';
|
||||
|
||||
import 'attachment.dart';
|
||||
import 'reaction.dart';
|
||||
import 'serialization.dart';
|
||||
import 'user.dart';
|
||||
|
||||
part 'message.g.dart';
|
||||
|
||||
class _PinExpires {
|
||||
@@ -29,9 +28,11 @@ enum MessageSendingStatus {
|
||||
failed,
|
||||
|
||||
/// Message failed to updated
|
||||
// ignore: constant_identifier_names
|
||||
failed_update,
|
||||
|
||||
/// Message failed to delete
|
||||
// ignore: constant_identifier_names
|
||||
failed_delete,
|
||||
|
||||
/// Message correctly sent
|
||||
@@ -41,7 +42,46 @@ enum MessageSendingStatus {
|
||||
/// The class that contains the information about a message
|
||||
@JsonSerializable()
|
||||
class Message {
|
||||
/// The message ID. This is either created by Stream or set client side when the message is added.
|
||||
/// Constructor used for json serialization
|
||||
Message({
|
||||
String id,
|
||||
this.text,
|
||||
this.type,
|
||||
this.attachments,
|
||||
this.mentionedUsers,
|
||||
this.silent,
|
||||
this.shadowed,
|
||||
this.reactionCounts,
|
||||
this.reactionScores,
|
||||
this.latestReactions,
|
||||
this.ownReactions,
|
||||
this.parentId,
|
||||
this.quotedMessage,
|
||||
this.quotedMessageId,
|
||||
this.replyCount = 0,
|
||||
this.threadParticipants,
|
||||
this.showInChannel,
|
||||
this.command,
|
||||
this.createdAt,
|
||||
this.updatedAt,
|
||||
this.user,
|
||||
this.pinned = false,
|
||||
this.pinnedAt,
|
||||
DateTime pinExpires,
|
||||
this.pinnedBy,
|
||||
this.extraData,
|
||||
this.deletedAt,
|
||||
this.status = MessageSendingStatus.sent,
|
||||
this.skipPush,
|
||||
}) : id = id ?? Uuid().v4(),
|
||||
pinExpires = pinExpires?.toUtc();
|
||||
|
||||
/// Create a new instance from a json
|
||||
factory Message.fromJson(Map<String, dynamic> json) => _$MessageFromJson(
|
||||
Serialization.moveToExtraDataFromRoot(json, topLevelFields));
|
||||
|
||||
/// The message ID. This is either created by Stream or set client side when
|
||||
/// the message is added.
|
||||
final String id;
|
||||
|
||||
/// The text of this message
|
||||
@@ -55,7 +95,8 @@ class Message {
|
||||
@JsonKey(includeIfNull: false, toJson: Serialization.readOnly)
|
||||
final String type;
|
||||
|
||||
/// The list of attachments, either provided by the user or generated from a command or as a result of URL scraping.
|
||||
/// The list of attachments, either provided by the user or generated from a
|
||||
/// command or as a result of URL scraping.
|
||||
@JsonKey(includeIfNull: false)
|
||||
final List<Attachment> attachments;
|
||||
|
||||
@@ -103,6 +144,9 @@ class Message {
|
||||
/// If true the message is silent
|
||||
final bool silent;
|
||||
|
||||
/// If true the message will not send a push notification
|
||||
final bool skipPush;
|
||||
|
||||
/// If true the message is shadowed
|
||||
@JsonKey(includeIfNull: false, toJson: Serialization.readOnly)
|
||||
final bool shadowed;
|
||||
@@ -186,45 +230,9 @@ class Message {
|
||||
'pinned_at',
|
||||
'pin_expires',
|
||||
'pinned_by',
|
||||
'skip_push',
|
||||
];
|
||||
|
||||
/// Constructor used for json serialization
|
||||
Message({
|
||||
String id,
|
||||
this.text,
|
||||
this.type,
|
||||
this.attachments,
|
||||
this.mentionedUsers,
|
||||
this.silent,
|
||||
this.shadowed,
|
||||
this.reactionCounts,
|
||||
this.reactionScores,
|
||||
this.latestReactions,
|
||||
this.ownReactions,
|
||||
this.parentId,
|
||||
this.quotedMessage,
|
||||
this.quotedMessageId,
|
||||
this.replyCount = 0,
|
||||
this.threadParticipants,
|
||||
this.showInChannel,
|
||||
this.command,
|
||||
this.createdAt,
|
||||
this.updatedAt,
|
||||
this.user,
|
||||
this.pinned = false,
|
||||
this.pinnedAt,
|
||||
DateTime pinExpires,
|
||||
this.pinnedBy,
|
||||
this.extraData,
|
||||
this.deletedAt,
|
||||
this.status = MessageSendingStatus.sent,
|
||||
}) : id = id ?? Uuid().v4(),
|
||||
pinExpires = pinExpires?.toUtc();
|
||||
|
||||
/// Create a new instance from a json
|
||||
factory Message.fromJson(Map<String, dynamic> json) => _$MessageFromJson(
|
||||
Serialization.moveToExtraDataFromRoot(json, topLevelFields));
|
||||
|
||||
/// Serialize to json
|
||||
Map<String, dynamic> toJson() => Serialization.moveFromExtraDataToRoot(
|
||||
_$MessageToJson(this), topLevelFields);
|
||||
@@ -259,6 +267,7 @@ class Message {
|
||||
User pinnedBy,
|
||||
Map<String, dynamic> extraData,
|
||||
MessageSendingStatus status,
|
||||
bool skipPush,
|
||||
}) {
|
||||
assert(() {
|
||||
if (pinExpires is! DateTime &&
|
||||
@@ -267,7 +276,7 @@ class Message {
|
||||
throw ArgumentError('`pinExpires` can only be set as DateTime or null');
|
||||
}
|
||||
return true;
|
||||
}());
|
||||
}(), 'Validate type for pinExpires');
|
||||
return Message(
|
||||
id: id ?? this.id,
|
||||
text: text ?? this.text,
|
||||
@@ -297,11 +306,12 @@ class Message {
|
||||
pinnedAt: pinnedAt ?? this.pinnedAt,
|
||||
pinnedBy: pinnedBy ?? this.pinnedBy,
|
||||
pinExpires: pinExpires == _pinExpires ? this.pinExpires : pinExpires,
|
||||
skipPush: skipPush ?? this.skipPush,
|
||||
);
|
||||
}
|
||||
|
||||
/// Returns a new [Message] that is a combination of this message and the given
|
||||
/// [other] message.
|
||||
/// Returns a new [Message] that is a combination of this message and the
|
||||
/// given [other] message.
|
||||
Message merge(Message other) {
|
||||
if (other == null) return this;
|
||||
return copyWith(
|
||||
@@ -344,6 +354,12 @@ class TranslatedMessage extends Message {
|
||||
/// Constructor used for json serialization
|
||||
TranslatedMessage(this.i18n);
|
||||
|
||||
/// Create a new instance from a json
|
||||
factory TranslatedMessage.fromJson(Map<String, dynamic> json) =>
|
||||
_$TranslatedMessageFromJson(
|
||||
Serialization.moveToExtraDataFromRoot(json, topLevelFields),
|
||||
);
|
||||
|
||||
/// A Map of
|
||||
final Map<String, String> i18n;
|
||||
|
||||
@@ -354,13 +370,6 @@ class TranslatedMessage extends Message {
|
||||
...Message.topLevelFields,
|
||||
];
|
||||
|
||||
/// Create a new instance from a json
|
||||
factory TranslatedMessage.fromJson(Map<String, dynamic> json) {
|
||||
return _$TranslatedMessageFromJson(
|
||||
Serialization.moveToExtraDataFromRoot(json, topLevelFields),
|
||||
);
|
||||
}
|
||||
|
||||
/// Serialize to json
|
||||
@override
|
||||
Map<String, dynamic> toJson() => Serialization.moveFromExtraDataToRoot(
|
||||
|
||||
@@ -93,6 +93,7 @@ Message _$MessageFromJson(Map json) {
|
||||
deletedAt: json['deleted_at'] == null
|
||||
? null
|
||||
: DateTime.parse(json['deleted_at'] as String),
|
||||
skipPush: json['skip_push'] as bool,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -123,6 +124,7 @@ Map<String, dynamic> _$MessageToJson(Message instance) {
|
||||
writeNotNull('thread_participants', readonly(instance.threadParticipants));
|
||||
val['show_in_channel'] = instance.showInChannel;
|
||||
val['silent'] = instance.silent;
|
||||
val['skip_push'] = instance.skipPush;
|
||||
writeNotNull('shadowed', readonly(instance.shadowed));
|
||||
writeNotNull('command', readonly(instance.command));
|
||||
writeNotNull('created_at', readonly(instance.createdAt));
|
||||
|
||||
@@ -1,14 +1,19 @@
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
import 'package:stream_chat/src/models/channel_model.dart';
|
||||
|
||||
import 'serialization.dart';
|
||||
import 'user.dart';
|
||||
import 'package:stream_chat/src/models/serialization.dart';
|
||||
import 'package:stream_chat/src/models/user.dart';
|
||||
|
||||
part 'mute.g.dart';
|
||||
|
||||
/// The class that contains the information about a muted user
|
||||
@JsonSerializable()
|
||||
class Mute {
|
||||
/// Constructor used for json serialization
|
||||
Mute({this.user, this.channel, this.createdAt, this.updatedAt});
|
||||
|
||||
/// Create a new instance from a json
|
||||
factory Mute.fromJson(Map<String, dynamic> json) => _$MuteFromJson(json);
|
||||
|
||||
/// The user that performed the muting action
|
||||
@JsonKey(includeIfNull: false, toJson: Serialization.readOnly)
|
||||
final User user;
|
||||
@@ -25,12 +30,6 @@ class Mute {
|
||||
@JsonKey(includeIfNull: false, toJson: Serialization.readOnly)
|
||||
final DateTime updatedAt;
|
||||
|
||||
/// Constructor used for json serialization
|
||||
Mute({this.user, this.channel, this.createdAt, this.updatedAt});
|
||||
|
||||
/// Create a new instance from a json
|
||||
factory Mute.fromJson(Map<String, dynamic> json) => _$MuteFromJson(json);
|
||||
|
||||
/// Serialize to json
|
||||
Map<String, dynamic> toJson() => _$MuteToJson(this);
|
||||
}
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
|
||||
import 'device.dart';
|
||||
import 'mute.dart';
|
||||
import 'serialization.dart';
|
||||
import 'user.dart';
|
||||
import 'package:stream_chat/src/models/device.dart';
|
||||
import 'package:stream_chat/src/models/mute.dart';
|
||||
import 'package:stream_chat/src/models/serialization.dart';
|
||||
import 'package:stream_chat/src/models/user.dart';
|
||||
|
||||
part 'own_user.g.dart';
|
||||
|
||||
@@ -11,6 +10,36 @@ part 'own_user.g.dart';
|
||||
/// This object can be found in [Event]
|
||||
@JsonSerializable()
|
||||
class OwnUser extends User {
|
||||
/// Constructor used for json serialization
|
||||
OwnUser({
|
||||
this.devices,
|
||||
this.mutes,
|
||||
this.totalUnreadCount,
|
||||
this.unreadChannels,
|
||||
this.channelMutes,
|
||||
String id,
|
||||
String role,
|
||||
DateTime createdAt,
|
||||
DateTime updatedAt,
|
||||
DateTime lastActive,
|
||||
bool online,
|
||||
Map<String, dynamic> extraData,
|
||||
bool banned,
|
||||
}) : super(
|
||||
id: id,
|
||||
role: role,
|
||||
createdAt: createdAt,
|
||||
updatedAt: updatedAt,
|
||||
lastActive: lastActive,
|
||||
online: online,
|
||||
extraData: extraData,
|
||||
banned: banned,
|
||||
);
|
||||
|
||||
/// Create a new instance from a json
|
||||
factory OwnUser.fromJson(Map<String, dynamic> json) => _$OwnUserFromJson(
|
||||
Serialization.moveToExtraDataFromRoot(json, topLevelFields));
|
||||
|
||||
/// List of user devices
|
||||
@JsonKey(includeIfNull: false, toJson: Serialization.readOnly)
|
||||
final List<Device> devices;
|
||||
@@ -42,42 +71,8 @@ class OwnUser extends User {
|
||||
...User.topLevelFields,
|
||||
];
|
||||
|
||||
/// Constructor used for json serialization
|
||||
OwnUser({
|
||||
this.devices,
|
||||
this.mutes,
|
||||
this.totalUnreadCount,
|
||||
this.unreadChannels,
|
||||
this.channelMutes,
|
||||
String id,
|
||||
String role,
|
||||
DateTime createdAt,
|
||||
DateTime updatedAt,
|
||||
DateTime lastActive,
|
||||
bool online,
|
||||
Map<String, dynamic> extraData,
|
||||
bool banned,
|
||||
}) : super(
|
||||
id: id,
|
||||
role: role,
|
||||
createdAt: createdAt,
|
||||
updatedAt: updatedAt,
|
||||
lastActive: lastActive,
|
||||
online: online,
|
||||
extraData: extraData,
|
||||
banned: banned,
|
||||
);
|
||||
|
||||
/// Create a new instance from a json
|
||||
factory OwnUser.fromJson(Map<String, dynamic> json) {
|
||||
return _$OwnUserFromJson(
|
||||
Serialization.moveToExtraDataFromRoot(json, topLevelFields));
|
||||
}
|
||||
|
||||
/// Serialize to json
|
||||
@override
|
||||
Map<String, dynamic> toJson() {
|
||||
return Serialization.moveFromExtraDataToRoot(
|
||||
_$OwnUserToJson(this), topLevelFields);
|
||||
}
|
||||
Map<String, dynamic> toJson() => Serialization.moveFromExtraDataToRoot(
|
||||
_$OwnUserToJson(this), topLevelFields);
|
||||
}
|
||||
|
||||
@@ -1,13 +1,27 @@
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
|
||||
import 'serialization.dart';
|
||||
import 'user.dart';
|
||||
import 'package:stream_chat/src/models/serialization.dart';
|
||||
import 'package:stream_chat/src/models/user.dart';
|
||||
|
||||
part 'reaction.g.dart';
|
||||
|
||||
/// The class that defines a reaction
|
||||
@JsonSerializable()
|
||||
class Reaction {
|
||||
/// Constructor used for json serialization
|
||||
Reaction({
|
||||
this.messageId,
|
||||
this.createdAt,
|
||||
this.type,
|
||||
this.user,
|
||||
String userId,
|
||||
this.score,
|
||||
this.extraData,
|
||||
}) : userId = userId ?? user?.id;
|
||||
|
||||
/// Create a new instance from a json
|
||||
factory Reaction.fromJson(Map<String, dynamic> json) => _$ReactionFromJson(
|
||||
Serialization.moveToExtraDataFromRoot(json, topLevelFields));
|
||||
|
||||
/// The messageId to which the reaction belongs
|
||||
final String messageId;
|
||||
|
||||
@@ -43,28 +57,9 @@ class Reaction {
|
||||
'score',
|
||||
];
|
||||
|
||||
/// Constructor used for json serialization
|
||||
Reaction({
|
||||
this.messageId,
|
||||
this.createdAt,
|
||||
this.type,
|
||||
this.user,
|
||||
String userId,
|
||||
this.score,
|
||||
this.extraData,
|
||||
}) : userId = userId ?? user?.id;
|
||||
|
||||
/// Create a new instance from a json
|
||||
factory Reaction.fromJson(Map<String, dynamic> json) {
|
||||
return _$ReactionFromJson(
|
||||
Serialization.moveToExtraDataFromRoot(json, topLevelFields));
|
||||
}
|
||||
|
||||
/// Serialize to json
|
||||
Map<String, dynamic> toJson() {
|
||||
return Serialization.moveFromExtraDataToRoot(
|
||||
_$ReactionToJson(this), topLevelFields);
|
||||
}
|
||||
Map<String, dynamic> toJson() => Serialization.moveFromExtraDataToRoot(
|
||||
_$ReactionToJson(this), topLevelFields);
|
||||
|
||||
/// Creates a copy of [Reaction] with specified attributes overridden.
|
||||
Reaction copyWith({
|
||||
@@ -75,20 +70,19 @@ class Reaction {
|
||||
String userId,
|
||||
int score,
|
||||
Map<String, dynamic> extraData,
|
||||
}) {
|
||||
return Reaction(
|
||||
messageId: messageId ?? this.messageId,
|
||||
createdAt: createdAt ?? this.createdAt,
|
||||
type: type ?? this.type,
|
||||
user: user ?? this.user,
|
||||
userId: userId ?? this.userId,
|
||||
score: score ?? this.score,
|
||||
extraData: extraData ?? this.extraData,
|
||||
);
|
||||
}
|
||||
}) =>
|
||||
Reaction(
|
||||
messageId: messageId ?? this.messageId,
|
||||
createdAt: createdAt ?? this.createdAt,
|
||||
type: type ?? this.type,
|
||||
user: user ?? this.user,
|
||||
userId: userId ?? this.userId,
|
||||
score: score ?? this.score,
|
||||
extraData: extraData ?? this.extraData,
|
||||
);
|
||||
|
||||
/// Returns a new [Reaction] that is a combination of this reaction and the given
|
||||
/// [other] reaction.
|
||||
/// Returns a new [Reaction] that is a combination of this reaction and the
|
||||
/// given [other] reaction.
|
||||
Reaction merge(Reaction other) {
|
||||
if (other == null) return this;
|
||||
return copyWith(
|
||||
|
||||
@@ -1,21 +1,11 @@
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
|
||||
import 'user.dart';
|
||||
import 'package:stream_chat/src/models/user.dart';
|
||||
|
||||
part 'read.g.dart';
|
||||
|
||||
/// The class that defines a read event
|
||||
@JsonSerializable()
|
||||
class Read {
|
||||
/// Date of the read event
|
||||
final DateTime lastRead;
|
||||
|
||||
/// User who sent the event
|
||||
final User user;
|
||||
|
||||
/// Number of unread messages
|
||||
final int unreadMessages;
|
||||
|
||||
/// Constructor used for json serialization
|
||||
Read({
|
||||
this.lastRead,
|
||||
@@ -26,6 +16,15 @@ class Read {
|
||||
/// Create a new instance from a json
|
||||
factory Read.fromJson(Map<String, dynamic> json) => _$ReadFromJson(json);
|
||||
|
||||
/// Date of the read event
|
||||
final DateTime lastRead;
|
||||
|
||||
/// User who sent the event
|
||||
final User user;
|
||||
|
||||
/// Number of unread messages
|
||||
final int unreadMessages;
|
||||
|
||||
/// Serialize to json
|
||||
Map<String, dynamic> toJson() => _$ReadToJson(this);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import 'user.dart';
|
||||
import 'package:stream_chat/src/models/user.dart';
|
||||
|
||||
/// Used to avoid to serialize properties to json
|
||||
// ignore: prefer_void_to_null
|
||||
Null readonly(_) => null;
|
||||
|
||||
/// Helper class for serialization to and from json
|
||||
@@ -9,9 +10,8 @@ class Serialization {
|
||||
static const Function readOnly = readonly;
|
||||
|
||||
/// List of users to list of userIds
|
||||
static List<String> userIds(List<User> users) {
|
||||
return users?.map((u) => u.id)?.toList();
|
||||
}
|
||||
static List<String> userIds(List<User> users) =>
|
||||
users?.map((u) => u.id)?.toList();
|
||||
|
||||
/// Takes unknown json keys and puts them in the `extra_data` key
|
||||
static Map<String, dynamic> moveToExtraDataFromRoot(
|
||||
@@ -34,7 +34,8 @@ class Serialization {
|
||||
});
|
||||
}
|
||||
|
||||
/// Takes values in `extra_data` key and puts them on the root level of the json map
|
||||
/// Takes values in `extra_data` key and puts them on the root level of
|
||||
/// the json map
|
||||
static Map<String, dynamic> moveFromExtraDataToRoot(
|
||||
Map<String, dynamic> json,
|
||||
List<String> topLevelFields,
|
||||
|
||||
@@ -1,12 +1,53 @@
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
|
||||
import 'serialization.dart';
|
||||
import 'package:stream_chat/src/models/serialization.dart';
|
||||
|
||||
part 'user.g.dart';
|
||||
|
||||
/// The class that defines the user model
|
||||
@JsonSerializable()
|
||||
class User {
|
||||
/// Constructor used for json serialization
|
||||
User({
|
||||
this.id,
|
||||
this.role,
|
||||
this.createdAt,
|
||||
this.updatedAt,
|
||||
this.lastActive,
|
||||
this.online,
|
||||
this.extraData,
|
||||
this.banned,
|
||||
this.teams,
|
||||
});
|
||||
|
||||
/// Create a new instance from a json
|
||||
factory User.fromJson(Map<String, dynamic> json) => _$UserFromJson(
|
||||
Serialization.moveToExtraDataFromRoot(json, topLevelFields));
|
||||
|
||||
/// Use this named constructor to create a new user instance
|
||||
User.init(
|
||||
this.id, {
|
||||
this.online,
|
||||
this.extraData,
|
||||
}) : createdAt = null,
|
||||
updatedAt = null,
|
||||
lastActive = null,
|
||||
banned = null,
|
||||
teams = null,
|
||||
role = null;
|
||||
|
||||
/// Known top level fields.
|
||||
/// Useful for [Serialization] methods.
|
||||
static const topLevelFields = [
|
||||
'id',
|
||||
'role',
|
||||
'created_at',
|
||||
'updated_at',
|
||||
'last_active',
|
||||
'online',
|
||||
'banned',
|
||||
'teams',
|
||||
];
|
||||
|
||||
/// User id
|
||||
final String id;
|
||||
|
||||
@@ -42,43 +83,8 @@ class User {
|
||||
@JsonKey(includeIfNull: false)
|
||||
final Map<String, dynamic> extraData;
|
||||
|
||||
/// Known top level fields.
|
||||
/// Useful for [Serialization] methods.
|
||||
static const topLevelFields = [
|
||||
'id',
|
||||
'role',
|
||||
'created_at',
|
||||
'updated_at',
|
||||
'last_active',
|
||||
'online',
|
||||
'banned',
|
||||
'teams',
|
||||
];
|
||||
|
||||
/// Use this named constructor to create a new user instance
|
||||
User.init(
|
||||
this.id, {
|
||||
this.online,
|
||||
this.extraData,
|
||||
}) : createdAt = null,
|
||||
updatedAt = null,
|
||||
lastActive = null,
|
||||
banned = null,
|
||||
teams = null,
|
||||
role = null;
|
||||
|
||||
/// Constructor used for json serialization
|
||||
User({
|
||||
this.id,
|
||||
this.role,
|
||||
this.createdAt,
|
||||
this.updatedAt,
|
||||
this.lastActive,
|
||||
this.online,
|
||||
this.extraData,
|
||||
this.banned,
|
||||
this.teams,
|
||||
});
|
||||
@override
|
||||
int get hashCode => id.hashCode;
|
||||
|
||||
/// Shortcut for user name
|
||||
String get name =>
|
||||
@@ -86,23 +92,12 @@ class User {
|
||||
? extraData['name']
|
||||
: id;
|
||||
|
||||
/// Create a new instance from a json
|
||||
factory User.fromJson(Map<String, dynamic> json) {
|
||||
return _$UserFromJson(
|
||||
Serialization.moveToExtraDataFromRoot(json, topLevelFields));
|
||||
}
|
||||
|
||||
/// Serialize to json
|
||||
Map<String, dynamic> toJson() {
|
||||
return Serialization.moveFromExtraDataToRoot(
|
||||
_$UserToJson(this), topLevelFields);
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) =>
|
||||
identical(this, other) ||
|
||||
other is User && runtimeType == other.runtimeType && id == other.id;
|
||||
|
||||
@override
|
||||
int get hashCode => id.hashCode;
|
||||
/// Serialize to json
|
||||
Map<String, dynamic> toJson() =>
|
||||
Serialization.moveFromExtraDataToRoot(_$UserToJson(this), topLevelFields);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user