rename package folders

This commit is contained in:
Salvatore Giordano
2021-02-01 15:45:58 +01:00
parent 6682ad5e8b
commit 964a428f2e
445 changed files with 1 additions and 343 deletions
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,11 @@
/// Used to notify the WS connection status
enum ConnectionStatus {
/// WS is connected and everything is good
connected,
/// WS is connecting (usually reconnecting)
connecting,
/// WS is disconnected and it's not reconnecting
disconnected,
}
@@ -0,0 +1,97 @@
import 'package:json_annotation/json_annotation.dart';
part 'requests.g.dart';
/// Sorting options
@JsonSerializable(createFactory: false)
class SortOption {
/// Ascending order
static const ASC = 1;
/// Descending order
static const DESC = -1;
/// A sorting field name
final String field;
/// A sorting direction
final int direction;
/// Creates a new SortOption instance
///
/// For example:
/// ```dart
/// // Sort channels by the last message date:
/// final sorting = SortOption("last_message_at")
/// ```
const SortOption(this.field, {this.direction = DESC});
/// Serialize model to json
Map<String, dynamic> toJson() => _$SortOptionToJson(this);
}
/// Pagination options.
@JsonSerializable(createFactory: false, includeIfNull: false)
class PaginationParams {
/// The amount of items requested from the APIs.
final int limit;
/// The offset of requesting items.
final int offset;
/// Filter on ids greater than the given value.
@JsonKey(name: 'id_gt')
final String greaterThan;
/// Filter on ids greater than or equal to the given value.
@JsonKey(name: 'id_gte')
final String greaterThanOrEqual;
/// Filter on ids smaller than the given value.
@JsonKey(name: 'id_lt')
final String lessThan;
/// Filter on ids smaller than or equal to the given value.
@JsonKey(name: 'id_lte')
final String lessThanOrEqual;
/// Creates a new PaginationParams instance
///
/// For example:
/// ```dart
/// // limit to 50
/// final paginationParams = PaginationParams(limit: 50);
///
/// // limit to 50 with offset
/// final paginationParams = PaginationParams(limit: 50, offset: 50);
/// ```
const PaginationParams({
this.limit = 10,
this.offset,
this.greaterThan,
this.greaterThanOrEqual,
this.lessThan,
this.lessThanOrEqual,
});
/// Serialize model to json
Map<String, dynamic> toJson() => _$PaginationParamsToJson(this);
/// Creates a copy of [PaginationParams] with specified attributes overridden.
PaginationParams copyWith({
int limit,
int offset,
String greaterThan,
String greaterThanOrEqual,
String lessThan,
String lessThanOrEqual,
}) =>
PaginationParams(
limit: limit ?? this.limit,
offset: offset ?? this.offset,
greaterThan: greaterThan ?? this.greaterThan,
greaterThanOrEqual: greaterThanOrEqual ?? this.greaterThanOrEqual,
lessThan: lessThan ?? this.lessThan,
lessThanOrEqual: lessThanOrEqual ?? this.lessThanOrEqual,
);
}
@@ -0,0 +1,31 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'requests.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
Map<String, dynamic> _$SortOptionToJson(SortOption instance) =>
<String, dynamic>{
'field': instance.field,
'direction': instance.direction,
};
Map<String, dynamic> _$PaginationParamsToJson(PaginationParams instance) {
final val = <String, dynamic>{};
void writeNotNull(String key, dynamic value) {
if (value != null) {
val[key] = value;
}
}
writeNotNull('limit', instance.limit);
writeNotNull('offset', instance.offset);
writeNotNull('id_gt', instance.greaterThan);
writeNotNull('id_gte', instance.greaterThanOrEqual);
writeNotNull('id_lt', instance.lessThan);
writeNotNull('id_lte', instance.lessThanOrEqual);
return val;
}
@@ -0,0 +1,375 @@
import 'package:json_annotation/json_annotation.dart';
import 'package:stream_chat/src/client.dart';
import 'package:stream_chat/src/models/device.dart';
import 'package:stream_chat/src/models/event.dart';
import '../models/channel_model.dart';
import '../models/channel_state.dart';
import '../models/member.dart';
import '../models/message.dart';
import '../models/reaction.dart';
import '../models/read.dart';
import '../models/user.dart';
part 'responses.g.dart';
class _BaseResponse {
String duration;
}
/// Model response for [StreamChatClient.resync] api call
@JsonSerializable(createToJson: false)
class SyncResponse extends _BaseResponse {
/// The list of events
List<Event> events;
/// Create a new instance from a json
static SyncResponse fromJson(Map<String, dynamic> json) =>
_$SyncResponseFromJson(json);
}
/// Model response for [StreamChatClient.queryChannels] api call
@JsonSerializable(createToJson: false)
class QueryChannelsResponse extends _BaseResponse {
/// List of channels state returned by the query
List<ChannelState> channels;
/// Create a new instance from a json
static QueryChannelsResponse fromJson(Map<String, dynamic> json) =>
_$QueryChannelsResponseFromJson(json);
}
/// Model response for [StreamChatClient.queryChannels] api call
@JsonSerializable(createToJson: false)
class TranslateMessageResponse extends _BaseResponse {
/// List of channels state returned by the query
TranslatedMessage message;
/// Create a new instance from a json
static TranslateMessageResponse fromJson(Map<String, dynamic> json) =>
_$TranslateMessageResponseFromJson(json);
}
/// Model response for [StreamChatClient.queryChannels] api call
@JsonSerializable(createToJson: false)
class QueryMembersResponse extends _BaseResponse {
/// List of channels state returned by the query
List<Member> members;
/// Create a new instance from a json
static QueryMembersResponse fromJson(Map<String, dynamic> json) =>
_$QueryMembersResponseFromJson(json);
}
/// Model response for [StreamChatClient.queryUsers] api call
@JsonSerializable(createToJson: false)
class QueryUsersResponse extends _BaseResponse {
/// List of users returned by the query
List<User> users;
/// Create a new instance from a json
static QueryUsersResponse fromJson(Map<String, dynamic> json) =>
_$QueryUsersResponseFromJson(json);
}
/// Model response for [channel.getReactions] api call
@JsonSerializable(createToJson: false)
class QueryReactionsResponse extends _BaseResponse {
/// List of reactions returned by the query
List<Reaction> reactions;
/// Create a new instance from a json
static QueryReactionsResponse fromJson(Map<String, dynamic> json) =>
_$QueryReactionsResponseFromJson(json);
}
/// Model response for [Channel.getReplies] api call
@JsonSerializable(createToJson: false)
class QueryRepliesResponse extends _BaseResponse {
/// List of messages returned by the api call
List<Message> messages;
/// Create a new instance from a json
static QueryRepliesResponse fromJson(Map<String, dynamic> json) =>
_$QueryRepliesResponseFromJson(json);
}
/// Model response for [StreamChatClient.getDevices] api call
@JsonSerializable(createToJson: false)
class ListDevicesResponse extends _BaseResponse {
/// List of user devices
List<Device> devices;
/// Create a new instance from a json
static ListDevicesResponse fromJson(Map<String, dynamic> json) =>
_$ListDevicesResponseFromJson(json);
}
/// Model response for [Channel.sendFile] api call
@JsonSerializable(createToJson: false)
class SendFileResponse extends _BaseResponse {
/// The url of the uploaded file
String file;
/// Create a new instance from a json
static SendFileResponse fromJson(Map<String, dynamic> json) =>
_$SendFileResponseFromJson(json);
}
/// Model response for [Channel.sendImage] api call
@JsonSerializable(createToJson: false)
class SendImageResponse extends _BaseResponse {
/// The url of the uploaded file
String file;
/// Create a new instance from a json
static SendImageResponse fromJson(Map<String, dynamic> json) =>
_$SendImageResponseFromJson(json);
}
/// Model response for [Channel.sendReaction] api call
@JsonSerializable(createToJson: false)
class SendReactionResponse extends _BaseResponse {
/// Message returned by the api call
Message message;
/// The reaction created by the api call
Reaction reaction;
/// Create a new instance from a json
static SendReactionResponse fromJson(Map<String, dynamic> json) =>
_$SendReactionResponseFromJson(json);
}
/// Model response for [StreamChatClient.setGuestUser] api call
@JsonSerializable(createToJson: false)
class SetGuestUserResponse extends _BaseResponse {
/// Guest user access token
String accessToken;
/// Guest user
User user;
/// Create a new instance from a json
static SetGuestUserResponse fromJson(Map<String, dynamic> json) =>
_$SetGuestUserResponseFromJson(json);
}
/// Model response for [StreamChatClient.updateUser] api call
@JsonSerializable(createToJson: false)
class UpdateUsersResponse extends _BaseResponse {
/// Updated users
Map<String, User> users;
/// Create a new instance from a json
static UpdateUsersResponse fromJson(Map<String, dynamic> json) =>
_$UpdateUsersResponseFromJson(json);
}
/// Model response for [StreamChatClient.updateMessage] api call
@JsonSerializable(createToJson: false)
class UpdateMessageResponse extends _BaseResponse {
/// Message returned by the api call
Message message;
/// Create a new instance from a json
static UpdateMessageResponse fromJson(Map<String, dynamic> json) =>
_$UpdateMessageResponseFromJson(json);
}
/// Model response for [Channel.sendMessage] api call
@JsonSerializable(createToJson: false)
class SendMessageResponse extends _BaseResponse {
/// Message returned by the api call
Message message;
/// Create a new instance from a json
static SendMessageResponse fromJson(Map<String, dynamic> json) =>
_$SendMessageResponseFromJson(json);
}
/// Model response for [StreamChatClient.getMessage] api call
@JsonSerializable(createToJson: false)
class GetMessageResponse extends _BaseResponse {
/// Message returned by the api call
Message message;
/// Channel of the message
ChannelModel channel;
/// Create a new instance from a json
static GetMessageResponse fromJson(Map<String, dynamic> json) {
final res = _$GetMessageResponseFromJson(json);
final jsonChannel = res.message?.extraData?.remove('channel');
if (jsonChannel != null) {
res.channel = ChannelModel.fromJson(jsonChannel);
}
return res;
}
}
/// Model response for [StreamChatClient.search] api call
@JsonSerializable(createToJson: false)
class SearchMessagesResponse extends _BaseResponse {
/// List of messages returned by the api call
List<GetMessageResponse> results;
/// Create a new instance from a json
static SearchMessagesResponse fromJson(Map<String, dynamic> json) =>
_$SearchMessagesResponseFromJson(json);
}
/// Model response for [Channel.getMessagesById] api call
@JsonSerializable(createToJson: false)
class GetMessagesByIdResponse extends _BaseResponse {
/// Message returned by the api call
List<Message> messages;
/// Create a new instance from a json
static GetMessagesByIdResponse fromJson(Map<String, dynamic> json) =>
_$GetMessagesByIdResponseFromJson(json);
}
/// Model response for [Channel.update] api call
@JsonSerializable(createToJson: false)
class UpdateChannelResponse extends _BaseResponse {
/// Updated channel
ChannelModel channel;
/// Channel members
List<Member> members;
/// Message returned by the api call
Message message;
/// Create a new instance from a json
static UpdateChannelResponse fromJson(Map<String, dynamic> json) =>
_$UpdateChannelResponseFromJson(json);
}
/// Model response for [Channel.inviteMembers] api call
@JsonSerializable(createToJson: false)
class InviteMembersResponse extends _BaseResponse {
/// Updated channel
ChannelModel channel;
/// Channel members
List<Member> members;
/// Message returned by the api call
Message message;
/// Create a new instance from a json
static InviteMembersResponse fromJson(Map<String, dynamic> json) =>
_$InviteMembersResponseFromJson(json);
}
/// Model response for [Channel.removeMembers] api call
@JsonSerializable(createToJson: false)
class RemoveMembersResponse extends _BaseResponse {
/// Updated channel
ChannelModel channel;
/// Channel members
List<Member> members;
/// Message returned by the api call
Message message;
/// Create a new instance from a json
static RemoveMembersResponse fromJson(Map<String, dynamic> json) =>
_$RemoveMembersResponseFromJson(json);
}
/// Model response for [Channel.sendAction] api call
@JsonSerializable(createToJson: false)
class SendActionResponse extends _BaseResponse {
/// Message returned by the api call
Message message;
/// Create a new instance from a json
static SendActionResponse fromJson(Map<String, dynamic> json) =>
_$SendActionResponseFromJson(json);
}
/// Model response for [Channel.addMembers] api call
@JsonSerializable(createToJson: false)
class AddMembersResponse extends _BaseResponse {
/// Updated channel
ChannelModel channel;
/// Channel members
List<Member> members;
/// Message returned by the api call
Message message;
/// Create a new instance from a json
static AddMembersResponse fromJson(Map<String, dynamic> json) =>
_$AddMembersResponseFromJson(json);
}
/// Model response for [Channel.acceptInvite] api call
@JsonSerializable(createToJson: false)
class AcceptInviteResponse extends _BaseResponse {
/// Updated channel
ChannelModel channel;
/// Channel members
List<Member> members;
/// Message returned by the api call
Message message;
/// Create a new instance from a json
static AcceptInviteResponse fromJson(Map<String, dynamic> json) =>
_$AcceptInviteResponseFromJson(json);
}
/// Model response for [Channel.rejectInvite] api call
@JsonSerializable(createToJson: false)
class RejectInviteResponse extends _BaseResponse {
/// Updated channel
ChannelModel channel;
/// Channel members
List<Member> members;
/// Message returned by the api call
Message message;
/// Create a new instance from a json
static RejectInviteResponse fromJson(Map<String, dynamic> json) =>
_$RejectInviteResponseFromJson(json);
}
/// Model response for empty responses
@JsonSerializable(createToJson: false)
class EmptyResponse extends _BaseResponse {
/// Create a new instance from a json
static EmptyResponse fromJson(Map<String, dynamic> json) =>
_$EmptyResponseFromJson(json);
}
/// Model response for [Channel.query] api call
@JsonSerializable(createToJson: false)
class ChannelStateResponse extends _BaseResponse {
/// Updated channel
ChannelModel channel;
/// List of messages returned by the api call
List<Message> messages;
/// Channel members
List<Member> members;
/// Number of users watching the channel
int watcherCount;
/// List of read states
List<Read> read;
/// Create a new instance from a json
static ChannelStateResponse fromJson(Map<String, dynamic> json) =>
_$ChannelStateResponseFromJson(json);
}
@@ -0,0 +1,382 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'responses.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
SyncResponse _$SyncResponseFromJson(Map json) {
return SyncResponse()
..duration = json['duration'] as String
..events = (json['events'] as List)
?.map((e) => e == null
? null
: Event.fromJson((e as Map)?.map(
(k, e) => MapEntry(k as String, e),
)))
?.toList();
}
QueryChannelsResponse _$QueryChannelsResponseFromJson(Map json) {
return QueryChannelsResponse()
..duration = json['duration'] as String
..channels = (json['channels'] as List)
?.map((e) => e == null ? null : ChannelState.fromJson(e as Map))
?.toList();
}
TranslateMessageResponse _$TranslateMessageResponseFromJson(Map json) {
return TranslateMessageResponse()
..duration = json['duration'] as String
..message = json['message'] == null
? null
: TranslatedMessage.fromJson((json['message'] as Map)?.map(
(k, e) => MapEntry(k as String, e),
));
}
QueryMembersResponse _$QueryMembersResponseFromJson(Map json) {
return QueryMembersResponse()
..duration = json['duration'] as String
..members = (json['members'] as List)
?.map((e) => e == null
? null
: Member.fromJson((e as Map)?.map(
(k, e) => MapEntry(k as String, e),
)))
?.toList();
}
QueryUsersResponse _$QueryUsersResponseFromJson(Map json) {
return QueryUsersResponse()
..duration = json['duration'] as String
..users = (json['users'] as List)
?.map((e) => e == null
? null
: User.fromJson((e as Map)?.map(
(k, e) => MapEntry(k as String, e),
)))
?.toList();
}
QueryReactionsResponse _$QueryReactionsResponseFromJson(Map json) {
return QueryReactionsResponse()
..duration = json['duration'] as String
..reactions = (json['reactions'] as List)
?.map((e) => e == null
? null
: Reaction.fromJson((e as Map)?.map(
(k, e) => MapEntry(k as String, e),
)))
?.toList();
}
QueryRepliesResponse _$QueryRepliesResponseFromJson(Map json) {
return QueryRepliesResponse()
..duration = json['duration'] as String
..messages = (json['messages'] as List)
?.map((e) => e == null
? null
: Message.fromJson((e as Map)?.map(
(k, e) => MapEntry(k as String, e),
)))
?.toList();
}
ListDevicesResponse _$ListDevicesResponseFromJson(Map json) {
return ListDevicesResponse()
..duration = json['duration'] as String
..devices = (json['devices'] as List)
?.map((e) => e == null
? null
: Device.fromJson((e as Map)?.map(
(k, e) => MapEntry(k as String, e),
)))
?.toList();
}
SendFileResponse _$SendFileResponseFromJson(Map json) {
return SendFileResponse()
..duration = json['duration'] as String
..file = json['file'] as String;
}
SendImageResponse _$SendImageResponseFromJson(Map json) {
return SendImageResponse()
..duration = json['duration'] as String
..file = json['file'] as String;
}
SendReactionResponse _$SendReactionResponseFromJson(Map json) {
return SendReactionResponse()
..duration = json['duration'] as String
..message = json['message'] == null
? null
: Message.fromJson((json['message'] as Map)?.map(
(k, e) => MapEntry(k as String, e),
))
..reaction = json['reaction'] == null
? null
: Reaction.fromJson((json['reaction'] as Map)?.map(
(k, e) => MapEntry(k as String, e),
));
}
SetGuestUserResponse _$SetGuestUserResponseFromJson(Map json) {
return SetGuestUserResponse()
..duration = json['duration'] as String
..accessToken = json['access_token'] as String
..user = json['user'] == null
? null
: User.fromJson((json['user'] as Map)?.map(
(k, e) => MapEntry(k as String, e),
));
}
UpdateUsersResponse _$UpdateUsersResponseFromJson(Map json) {
return UpdateUsersResponse()
..duration = json['duration'] as String
..users = (json['users'] as Map)?.map(
(k, e) => MapEntry(
k as String,
e == null
? null
: User.fromJson((e as Map)?.map(
(k, e) => MapEntry(k as String, e),
))),
);
}
UpdateMessageResponse _$UpdateMessageResponseFromJson(Map json) {
return UpdateMessageResponse()
..duration = json['duration'] as String
..message = json['message'] == null
? null
: Message.fromJson((json['message'] as Map)?.map(
(k, e) => MapEntry(k as String, e),
));
}
SendMessageResponse _$SendMessageResponseFromJson(Map json) {
return SendMessageResponse()
..duration = json['duration'] as String
..message = json['message'] == null
? null
: Message.fromJson((json['message'] as Map)?.map(
(k, e) => MapEntry(k as String, e),
));
}
GetMessageResponse _$GetMessageResponseFromJson(Map json) {
return GetMessageResponse()
..duration = json['duration'] as String
..message = json['message'] == null
? null
: Message.fromJson((json['message'] as Map)?.map(
(k, e) => MapEntry(k as String, e),
))
..channel = json['channel'] == null
? null
: ChannelModel.fromJson((json['channel'] as Map)?.map(
(k, e) => MapEntry(k as String, e),
));
}
SearchMessagesResponse _$SearchMessagesResponseFromJson(Map json) {
return SearchMessagesResponse()
..duration = json['duration'] as String
..results = (json['results'] as List)
?.map((e) => e == null ? null : GetMessageResponse.fromJson(e as Map))
?.toList();
}
GetMessagesByIdResponse _$GetMessagesByIdResponseFromJson(Map json) {
return GetMessagesByIdResponse()
..duration = json['duration'] as String
..messages = (json['messages'] as List)
?.map((e) => e == null
? null
: Message.fromJson((e as Map)?.map(
(k, e) => MapEntry(k as String, e),
)))
?.toList();
}
UpdateChannelResponse _$UpdateChannelResponseFromJson(Map json) {
return UpdateChannelResponse()
..duration = json['duration'] as String
..channel = json['channel'] == null
? null
: ChannelModel.fromJson((json['channel'] as Map)?.map(
(k, e) => MapEntry(k as String, e),
))
..members = (json['members'] as List)
?.map((e) => e == null
? null
: Member.fromJson((e as Map)?.map(
(k, e) => MapEntry(k as String, e),
)))
?.toList()
..message = json['message'] == null
? null
: Message.fromJson((json['message'] as Map)?.map(
(k, e) => MapEntry(k as String, e),
));
}
InviteMembersResponse _$InviteMembersResponseFromJson(Map json) {
return InviteMembersResponse()
..duration = json['duration'] as String
..channel = json['channel'] == null
? null
: ChannelModel.fromJson((json['channel'] as Map)?.map(
(k, e) => MapEntry(k as String, e),
))
..members = (json['members'] as List)
?.map((e) => e == null
? null
: Member.fromJson((e as Map)?.map(
(k, e) => MapEntry(k as String, e),
)))
?.toList()
..message = json['message'] == null
? null
: Message.fromJson((json['message'] as Map)?.map(
(k, e) => MapEntry(k as String, e),
));
}
RemoveMembersResponse _$RemoveMembersResponseFromJson(Map json) {
return RemoveMembersResponse()
..duration = json['duration'] as String
..channel = json['channel'] == null
? null
: ChannelModel.fromJson((json['channel'] as Map)?.map(
(k, e) => MapEntry(k as String, e),
))
..members = (json['members'] as List)
?.map((e) => e == null
? null
: Member.fromJson((e as Map)?.map(
(k, e) => MapEntry(k as String, e),
)))
?.toList()
..message = json['message'] == null
? null
: Message.fromJson((json['message'] as Map)?.map(
(k, e) => MapEntry(k as String, e),
));
}
SendActionResponse _$SendActionResponseFromJson(Map json) {
return SendActionResponse()
..duration = json['duration'] as String
..message = json['message'] == null
? null
: Message.fromJson((json['message'] as Map)?.map(
(k, e) => MapEntry(k as String, e),
));
}
AddMembersResponse _$AddMembersResponseFromJson(Map json) {
return AddMembersResponse()
..duration = json['duration'] as String
..channel = json['channel'] == null
? null
: ChannelModel.fromJson((json['channel'] as Map)?.map(
(k, e) => MapEntry(k as String, e),
))
..members = (json['members'] as List)
?.map((e) => e == null
? null
: Member.fromJson((e as Map)?.map(
(k, e) => MapEntry(k as String, e),
)))
?.toList()
..message = json['message'] == null
? null
: Message.fromJson((json['message'] as Map)?.map(
(k, e) => MapEntry(k as String, e),
));
}
AcceptInviteResponse _$AcceptInviteResponseFromJson(Map json) {
return AcceptInviteResponse()
..duration = json['duration'] as String
..channel = json['channel'] == null
? null
: ChannelModel.fromJson((json['channel'] as Map)?.map(
(k, e) => MapEntry(k as String, e),
))
..members = (json['members'] as List)
?.map((e) => e == null
? null
: Member.fromJson((e as Map)?.map(
(k, e) => MapEntry(k as String, e),
)))
?.toList()
..message = json['message'] == null
? null
: Message.fromJson((json['message'] as Map)?.map(
(k, e) => MapEntry(k as String, e),
));
}
RejectInviteResponse _$RejectInviteResponseFromJson(Map json) {
return RejectInviteResponse()
..duration = json['duration'] as String
..channel = json['channel'] == null
? null
: ChannelModel.fromJson((json['channel'] as Map)?.map(
(k, e) => MapEntry(k as String, e),
))
..members = (json['members'] as List)
?.map((e) => e == null
? null
: Member.fromJson((e as Map)?.map(
(k, e) => MapEntry(k as String, e),
)))
?.toList()
..message = json['message'] == null
? null
: Message.fromJson((json['message'] as Map)?.map(
(k, e) => MapEntry(k as String, e),
));
}
EmptyResponse _$EmptyResponseFromJson(Map json) {
return EmptyResponse()..duration = json['duration'] as String;
}
ChannelStateResponse _$ChannelStateResponseFromJson(Map json) {
return ChannelStateResponse()
..duration = json['duration'] as String
..channel = json['channel'] == null
? null
: ChannelModel.fromJson((json['channel'] as Map)?.map(
(k, e) => MapEntry(k as String, e),
))
..messages = (json['messages'] as List)
?.map((e) => e == null
? null
: Message.fromJson((e as Map)?.map(
(k, e) => MapEntry(k as String, e),
)))
?.toList()
..members = (json['members'] as List)
?.map((e) => e == null
? null
: Member.fromJson((e as Map)?.map(
(k, e) => MapEntry(k as String, e),
)))
?.toList()
..watcherCount = json['watcher_count'] as int
..read = (json['read'] as List)
?.map((e) => e == null
? null
: Read.fromJson((e as Map)?.map(
(k, e) => MapEntry(k as String, e),
)))
?.toList();
}
@@ -0,0 +1,38 @@
import 'package:meta/meta.dart';
import 'package:stream_chat/src/client.dart';
import 'package:stream_chat/src/exceptions.dart';
/// The retry options
class RetryPolicy {
/// Instantiate a new RetryPolicy
RetryPolicy({
@required this.shouldRetry,
@required this.retryTimeout,
this.attempt,
});
/// The number of attempts tried so far
int attempt = 0;
/// This function evaluates if we should retry the failure
final bool Function(StreamChatClient client, int attempt, ApiError apiError)
shouldRetry;
/// In the case that we want to retry a failed request the retryTimeout method is called to determine the timeout
final Duration Function(
StreamChatClient client, int attempt, ApiError apiError) retryTimeout;
/// Creates a copy of [RetryPolicy] with specified attributes overridden.
RetryPolicy copyWith({
bool Function(StreamChatClient client, int attempt, ApiError apiError)
shouldRetry,
Duration Function(StreamChatClient client, int attempt, ApiError apiError)
retryTimeout,
int attempt,
}) =>
RetryPolicy(
retryTimeout: retryTimeout ?? this.retryTimeout,
shouldRetry: shouldRetry ?? this.shouldRetry,
attempt: attempt ?? this.attempt,
);
}
@@ -0,0 +1,201 @@
import 'dart:async';
import 'package:collection/collection.dart';
import 'package:meta/meta.dart';
import 'package:logging/logging.dart';
import 'package:stream_chat/src/api/channel.dart';
import 'package:stream_chat/src/api/retry_policy.dart';
import 'package:stream_chat/src/event_type.dart';
import 'package:stream_chat/src/exceptions.dart';
import 'package:stream_chat/src/models/message.dart';
import 'package:stream_chat/stream_chat.dart';
/// The retry queue associated to a channel
class RetryQueue {
/// The channel of this queue
final Channel channel;
/// The logger associated to this queue
final Logger logger;
/// Instantiate a new RetryQueue object
RetryQueue({
@required this.channel,
this.logger,
}) {
_retryPolicy = channel.client.retryPolicy;
_listenConnectionRecovered();
_listenFailedEvents();
}
final _subscriptions = <StreamSubscription>[];
void _listenConnectionRecovered() {
_subscriptions
.add(channel.client.on(EventType.connectionRecovered).listen((event) {
if (!_isRetrying && event.online) {
_startRetrying();
}
}));
}
final HeapPriorityQueue<Message> _messageQueue = HeapPriorityQueue(_byDate);
bool _isRetrying = false;
RetryPolicy _retryPolicy;
/// Add a list of messages
void add(List<Message> messages) {
final messageList = _messageQueue.toList();
_messageQueue.addAll(messages
.where((element) => !messageList.any((m) => m.id == element.id)));
if (_messageQueue.isNotEmpty && !_isRetrying) {
_startRetrying();
}
}
Future<void> _startRetrying() async {
logger?.info('start retrying');
_isRetrying = true;
final retryPolicy = _retryPolicy.copyWith(attempt: 0);
while (_messageQueue.isNotEmpty) {
final message = _messageQueue.first;
try {
logger?.info('retry attempt ${retryPolicy.attempt}');
await _sendMessage(message);
logger?.info('message sent - removing it from the queue');
_messageQueue.remove(message);
logger?.info('now ${_messageQueue.length} messages in the queue');
retryPolicy.attempt = 0;
} catch (error) {
ApiError apiError;
if (error is DioError) {
if (error.type == DioErrorType.RESPONSE) {
_messageQueue.remove(message);
return;
}
apiError = ApiError(
error.response?.data,
error.response?.statusCode,
);
} else if (error is ApiError) {
apiError = error;
if (apiError.status?.toString()?.startsWith('4') == true) {
_messageQueue.remove(message);
return;
}
}
if (!retryPolicy.shouldRetry(
channel.client,
retryPolicy.attempt,
apiError,
)) {
_messageQueue.toList().forEach(_sendFailedEvent);
_isRetrying = false;
return;
}
retryPolicy.attempt++;
final timeout = retryPolicy.retryTimeout(
channel.client,
retryPolicy.attempt,
apiError,
);
await Future.delayed(timeout);
}
}
_isRetrying = false;
}
void _sendFailedEvent(Message message) {
final newStatus = message.status == MessageSendingStatus.sending
? MessageSendingStatus.failed
: (message.status == MessageSendingStatus.updating
? MessageSendingStatus.failed_update
: MessageSendingStatus.failed_delete);
channel.state.addMessage(message.copyWith(
status: newStatus,
));
}
Future<void> _sendMessage(Message message) async {
if (message.status == MessageSendingStatus.failed_update ||
message.status == MessageSendingStatus.updating) {
await channel.client.updateMessage(
message,
channel.cid,
);
} else if (message.status == MessageSendingStatus.failed ||
message.status == MessageSendingStatus.sending) {
await channel.sendMessage(
message,
);
} else if (message.status == MessageSendingStatus.failed_delete ||
message.status == MessageSendingStatus.deleting) {
await channel.client.deleteMessage(
message,
channel.cid,
);
}
}
void _listenFailedEvents() {
_subscriptions.add(channel.on().listen((event) {
final messageList = _messageQueue.toList();
if (event.message != null) {
final messageIndex =
messageList.indexWhere((m) => m.id == event.message.id);
if (messageIndex == -1 &&
[
MessageSendingStatus.failed_update,
MessageSendingStatus.failed,
MessageSendingStatus.failed_delete,
].contains(event.message.status)) {
logger?.info('add message from events');
add([event.message]);
} else if (messageIndex != -1 &&
[
MessageSendingStatus.sent,
null,
].contains(event.message.status)) {
_messageQueue.remove(messageList[messageIndex]);
}
}
}));
}
/// Call this method to dispose this object
void dispose() {
_messageQueue.clear();
_subscriptions.forEach((s) => s.cancel());
}
static int _byDate(Message m1, Message m2) {
final date1 = _getMessageDate(m1);
final date2 = _getMessageDate(m2);
return date1.compareTo(date2);
}
static DateTime _getMessageDate(Message m1) {
switch (m1.status) {
case MessageSendingStatus.failed_delete:
case MessageSendingStatus.deleting:
return m1.deletedAt;
case MessageSendingStatus.failed:
case MessageSendingStatus.sending:
return m1.createdAt;
case MessageSendingStatus.failed_update:
case MessageSendingStatus.updating:
return m1.updatedAt;
default:
return null;
}
}
}
@@ -0,0 +1,7 @@
import 'package:web_socket_channel/html.dart';
import 'package:web_socket_channel/web_socket_channel.dart';
/// Html version of websocket implementation
/// Used in Flutter web version
WebSocketChannel connectWebSocket(String url, {Iterable<String> protocols}) =>
HtmlWebSocketChannel.connect(url, protocols: protocols);
@@ -0,0 +1,7 @@
import 'package:web_socket_channel/io.dart';
import 'package:web_socket_channel/web_socket_channel.dart';
/// IO version of websocket implementation
/// Used in Flutter mobile version
WebSocketChannel connectWebSocket(String url, {Iterable<String> protocols}) =>
IOWebSocketChannel.connect(url, protocols: protocols);
@@ -0,0 +1,9 @@
import 'package:web_socket_channel/web_socket_channel.dart';
/// Stub version of websocket implementation
/// Used just for conditional library import
WebSocketChannel connectWebSocket(String url,
{Iterable<String> protocols,
Map<String, dynamic> headers,
Duration pingInterval}) =>
throw UnimplementedError();
@@ -0,0 +1,316 @@
import 'dart:async';
import 'dart:convert';
import 'dart:math';
import 'package:meta/meta.dart';
import 'package:logging/logging.dart';
import 'package:rxdart/rxdart.dart';
import 'package:web_socket_channel/web_socket_channel.dart';
import '../models/event.dart';
import '../models/user.dart';
import 'connection_status.dart';
import 'web_socket_channel_stub.dart'
if (dart.library.html) 'web_socket_channel_html.dart'
if (dart.library.io) 'web_socket_channel_io.dart';
/// Typedef which exposes an [Event] as the only parameter.
typedef EventHandler = void Function(Event);
/// Typedef used for connecting to a websocket. Method returns a [WebSocketChannel]
/// and accepts a connection [url] and an optional [Iterable] of `protocols`.
typedef ConnectWebSocket = WebSocketChannel Function(String url,
{Iterable<String> protocols});
// TODO: parse error even
// TODO: if parsing an error into an event fails we should not hide the original error
/// A WebSocket connection that reconnects upon failure.
class WebSocket {
/// Creates a new websocket
/// To connect the WS call [connect]
WebSocket({
@required this.baseUrl,
this.user,
this.connectParams,
this.connectPayload,
this.handler,
this.logger,
this.connectFunc = connectWebSocket,
this.reconnectionMonitorInterval = 1,
this.healthCheckInterval = 20,
this.reconnectionMonitorTimeout = 40,
}) {
final qs = Map<String, String>.from(connectParams);
final data = Map<String, dynamic>.from(connectPayload);
data['user_details'] = user.toJson();
qs['json'] = json.encode(data);
if (baseUrl.startsWith('https')) {
_path = baseUrl.replaceFirst('https://', '');
_path = Uri.https(_path, 'connect', qs)
.toString()
.replaceFirst('https', 'wss');
} else if (baseUrl.startsWith('http')) {
_path = baseUrl.replaceFirst('http://', '');
_path =
Uri.http(_path, 'connect', qs).toString().replaceFirst('http', 'ws');
} else {
_path = Uri.https(baseUrl, 'connect', qs)
.toString()
.replaceFirst('https', 'wss');
}
}
/// WS base url
final String baseUrl;
/// User performing the WS connection
final User user;
/// Querystring connection parameters
final Map<String, String> connectParams;
/// WS connection payload
final Map<String, dynamic> connectPayload;
/// Functions that will be called every time a new event is received from the connection
final EventHandler handler;
/// A WS specific logger instance
final Logger logger;
/// Connection function
/// Used only for testing purpose
@visibleForTesting
final ConnectWebSocket connectFunc;
/// Interval of the reconnection monitor timer
/// This checks that it received a new event in the last [reconnectionMonitorTimeout] seconds,
/// otherwise it considers the connection unhealthy and reconnects the WS
final int reconnectionMonitorInterval;
/// Interval of the health event sending timer
/// This sends a health event every [healthCheckInterval] seconds in order to
/// make the server aware that the client is still listening
final int healthCheckInterval;
/// The timeout that uses the reconnection monitor timer to consider the connection unhealthy
final int reconnectionMonitorTimeout;
final _connectionStatusController =
BehaviorSubject.seeded(ConnectionStatus.disconnected);
set _connectionStatus(ConnectionStatus status) =>
_connectionStatusController.add(status);
/// The current connection status value
ConnectionStatus get connectionStatus => _connectionStatusController.value;
/// This notifies of connection status changes
Stream<ConnectionStatus> get connectionStatusStream =>
_connectionStatusController.stream;
String _path;
int _retryAttempt = 1;
WebSocketChannel _channel;
Timer _healthCheck, _reconnectionMonitor;
DateTime _lastEventAt;
bool _manuallyDisconnected = false,
_connecting = false,
_reconnecting = false;
Event _decodeEvent(String source) {
return Event.fromJson(json.decode(source));
}
Completer<Event> _connectionCompleter = Completer<Event>();
/// Connect the WS using the parameters passed in the constructor
Future<Event> connect() {
_manuallyDisconnected = false;
if (_connecting) {
logger.severe('already connecting');
return null;
}
_connecting = true;
_connectionStatus = ConnectionStatus.connecting;
logger.info('connecting to $_path');
_channel = connectFunc(_path);
_channel.stream.listen(
(data) {
final jsonData = json.decode(data);
if (jsonData['error'] != null) {
return _onConnectionError(jsonData['error']);
}
_onData(data);
},
onError: (error, stacktrace) {
_onConnectionError(error, stacktrace);
},
onDone: () {
_onDone();
},
);
return _connectionCompleter.future;
}
void _onDone() {
_connecting = false;
if (_manuallyDisconnected) {
return;
}
logger.info(
'connection closed | closeCode: ${_channel.closeCode} | closedReason: ${_channel.closeReason}');
if (!_reconnecting) {
_reconnect();
}
}
void _onData(data) {
final event = _decodeEvent(data);
logger.info('received new event: $data');
if (_lastEventAt == null) {
logger.info('connection estabilished');
_connecting = false;
_reconnecting = false;
_lastEventAt = DateTime.now();
_connectionStatus = ConnectionStatus.connected;
_retryAttempt = 1;
if (!_connectionCompleter.isCompleted) {
_connectionCompleter.complete(event);
}
_startReconnectionMonitor();
_startHealthCheck();
}
handler(event);
_lastEventAt = DateTime.now();
}
Future<void> _onConnectionError(error, [stacktrace]) async {
logger.severe('error connecting');
logger.severe(error);
if (stacktrace != null) {
logger.severe(stacktrace);
}
_connecting = false;
if (!_reconnecting) {
_connectionStatus = ConnectionStatus.disconnected;
}
if (!_connectionCompleter.isCompleted) {
_cancelTimers();
_connectionCompleter.completeError(error, stacktrace);
} else if (!_reconnecting) {
return _reconnect();
}
}
void _startReconnectionMonitor() {
final reconnectionTimer = (_) {
final now = DateTime.now();
if (_lastEventAt != null &&
now.difference(_lastEventAt).inSeconds > reconnectionMonitorTimeout) {
_channel.sink.close();
}
};
_reconnectionMonitor = Timer.periodic(
Duration(seconds: reconnectionMonitorInterval),
reconnectionTimer,
);
reconnectionTimer(_reconnectionMonitor);
}
void _reconnectTimer() async {
if (!_reconnecting) {
return;
}
if (_connecting) {
logger.info('already connecting');
return;
}
logger.info('reconnecting..');
_cancelTimers();
try {
await connect();
} catch (e) {
logger.log(Level.SEVERE, e.toString());
}
await Future.delayed(
Duration(seconds: min(_retryAttempt * 5, 25)),
() {
_reconnectTimer();
_retryAttempt++;
},
);
}
Future<void> _reconnect() async {
logger.info('reconnect');
if (!_reconnecting) {
_reconnecting = true;
_connectionStatus = ConnectionStatus.connecting;
}
_reconnectTimer();
}
void _cancelTimers() {
_lastEventAt = null;
if (_healthCheck != null) {
_healthCheck.cancel();
}
if (_reconnectionMonitor != null) {
_reconnectionMonitor.cancel();
}
}
void _startHealthCheck() {
logger.info('start health check monitor');
final healthCheckTimer = (_) {
logger.info('sending health.check');
_channel.sink.add("{'type': 'health.check'}");
};
_healthCheck = Timer.periodic(
Duration(seconds: healthCheckInterval),
healthCheckTimer,
);
healthCheckTimer(_healthCheck);
}
/// Disconnects the WS and releases eventual resources
Future<void> disconnect() async {
if (_manuallyDisconnected) {
return;
}
logger.info('disconnecting');
_connectionCompleter = Completer();
_cancelTimers();
_reconnecting = false;
_manuallyDisconnected = true;
_connectionStatus = ConnectionStatus.disconnected;
await _connectionStatusController.close();
return _channel.sink.close();
}
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,224 @@
import 'package:stream_chat/src/api/requests.dart';
import 'package:stream_chat/src/models/channel_model.dart';
import 'package:stream_chat/src/models/channel_state.dart';
import 'package:stream_chat/src/models/event.dart';
import 'package:stream_chat/src/models/member.dart';
import 'package:stream_chat/src/models/message.dart';
import 'package:stream_chat/src/models/reaction.dart';
import 'package:stream_chat/src/models/read.dart';
import 'package:stream_chat/src/models/user.dart';
/// A simple client used for persisting chat data locally.
abstract class ChatPersistenceClient {
/// Creates a new connection to the client
Future<void> connect(String userId);
/// Closes the client connection
/// If [flush] is true, the data will also be deleted
Future<void> disconnect({bool flush = false});
/// Get stored replies by messageId
Future<List<Message>> getReplies(
String parentId, {
PaginationParams options,
});
/// Get stored connection event
Future<Event> getConnectionInfo();
/// Get stored lastSyncAt
Future<DateTime> getLastSyncAt();
/// Update stored connection event
Future<void> updateConnectionInfo(Event event);
/// Update stored lastSyncAt
Future<void> updateLastSyncAt(DateTime lastSyncAt);
/// Get the channel cids saved in the offline storage
Future<List<String>> getChannelCids();
/// Get stored [ChannelModel]s by providing channel [cid]
Future<ChannelModel> getChannelByCid(String cid);
/// Get stored channel [Member]s by providing channel [cid]
Future<List<Member>> getMembersByCid(String cid);
/// Get stored channel [Read]s by providing channel [cid]
Future<List<Read>> getReadsByCid(String cid);
/// Get stored [Message]s by providing channel [cid]
///
/// Optionally, you can [messagePagination]
/// for filtering out messages
Future<List<Message>> getMessagesByCid(
String cid, {
PaginationParams messagePagination,
});
/// Get [ChannelState] data by providing channel [cid]
Future<ChannelState> getChannelStateByCid(
String cid, {
PaginationParams messagePagination,
}) async {
final members = await getMembersByCid(cid);
final reads = await getReadsByCid(cid);
final channel = await getChannelByCid(cid);
final messages = await getMessagesByCid(
cid,
messagePagination: messagePagination,
);
return ChannelState(
members: members,
read: reads,
messages: messages,
channel: channel,
);
}
/// Get all the stored [ChannelState]s
///
/// Optionally, pass [filter], [sort], [paginationParams]
/// for filtering out states.
Future<List<ChannelState>> getChannelStates({
Map<String, dynamic> filter,
List<SortOption> sort = const [],
PaginationParams paginationParams,
});
/// Update list of channel queries.
///
/// If [clearQueryCache] is true before the insert
/// the list of matching rows will be deleted
Future<void> updateChannelQueries(
Map<String, dynamic> filter,
List<String> cids,
bool clearQueryCache,
);
/// Remove a message by [messageId]
Future<void> deleteMessageById(String messageId) {
return deleteMessageByIds([messageId]);
}
/// Remove a message by [messageIds]
Future<void> deleteMessageByIds(List<String> messageIds);
/// Remove a message by channel [cid]
Future<void> deleteMessageByCid(String cid) {
return deleteMessageByCids([cid]);
}
/// Remove a message by message [cids]
Future<void> deleteMessageByCids(List<String> cids);
/// Remove a channel by [cid]
Future<void> deleteChannels(List<String> cids);
/// Updates the message data of a particular channel [cid] with
/// the new [messages] data
Future<void> updateMessages(String cid, List<Message> messages);
/// Returns all the threads by parent message of a particular channel by
/// providing channel [cid]
Future<Map<String, List<Message>>> getChannelThreads(String cid);
/// Updates all the channels using the new [channels] data.
Future<void> updateChannels(List<ChannelModel> channels);
/// Updates all the members of a particular channle [cid]
/// with the new [members] data
Future<void> updateMembers(String cid, List<Member> members);
/// Updates the read data of a particular channel [cid] with
/// the new [reads] data
Future<void> updateReads(String cid, List<Read> reads);
/// Updates the users data with the new [users] data
Future<void> updateUsers(List<User> users);
/// Updates the reactions data with the new [reactions] data
Future<void> updateReactions(List<Reaction> reactions);
/// Deletes all the reactions by [messageIds]
Future<void> deleteReactionsByMessageId(List<String> messageIds);
/// Deletes all the members by channel [cids]
Future<void> deleteMembersByCids(List<String> cids);
/// Update the channel state data using [channelState]
Future<void> updateChannelState(ChannelState channelState) {
return updateChannelStates([channelState]);
}
/// Update list of channel states
Future<void> updateChannelStates(List<ChannelState> channelStates) async {
final deleteReactions = deleteReactionsByMessageId(channelStates
.expand((it) => it.messages)
.map((m) => m.id)
.toList(growable: false));
final deleteMembers = deleteMembersByCids(
channelStates.map((it) => it.channel.cid).toList(growable: false),
);
await Future.wait([
deleteReactions,
deleteMembers,
]);
final channels = channelStates.map((it) {
return it.channel;
}).where((it) => it != null);
final reactions = channelStates.expand((it) => it.messages).expand((it) {
return [
...it.ownReactions.where((r) => r.userId != null),
...it.latestReactions.where((r) => r.userId != null)
];
}).where((it) => it != null);
final users = channelStates
.map((cs) => [
cs.channel?.createdBy,
...cs.messages?.map((m) {
return [
m.user,
...m.latestReactions?.map((r) => r.user),
...m.ownReactions?.map((r) => r.user),
];
})?.expand((v) => v),
...cs.read?.map((r) => r.user),
...cs.members?.map((m) => m.user),
])
.expand((it) => it)
.where((it) => it != null);
final updateMessagesFuture = channelStates.map((it) {
final cid = it.channel.cid;
final messages = it.messages.where((it) => it != null);
return updateMessages(cid, messages.toList(growable: false));
}).toList(growable: false);
final updateReadsFuture = channelStates.map((it) {
final cid = it.channel.cid;
final reads = it.read.where((it) => it != null);
return updateReads(cid, reads.toList(growable: false));
}).toList(growable: false);
final updateMembersFuture = channelStates.map((it) {
final cid = it.channel.cid;
final members = it.members.where((it) => it != null);
return updateMembers(cid, members.toList(growable: false));
}).toList(growable: false);
await Future.wait([
...updateMessagesFuture,
...updateReadsFuture,
...updateMembersFuture,
updateUsers(users.toList(growable: false)),
updateChannels(channels.toList(growable: false)),
updateReactions(reactions.toList(growable: false)),
]);
}
}
@@ -0,0 +1,94 @@
/// This class defines some basic event types
class EventType {
/// Indicates any type of events
static const String any = '*';
/// Event sent when a user starts typing a message
static const String typingStart = 'typing.start';
/// Event sent when a user stops typing a message
static const String typingStop = 'typing.stop';
/// Event sent when receiving a new message
static const String messageNew = 'message.new';
/// Event sent when receiving a new message
static const String notificationMessageNew = 'notification.message_new';
/// Event sent when the unread count changes
static const String notificationMarkRead = 'notification.mark_read';
/// Event sent when deleting a new message
static const String messageDeleted = 'message.deleted';
/// Event sent when receiving a new reaction
static const String reactionNew = 'reaction.new';
/// Event sent when deleting a reaction
static const String reactionDeleted = 'reaction.deleted';
/// Event sent when updating a reaction
static const String reactionUpdated = 'reaction.updated';
/// Event sent when updating a message
static const String messageUpdated = 'message.updated';
/// Event sent when reading a message
static const String messageRead = 'message.read';
/// Event sent when a channel is deleted
static const String channelDeleted = 'channel.deleted';
/// Event sent when a channel is deleted
static const String notificationChannelDeleted =
'notification.channel_deleted';
/// Event sent when a channel is truncated
static const String channelTruncated = 'channel.truncated';
/// Event sent when a channel is truncated
static const String notificationChannelTruncated =
'notification.channel_truncated';
/// Event sent when the user is added to a channel
static const String notificationAddedToChannel =
'notification.added_to_channel';
/// Event sent when the user is removed to a channel
static const String notificationRemovedFromChannel =
'notification.removed_from_channel';
/// Event sent when a channel is updated
static const String channelUpdated = 'channel.updated';
/// Event sent when a user is updated
static const String userUpdated = 'user.updated';
/// Event sent when a member is added to a channel
static const String memberAdded = 'member.added';
/// Event sent when a member is removed to a channel
static const String memberRemoved = 'member.removed';
/// Event sent when a channel is hidden
static const String channelHidden = 'channel.hidden';
/// Event sent when a channel is visible
static const String channelVisible = 'channel.visible';
/// Event sent when the connection status changes
static const String connectionChanged = 'connection.changed';
/// Event sent when the connection is recovered
static const String connectionRecovered = 'connection.recovered';
/// Event sent when the user is accepts an invite
static const String notificationInviteAccepted =
'notification.invite_accepted';
/// Event sent when the user is invited
static const String notificationInvited = 'notification.invited';
/// Event sent when the user's mutes list is updated
static const String notificationMutesUpdated = 'notification.mutes_updated';
}
@@ -0,0 +1,54 @@
import 'dart:convert';
/// Exception related to api calls
class ApiError extends Error {
/// Raw body of the response
final String body;
/// Json parsed body
final Map<String, dynamic> jsonData;
/// Http status code of the response
final int status;
/// Stream specific error code
int get code => _code;
int _code;
static Map<String, dynamic> _decode(String body) {
try {
if (body == null) {
return null;
}
return json.decode(body);
} on FormatException {
return null;
}
}
/// Creates a new ApiError instance using the response body and status code
ApiError(this.body, this.status) : jsonData = _decode(body) {
if (jsonData != null && jsonData.containsKey('code')) {
_code = jsonData['code'];
}
}
@override
bool operator ==(Object other) =>
identical(this, other) ||
other is ApiError &&
runtimeType == other.runtimeType &&
body == other.body &&
jsonData == other.jsonData &&
status == other.status &&
_code == other._code;
@override
int get hashCode =>
body.hashCode ^ jsonData.hashCode ^ status.hashCode ^ _code.hashCode;
@override
String toString() {
return 'ApiError{body: $body, jsonData: $jsonData, status: $status, code: $_code}';
}
}
@@ -0,0 +1,31 @@
import 'package:json_annotation/json_annotation.dart';
part 'action.g.dart';
/// The class that contains the information about an action
@JsonSerializable()
class Action {
/// The name of the action
final String name;
/// The style of the action
final String style;
/// The test of the action
final String text;
/// The type of the action
final String type;
/// 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);
}
@@ -0,0 +1,25 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'action.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
Action _$ActionFromJson(Map json) {
return Action(
name: json['name'] as String,
style: json['style'] as String,
text: json['text'] as String,
type: json['type'] as String,
value: json['value'] as String,
);
}
Map<String, dynamic> _$ActionToJson(Action instance) => <String, dynamic>{
'name': instance.name,
'style': instance.style,
'text': instance.text,
'type': instance.type,
'value': instance.value,
};
@@ -0,0 +1,207 @@
// ignore_for_file: public_member_api_docs
import 'package:json_annotation/json_annotation.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
final String type;
///The link to which the attachment message points to.
final String titleLink;
/// The attachment title
final String title;
/// 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.
final String text;
/// Optional text that appears above the attachment block
final String pretext;
/// 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)
final String imageUrl;
final String footerIcon;
final String footer;
final dynamic fields;
final String fallback;
final String color;
/// The name of the author.
final String authorName;
final String authorLink;
final String authorIcon;
/// The URL to the audio, video or image related to the URL.
final String assetUrl;
/// Actions from a command
final List<Action> actions;
final Uri localUri;
/// Map of custom channel extraData
@JsonKey(includeIfNull: false)
final Map<String, dynamic> extraData;
/// Known top level fields.
/// Useful for [Serialization] methods.
static const topLevelFields = [
'type',
'title_link',
'title',
'thumb_url',
'text',
'pretext',
'og_scrape_url',
'image_url',
'footer_icon',
'footer',
'fields',
'fallback',
'color',
'author_name',
'author_link',
'author_icon',
'asset_url',
'actions',
];
/// Constructor used for json serialization
Attachment({
this.type,
this.titleLink,
this.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.localUri,
});
/// 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);
Attachment copyWith({
String type,
String titleLink,
String title,
String thumbUrl,
String text,
String pretext,
String ogScrapeUrl,
String imageUrl,
String footerIcon,
String footer,
dynamic fields,
String fallback,
String color,
String authorName,
String authorLink,
String authorIcon,
String assetUrl,
List<Action> actions,
Uri localUri,
Map<String, dynamic> extraData,
}) =>
Attachment(
type: type ?? this.type,
titleLink: titleLink ?? this.titleLink,
title: title ?? this.title,
thumbUrl: thumbUrl ?? this.thumbUrl,
text: text ?? this.text,
pretext: pretext ?? this.pretext,
ogScrapeUrl: ogScrapeUrl ?? this.ogScrapeUrl,
imageUrl: imageUrl ?? this.imageUrl,
footerIcon: footerIcon ?? this.footerIcon,
footer: footer ?? this.footer,
fields: fields ?? this.fields,
fallback: fallback ?? this.fallback,
color: color ?? this.color,
authorName: authorName ?? this.authorName,
authorLink: authorLink ?? this.authorLink,
authorIcon: authorIcon ?? this.authorIcon,
assetUrl: assetUrl ?? this.assetUrl,
actions: actions ?? this.actions,
localUri: localUri ?? this.localUri,
extraData: extraData ?? this.extraData,
);
@override
bool operator ==(Object other) =>
identical(this, other) ||
other is Attachment &&
runtimeType == other.runtimeType &&
type == other.type &&
titleLink == other.titleLink &&
title == other.title &&
thumbUrl == other.thumbUrl &&
text == other.text &&
pretext == other.pretext &&
ogScrapeUrl == other.ogScrapeUrl &&
imageUrl == other.imageUrl &&
footerIcon == other.footerIcon &&
footer == other.footer &&
fields == other.fields &&
fallback == other.fallback &&
color == other.color &&
authorName == other.authorName &&
authorLink == other.authorLink &&
authorIcon == other.authorIcon &&
assetUrl == other.assetUrl &&
actions == other.actions &&
extraData == other.extraData;
@override
int get hashCode =>
type.hashCode ^
titleLink.hashCode ^
title.hashCode ^
thumbUrl.hashCode ^
text.hashCode ^
pretext.hashCode ^
ogScrapeUrl.hashCode ^
imageUrl.hashCode ^
footerIcon.hashCode ^
footer.hashCode ^
fields.hashCode ^
fallback.hashCode ^
color.hashCode ^
authorName.hashCode ^
authorLink.hashCode ^
authorIcon.hashCode ^
assetUrl.hashCode ^
actions.hashCode ^
extraData.hashCode;
}
@@ -0,0 +1,74 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'attachment.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
Attachment _$AttachmentFromJson(Map json) {
return Attachment(
type: json['type'] as String,
titleLink: json['title_link'] as String,
title: json['title'] as String,
thumbUrl: json['thumb_url'] as String,
text: json['text'] as String,
pretext: json['pretext'] as String,
ogScrapeUrl: json['og_scrape_url'] as String,
imageUrl: json['image_url'] as String,
footerIcon: json['footer_icon'] as String,
footer: json['footer'] as String,
fields: json['fields'],
fallback: json['fallback'] as String,
color: json['color'] as String,
authorName: json['author_name'] as String,
authorLink: json['author_link'] as String,
authorIcon: json['author_icon'] as String,
assetUrl: json['asset_url'] as String,
actions: (json['actions'] as List)
?.map((e) => e == null
? null
: Action.fromJson((e as Map)?.map(
(k, e) => MapEntry(k as String, e),
)))
?.toList(),
extraData: (json['extra_data'] as Map)?.map(
(k, e) => MapEntry(k as String, e),
),
localUri: json['local_uri'] == null
? null
: Uri.parse(json['local_uri'] as String),
);
}
Map<String, dynamic> _$AttachmentToJson(Attachment instance) {
final val = <String, dynamic>{};
void writeNotNull(String key, dynamic value) {
if (value != null) {
val[key] = value;
}
}
writeNotNull('type', instance.type);
writeNotNull('title_link', instance.titleLink);
writeNotNull('title', instance.title);
writeNotNull('thumb_url', instance.thumbUrl);
writeNotNull('text', instance.text);
writeNotNull('pretext', instance.pretext);
writeNotNull('og_scrape_url', instance.ogScrapeUrl);
writeNotNull('image_url', instance.imageUrl);
writeNotNull('footer_icon', instance.footerIcon);
writeNotNull('footer', instance.footer);
writeNotNull('fields', instance.fields);
writeNotNull('fallback', instance.fallback);
writeNotNull('color', instance.color);
writeNotNull('author_name', instance.authorName);
writeNotNull('author_link', instance.authorLink);
writeNotNull('author_icon', instance.authorIcon);
writeNotNull('asset_url', instance.assetUrl);
writeNotNull('actions', instance.actions?.map((e) => e?.toJson())?.toList());
writeNotNull('local_uri', instance.localUri?.toString());
writeNotNull('extra_data', instance.extraData);
return val;
}
@@ -0,0 +1,84 @@
import 'package:json_annotation/json_annotation.dart';
import 'command.dart';
part 'channel_config.g.dart';
/// The class that contains the information about the configuration of a channel
@JsonSerializable()
class ChannelConfig {
/// Moderation configuration
final String automod;
/// List of available commands
final List<Command> commands;
/// True if the channel should send connect events
final bool connectEvents;
/// Date of channel creation
final DateTime createdAt;
/// Date of last channel update
final DateTime updatedAt;
/// Max channel message length
final int maxMessageLength;
/// Duration of message retention
final String messageRetention;
/// True if users can be muted
final bool mutes;
/// Name of the channel
final String name;
/// True if reaction are active for this channel
final bool reactions;
/// True if readEvents are active for this channel
final bool readEvents;
/// True if reply message are active for this channel
final bool replies;
/// True if it's possible to perform a search in this channel
final bool search;
/// True if typing events should be sent for this channel
final bool typingEvents;
/// True if it's possible to upload files to this channel
final bool uploads;
/// 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);
}
@@ -0,0 +1,58 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'channel_config.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
ChannelConfig _$ChannelConfigFromJson(Map json) {
return ChannelConfig(
automod: json['automod'] as String,
commands: (json['commands'] as List)
?.map((e) => e == null
? null
: Command.fromJson((e as Map)?.map(
(k, e) => MapEntry(k as String, e),
)))
?.toList(),
connectEvents: json['connect_events'] as bool,
createdAt: json['created_at'] == null
? null
: DateTime.parse(json['created_at'] as String),
updatedAt: json['updated_at'] == null
? null
: DateTime.parse(json['updated_at'] as String),
maxMessageLength: json['max_message_length'] as int,
messageRetention: json['message_retention'] as String,
mutes: json['mutes'] as bool,
name: json['name'] as String,
reactions: json['reactions'] as bool,
readEvents: json['read_events'] as bool,
replies: json['replies'] as bool,
search: json['search'] as bool,
typingEvents: json['typing_events'] as bool,
uploads: json['uploads'] as bool,
urlEnrichment: json['url_enrichment'] as bool,
);
}
Map<String, dynamic> _$ChannelConfigToJson(ChannelConfig instance) =>
<String, dynamic>{
'automod': instance.automod,
'commands': instance.commands?.map((e) => e?.toJson())?.toList(),
'connect_events': instance.connectEvents,
'created_at': instance.createdAt?.toIso8601String(),
'updated_at': instance.updatedAt?.toIso8601String(),
'max_message_length': instance.maxMessageLength,
'message_retention': instance.messageRetention,
'mutes': instance.mutes,
'name': instance.name,
'reactions': instance.reactions,
'read_events': instance.readEvents,
'replies': instance.replies,
'search': instance.search,
'typing_events': instance.typingEvents,
'uploads': instance.uploads,
'url_enrichment': instance.urlEnrichment,
};
@@ -0,0 +1,166 @@
import 'package:json_annotation/json_annotation.dart';
import 'channel_config.dart';
import 'serialization.dart';
import 'user.dart';
part 'channel_model.g.dart';
/// The class that contains the information about a channel
@JsonSerializable()
class ChannelModel {
/// The id of this channel
final String id;
/// The type of this channel
final String type;
/// The cid of this channel
@JsonKey(includeIfNull: false, toJson: Serialization.readOnly)
final String cid;
/// The channel configuration data
@JsonKey(includeIfNull: false, toJson: Serialization.readOnly)
final ChannelConfig config;
/// The user that created this channel
@JsonKey(includeIfNull: false, toJson: Serialization.readOnly)
final User createdBy;
/// True if this channel is frozen
@JsonKey(includeIfNull: false)
final bool frozen;
/// The date of the last message
@JsonKey(includeIfNull: false, toJson: Serialization.readOnly)
final DateTime lastMessageAt;
/// The date of channel creation
@JsonKey(includeIfNull: false, toJson: Serialization.readOnly)
final DateTime createdAt;
/// The date of the last channel update
@JsonKey(includeIfNull: false, toJson: Serialization.readOnly)
final DateTime updatedAt;
/// The date of channel deletion
@JsonKey(includeIfNull: false, toJson: Serialization.readOnly)
final DateTime deletedAt;
/// The count of this channel members
@JsonKey(includeIfNull: false, toJson: Serialization.readOnly)
final int memberCount;
/// Map of custom channel extraData
@JsonKey(includeIfNull: false)
final Map<String, dynamic> extraData;
/// The team the channel belongs to
@JsonKey(includeIfNull: false, toJson: Serialization.readOnly)
final String team;
/// Known top level fields.
/// Useful for [Serialization] methods.
static const topLevelFields = [
'id',
'type',
'cid',
'config',
'created_by',
'frozen',
'last_message_at',
'created_at',
'updated_at',
'deleted_at',
'member_count',
'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,
);
}
/// Creates a copy of [ChannelModel] with specified attributes overridden.
ChannelModel copyWith({
String id,
String type,
String cid,
ChannelConfig config,
User createdBy,
bool frozen,
DateTime lastMessageAt,
DateTime createdAt,
DateTime updatedAt,
DateTime deletedAt,
int memberCount,
Map<String, dynamic> extraData,
String team,
}) =>
ChannelModel(
id: id ?? this.id,
type: type ?? this.type,
cid: cid ?? this.cid,
config: config ?? this.config,
createdBy: createdBy ?? this.createdBy,
frozen: frozen ?? this.frozen,
lastMessageAt: lastMessageAt ?? this.lastMessageAt,
createdAt: createdAt ?? this.createdAt,
updatedAt: updatedAt ?? this.updatedAt,
deletedAt: deletedAt ?? this.deletedAt,
memberCount: memberCount ?? this.memberCount,
extraData: extraData ?? this.extraData,
team: team ?? this.team,
);
/// 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(
id: other.id,
type: other.type,
cid: other.cid,
config: other.config,
createdBy: other.createdBy,
frozen: other.frozen,
lastMessageAt: other.lastMessageAt,
createdAt: other.createdAt,
updatedAt: other.updatedAt,
deletedAt: other.deletedAt,
memberCount: other.memberCount,
extraData: other.extraData,
team: other.team,
);
}
}
@@ -0,0 +1,69 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'channel_model.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
ChannelModel _$ChannelModelFromJson(Map json) {
return ChannelModel(
id: json['id'] as String,
type: json['type'] as String,
cid: json['cid'] as String,
config: json['config'] == null
? null
: ChannelConfig.fromJson((json['config'] as Map)?.map(
(k, e) => MapEntry(k as String, e),
)),
createdBy: json['created_by'] == null
? null
: User.fromJson((json['created_by'] as Map)?.map(
(k, e) => MapEntry(k as String, e),
)),
frozen: json['frozen'] as bool,
lastMessageAt: json['last_message_at'] == null
? null
: DateTime.parse(json['last_message_at'] as String),
createdAt: json['created_at'] == null
? null
: DateTime.parse(json['created_at'] as String),
updatedAt: json['updated_at'] == null
? null
: DateTime.parse(json['updated_at'] as String),
deletedAt: json['deleted_at'] == null
? null
: DateTime.parse(json['deleted_at'] as String),
memberCount: json['member_count'] as int,
extraData: (json['extra_data'] as Map)?.map(
(k, e) => MapEntry(k as String, e),
),
team: json['team'] as String,
);
}
Map<String, dynamic> _$ChannelModelToJson(ChannelModel instance) {
final val = <String, dynamic>{
'id': instance.id,
'type': instance.type,
};
void writeNotNull(String key, dynamic value) {
if (value != null) {
val[key] = value;
}
}
writeNotNull('cid', readonly(instance.cid));
writeNotNull('config', readonly(instance.config));
writeNotNull('created_by', readonly(instance.createdBy));
writeNotNull('frozen', instance.frozen);
writeNotNull('last_message_at', readonly(instance.lastMessageAt));
writeNotNull('created_at', readonly(instance.createdAt));
writeNotNull('updated_at', readonly(instance.updatedAt));
writeNotNull('deleted_at', readonly(instance.deletedAt));
writeNotNull('member_count', readonly(instance.memberCount));
writeNotNull('extra_data', instance.extraData);
writeNotNull('team', readonly(instance.team));
return val;
}
@@ -0,0 +1,66 @@
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';
part 'channel_state.g.dart';
/// The class that contains the information about a command
@JsonSerializable()
class ChannelState {
/// The channel to which this state belongs
final ChannelModel channel;
/// A paginated list of channel messages
final List<Message> messages;
/// A paginated list of channel members
final List<Member> members;
/// The count of users watching the channel
final int watcherCount;
/// A paginated list of users watching the channel
final List<User> watchers;
/// The list of channel reads
final List<Read> read;
/// Constructor used for json serialization
ChannelState({
this.channel,
this.messages = const [],
this.members = 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);
/// Serialize to json
Map<String, dynamic> toJson() => _$ChannelStateToJson(this);
/// Creates a copy of [ChannelState] with specified attributes overridden.
ChannelState copyWith({
ChannelModel channel,
List<Message> messages,
List<Member> members,
int watcherCount,
List<User> watchers,
List<Read> read,
}) =>
ChannelState(
channel: channel ?? this.channel,
messages: messages ?? this.messages,
members: members ?? this.members,
watcherCount: watcherCount ?? this.watcherCount,
watchers: watchers ?? this.watchers,
read: read ?? this.read,
);
}
@@ -0,0 +1,56 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'channel_state.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
ChannelState _$ChannelStateFromJson(Map json) {
return ChannelState(
channel: json['channel'] == null
? null
: ChannelModel.fromJson((json['channel'] as Map)?.map(
(k, e) => MapEntry(k as String, e),
)),
messages: (json['messages'] as List)
?.map((e) => e == null
? null
: Message.fromJson((e as Map)?.map(
(k, e) => MapEntry(k as String, e),
)))
?.toList(),
members: (json['members'] as List)
?.map((e) => e == null
? null
: Member.fromJson((e as Map)?.map(
(k, e) => MapEntry(k as String, e),
)))
?.toList(),
watcherCount: json['watcher_count'] as int,
watchers: (json['watchers'] as List)
?.map((e) => e == null
? null
: User.fromJson((e as Map)?.map(
(k, e) => MapEntry(k as String, e),
)))
?.toList(),
read: (json['read'] as List)
?.map((e) => e == null
? null
: Read.fromJson((e as Map)?.map(
(k, e) => MapEntry(k as String, e),
)))
?.toList(),
);
}
Map<String, dynamic> _$ChannelStateToJson(ChannelState instance) =>
<String, dynamic>{
'channel': instance.channel?.toJson(),
'messages': instance.messages?.map((e) => e?.toJson())?.toList(),
'members': instance.members?.map((e) => e?.toJson())?.toList(),
'watcher_count': instance.watcherCount,
'watchers': instance.watchers?.map((e) => e?.toJson())?.toList(),
'read': instance.read?.map((e) => e?.toJson())?.toList(),
};
@@ -0,0 +1,30 @@
import 'package:json_annotation/json_annotation.dart';
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,
this.description,
this.args,
});
/// Create a new instance from a json
factory Command.fromJson(Map<String, dynamic> json) =>
_$CommandFromJson(json);
/// Serialize to json
Map<String, dynamic> toJson() => _$CommandToJson(this);
}
@@ -0,0 +1,21 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'command.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
Command _$CommandFromJson(Map json) {
return Command(
name: json['name'] as String,
description: json['description'] as String,
args: json['args'] as String,
);
}
Map<String, dynamic> _$CommandToJson(Command instance) => <String, dynamic>{
'name': instance.name,
'description': instance.description,
'args': instance.args,
};
@@ -0,0 +1,25 @@
import 'package:json_annotation/json_annotation.dart';
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,
this.pushProvider,
});
/// Create a new instance from a json
factory Device.fromJson(Map<String, dynamic> json) => _$DeviceFromJson(json);
/// Serialize to json
Map<String, dynamic> toJson() => _$DeviceToJson(this);
}
@@ -0,0 +1,19 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'device.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
Device _$DeviceFromJson(Map json) {
return Device(
id: json['id'] as String,
pushProvider: json['push_provider'] as String,
);
}
Map<String, dynamic> _$DeviceToJson(Device instance) => <String, dynamic>{
'id': instance.id,
'push_provider': instance.pushProvider,
};
@@ -0,0 +1,183 @@
import 'package:json_annotation/json_annotation.dart';
import 'package:stream_chat/src/models/channel_model.dart';
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 {
/// The type of the event
/// [EventType] contains some predefined constant types
final String type;
/// The channel cid to which the event belongs
final String cid;
/// The channel id to which the event belongs
final String channelId;
/// The channel type to which the event belongs
final String channelType;
/// The connection id in which the event has been sent
final String connectionId;
/// The date of creation of the event
final DateTime createdAt;
/// User object of the health check user
final OwnUser me;
/// User object of the current user
final User user;
/// The message sent with the event
final Message message;
/// The channel sent with the event
final EventChannel channel;
/// The member sent with the event
final Member member;
/// The reaction sent with the event
final Reaction reaction;
/// The number of unread messages for current user
final int totalUnreadCount;
/// User total unread channels
final int unreadChannels;
/// Online status
final bool online;
/// The id of the parent message of a thread
final String parentId;
/// True if the event is generated by this client
bool isLocal;
/// Map of custom channel extraData
@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 = [
'type',
'cid',
'connection_id',
'created_at',
'me',
'user',
'message',
'total_unread_count',
'unread_channels',
'reaction',
'online',
'channel',
'member',
'channel_id',
'channel_type',
'parent_id',
'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),
topLevelFields,
);
}
/// 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,
String id,
String type,
String cid,
ChannelConfig config,
User createdBy,
bool frozen,
DateTime lastMessageAt,
DateTime createdAt,
DateTime updatedAt,
DateTime deletedAt,
int memberCount,
Map<String, dynamic> extraData,
}) : super(
id: id,
type: type,
cid: cid,
config: config,
createdBy: createdBy,
frozen: frozen,
lastMessageAt: lastMessageAt,
createdAt: createdAt,
updatedAt: updatedAt,
deletedAt: deletedAt,
memberCount: memberCount,
extraData: extraData,
);
/// Create a new instance from a json
factory EventChannel.fromJson(Map<String, dynamic> json) {
return _$EventChannelFromJson(Serialization.moveToExtraDataFromRoot(
json,
topLevelFields,
));
}
}
@@ -0,0 +1,156 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'event.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
Event _$EventFromJson(Map json) {
return Event(
type: json['type'] as String,
cid: json['cid'] as String,
connectionId: json['connection_id'] as String,
createdAt: json['created_at'] == null
? null
: DateTime.parse(json['created_at'] as String),
me: json['me'] == null
? null
: OwnUser.fromJson((json['me'] as Map)?.map(
(k, e) => MapEntry(k as String, e),
)),
user: json['user'] == null
? null
: User.fromJson((json['user'] as Map)?.map(
(k, e) => MapEntry(k as String, e),
)),
message: json['message'] == null
? null
: Message.fromJson((json['message'] as Map)?.map(
(k, e) => MapEntry(k as String, e),
)),
totalUnreadCount: json['total_unread_count'] as int,
unreadChannels: json['unread_channels'] as int,
reaction: json['reaction'] == null
? null
: Reaction.fromJson((json['reaction'] as Map)?.map(
(k, e) => MapEntry(k as String, e),
)),
online: json['online'] as bool,
channel: json['channel'] == null
? null
: EventChannel.fromJson((json['channel'] as Map)?.map(
(k, e) => MapEntry(k as String, e),
)),
member: json['member'] == null
? null
: Member.fromJson((json['member'] as Map)?.map(
(k, e) => MapEntry(k as String, e),
)),
channelId: json['channel_id'] as String,
channelType: json['channel_type'] as String,
parentId: json['parent_id'] as String,
extraData: (json['extra_data'] as Map)?.map(
(k, e) => MapEntry(k as String, e),
),
)..isLocal = json['is_local'] as bool;
}
Map<String, dynamic> _$EventToJson(Event instance) {
final val = <String, dynamic>{
'type': instance.type,
'cid': instance.cid,
'channel_id': instance.channelId,
'channel_type': instance.channelType,
'connection_id': instance.connectionId,
'created_at': instance.createdAt?.toIso8601String(),
'me': instance.me?.toJson(),
'user': instance.user?.toJson(),
'message': instance.message?.toJson(),
'channel': instance.channel?.toJson(),
'member': instance.member?.toJson(),
'reaction': instance.reaction?.toJson(),
'total_unread_count': instance.totalUnreadCount,
'unread_channels': instance.unreadChannels,
'online': instance.online,
'parent_id': instance.parentId,
'is_local': instance.isLocal,
};
void writeNotNull(String key, dynamic value) {
if (value != null) {
val[key] = value;
}
}
writeNotNull('extra_data', instance.extraData);
return val;
}
EventChannel _$EventChannelFromJson(Map json) {
return EventChannel(
members: (json['members'] as List)
?.map((e) => e == null
? null
: Member.fromJson((e as Map)?.map(
(k, e) => MapEntry(k as String, e),
)))
?.toList(),
id: json['id'] as String,
type: json['type'] as String,
cid: json['cid'] as String,
config: json['config'] == null
? null
: ChannelConfig.fromJson((json['config'] as Map)?.map(
(k, e) => MapEntry(k as String, e),
)),
createdBy: json['created_by'] == null
? null
: User.fromJson((json['created_by'] as Map)?.map(
(k, e) => MapEntry(k as String, e),
)),
frozen: json['frozen'] as bool,
lastMessageAt: json['last_message_at'] == null
? null
: DateTime.parse(json['last_message_at'] as String),
createdAt: json['created_at'] == null
? null
: DateTime.parse(json['created_at'] as String),
updatedAt: json['updated_at'] == null
? null
: DateTime.parse(json['updated_at'] as String),
deletedAt: json['deleted_at'] == null
? null
: DateTime.parse(json['deleted_at'] as String),
memberCount: json['member_count'] as int,
extraData: (json['extra_data'] as Map)?.map(
(k, e) => MapEntry(k as String, e),
),
);
}
Map<String, dynamic> _$EventChannelToJson(EventChannel instance) {
final val = <String, dynamic>{
'id': instance.id,
'type': instance.type,
};
void writeNotNull(String key, dynamic value) {
if (value != null) {
val[key] = value;
}
}
writeNotNull('cid', readonly(instance.cid));
writeNotNull('config', readonly(instance.config));
writeNotNull('created_by', readonly(instance.createdBy));
writeNotNull('frozen', instance.frozen);
writeNotNull('last_message_at', readonly(instance.lastMessageAt));
writeNotNull('created_at', readonly(instance.createdAt));
writeNotNull('updated_at', readonly(instance.updatedAt));
writeNotNull('deleted_at', readonly(instance.deletedAt));
writeNotNull('member_count', readonly(instance.memberCount));
writeNotNull('extra_data', instance.extraData);
val['members'] = instance.members?.map((e) => e?.toJson())?.toList();
return val;
}
@@ -0,0 +1,96 @@
import 'package:json_annotation/json_annotation.dart';
import '../models/user.dart';
part 'member.g.dart';
/// The class that contains the information about the user membership in a channel
@JsonSerializable()
class Member {
/// The interested user
final User user;
/// The date in which the user accepted the invite to the channel
final DateTime inviteAcceptedAt;
/// The date in which the user rejected the invite to the channel
final DateTime inviteRejectedAt;
/// True if the user has been invited to the channel
final bool invited;
/// The role of the user in the channel
final String role;
/// The id of the interested user
final String userId;
/// True if the user is a moderator of the channel
final bool isModerator;
/// True if the member is banned from the channel
final bool banned;
/// True if the member is shadow banned from the channel
final bool shadowBanned;
/// The date of creation
final DateTime createdAt;
/// 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,
DateTime inviteAcceptedAt,
DateTime inviteRejectedAt,
bool invited,
String role,
String userId,
bool isModerator,
DateTime createdAt,
DateTime updatedAt,
bool banned,
bool shadowBanned,
}) =>
Member(
user: user ?? this.user,
inviteAcceptedAt: inviteAcceptedAt ?? this.inviteAcceptedAt,
inviteRejectedAt: inviteRejectedAt ?? this.inviteRejectedAt,
invited: invited ?? this.invited,
banned: banned ?? this.banned,
shadowBanned: shadowBanned ?? this.shadowBanned,
role: role ?? this.role,
userId: userId ?? this.userId,
isModerator: isModerator ?? this.isModerator,
createdAt: createdAt ?? this.createdAt,
updatedAt: updatedAt ?? this.updatedAt,
);
/// Serialize to json
Map<String, dynamic> toJson() => _$MemberToJson(this);
}
@@ -0,0 +1,49 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'member.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
Member _$MemberFromJson(Map json) {
return Member(
user: json['user'] == null
? null
: User.fromJson((json['user'] as Map)?.map(
(k, e) => MapEntry(k as String, e),
)),
inviteAcceptedAt: json['invite_accepted_at'] == null
? null
: DateTime.parse(json['invite_accepted_at'] as String),
inviteRejectedAt: json['invite_rejected_at'] == null
? null
: DateTime.parse(json['invite_rejected_at'] as String),
invited: json['invited'] as bool,
role: json['role'] as String,
userId: json['user_id'] as String,
isModerator: json['is_moderator'] as bool,
createdAt: json['created_at'] == null
? null
: DateTime.parse(json['created_at'] as String),
updatedAt: json['updated_at'] == null
? null
: DateTime.parse(json['updated_at'] as String),
banned: json['banned'] as bool,
shadowBanned: json['shadow_banned'] as bool,
);
}
Map<String, dynamic> _$MemberToJson(Member instance) => <String, dynamic>{
'user': instance.user?.toJson(),
'invite_accepted_at': instance.inviteAcceptedAt?.toIso8601String(),
'invite_rejected_at': instance.inviteRejectedAt?.toIso8601String(),
'invited': instance.invited,
'role': instance.role,
'user_id': instance.userId,
'is_moderator': instance.isModerator,
'banned': instance.banned,
'shadow_banned': instance.shadowBanned,
'created_at': instance.createdAt?.toIso8601String(),
'updated_at': instance.updatedAt?.toIso8601String(),
};
@@ -0,0 +1,310 @@
import 'package:json_annotation/json_annotation.dart';
import 'attachment.dart';
import 'reaction.dart';
import 'serialization.dart';
import 'user.dart';
part 'message.g.dart';
/// Enum defining the status of a sending message
enum MessageSendingStatus {
/// Message is being sent
sending,
/// Message is being updated
updating,
/// Message is being deleted
deleting,
/// Message failed to send
failed,
/// Message failed to updated
failed_update,
/// Message failed to delete
failed_delete,
/// Message correctly sent
sent,
}
/// 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.
final String id;
/// The text of this message
final String text;
/// The status of a sending message
@JsonKey(ignore: true)
final MessageSendingStatus status;
/// The message type
@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.
@JsonKey(includeIfNull: false)
final List<Attachment> attachments;
/// The list of user mentioned in the message
@JsonKey(toJson: Serialization.userIds)
final List<User> mentionedUsers;
/// A map describing the count of number of every reaction
@JsonKey(includeIfNull: false, toJson: Serialization.readOnly)
final Map<String, int> reactionCounts;
/// A map describing the count of score of every reaction
@JsonKey(includeIfNull: false, toJson: Serialization.readOnly)
final Map<String, int> reactionScores;
/// The latest reactions to the message created by any user.
@JsonKey(includeIfNull: false, toJson: Serialization.readOnly)
final List<Reaction> latestReactions;
/// The reactions added to the message by the current user.
@JsonKey(includeIfNull: false, toJson: Serialization.readOnly)
final List<Reaction> ownReactions;
/// The ID of the parent message, if the message is a thread reply.
final String parentId;
/// A quoted reply message
@JsonKey(toJson: Serialization.readOnly)
final Message quotedMessage;
/// The ID of the quoted message, if the message is a quoted reply.
final String quotedMessageId;
/// Reserved field indicating the number of replies for this message.
@JsonKey(includeIfNull: false, toJson: Serialization.readOnly)
final int replyCount;
/// Reserved field indicating the thread participants for this message.
@JsonKey(includeIfNull: false, toJson: Serialization.readOnly)
final List<User> threadParticipants;
/// Check if this message needs to show in the channel.
final bool showInChannel;
/// If true the message is silent
final bool silent;
/// If true the message is shadowed
@JsonKey(includeIfNull: false, toJson: Serialization.readOnly)
final bool shadowed;
/// A used command name.
@JsonKey(includeIfNull: false, toJson: Serialization.readOnly)
final String command;
/// Reserved field indicating when the message was created.
@JsonKey(includeIfNull: false, toJson: Serialization.readOnly)
final DateTime createdAt;
/// Reserved field indicating when the message was updated last time.
@JsonKey(includeIfNull: false, toJson: Serialization.readOnly)
final DateTime updatedAt;
/// User who sent the message
@JsonKey(includeIfNull: false, toJson: Serialization.readOnly)
final User user;
/// Message custom extraData
@JsonKey(includeIfNull: false)
final Map<String, dynamic> extraData;
/// True if the message is a system info
bool get isSystem => type == 'system';
/// True if the message has been deleted
bool get isDeleted => type == 'deleted';
/// True if the message is ephemeral
bool get isEphemeral => type == 'ephemeral';
/// Reserved field indicating when the message was deleted.
@JsonKey(includeIfNull: false, toJson: Serialization.readOnly)
final DateTime deletedAt;
/// Known top level fields.
/// Useful for [Serialization] methods.
static const topLevelFields = [
'id',
'text',
'type',
'silent',
'attachments',
'latest_reactions',
'shadowed',
'own_reactions',
'mentioned_users',
'reaction_counts',
'reaction_scores',
'silent',
'parent_id',
'quoted_message',
'quoted_message_id',
'reply_count',
'thread_participants',
'show_in_channel',
'command',
'created_at',
'updated_at',
'deleted_at',
'user',
];
/// Constructor used for json serialization
Message({
this.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.extraData,
this.deletedAt,
this.status = MessageSendingStatus.sent,
});
/// 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);
/// Creates a copy of [Message] with specified attributes overridden.
Message copyWith({
String id,
String text,
String type,
List<Attachment> attachments,
List<User> mentionedUsers,
Map<String, int> reactionCounts,
Map<String, int> reactionScores,
List<Reaction> latestReactions,
List<Reaction> ownReactions,
String parentId,
Message quotedMessage,
String quotedMessageId,
int replyCount,
List<User> threadParticipants,
bool showInChannel,
bool shadowed,
bool silent,
String command,
DateTime createdAt,
DateTime updatedAt,
DateTime deletedAt,
User user,
Map<String, dynamic> extraData,
MessageSendingStatus status,
}) =>
Message(
id: id ?? this.id,
text: text ?? this.text,
type: type ?? this.type,
attachments: attachments ?? this.attachments,
mentionedUsers: mentionedUsers ?? this.mentionedUsers,
reactionCounts: reactionCounts ?? this.reactionCounts,
reactionScores: reactionScores ?? this.reactionScores,
latestReactions: latestReactions ?? this.latestReactions,
ownReactions: ownReactions ?? this.ownReactions,
parentId: parentId ?? this.parentId,
quotedMessage: quotedMessage ?? this.quotedMessage,
quotedMessageId: quotedMessageId ?? this.quotedMessageId,
replyCount: replyCount ?? this.replyCount,
threadParticipants: threadParticipants ?? this.threadParticipants,
showInChannel: showInChannel ?? this.showInChannel,
command: command ?? this.command,
createdAt: createdAt ?? this.createdAt,
silent: silent ?? this.silent,
extraData: extraData ?? this.extraData,
user: user ?? this.user,
shadowed: shadowed ?? this.shadowed,
updatedAt: updatedAt ?? this.updatedAt,
deletedAt: deletedAt ?? this.deletedAt,
status: status ?? this.status,
);
/// 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(
id: other.id,
text: other.text,
type: other.type,
attachments: other.attachments,
mentionedUsers: other.mentionedUsers,
reactionCounts: other.reactionCounts,
reactionScores: other.reactionScores,
latestReactions: other.latestReactions,
ownReactions: other.ownReactions,
parentId: other.parentId,
quotedMessage: other.quotedMessage,
quotedMessageId: other.quotedMessageId,
replyCount: other.replyCount,
threadParticipants: other.threadParticipants,
showInChannel: other.showInChannel,
command: other.command,
createdAt: other.createdAt,
silent: other.silent,
extraData: other.extraData,
user: other.user,
shadowed: other.shadowed,
updatedAt: other.updatedAt,
deletedAt: other.deletedAt,
status: other.status,
);
}
}
/// A translated message
/// It has an additional property called [i18n]
@JsonSerializable()
class TranslatedMessage extends Message {
/// Constructor used for json serialization
TranslatedMessage(this.i18n);
/// A Map of
final Map<String, String> i18n;
/// Known top level fields.
/// Useful for [Serialization] methods.
static final topLevelFields = [
'i18n',
...Message.topLevelFields,
];
/// Create a new instance from a json
factory TranslatedMessage.fromJson(Map<String, dynamic> json) {
return _$TranslatedMessageFromJson(
Serialization.moveToExtraDataFromRoot(json, topLevelFields),
);
}
}
@@ -0,0 +1,135 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'message.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
Message _$MessageFromJson(Map json) {
return Message(
id: json['id'] as String,
text: json['text'] as String,
type: json['type'] as String,
attachments: (json['attachments'] as List)
?.map((e) => e == null
? null
: Attachment.fromJson((e as Map)?.map(
(k, e) => MapEntry(k as String, e),
)))
?.toList(),
mentionedUsers: (json['mentioned_users'] as List)
?.map((e) => e == null
? null
: User.fromJson((e as Map)?.map(
(k, e) => MapEntry(k as String, e),
)))
?.toList(),
silent: json['silent'] as bool,
shadowed: json['shadowed'] as bool,
reactionCounts: (json['reaction_counts'] as Map)?.map(
(k, e) => MapEntry(k as String, e as int),
),
reactionScores: (json['reaction_scores'] as Map)?.map(
(k, e) => MapEntry(k as String, e as int),
),
latestReactions: (json['latest_reactions'] as List)
?.map((e) => e == null
? null
: Reaction.fromJson((e as Map)?.map(
(k, e) => MapEntry(k as String, e),
)))
?.toList(),
ownReactions: (json['own_reactions'] as List)
?.map((e) => e == null
? null
: Reaction.fromJson((e as Map)?.map(
(k, e) => MapEntry(k as String, e),
)))
?.toList(),
parentId: json['parent_id'] as String,
quotedMessage: json['quoted_message'] == null
? null
: Message.fromJson((json['quoted_message'] as Map)?.map(
(k, e) => MapEntry(k as String, e),
)),
quotedMessageId: json['quoted_message_id'] as String,
replyCount: json['reply_count'] as int,
threadParticipants: (json['thread_participants'] as List)
?.map((e) => e == null
? null
: User.fromJson((e as Map)?.map(
(k, e) => MapEntry(k as String, e),
)))
?.toList(),
showInChannel: json['show_in_channel'] as bool,
command: json['command'] as String,
createdAt: json['created_at'] == null
? null
: DateTime.parse(json['created_at'] as String),
updatedAt: json['updated_at'] == null
? null
: DateTime.parse(json['updated_at'] as String),
user: json['user'] == null
? null
: User.fromJson((json['user'] as Map)?.map(
(k, e) => MapEntry(k as String, e),
)),
extraData: (json['extra_data'] as Map)?.map(
(k, e) => MapEntry(k as String, e),
),
deletedAt: json['deleted_at'] == null
? null
: DateTime.parse(json['deleted_at'] as String),
);
}
Map<String, dynamic> _$MessageToJson(Message instance) {
final val = <String, dynamic>{
'id': instance.id,
'text': instance.text,
};
void writeNotNull(String key, dynamic value) {
if (value != null) {
val[key] = value;
}
}
writeNotNull('type', readonly(instance.type));
writeNotNull(
'attachments', instance.attachments?.map((e) => e?.toJson())?.toList());
val['mentioned_users'] = Serialization.userIds(instance.mentionedUsers);
writeNotNull('reaction_counts', readonly(instance.reactionCounts));
writeNotNull('reaction_scores', readonly(instance.reactionScores));
writeNotNull('latest_reactions', readonly(instance.latestReactions));
writeNotNull('own_reactions', readonly(instance.ownReactions));
val['parent_id'] = instance.parentId;
val['quoted_message'] = readonly(instance.quotedMessage);
val['quoted_message_id'] = instance.quotedMessageId;
writeNotNull('reply_count', readonly(instance.replyCount));
writeNotNull('thread_participants', readonly(instance.threadParticipants));
val['show_in_channel'] = instance.showInChannel;
val['silent'] = instance.silent;
writeNotNull('shadowed', readonly(instance.shadowed));
writeNotNull('command', readonly(instance.command));
writeNotNull('created_at', readonly(instance.createdAt));
writeNotNull('updated_at', readonly(instance.updatedAt));
writeNotNull('user', readonly(instance.user));
writeNotNull('extra_data', instance.extraData);
writeNotNull('deleted_at', readonly(instance.deletedAt));
return val;
}
TranslatedMessage _$TranslatedMessageFromJson(Map json) {
return TranslatedMessage(
(json['i18n'] as Map)?.map(
(k, e) => MapEntry(k as String, e as String),
),
);
}
Map<String, dynamic> _$TranslatedMessageToJson(TranslatedMessage instance) =>
<String, dynamic>{
'i18n': instance.i18n,
};
@@ -0,0 +1,36 @@
import 'package:json_annotation/json_annotation.dart';
import 'package:stream_chat/src/models/channel_model.dart';
import 'serialization.dart';
import 'user.dart';
part 'mute.g.dart';
/// The class that contains the information about a muted user
@JsonSerializable()
class Mute {
/// The user that performed the muting action
@JsonKey(includeIfNull: false, toJson: Serialization.readOnly)
final User user;
/// The target user
@JsonKey(includeIfNull: false, toJson: Serialization.readOnly)
final ChannelModel channel;
/// The date in which the use was muted
@JsonKey(includeIfNull: false, toJson: Serialization.readOnly)
final DateTime createdAt;
/// The date of the last update
@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);
}
@@ -0,0 +1,44 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'mute.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
Mute _$MuteFromJson(Map json) {
return Mute(
user: json['user'] == null
? null
: User.fromJson((json['user'] as Map)?.map(
(k, e) => MapEntry(k as String, e),
)),
channel: json['channel'] == null
? null
: ChannelModel.fromJson((json['channel'] as Map)?.map(
(k, e) => MapEntry(k as String, e),
)),
createdAt: json['created_at'] == null
? null
: DateTime.parse(json['created_at'] as String),
updatedAt: json['updated_at'] == null
? null
: DateTime.parse(json['updated_at'] as String),
);
}
Map<String, dynamic> _$MuteToJson(Mute instance) {
final val = <String, dynamic>{};
void writeNotNull(String key, dynamic value) {
if (value != null) {
val[key] = value;
}
}
writeNotNull('user', readonly(instance.user));
writeNotNull('channel', readonly(instance.channel));
writeNotNull('created_at', readonly(instance.createdAt));
writeNotNull('updated_at', readonly(instance.updatedAt));
return val;
}
@@ -0,0 +1,83 @@
import 'package:json_annotation/json_annotation.dart';
import 'device.dart';
import 'mute.dart';
import 'serialization.dart';
import 'user.dart';
part 'own_user.g.dart';
/// The class that defines the own user model
/// This object can be found in [Event]
@JsonSerializable()
class OwnUser extends User {
/// List of user devices
@JsonKey(includeIfNull: false, toJson: Serialization.readOnly)
final List<Device> devices;
/// List of users muted by the user
@JsonKey(includeIfNull: false, toJson: Serialization.readOnly)
final List<Mute> mutes;
/// List of users muted by the user
@JsonKey(includeIfNull: false, toJson: Serialization.readOnly)
final List<Mute> channelMutes;
/// Total unread messages by the user
@JsonKey(includeIfNull: false, toJson: Serialization.readOnly)
final int totalUnreadCount;
/// Total unread channels by the user
@JsonKey(includeIfNull: false, toJson: Serialization.readOnly)
final int unreadChannels;
/// Known top level fields.
/// Useful for [Serialization] methods.
static final topLevelFields = [
'devices',
'mutes',
'total_unread_count',
'unread_channels',
'channel_mutes',
...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);
}
}
@@ -0,0 +1,77 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'own_user.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
OwnUser _$OwnUserFromJson(Map json) {
return OwnUser(
devices: (json['devices'] as List)
?.map((e) => e == null
? null
: Device.fromJson((e as Map)?.map(
(k, e) => MapEntry(k as String, e),
)))
?.toList(),
mutes: (json['mutes'] as List)
?.map((e) => e == null
? null
: Mute.fromJson((e as Map)?.map(
(k, e) => MapEntry(k as String, e),
)))
?.toList(),
totalUnreadCount: json['total_unread_count'] as int,
unreadChannels: json['unread_channels'] as int,
channelMutes: (json['channel_mutes'] as List)
?.map((e) => e == null
? null
: Mute.fromJson((e as Map)?.map(
(k, e) => MapEntry(k as String, e),
)))
?.toList(),
id: json['id'] as String,
role: json['role'] as String,
createdAt: json['created_at'] == null
? null
: DateTime.parse(json['created_at'] as String),
updatedAt: json['updated_at'] == null
? null
: DateTime.parse(json['updated_at'] as String),
lastActive: json['last_active'] == null
? null
: DateTime.parse(json['last_active'] as String),
online: json['online'] as bool,
extraData: (json['extra_data'] as Map)?.map(
(k, e) => MapEntry(k as String, e),
),
banned: json['banned'] as bool,
);
}
Map<String, dynamic> _$OwnUserToJson(OwnUser instance) {
final val = <String, dynamic>{
'id': instance.id,
};
void writeNotNull(String key, dynamic value) {
if (value != null) {
val[key] = value;
}
}
writeNotNull('role', readonly(instance.role));
writeNotNull('created_at', readonly(instance.createdAt));
writeNotNull('updated_at', readonly(instance.updatedAt));
writeNotNull('last_active', readonly(instance.lastActive));
writeNotNull('online', readonly(instance.online));
writeNotNull('banned', readonly(instance.banned));
writeNotNull('extra_data', instance.extraData);
writeNotNull('devices', readonly(instance.devices));
writeNotNull('mutes', readonly(instance.mutes));
writeNotNull('channel_mutes', readonly(instance.channelMutes));
writeNotNull('total_unread_count', readonly(instance.totalUnreadCount));
writeNotNull('unread_channels', readonly(instance.unreadChannels));
return val;
}
@@ -0,0 +1,68 @@
import 'package:json_annotation/json_annotation.dart';
import 'serialization.dart';
import 'user.dart';
part 'reaction.g.dart';
/// The class that defines a reaction
@JsonSerializable()
class Reaction {
/// The messageId to which the reaction belongs
final String messageId;
/// The type of the reaction
final String type;
/// The date of the reaction
@JsonKey(includeIfNull: false, toJson: Serialization.readOnly)
final DateTime createdAt;
/// The user that sent the reaction
@JsonKey(includeIfNull: false, toJson: Serialization.readOnly)
final User user;
/// The score of the reaction (ie. number of reactions sent)
final int score;
/// The userId that sent the reaction
@JsonKey(includeIfNull: false, toJson: Serialization.readOnly)
final String userId;
/// Reaction custom extraData
@JsonKey(includeIfNull: false)
final Map<String, dynamic> extraData;
/// Map of custom user extraData
static const topLevelFields = [
'message_id',
'created_at',
'type',
'user',
'user_id',
'score',
];
/// Constructor used for json serialization
Reaction({
this.messageId,
this.createdAt,
this.type,
this.user,
this.userId,
this.score,
this.extraData,
});
/// 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);
}
}
@@ -0,0 +1,47 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'reaction.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
Reaction _$ReactionFromJson(Map json) {
return Reaction(
messageId: json['message_id'] as String,
createdAt: json['created_at'] == null
? null
: DateTime.parse(json['created_at'] as String),
type: json['type'] as String,
user: json['user'] == null
? null
: User.fromJson((json['user'] as Map)?.map(
(k, e) => MapEntry(k as String, e),
)),
userId: json['user_id'] as String,
score: json['score'] as int,
extraData: (json['extra_data'] as Map)?.map(
(k, e) => MapEntry(k as String, e),
),
);
}
Map<String, dynamic> _$ReactionToJson(Reaction instance) {
final val = <String, dynamic>{
'message_id': instance.messageId,
'type': instance.type,
};
void writeNotNull(String key, dynamic value) {
if (value != null) {
val[key] = value;
}
}
writeNotNull('created_at', readonly(instance.createdAt));
writeNotNull('user', readonly(instance.user));
val['score'] = instance.score;
writeNotNull('user_id', readonly(instance.userId));
writeNotNull('extra_data', instance.extraData);
return val;
}
@@ -0,0 +1,31 @@
import 'package:json_annotation/json_annotation.dart';
import '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,
this.user,
this.unreadMessages,
});
/// Create a new instance from a json
factory Read.fromJson(Map<String, dynamic> json) => _$ReadFromJson(json);
/// Serialize to json
Map<String, dynamic> toJson() => _$ReadToJson(this);
}
@@ -0,0 +1,27 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'read.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
Read _$ReadFromJson(Map json) {
return Read(
lastRead: json['last_read'] == null
? null
: DateTime.parse(json['last_read'] as String),
user: json['user'] == null
? null
: User.fromJson((json['user'] as Map)?.map(
(k, e) => MapEntry(k as String, e),
)),
unreadMessages: json['unread_messages'] as int,
);
}
Map<String, dynamic> _$ReadToJson(Read instance) => <String, dynamic>{
'last_read': instance.lastRead?.toIso8601String(),
'user': instance.user?.toJson(),
'unread_messages': instance.unreadMessages,
};
@@ -0,0 +1,49 @@
import 'user.dart';
/// Used to avoid to serialize properties to json
Null readonly(_) => null;
/// Helper class for serialization to and from json
class Serialization {
/// Used to avoid to serialize properties to json
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();
}
/// Takes unknown json keys and puts them in the `extra_data` key
static Map<String, dynamic> moveToExtraDataFromRoot(
Map<String, dynamic> json,
List<String> topLevelFields,
) {
if (json == null) return null;
final jsonClone = Map<String, dynamic>.from(json);
final extraDataMap = Map<String, dynamic>.from(json)
..removeWhere(
(key, value) => topLevelFields.contains(key),
);
final rootFields = jsonClone
..removeWhere((key, value) => extraDataMap.keys.contains(key));
return rootFields
..addAll({
'extra_data': extraDataMap,
});
}
/// 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,
) {
final jsonClone = Map<String, dynamic>.from(json);
return jsonClone
..addAll({
if (json['extra_data'] != null) ...json['extra_data'],
})
..remove('extra_data');
}
}
@@ -0,0 +1,108 @@
import 'package:json_annotation/json_annotation.dart';
import 'serialization.dart';
part 'user.g.dart';
/// The class that defines the user model
@JsonSerializable()
class User {
/// User id
final String id;
/// User role
@JsonKey(includeIfNull: false, toJson: Serialization.readOnly)
final String role;
/// User role
@JsonKey(includeIfNull: false, toJson: Serialization.readOnly)
final List<String> teams;
/// Date of user creation
@JsonKey(includeIfNull: false, toJson: Serialization.readOnly)
final DateTime createdAt;
/// Date of last user update
@JsonKey(includeIfNull: false, toJson: Serialization.readOnly)
final DateTime updatedAt;
/// Date of last user connection
@JsonKey(includeIfNull: false, toJson: Serialization.readOnly)
final DateTime lastActive;
/// True if user is online
@JsonKey(includeIfNull: false, toJson: Serialization.readOnly)
final bool online;
/// True if user is banned from the chat
@JsonKey(includeIfNull: false, toJson: Serialization.readOnly)
final bool banned;
/// Map of custom user extraData
@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,
});
/// Shortcut for user name
String get name =>
(extraData?.containsKey('name') == true && extraData['name'] != '')
? 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;
}
@@ -0,0 +1,51 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'user.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
User _$UserFromJson(Map json) {
return User(
id: json['id'] as String,
role: json['role'] as String,
createdAt: json['created_at'] == null
? null
: DateTime.parse(json['created_at'] as String),
updatedAt: json['updated_at'] == null
? null
: DateTime.parse(json['updated_at'] as String),
lastActive: json['last_active'] == null
? null
: DateTime.parse(json['last_active'] as String),
online: json['online'] as bool,
extraData: (json['extra_data'] as Map)?.map(
(k, e) => MapEntry(k as String, e),
),
banned: json['banned'] as bool,
teams: (json['teams'] as List)?.map((e) => e as String)?.toList(),
);
}
Map<String, dynamic> _$UserToJson(User instance) {
final val = <String, dynamic>{
'id': instance.id,
};
void writeNotNull(String key, dynamic value) {
if (value != null) {
val[key] = value;
}
}
writeNotNull('role', readonly(instance.role));
writeNotNull('teams', readonly(instance.teams));
writeNotNull('created_at', readonly(instance.createdAt));
writeNotNull('updated_at', readonly(instance.updatedAt));
writeNotNull('last_active', readonly(instance.lastActive));
writeNotNull('online', readonly(instance.online));
writeNotNull('banned', readonly(instance.banned));
writeNotNull('extra_data', instance.extraData);
return val;
}