Merge branch 'develop' into perf

This commit is contained in:
Salvatore Giordano
2021-05-21 15:04:19 +02:00
37 changed files with 784 additions and 317 deletions
+6
View File
@@ -1,3 +1,9 @@
## 2.0.0-nullsafety.2
- Added new `Filter.raw` constructor
- Changed extraData
- Minor fixes
## 2.0.0-nullsafety.1 ## 2.0.0-nullsafety.1
- Migrate this package to null safety - Migrate this package to null safety
@@ -1427,7 +1427,7 @@ class ChannelClientState {
/// This flag should be managed by UI sdks. /// This flag should be managed by UI sdks.
/// When false, any new message (received by WebSocket event /// When false, any new message (received by WebSocket event
/// - [EventType.messageNew]) will not be pushed on to message list. /// - [EventType.messageNew]) will not be pushed on to message list.
bool get isUpToDate => _isUpToDateController.value ?? true; bool get isUpToDate => _isUpToDateController.value;
set isUpToDate(bool isUpToDate) => _isUpToDateController.add(isUpToDate); set isUpToDate(bool isUpToDate) => _isUpToDateController.add(isUpToDate);
@@ -1528,7 +1528,7 @@ class ChannelClientState {
} }
if (_countMessageAsUnread(message)) { if (_countMessageAsUnread(message)) {
_unreadCountController.add(_unreadCountController.value! + 1); _unreadCountController.add(_unreadCountController.value + 1);
} }
})); }));
} }
@@ -1766,13 +1766,13 @@ class ChannelClientState {
a.createdAt.compareTo(b.createdAt); a.createdAt.compareTo(b.createdAt);
/// The channel state related to this client /// The channel state related to this client
ChannelState get _channelState => _channelStateController.value!; ChannelState get _channelState => _channelStateController.value;
/// The channel state related to this client as a stream /// The channel state related to this client as a stream
Stream<ChannelState> get channelStateStream => _channelStateController.stream; Stream<ChannelState> get channelStateStream => _channelStateController.stream;
/// The channel state related to this client /// The channel state related to this client
ChannelState get channelState => _channelStateController.value!; ChannelState get channelState => _channelStateController.value;
late BehaviorSubject<ChannelState> _channelStateController; late BehaviorSubject<ChannelState> _channelStateController;
final Debounce _debouncedUpdatePersistenceChannelState; final Debounce _debouncedUpdatePersistenceChannelState;
@@ -1784,7 +1784,7 @@ class ChannelClientState {
/// The channel threads related to this channel /// The channel threads related to this channel
Map<String, List<Message>> get threads => Map<String, List<Message>> get threads =>
_threadsController.value!.map((key, value) => MapEntry(key, value)); _threadsController.value.map((key, value) => MapEntry(key, value));
/// The channel threads related to this channel as a stream /// The channel threads related to this channel as a stream
Stream<Map<String, List<Message>>> get threadsStream => Stream<Map<String, List<Message>>> get threadsStream =>
@@ -1801,7 +1801,7 @@ class ChannelClientState {
} }
/// Channel related typing users last value /// Channel related typing users last value
List<User> get typingEvents => _typingEventsController.value!; List<User> get typingEvents => _typingEventsController.value;
/// Channel related typing users stream /// Channel related typing users stream
Stream<List<User>> get typingEventsStream => _typingEventsController.stream; Stream<List<User>> get typingEventsStream => _typingEventsController.stream;
+5 -5
View File
@@ -1489,25 +1489,25 @@ class ClientState {
void _updateUser(User? user) => _updateUsers([user]); void _updateUser(User? user) => _updateUsers([user]);
/// The current user /// The current user
OwnUser? get user => _userController.value; OwnUser? get user => _userController.valueOrNull;
/// The current user as a stream /// The current user as a stream
Stream<OwnUser?> get userStream => _userController.stream; Stream<OwnUser?> get userStream => _userController.stream;
/// The current user /// The current user
Map<String?, User?> get users => _usersController.value!; Map<String?, User?> get users => _usersController.value;
/// The current user as a stream /// The current user as a stream
Stream<Map<String?, User?>> get usersStream => _usersController.stream; Stream<Map<String?, User?>> get usersStream => _usersController.stream;
/// The current unread channels count /// The current unread channels count
int? get unreadChannels => _unreadChannelsController.value; int? get unreadChannels => _unreadChannelsController.valueOrNull;
/// The current unread channels count as a stream /// The current unread channels count as a stream
Stream<int?> get unreadChannelsStream => _unreadChannelsController.stream; Stream<int?> get unreadChannelsStream => _unreadChannelsController.stream;
/// The current total unread messages count /// The current total unread messages count
int? get totalUnreadCount => _totalUnreadCountController.value; int? get totalUnreadCount => _totalUnreadCountController.valueOrNull;
/// The current total unread messages count as a stream /// The current total unread messages count as a stream
Stream<int?> get totalUnreadCountStream => _totalUnreadCountController.stream; Stream<int?> get totalUnreadCountStream => _totalUnreadCountController.stream;
@@ -1517,7 +1517,7 @@ class ClientState {
_channelsController.stream; _channelsController.stream;
/// The current list of channels in memory /// The current list of channels in memory
Map<String, Channel> get channels => _channelsController.value!; Map<String, Channel> get channels => _channelsController.value;
set channels(Map<String, Channel> v) { set channels(Map<String, Channel> v) {
_channelsController.add(v); _channelsController.add(v);
+1 -1
View File
@@ -3,4 +3,4 @@ import 'package:stream_chat/src/client.dart';
/// Current package version /// Current package version
/// Used in [StreamChatClient] to build the `x-stream-client` header /// Used in [StreamChatClient] to build the `x-stream-client` header
// ignore: constant_identifier_names // ignore: constant_identifier_names
const PACKAGE_VERSION = '2.0.0-nullsafety.1'; const PACKAGE_VERSION = '2.0.0-nullsafety.2';
+2 -2
View File
@@ -1,7 +1,7 @@
name: stream_chat name: stream_chat
homepage: https://getstream.io/ homepage: https://getstream.io/
description: The official Dart client for Stream Chat, a service for building chat applications. description: The official Dart client for Stream Chat, a service for building chat applications.
version: 2.0.0-nullsafety.1 version: 2.0.0-nullsafety.2
repository: https://github.com/GetStream/stream-chat-flutter repository: https://github.com/GetStream/stream-chat-flutter
issue_tracker: https://github.com/GetStream/stream-chat-flutter/issues issue_tracker: https://github.com/GetStream/stream-chat-flutter/issues
@@ -19,7 +19,7 @@ dependencies:
logging: ^1.0.1 logging: ^1.0.1
meta: ^1.3.0 meta: ^1.3.0
mime: ^1.0.0 mime: ^1.0.0
rxdart: ^0.26.0 rxdart: ^0.27.0
uuid: ^3.0.4 uuid: ^3.0.4
web_socket_channel: ^2.0.0 web_socket_channel: ^2.0.0
@@ -1,3 +1,9 @@
## 2.0.0-nullsafety.4
- Minor fixes and improvements
- Updated `stream_chat_core` dependency
- Improved performance of `MessageWidget` component
## 2.0.0-nullsafety.3 ## 2.0.0-nullsafety.3
- Fix MessageInput overflow when there are no actions - Fix MessageInput overflow when there are no actions
@@ -0,0 +1,150 @@
analyzer:
enable-experiment:
- extension-methods
exclude:
- lib/**/*.g.dart
- example/**
- lib/src/emoji
- lib/**/*.freezed.dart
- test/**
linter:
rules:
# these rules are documented on and in the same order as
# the Dart Lint rules page to make maintenance easier
# https://github.com/dart-lang/linter/blob/master/example/all.yaml
- always_use_package_imports
- avoid_empty_else
- avoid_relative_lib_imports
- avoid_slow_async_io
- avoid_types_as_parameter_names
- cancel_subscriptions
- close_sinks
- control_flow_in_finally
- empty_statements
- hash_and_equals
- invariant_booleans
- iterable_contains_unrelated_type
- list_remove_unrelated_type
- literal_only_boolean_expressions
- no_adjacent_strings_in_list
- no_duplicate_case_values
- no_logic_in_create_state
- prefer_void_to_null
- test_types_in_equals
- throw_in_finally
- unnecessary_statements
- unrelated_type_equality_checks
- omit_local_variable_types
- use_key_in_widget_constructors
- valid_regexps
- always_declare_return_types
- always_require_non_null_named_parameters
- annotate_overrides
- avoid_bool_literals_in_conditional_expressions
- avoid_catching_errors
- avoid_init_to_null
- avoid_null_checks_in_equality_operators
- avoid_positional_boolean_parameters
- avoid_private_typedef_functions
- avoid_redundant_argument_values
- avoid_return_types_on_setters
- avoid_returning_null_for_void
- avoid_shadowing_type_parameters
- avoid_single_cascade_in_expression_statements
- avoid_unnecessary_containers
- avoid_unused_constructor_parameters
- await_only_futures
- camel_case_extensions
- camel_case_types
- cascade_invocations
- constant_identifier_names
- curly_braces_in_flow_control_structures
- directives_ordering
- empty_catches
- empty_constructor_bodies
- exhaustive_cases
- file_names
- implementation_imports
- join_return_with_assignment
- leading_newlines_in_multiline_strings
- library_names
- library_prefixes
- lines_longer_than_80_chars
- missing_whitespace_between_adjacent_strings
- non_constant_identifier_names
- null_closures
- one_member_abstracts
- only_throw_errors
- package_api_docs
- package_prefixed_library_names
- parameter_assignments
- prefer_adjacent_string_concatenation
- prefer_asserts_in_initializer_lists
- prefer_asserts_with_message
- prefer_collection_literals
- prefer_conditional_assignment
- prefer_const_constructors
- prefer_const_constructors_in_immutables
- prefer_const_declarations
- prefer_const_literals_to_create_immutables
- prefer_constructors_over_static_methods
- prefer_contains
- prefer_equal_for_default_values
- prefer_expression_function_bodies
- prefer_final_fields
- prefer_final_in_for_each
- prefer_final_locals
- prefer_function_declarations_over_variables
- prefer_generic_function_type_aliases
- prefer_if_elements_to_conditional_expressions
- prefer_if_null_operators
- prefer_initializing_formals
- prefer_inlined_adds
- prefer_int_literals
- prefer_interpolation_to_compose_strings
- prefer_is_empty
- prefer_is_not_empty
- prefer_is_not_operator
- prefer_null_aware_operators
- prefer_single_quotes
- prefer_spread_collections
- prefer_typing_uninitialized_variables
- provide_deprecation_message
- public_member_api_docs
- recursive_getters
- sized_box_for_whitespace
- slash_for_doc_comments
- sort_child_properties_last
- sort_constructors_first
- sort_unnamed_constructors_first
- type_annotate_public_apis
- type_init_formals
- unnecessary_await_in_return
- unnecessary_brace_in_string_interps
- unnecessary_const
- unnecessary_getters_setters
- unnecessary_lambdas
- unnecessary_new
- unnecessary_null_aware_assignments
- unnecessary_null_in_if_null_operators
- unnecessary_nullable_for_final_variable_declarations
- unnecessary_parenthesis
- unnecessary_raw_strings
- unnecessary_string_escapes
- unnecessary_string_interpolations
- unnecessary_this
- use_is_even_rather_than_modulo
- use_late_for_private_fields_and_variables
- use_rethrow_when_possible
- use_setters_to_change_properties
- use_to_and_as_if_applicable
- package_names
- sort_pub_dependencies
- cast_nullable_to_non_nullable
- unnecessary_null_checks
- tighten_type_of_initializing_formals
- null_check_on_nullable_type_parameter
@@ -159,6 +159,7 @@ class FileAttachment extends AttachmentWidget {
shape: _getDefaultShape(context), shape: _getDefaultShape(context),
child: source.when( child: source.when(
local: () => VideoThumbnailImage( local: () => VideoThumbnailImage(
fit: BoxFit.cover,
video: attachment.file!.path!, video: attachment.file!.path!,
placeholderBuilder: (_) => const Center( placeholderBuilder: (_) => const Center(
child: SizedBox( child: SizedBox(
@@ -169,6 +170,7 @@ class FileAttachment extends AttachmentWidget {
), ),
), ),
network: () => VideoThumbnailImage( network: () => VideoThumbnailImage(
fit: BoxFit.cover,
video: attachment.assetUrl!, video: attachment.assetUrl!,
placeholderBuilder: (_) => const Center( placeholderBuilder: (_) => const Center(
child: SizedBox( child: SizedBox(
@@ -212,50 +214,42 @@ class FileAttachment extends AttachmentWidget {
final attachmentId = attachment.id; final attachmentId = attachment.id;
var trailingWidget = trailing; var trailingWidget = trailing;
trailingWidget ??= attachment.uploadState.when( trailingWidget ??= attachment.uploadState.when(
preparing: () => Padding( preparing: () => Padding(
padding: const EdgeInsets.all(8), padding: const EdgeInsets.all(8),
child: _buildButton( child: _buildButton(
icon: StreamSvgIcon.close(color: theme.colorTheme.white), icon: StreamSvgIcon.close(color: theme.colorTheme.white),
fillColor: theme.colorTheme.overlayDark, fillColor: theme.colorTheme.overlayDark,
onPressed: () => channel.cancelAttachmentUpload(attachmentId), onPressed: () => channel.cancelAttachmentUpload(attachmentId),
), ),
),
inProgress: (_, __) => Padding(
padding: const EdgeInsets.all(8),
child: _buildButton(
icon: StreamSvgIcon.close(color: theme.colorTheme.white),
fillColor: theme.colorTheme.overlayDark,
onPressed: () => channel.cancelAttachmentUpload(attachmentId),
),
),
success: () => Padding(
padding: const EdgeInsets.all(8),
child: CircleAvatar(
backgroundColor: theme.colorTheme.accentBlue,
maxRadius: 12,
child: StreamSvgIcon.check(color: theme.colorTheme.white),
),
),
failed: (_) => Padding(
padding: const EdgeInsets.all(8),
child: _buildButton(
icon: StreamSvgIcon.retry(color: theme.colorTheme.white),
fillColor: theme.colorTheme.overlayDark,
onPressed: () => channel.retryAttachmentUpload(
message.id,
attachmentId,
), ),
inProgress: (_, __) => Padding( ),
padding: const EdgeInsets.all(8), ),
child: _buildButton( );
icon: StreamSvgIcon.close(color: theme.colorTheme.white),
fillColor: theme.colorTheme.overlayDark,
onPressed: () => channel.cancelAttachmentUpload(attachmentId),
),
),
success: () => Padding(
padding: const EdgeInsets.all(8),
child: CircleAvatar(
backgroundColor: theme.colorTheme.accentBlue,
maxRadius: 12,
child: StreamSvgIcon.check(color: theme.colorTheme.white),
),
),
failed: (_) => Padding(
padding: const EdgeInsets.all(8),
child: _buildButton(
icon: StreamSvgIcon.retry(color: theme.colorTheme.white),
fillColor: theme.colorTheme.overlayDark,
onPressed: () => channel.retryAttachmentUpload(
message.id,
attachmentId,
),
),
),
) ??
IconButton(
icon: StreamSvgIcon.cloudDownload(color: theme.colorTheme.black),
visualDensity: VisualDensity.compact,
splashRadius: 16,
onPressed: () {
launchURL(context, attachment.assetUrl);
},
);
if (message.status == MessageSendingStatus.sent) { if (message.status == MessageSendingStatus.sent) {
trailingWidget = IconButton( trailingWidget = IconButton(
@@ -281,25 +275,17 @@ class FileAttachment extends AttachmentWidget {
color: theme.colorTheme.grey, color: theme.colorTheme.grey,
); );
return attachment.uploadState.when( return attachment.uploadState.when(
preparing: () => UploadProgressIndicator( preparing: () => Text(fileSize(size), style: textStyle),
uploaded: 0, inProgress: (sent, total) => UploadProgressIndicator(
total: double.maxFinite.toInt(), uploaded: sent,
showBackground: false, total: total,
padding: EdgeInsets.zero, showBackground: false,
textStyle: textStyle, padding: EdgeInsets.zero,
progressIndicatorColor: theme.colorTheme.accentBlue, textStyle: textStyle,
), progressIndicatorColor: theme.colorTheme.accentBlue,
inProgress: (sent, total) => UploadProgressIndicator( ),
uploaded: sent, success: () => Text(fileSize(size), style: textStyle),
total: total, failed: (_) => Text('UPLOAD ERROR', style: textStyle),
showBackground: false, );
padding: EdgeInsets.zero,
textStyle: textStyle,
progressIndicatorColor: theme.colorTheme.accentBlue,
),
success: () => Text(fileSize(size), style: textStyle),
failed: (_) => Text('UPLOAD ERROR', style: textStyle),
) ??
Text(fileSize(size), style: textStyle);
} }
} }
@@ -76,7 +76,7 @@ class _ImageFooterState extends State<ImageFooter> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final showShareButton = !kIsWeb; const showShareButton = !kIsWeb;
final mediaQueryData = MediaQuery.of(context); final mediaQueryData = MediaQuery.of(context);
final chatThemeData = StreamChatTheme.of(context); final chatThemeData = StreamChatTheme.of(context);
return SizedBox.fromSize( return SizedBox.fromSize(
@@ -76,7 +76,7 @@ enum SendButtonLocation {
const _kMinMediaPickerSize = 360.0; const _kMinMediaPickerSize = 360.0;
const _kMaxAttachmentSize = 20971520; // 20MB in Bytes const _kDefaultMaxAttachmentSize = 20971520; // 20MB in Bytes
/// Inactive state /// Inactive state
/// ![screenshot](https://raw.githubusercontent.com/GetStream/stream-chat-flutter/master/screenshots/message_input.png) /// ![screenshot](https://raw.githubusercontent.com/GetStream/stream-chat-flutter/master/screenshots/message_input.png)
@@ -148,11 +148,17 @@ class MessageInput extends StatefulWidget {
this.activeSendButton, this.activeSendButton,
this.showCommandsButton = true, this.showCommandsButton = true,
this.mentionsTileBuilder, this.mentionsTileBuilder,
this.maxAttachmentSize = _kDefaultMaxAttachmentSize,
}) : super(key: key); }) : super(key: key);
/// Message to edit /// Message to edit
final Message? editMessage; final Message? editMessage;
/// Max attachment size in bytes
/// Defaults to 20 MB
/// do not set it if you're using our default CDN
final int maxAttachmentSize;
/// Message to start with /// Message to start with
final Message? initialMessage; final Message? initialMessage;
@@ -1108,12 +1114,12 @@ class MessageInputState extends State<MessageInput> {
bytes: mediaFile.readAsBytesSync(), bytes: mediaFile.readAsBytesSync(),
); );
if (file.size! > _kMaxAttachmentSize) { if (file.size! > widget.maxAttachmentSize) {
if (medium.type == AssetType.video) { if (medium.type == AssetType.video && file.path != null) {
final mediaInfo = await (VideoService.compressVideo(file.path) final mediaInfo = await (VideoService.compressVideo(file.path!)
as FutureOr<MediaInfo>); as FutureOr<MediaInfo>);
if (mediaInfo.filesize! > _kMaxAttachmentSize) { if (mediaInfo.filesize! > widget.maxAttachmentSize) {
_showErrorAlert( _showErrorAlert(
// ignore: lines_longer_than_80_chars // ignore: lines_longer_than_80_chars
'The file is too large to upload. The file size limit is 20MB. We tried compressing it, but it was not enough.', 'The file is too large to upload. The file size limit is 20MB. We tried compressing it, but it was not enough.',
@@ -1473,16 +1479,12 @@ class MessageInputState extends State<MessageInput> {
final containsUrl = widget.quotedMessage!.attachments final containsUrl = widget.quotedMessage!.attachments
.any((element) => element.ogScrapeUrl != null) == .any((element) => element.ogScrapeUrl != null) ==
true; true;
return Transform( return QuotedMessageWidget(
transform: Matrix4.rotationY(pi), reverse: true,
alignment: Alignment.center, showBorder: !containsUrl,
child: QuotedMessageWidget( message: widget.quotedMessage!,
reverse: true, messageTheme: StreamChatTheme.of(context).otherMessageTheme,
showBorder: !containsUrl, padding: const EdgeInsets.fromLTRB(8, 8, 8, 0),
message: widget.quotedMessage!,
messageTheme: StreamChatTheme.of(context).otherMessageTheme,
padding: const EdgeInsets.fromLTRB(8, 8, 8, 0),
),
); );
} }
@@ -1509,7 +1511,9 @@ class MessageInputState extends State<MessageInput> {
(e) => ClipRRect( (e) => ClipRRect(
borderRadius: BorderRadius.circular(10), borderRadius: BorderRadius.circular(10),
child: FileAttachment( child: FileAttachment(
message: Message(), // dummy message message: Message(
status: MessageSendingStatus.sending,
), // dummy message
attachment: e, attachment: e,
size: Size( size: Size(
MediaQuery.of(context).size.width * 0.65, MediaQuery.of(context).size.width * 0.65,
@@ -1897,15 +1901,16 @@ class MessageInputState extends State<MessageInput> {
final attachment = Attachment( final attachment = Attachment(
file: file, file: file,
type: attachmentType, type: attachmentType,
uploadState: const UploadState.preparing(),
extraData: extraDataMap, extraData: extraDataMap,
); );
if (file.size! > _kMaxAttachmentSize) { if (file.size! > widget.maxAttachmentSize) {
if (attachmentType == 'Video') { if (attachmentType == 'video' && file.path != null) {
final mediaInfo = await (VideoService.compressVideo(file.path) final mediaInfo = await (VideoService.compressVideo(file.path!)
as FutureOr<MediaInfo>); as FutureOr<MediaInfo>);
if (mediaInfo.filesize! > _kMaxAttachmentSize) { if (mediaInfo.filesize! > widget.maxAttachmentSize) {
_showErrorAlert( _showErrorAlert(
// ignore: lines_longer_than_80_chars // ignore: lines_longer_than_80_chars
'The file is too large to upload. The file size limit is 20MB. We tried compressing it, but it was not enough.', 'The file is too large to upload. The file size limit is 20MB. We tried compressing it, but it was not enough.',
@@ -815,11 +815,13 @@ class _MessageListViewState extends State<MessageListView> {
padding: const EdgeInsets.all(8), padding: const EdgeInsets.all(8),
showSendingIndicator: false, showSendingIndicator: false,
onThreadTap: _onThreadTap, onThreadTap: _onThreadTap,
borderRadiusGeometry: const BorderRadius.only( borderRadiusGeometry: BorderRadius.only(
topLeft: Radius.circular(16), topLeft: const Radius.circular(16),
bottomLeft: Radius.circular(2), bottomLeft:
topRight: Radius.circular(16), isMyMessage ? const Radius.circular(16) : const Radius.circular(2),
bottomRight: Radius.circular(16), topRight: const Radius.circular(16),
bottomRight:
isMyMessage ? const Radius.circular(2) : const Radius.circular(16),
), ),
textPadding: EdgeInsets.symmetric( textPadding: EdgeInsets.symmetric(
vertical: 8, vertical: 8,
@@ -102,21 +102,24 @@ class QuotedMessageWidget extends StatelessWidget {
bool get _containsText => message.text?.isNotEmpty == true; bool get _containsText => message.text?.isNotEmpty == true;
@override @override
Widget build(BuildContext context) => Padding( Widget build(BuildContext context) {
padding: padding, final children = [
child: InkWell( Flexible(child: _buildMessage(context)),
onTap: onTap, const SizedBox(width: 8),
child: Row( if (message.user != null) _buildUserAvatar(),
crossAxisAlignment: CrossAxisAlignment.end, ];
mainAxisSize: MainAxisSize.min, return Padding(
children: [ padding: padding,
Flexible(child: _buildMessage(context)), child: InkWell(
const SizedBox(width: 8), onTap: onTap,
if (message.user != null) _buildUserAvatar(), child: Row(
], crossAxisAlignment: CrossAxisAlignment.end,
), mainAxisSize: MainAxisSize.min,
children: reverse ? children.reversed.toList() : children,
), ),
); ),
);
}
Widget _buildMessage(BuildContext context) { Widget _buildMessage(BuildContext context) {
final isOnlyEmoji = message.text!.isOnlyEmoji; final isOnlyEmoji = message.text!.isOnlyEmoji;
@@ -154,10 +157,11 @@ class QuotedMessageWidget extends StatelessWidget {
color: StreamChatTheme.of(context).colorTheme.greyGainsboro, color: StreamChatTheme.of(context).colorTheme.greyGainsboro,
) )
: null, : null,
borderRadius: const BorderRadius.only( borderRadius: BorderRadius.only(
topRight: Radius.circular(12), topRight: const Radius.circular(12),
topLeft: Radius.circular(12), topLeft: const Radius.circular(12),
bottomLeft: Radius.circular(12), bottomRight: reverse ? const Radius.circular(12) : Radius.zero,
bottomLeft: reverse ? Radius.zero : const Radius.circular(12),
), ),
), ),
padding: const EdgeInsets.all(8), padding: const EdgeInsets.all(8),
@@ -28,9 +28,9 @@ class IVideoService {
/// ); /// );
/// debugPrint(info.toJson()); /// debugPrint(info.toJson());
/// ``` /// ```
Future<MediaInfo?> compressVideo(String? path) async => _lock.synchronized( Future<MediaInfo?> compressVideo(String path) async => _lock.synchronized(
() => VideoCompress.compressVideo( () => VideoCompress.compressVideo(
path!, path,
), ),
); );
+4 -4
View File
@@ -1,7 +1,7 @@
name: stream_chat_flutter name: stream_chat_flutter
homepage: https://github.com/GetStream/stream-chat-flutter homepage: https://github.com/GetStream/stream-chat-flutter
description: Stream Chat official Flutter SDK. Build your own chat experience using Dart and Flutter. description: Stream Chat official Flutter SDK. Build your own chat experience using Dart and Flutter.
version: 2.0.0-nullsafety.3 version: 2.0.0-nullsafety.4
repository: https://github.com/GetStream/stream-chat-flutter repository: https://github.com/GetStream/stream-chat-flutter
issue_tracker: https://github.com/GetStream/stream-chat-flutter/issues issue_tracker: https://github.com/GetStream/stream-chat-flutter/issues
@@ -30,13 +30,13 @@ dependencies:
lottie: ^1.0.1 lottie: ^1.0.1
meta: ^1.3.0 meta: ^1.3.0
path_provider: ^2.0.1 path_provider: ^2.0.1
photo_manager: ^1.1.4 photo_manager: ^1.1.6
photo_view: ^0.11.1 photo_view: ^0.11.1
rxdart: ^0.26.0 rxdart: ^0.27.0
scrollable_positioned_list: ^0.2.0-nullsafety.0 scrollable_positioned_list: ^0.2.0-nullsafety.0
share_plus: ^2.0.3 share_plus: ^2.0.3
shimmer: ^2.0.0 shimmer: ^2.0.0
stream_chat_flutter_core: ^2.0.0-nullsafety.2 stream_chat_flutter_core: ^2.0.0-nullsafety.3
substring_highlight: ^1.0.26 substring_highlight: ^1.0.26
synchronized: ^3.0.0 synchronized: ^3.0.0
url_launcher: ^6.0.3 url_launcher: ^6.0.3
@@ -1,3 +1,8 @@
## 2.0.0-nullsafety.3
* Update llc dependency
* Minor fixes and improvements
## 2.0.0-nullsafety.2 ## 2.0.0-nullsafety.2
* Fix ChannelsBloc not performing calls if pagination ended * Fix ChannelsBloc not performing calls if pagination ended
+1 -1
View File
@@ -1,4 +1,4 @@
# Official Core [Flutter SDK](https://getstream.io/chat/sdk/flutter/) for [Stream Chat API](https://getstream.io/chat/) # Official Core [Flutter SDK](https://getstream.io/chat/sdk/flutter/) for [Stream Chat](https://getstream.io/chat/)
> The official Flutter core components for Stream Chat, a service for > The official Flutter core components for Stream Chat, a service for
> building chat applications. > building chat applications.
@@ -0,0 +1,150 @@
analyzer:
enable-experiment:
- extension-methods
exclude:
- lib/**/*.g.dart
- example/**
- lib/src/emoji
- lib/**/*.freezed.dart
- test/**
linter:
rules:
# these rules are documented on and in the same order as
# the Dart Lint rules page to make maintenance easier
# https://github.com/dart-lang/linter/blob/master/example/all.yaml
- always_use_package_imports
- avoid_empty_else
- avoid_relative_lib_imports
- avoid_slow_async_io
- avoid_types_as_parameter_names
- cancel_subscriptions
- close_sinks
- control_flow_in_finally
- empty_statements
- hash_and_equals
- invariant_booleans
- iterable_contains_unrelated_type
- list_remove_unrelated_type
- literal_only_boolean_expressions
- no_adjacent_strings_in_list
- no_duplicate_case_values
- no_logic_in_create_state
- prefer_void_to_null
- test_types_in_equals
- throw_in_finally
- unnecessary_statements
- unrelated_type_equality_checks
- omit_local_variable_types
- use_key_in_widget_constructors
- valid_regexps
- always_declare_return_types
- always_require_non_null_named_parameters
- annotate_overrides
- avoid_bool_literals_in_conditional_expressions
- avoid_catching_errors
- avoid_init_to_null
- avoid_null_checks_in_equality_operators
- avoid_positional_boolean_parameters
- avoid_private_typedef_functions
- avoid_redundant_argument_values
- avoid_return_types_on_setters
- avoid_returning_null_for_void
- avoid_shadowing_type_parameters
- avoid_single_cascade_in_expression_statements
- avoid_unnecessary_containers
- avoid_unused_constructor_parameters
- await_only_futures
- camel_case_extensions
- camel_case_types
- cascade_invocations
- constant_identifier_names
- curly_braces_in_flow_control_structures
- directives_ordering
- empty_catches
- empty_constructor_bodies
- exhaustive_cases
- file_names
- implementation_imports
- join_return_with_assignment
- leading_newlines_in_multiline_strings
- library_names
- library_prefixes
- lines_longer_than_80_chars
- missing_whitespace_between_adjacent_strings
- non_constant_identifier_names
- null_closures
- one_member_abstracts
- only_throw_errors
- package_api_docs
- package_prefixed_library_names
- parameter_assignments
- prefer_adjacent_string_concatenation
- prefer_asserts_in_initializer_lists
- prefer_asserts_with_message
- prefer_collection_literals
- prefer_conditional_assignment
- prefer_const_constructors
- prefer_const_constructors_in_immutables
- prefer_const_declarations
- prefer_const_literals_to_create_immutables
- prefer_constructors_over_static_methods
- prefer_contains
- prefer_equal_for_default_values
- prefer_expression_function_bodies
- prefer_final_fields
- prefer_final_in_for_each
- prefer_final_locals
- prefer_function_declarations_over_variables
- prefer_generic_function_type_aliases
- prefer_if_elements_to_conditional_expressions
- prefer_if_null_operators
- prefer_initializing_formals
- prefer_inlined_adds
- prefer_int_literals
- prefer_interpolation_to_compose_strings
- prefer_is_empty
- prefer_is_not_empty
- prefer_is_not_operator
- prefer_null_aware_operators
- prefer_single_quotes
- prefer_spread_collections
- prefer_typing_uninitialized_variables
- provide_deprecation_message
- public_member_api_docs
- recursive_getters
- sized_box_for_whitespace
- slash_for_doc_comments
- sort_child_properties_last
- sort_constructors_first
- sort_unnamed_constructors_first
- type_annotate_public_apis
- type_init_formals
- unnecessary_await_in_return
- unnecessary_brace_in_string_interps
- unnecessary_const
- unnecessary_getters_setters
- unnecessary_lambdas
- unnecessary_new
- unnecessary_null_aware_assignments
- unnecessary_null_in_if_null_operators
- unnecessary_nullable_for_final_variable_declarations
- unnecessary_parenthesis
- unnecessary_raw_strings
- unnecessary_string_escapes
- unnecessary_string_interpolations
- unnecessary_this
- use_is_even_rather_than_modulo
- use_late_for_private_fields_and_variables
- use_rethrow_when_possible
- use_setters_to_change_properties
- use_to_and_as_if_applicable
- package_names
- sort_pub_dependencies
- cast_nullable_to_non_nullable
- unnecessary_null_checks
- tighten_type_of_initializing_formals
- null_check_on_nullable_type_parameter
@@ -71,7 +71,7 @@ class ChannelsBlocState extends State<ChannelsBloc>
} }
/// The current channel list /// The current channel list
List<Channel>? get channels => _channelsController.value; List<Channel>? get channels => _channelsController.valueOrNull;
/// The current channel list as a stream /// The current channel list as a stream
Stream<List<Channel>> get channelsStream => _channelsController.stream; Stream<List<Channel>> get channelsStream => _channelsController.stream;
@@ -128,7 +128,7 @@ class ChannelsBlocState extends State<ChannelsBloc>
_channelsController.add(temp); _channelsController.add(temp);
} }
if (_channelsController.hasValue && if (_channelsController.hasValue &&
_queryChannelsLoadingController.value!) { _queryChannelsLoadingController.value) {
_queryChannelsLoadingController.sink.add(false); _queryChannelsLoadingController.sink.add(false);
} }
} }
@@ -44,7 +44,8 @@ class MessageSearchBlocState extends State<MessageSearchBloc>
late StreamChatCoreState _streamChatCoreState; late StreamChatCoreState _streamChatCoreState;
/// The current messages list /// The current messages list
List<GetMessageResponse>? get messageResponses => _messageResponses.value; List<GetMessageResponse>? get messageResponses =>
_messageResponses.valueOrNull;
/// The current messages list as a stream /// The current messages list as a stream
Stream<List<GetMessageResponse>> get messagesStream => Stream<List<GetMessageResponse>> get messagesStream =>
@@ -93,8 +94,7 @@ class MessageSearchBlocState extends State<MessageSearchBloc>
final temp = oldMessages + messages.results; final temp = oldMessages + messages.results;
_messageResponses.add(temp); _messageResponses.add(temp);
} }
if (_messageResponses.hasValue && if (_messageResponses.hasValue && _queryMessagesLoadingController.value) {
_queryMessagesLoadingController.value!) {
_queryMessagesLoadingController.add(false); _queryMessagesLoadingController.add(false);
} }
} catch (e, stk) { } catch (e, stk) {
@@ -43,7 +43,7 @@ class UsersBloc extends StatefulWidget {
class UsersBlocState extends State<UsersBloc> class UsersBlocState extends State<UsersBloc>
with AutomaticKeepAliveClientMixin { with AutomaticKeepAliveClientMixin {
/// The current users list /// The current users list
List<User>? get users => _usersController.value; List<User>? get users => _usersController.valueOrNull;
/// The current users list as a stream /// The current users list as a stream
Stream<List<User>> get usersStream => _usersController.stream; Stream<List<User>> get usersStream => _usersController.stream;
@@ -92,7 +92,7 @@ class UsersBlocState extends State<UsersBloc>
final temp = oldUsers + usersResponse.users; final temp = oldUsers + usersResponse.users;
_usersController.add(temp); _usersController.add(temp);
} }
if (_usersController.hasValue && _queryUsersLoadingController.value!) { if (_usersController.hasValue && _queryUsersLoadingController.value) {
_queryUsersLoadingController.add(false); _queryUsersLoadingController.add(false);
} }
} catch (e, stk) { } catch (e, stk) {
@@ -1,7 +1,7 @@
name: stream_chat_flutter_core name: stream_chat_flutter_core
homepage: https://github.com/GetStream/stream-chat-flutter homepage: https://github.com/GetStream/stream-chat-flutter
description: Stream Chat official Flutter SDK Core. Build your own chat experience using Dart and Flutter. description: Stream Chat official Flutter SDK Core. Build your own chat experience using Dart and Flutter.
version: 2.0.0-nullsafety.2 version: 2.0.0-nullsafety.3
repository: https://github.com/GetStream/stream-chat-flutter repository: https://github.com/GetStream/stream-chat-flutter
issue_tracker: https://github.com/GetStream/stream-chat-flutter/issues issue_tracker: https://github.com/GetStream/stream-chat-flutter/issues
@@ -10,12 +10,12 @@ environment:
flutter: ">=1.17.0" flutter: ">=1.17.0"
dependencies: dependencies:
collection: ^1.15.0-nullsafety.4 collection: ^1.15.0
flutter: flutter:
sdk: flutter sdk: flutter
meta: ^1.3.0 meta: ^1.3.0
rxdart: ^0.26.0 rxdart: ^0.27.0
stream_chat: ^2.0.0-nullsafety.1 stream_chat: ^2.0.0-nullsafety.2
dev_dependencies: dev_dependencies:
fake_async: ^1.2.0 fake_async: ^1.2.0
@@ -1,3 +1,9 @@
## 2.0.0-nullsafety.2
* Update llc dependency
* Minor fixes and improvements
* Fixed bug not saving message.mentioned_users
## 2.0.0-nullsafety.1 ## 2.0.0-nullsafety.1
* Migrate this package to null safety * Migrate this package to null safety
@@ -0,0 +1,150 @@
analyzer:
enable-experiment:
- extension-methods
exclude:
- lib/**/*.g.dart
- example/**
- lib/src/emoji
- lib/**/*.freezed.dart
- test/**
linter:
rules:
# these rules are documented on and in the same order as
# the Dart Lint rules page to make maintenance easier
# https://github.com/dart-lang/linter/blob/master/example/all.yaml
- always_use_package_imports
- avoid_empty_else
- avoid_relative_lib_imports
- avoid_slow_async_io
- avoid_types_as_parameter_names
- cancel_subscriptions
- close_sinks
- control_flow_in_finally
- empty_statements
- hash_and_equals
- invariant_booleans
- iterable_contains_unrelated_type
- list_remove_unrelated_type
- literal_only_boolean_expressions
- no_adjacent_strings_in_list
- no_duplicate_case_values
- no_logic_in_create_state
- prefer_void_to_null
- test_types_in_equals
- throw_in_finally
- unnecessary_statements
- unrelated_type_equality_checks
- omit_local_variable_types
- use_key_in_widget_constructors
- valid_regexps
- always_declare_return_types
- always_require_non_null_named_parameters
- annotate_overrides
- avoid_bool_literals_in_conditional_expressions
- avoid_catching_errors
- avoid_init_to_null
- avoid_null_checks_in_equality_operators
- avoid_positional_boolean_parameters
- avoid_private_typedef_functions
- avoid_redundant_argument_values
- avoid_return_types_on_setters
- avoid_returning_null_for_void
- avoid_shadowing_type_parameters
- avoid_single_cascade_in_expression_statements
- avoid_unnecessary_containers
- avoid_unused_constructor_parameters
- await_only_futures
- camel_case_extensions
- camel_case_types
- cascade_invocations
- constant_identifier_names
- curly_braces_in_flow_control_structures
- directives_ordering
- empty_catches
- empty_constructor_bodies
- exhaustive_cases
- file_names
- implementation_imports
- join_return_with_assignment
- leading_newlines_in_multiline_strings
- library_names
- library_prefixes
- lines_longer_than_80_chars
- missing_whitespace_between_adjacent_strings
- non_constant_identifier_names
- null_closures
- one_member_abstracts
- only_throw_errors
- package_api_docs
- package_prefixed_library_names
- parameter_assignments
- prefer_adjacent_string_concatenation
- prefer_asserts_in_initializer_lists
- prefer_asserts_with_message
- prefer_collection_literals
- prefer_conditional_assignment
- prefer_const_constructors
- prefer_const_constructors_in_immutables
- prefer_const_declarations
- prefer_const_literals_to_create_immutables
- prefer_constructors_over_static_methods
- prefer_contains
- prefer_equal_for_default_values
- prefer_expression_function_bodies
- prefer_final_fields
- prefer_final_in_for_each
- prefer_final_locals
- prefer_function_declarations_over_variables
- prefer_generic_function_type_aliases
- prefer_if_elements_to_conditional_expressions
- prefer_if_null_operators
- prefer_initializing_formals
- prefer_inlined_adds
- prefer_int_literals
- prefer_interpolation_to_compose_strings
- prefer_is_empty
- prefer_is_not_empty
- prefer_is_not_operator
- prefer_null_aware_operators
- prefer_single_quotes
- prefer_spread_collections
- prefer_typing_uninitialized_variables
- provide_deprecation_message
- public_member_api_docs
- recursive_getters
- sized_box_for_whitespace
- slash_for_doc_comments
- sort_child_properties_last
- sort_constructors_first
- sort_unnamed_constructors_first
- type_annotate_public_apis
- type_init_formals
- unnecessary_await_in_return
- unnecessary_brace_in_string_interps
- unnecessary_const
- unnecessary_getters_setters
- unnecessary_lambdas
- unnecessary_new
- unnecessary_null_aware_assignments
- unnecessary_null_in_if_null_operators
- unnecessary_nullable_for_final_variable_declarations
- unnecessary_parenthesis
- unnecessary_raw_strings
- unnecessary_string_escapes
- unnecessary_string_interpolations
- unnecessary_this
- use_is_even_rather_than_modulo
- use_late_for_private_fields_and_variables
- use_rethrow_when_possible
- use_setters_to_change_properties
- use_to_and_as_if_applicable
- package_names
- sort_pub_dependencies
- cast_nullable_to_non_nullable
- unnecessary_null_checks
- tighten_type_of_initializing_formals
- null_check_on_nullable_type_parameter
@@ -1,5 +1,3 @@
import 'package:meta/meta.dart';
import 'package:moor/ffi.dart';
import 'package:moor/moor.dart'; import 'package:moor/moor.dart';
import 'package:stream_chat/stream_chat.dart'; import 'package:stream_chat/stream_chat.dart';
@@ -46,10 +44,6 @@ class MoorChatDatabase extends _$MoorChatDatabase {
DatabaseConnection connection, DatabaseConnection connection,
) : super.connect(connection); ) : super.connect(connection);
/// Custom constructor used only for testing
@visibleForTesting
MoorChatDatabase.testable(this._userId) : super(VmDatabase.memory());
final String _userId; final String _userId;
/// User id to which the database is connected /// User id to which the database is connected
@@ -60,31 +60,30 @@ class ChannelEntity extends DataClass implements Insertable<ChannelEntity> {
Map<String, dynamic> data, GeneratedDatabase db, Map<String, dynamic> data, GeneratedDatabase db,
{String? prefix}) { {String? prefix}) {
final effectivePrefix = prefix ?? ''; final effectivePrefix = prefix ?? '';
final stringType = db.typeSystem.forDartType<String>();
final boolType = db.typeSystem.forDartType<bool>();
final dateTimeType = db.typeSystem.forDartType<DateTime>();
final intType = db.typeSystem.forDartType<int>();
return ChannelEntity( return ChannelEntity(
id: stringType.mapFromDatabaseResponse(data['${effectivePrefix}id'])!, id: const StringType()
type: stringType.mapFromDatabaseResponse(data['${effectivePrefix}type'])!, .mapFromDatabaseResponse(data['${effectivePrefix}id'])!,
cid: stringType.mapFromDatabaseResponse(data['${effectivePrefix}cid'])!, type: const StringType()
config: $ChannelsTable.$converter0.mapToDart(stringType .mapFromDatabaseResponse(data['${effectivePrefix}type'])!,
cid: const StringType()
.mapFromDatabaseResponse(data['${effectivePrefix}cid'])!,
config: $ChannelsTable.$converter0.mapToDart(const StringType()
.mapFromDatabaseResponse(data['${effectivePrefix}config']))!, .mapFromDatabaseResponse(data['${effectivePrefix}config']))!,
frozen: frozen: const BoolType()
boolType.mapFromDatabaseResponse(data['${effectivePrefix}frozen'])!, .mapFromDatabaseResponse(data['${effectivePrefix}frozen'])!,
lastMessageAt: dateTimeType lastMessageAt: const DateTimeType()
.mapFromDatabaseResponse(data['${effectivePrefix}last_message_at']), .mapFromDatabaseResponse(data['${effectivePrefix}last_message_at']),
createdAt: dateTimeType createdAt: const DateTimeType()
.mapFromDatabaseResponse(data['${effectivePrefix}created_at'])!, .mapFromDatabaseResponse(data['${effectivePrefix}created_at'])!,
updatedAt: dateTimeType updatedAt: const DateTimeType()
.mapFromDatabaseResponse(data['${effectivePrefix}updated_at'])!, .mapFromDatabaseResponse(data['${effectivePrefix}updated_at'])!,
deletedAt: dateTimeType deletedAt: const DateTimeType()
.mapFromDatabaseResponse(data['${effectivePrefix}deleted_at']), .mapFromDatabaseResponse(data['${effectivePrefix}deleted_at']),
memberCount: intType memberCount: const IntType()
.mapFromDatabaseResponse(data['${effectivePrefix}member_count'])!, .mapFromDatabaseResponse(data['${effectivePrefix}member_count'])!,
createdById: stringType createdById: const StringType()
.mapFromDatabaseResponse(data['${effectivePrefix}created_by_id']), .mapFromDatabaseResponse(data['${effectivePrefix}created_by_id']),
extraData: $ChannelsTable.$converter1.mapToDart(stringType extraData: $ChannelsTable.$converter1.mapToDart(const StringType()
.mapFromDatabaseResponse(data['${effectivePrefix}extra_data'])), .mapFromDatabaseResponse(data['${effectivePrefix}extra_data'])),
); );
} }
@@ -226,7 +225,7 @@ class ChannelEntity extends DataClass implements Insertable<ChannelEntity> {
$mrjc(createdById.hashCode, $mrjc(createdById.hashCode,
extraData.hashCode)))))))))))); extraData.hashCode))))))))))));
@override @override
bool operator ==(dynamic other) => bool operator ==(Object other) =>
identical(this, other) || identical(this, other) ||
(other is ChannelEntity && (other is ChannelEntity &&
other.id == this.id && other.id == this.id &&
@@ -742,56 +741,54 @@ class MessageEntity extends DataClass implements Insertable<MessageEntity> {
Map<String, dynamic> data, GeneratedDatabase db, Map<String, dynamic> data, GeneratedDatabase db,
{String? prefix}) { {String? prefix}) {
final effectivePrefix = prefix ?? ''; final effectivePrefix = prefix ?? '';
final stringType = db.typeSystem.forDartType<String>();
final intType = db.typeSystem.forDartType<int>();
final boolType = db.typeSystem.forDartType<bool>();
final dateTimeType = db.typeSystem.forDartType<DateTime>();
return MessageEntity( return MessageEntity(
id: stringType.mapFromDatabaseResponse(data['${effectivePrefix}id'])!, id: const StringType()
messageText: stringType .mapFromDatabaseResponse(data['${effectivePrefix}id'])!,
messageText: const StringType()
.mapFromDatabaseResponse(data['${effectivePrefix}message_text']), .mapFromDatabaseResponse(data['${effectivePrefix}message_text']),
attachments: $MessagesTable.$converter0.mapToDart(stringType attachments: $MessagesTable.$converter0.mapToDart(const StringType()
.mapFromDatabaseResponse(data['${effectivePrefix}attachments']))!, .mapFromDatabaseResponse(data['${effectivePrefix}attachments']))!,
status: $MessagesTable.$converter1.mapToDart( status: $MessagesTable.$converter1.mapToDart(const IntType()
intType.mapFromDatabaseResponse(data['${effectivePrefix}status']))!, .mapFromDatabaseResponse(data['${effectivePrefix}status']))!,
type: stringType.mapFromDatabaseResponse(data['${effectivePrefix}type'])!, type: const StringType()
mentionedUsers: $MessagesTable.$converter2.mapToDart(stringType .mapFromDatabaseResponse(data['${effectivePrefix}type'])!,
mentionedUsers: $MessagesTable.$converter2.mapToDart(const StringType()
.mapFromDatabaseResponse(data['${effectivePrefix}mentioned_users']))!, .mapFromDatabaseResponse(data['${effectivePrefix}mentioned_users']))!,
reactionCounts: $MessagesTable.$converter3.mapToDart(stringType reactionCounts: $MessagesTable.$converter3.mapToDart(const StringType()
.mapFromDatabaseResponse(data['${effectivePrefix}reaction_counts'])), .mapFromDatabaseResponse(data['${effectivePrefix}reaction_counts'])),
reactionScores: $MessagesTable.$converter4.mapToDart(stringType reactionScores: $MessagesTable.$converter4.mapToDart(const StringType()
.mapFromDatabaseResponse(data['${effectivePrefix}reaction_scores'])), .mapFromDatabaseResponse(data['${effectivePrefix}reaction_scores'])),
parentId: stringType parentId: const StringType()
.mapFromDatabaseResponse(data['${effectivePrefix}parent_id']), .mapFromDatabaseResponse(data['${effectivePrefix}parent_id']),
quotedMessageId: stringType quotedMessageId: const StringType()
.mapFromDatabaseResponse(data['${effectivePrefix}quoted_message_id']), .mapFromDatabaseResponse(data['${effectivePrefix}quoted_message_id']),
replyCount: intType replyCount: const IntType()
.mapFromDatabaseResponse(data['${effectivePrefix}reply_count']), .mapFromDatabaseResponse(data['${effectivePrefix}reply_count']),
showInChannel: boolType showInChannel: const BoolType()
.mapFromDatabaseResponse(data['${effectivePrefix}show_in_channel']), .mapFromDatabaseResponse(data['${effectivePrefix}show_in_channel']),
shadowed: shadowed: const BoolType()
boolType.mapFromDatabaseResponse(data['${effectivePrefix}shadowed'])!, .mapFromDatabaseResponse(data['${effectivePrefix}shadowed'])!,
command: command: const StringType()
stringType.mapFromDatabaseResponse(data['${effectivePrefix}command']), .mapFromDatabaseResponse(data['${effectivePrefix}command']),
createdAt: dateTimeType createdAt: const DateTimeType()
.mapFromDatabaseResponse(data['${effectivePrefix}created_at'])!, .mapFromDatabaseResponse(data['${effectivePrefix}created_at'])!,
updatedAt: dateTimeType updatedAt: const DateTimeType()
.mapFromDatabaseResponse(data['${effectivePrefix}updated_at'])!, .mapFromDatabaseResponse(data['${effectivePrefix}updated_at'])!,
deletedAt: dateTimeType deletedAt: const DateTimeType()
.mapFromDatabaseResponse(data['${effectivePrefix}deleted_at']), .mapFromDatabaseResponse(data['${effectivePrefix}deleted_at']),
userId: userId: const StringType()
stringType.mapFromDatabaseResponse(data['${effectivePrefix}user_id']), .mapFromDatabaseResponse(data['${effectivePrefix}user_id']),
pinned: pinned: const BoolType()
boolType.mapFromDatabaseResponse(data['${effectivePrefix}pinned'])!, .mapFromDatabaseResponse(data['${effectivePrefix}pinned'])!,
pinnedAt: dateTimeType pinnedAt: const DateTimeType()
.mapFromDatabaseResponse(data['${effectivePrefix}pinned_at']), .mapFromDatabaseResponse(data['${effectivePrefix}pinned_at']),
pinExpires: dateTimeType pinExpires: const DateTimeType()
.mapFromDatabaseResponse(data['${effectivePrefix}pin_expires']), .mapFromDatabaseResponse(data['${effectivePrefix}pin_expires']),
pinnedByUserId: stringType pinnedByUserId: const StringType()
.mapFromDatabaseResponse(data['${effectivePrefix}pinned_by_user_id']), .mapFromDatabaseResponse(data['${effectivePrefix}pinned_by_user_id']),
channelCid: stringType channelCid: const StringType()
.mapFromDatabaseResponse(data['${effectivePrefix}channel_cid']), .mapFromDatabaseResponse(data['${effectivePrefix}channel_cid']),
extraData: $MessagesTable.$converter5.mapToDart(stringType extraData: $MessagesTable.$converter5.mapToDart(const StringType()
.mapFromDatabaseResponse(data['${effectivePrefix}extra_data'])), .mapFromDatabaseResponse(data['${effectivePrefix}extra_data'])),
); );
} }
@@ -1066,7 +1063,7 @@ class MessageEntity extends DataClass implements Insertable<MessageEntity> {
pinned.hashCode, pinned.hashCode,
$mrjc(pinnedAt.hashCode, $mrjc(pinExpires.hashCode, $mrjc(pinnedByUserId.hashCode, $mrjc(channelCid.hashCode, extraData.hashCode)))))))))))))))))))))))); $mrjc(pinnedAt.hashCode, $mrjc(pinExpires.hashCode, $mrjc(pinnedByUserId.hashCode, $mrjc(channelCid.hashCode, extraData.hashCode))))))))))))))))))))))));
@override @override
bool operator ==(dynamic other) => bool operator ==(Object other) =>
identical(this, other) || identical(this, other) ||
(other is MessageEntity && (other is MessageEntity &&
other.id == this.id && other.id == this.id &&
@@ -1923,56 +1920,57 @@ class PinnedMessageEntity extends DataClass
Map<String, dynamic> data, GeneratedDatabase db, Map<String, dynamic> data, GeneratedDatabase db,
{String? prefix}) { {String? prefix}) {
final effectivePrefix = prefix ?? ''; final effectivePrefix = prefix ?? '';
final stringType = db.typeSystem.forDartType<String>();
final intType = db.typeSystem.forDartType<int>();
final boolType = db.typeSystem.forDartType<bool>();
final dateTimeType = db.typeSystem.forDartType<DateTime>();
return PinnedMessageEntity( return PinnedMessageEntity(
id: stringType.mapFromDatabaseResponse(data['${effectivePrefix}id'])!, id: const StringType()
messageText: stringType .mapFromDatabaseResponse(data['${effectivePrefix}id'])!,
messageText: const StringType()
.mapFromDatabaseResponse(data['${effectivePrefix}message_text']), .mapFromDatabaseResponse(data['${effectivePrefix}message_text']),
attachments: $PinnedMessagesTable.$converter0.mapToDart(stringType attachments: $PinnedMessagesTable.$converter0.mapToDart(const StringType()
.mapFromDatabaseResponse(data['${effectivePrefix}attachments']))!, .mapFromDatabaseResponse(data['${effectivePrefix}attachments']))!,
status: $PinnedMessagesTable.$converter1.mapToDart( status: $PinnedMessagesTable.$converter1.mapToDart(const IntType()
intType.mapFromDatabaseResponse(data['${effectivePrefix}status']))!, .mapFromDatabaseResponse(data['${effectivePrefix}status']))!,
type: stringType.mapFromDatabaseResponse(data['${effectivePrefix}type'])!, type: const StringType()
mentionedUsers: $PinnedMessagesTable.$converter2.mapToDart(stringType .mapFromDatabaseResponse(data['${effectivePrefix}type'])!,
.mapFromDatabaseResponse(data['${effectivePrefix}mentioned_users']))!, mentionedUsers: $PinnedMessagesTable.$converter2.mapToDart(
reactionCounts: $PinnedMessagesTable.$converter3.mapToDart(stringType const StringType().mapFromDatabaseResponse(
.mapFromDatabaseResponse(data['${effectivePrefix}reaction_counts'])), data['${effectivePrefix}mentioned_users']))!,
reactionScores: $PinnedMessagesTable.$converter4.mapToDart(stringType reactionCounts: $PinnedMessagesTable.$converter3.mapToDart(
.mapFromDatabaseResponse(data['${effectivePrefix}reaction_scores'])), const StringType().mapFromDatabaseResponse(
parentId: stringType data['${effectivePrefix}reaction_counts'])),
reactionScores: $PinnedMessagesTable.$converter4.mapToDart(
const StringType().mapFromDatabaseResponse(
data['${effectivePrefix}reaction_scores'])),
parentId: const StringType()
.mapFromDatabaseResponse(data['${effectivePrefix}parent_id']), .mapFromDatabaseResponse(data['${effectivePrefix}parent_id']),
quotedMessageId: stringType quotedMessageId: const StringType()
.mapFromDatabaseResponse(data['${effectivePrefix}quoted_message_id']), .mapFromDatabaseResponse(data['${effectivePrefix}quoted_message_id']),
replyCount: intType replyCount: const IntType()
.mapFromDatabaseResponse(data['${effectivePrefix}reply_count']), .mapFromDatabaseResponse(data['${effectivePrefix}reply_count']),
showInChannel: boolType showInChannel: const BoolType()
.mapFromDatabaseResponse(data['${effectivePrefix}show_in_channel']), .mapFromDatabaseResponse(data['${effectivePrefix}show_in_channel']),
shadowed: shadowed: const BoolType()
boolType.mapFromDatabaseResponse(data['${effectivePrefix}shadowed'])!, .mapFromDatabaseResponse(data['${effectivePrefix}shadowed'])!,
command: command: const StringType()
stringType.mapFromDatabaseResponse(data['${effectivePrefix}command']), .mapFromDatabaseResponse(data['${effectivePrefix}command']),
createdAt: dateTimeType createdAt: const DateTimeType()
.mapFromDatabaseResponse(data['${effectivePrefix}created_at'])!, .mapFromDatabaseResponse(data['${effectivePrefix}created_at'])!,
updatedAt: dateTimeType updatedAt: const DateTimeType()
.mapFromDatabaseResponse(data['${effectivePrefix}updated_at'])!, .mapFromDatabaseResponse(data['${effectivePrefix}updated_at'])!,
deletedAt: dateTimeType deletedAt: const DateTimeType()
.mapFromDatabaseResponse(data['${effectivePrefix}deleted_at']), .mapFromDatabaseResponse(data['${effectivePrefix}deleted_at']),
userId: userId: const StringType()
stringType.mapFromDatabaseResponse(data['${effectivePrefix}user_id']), .mapFromDatabaseResponse(data['${effectivePrefix}user_id']),
pinned: pinned: const BoolType()
boolType.mapFromDatabaseResponse(data['${effectivePrefix}pinned'])!, .mapFromDatabaseResponse(data['${effectivePrefix}pinned'])!,
pinnedAt: dateTimeType pinnedAt: const DateTimeType()
.mapFromDatabaseResponse(data['${effectivePrefix}pinned_at']), .mapFromDatabaseResponse(data['${effectivePrefix}pinned_at']),
pinExpires: dateTimeType pinExpires: const DateTimeType()
.mapFromDatabaseResponse(data['${effectivePrefix}pin_expires']), .mapFromDatabaseResponse(data['${effectivePrefix}pin_expires']),
pinnedByUserId: stringType pinnedByUserId: const StringType()
.mapFromDatabaseResponse(data['${effectivePrefix}pinned_by_user_id']), .mapFromDatabaseResponse(data['${effectivePrefix}pinned_by_user_id']),
channelCid: stringType channelCid: const StringType()
.mapFromDatabaseResponse(data['${effectivePrefix}channel_cid']), .mapFromDatabaseResponse(data['${effectivePrefix}channel_cid']),
extraData: $PinnedMessagesTable.$converter5.mapToDart(stringType extraData: $PinnedMessagesTable.$converter5.mapToDart(const StringType()
.mapFromDatabaseResponse(data['${effectivePrefix}extra_data'])), .mapFromDatabaseResponse(data['${effectivePrefix}extra_data'])),
); );
} }
@@ -2247,7 +2245,7 @@ class PinnedMessageEntity extends DataClass
pinned.hashCode, pinned.hashCode,
$mrjc(pinnedAt.hashCode, $mrjc(pinExpires.hashCode, $mrjc(pinnedByUserId.hashCode, $mrjc(channelCid.hashCode, extraData.hashCode)))))))))))))))))))))))); $mrjc(pinnedAt.hashCode, $mrjc(pinExpires.hashCode, $mrjc(pinnedByUserId.hashCode, $mrjc(channelCid.hashCode, extraData.hashCode))))))))))))))))))))))));
@override @override
bool operator ==(dynamic other) => bool operator ==(Object other) =>
identical(this, other) || identical(this, other) ||
(other is PinnedMessageEntity && (other is PinnedMessageEntity &&
other.id == this.id && other.id == this.id &&
@@ -3031,19 +3029,18 @@ class ReactionEntity extends DataClass implements Insertable<ReactionEntity> {
Map<String, dynamic> data, GeneratedDatabase db, Map<String, dynamic> data, GeneratedDatabase db,
{String? prefix}) { {String? prefix}) {
final effectivePrefix = prefix ?? ''; final effectivePrefix = prefix ?? '';
final stringType = db.typeSystem.forDartType<String>();
final dateTimeType = db.typeSystem.forDartType<DateTime>();
final intType = db.typeSystem.forDartType<int>();
return ReactionEntity( return ReactionEntity(
userId: stringType userId: const StringType()
.mapFromDatabaseResponse(data['${effectivePrefix}user_id'])!, .mapFromDatabaseResponse(data['${effectivePrefix}user_id'])!,
messageId: stringType messageId: const StringType()
.mapFromDatabaseResponse(data['${effectivePrefix}message_id'])!, .mapFromDatabaseResponse(data['${effectivePrefix}message_id'])!,
type: stringType.mapFromDatabaseResponse(data['${effectivePrefix}type'])!, type: const StringType()
createdAt: dateTimeType .mapFromDatabaseResponse(data['${effectivePrefix}type'])!,
createdAt: const DateTimeType()
.mapFromDatabaseResponse(data['${effectivePrefix}created_at'])!, .mapFromDatabaseResponse(data['${effectivePrefix}created_at'])!,
score: intType.mapFromDatabaseResponse(data['${effectivePrefix}score'])!, score: const IntType()
extraData: $ReactionsTable.$converter0.mapToDart(stringType .mapFromDatabaseResponse(data['${effectivePrefix}score'])!,
extraData: $ReactionsTable.$converter0.mapToDart(const StringType()
.mapFromDatabaseResponse(data['${effectivePrefix}extra_data'])), .mapFromDatabaseResponse(data['${effectivePrefix}extra_data'])),
); );
} }
@@ -3125,7 +3122,7 @@ class ReactionEntity extends DataClass implements Insertable<ReactionEntity> {
$mrjc(createdAt.hashCode, $mrjc(createdAt.hashCode,
$mrjc(score.hashCode, extraData.hashCode)))))); $mrjc(score.hashCode, extraData.hashCode))))));
@override @override
bool operator ==(dynamic other) => bool operator ==(Object other) =>
identical(this, other) || identical(this, other) ||
(other is ReactionEntity && (other is ReactionEntity &&
other.userId == this.userId && other.userId == this.userId &&
@@ -3395,23 +3392,22 @@ class UserEntity extends DataClass implements Insertable<UserEntity> {
factory UserEntity.fromData(Map<String, dynamic> data, GeneratedDatabase db, factory UserEntity.fromData(Map<String, dynamic> data, GeneratedDatabase db,
{String? prefix}) { {String? prefix}) {
final effectivePrefix = prefix ?? ''; final effectivePrefix = prefix ?? '';
final stringType = db.typeSystem.forDartType<String>();
final dateTimeType = db.typeSystem.forDartType<DateTime>();
final boolType = db.typeSystem.forDartType<bool>();
return UserEntity( return UserEntity(
id: stringType.mapFromDatabaseResponse(data['${effectivePrefix}id'])!, id: const StringType()
role: stringType.mapFromDatabaseResponse(data['${effectivePrefix}role']), .mapFromDatabaseResponse(data['${effectivePrefix}id'])!,
createdAt: dateTimeType role: const StringType()
.mapFromDatabaseResponse(data['${effectivePrefix}role']),
createdAt: const DateTimeType()
.mapFromDatabaseResponse(data['${effectivePrefix}created_at'])!, .mapFromDatabaseResponse(data['${effectivePrefix}created_at'])!,
updatedAt: dateTimeType updatedAt: const DateTimeType()
.mapFromDatabaseResponse(data['${effectivePrefix}updated_at'])!, .mapFromDatabaseResponse(data['${effectivePrefix}updated_at'])!,
lastActive: dateTimeType lastActive: const DateTimeType()
.mapFromDatabaseResponse(data['${effectivePrefix}last_active']), .mapFromDatabaseResponse(data['${effectivePrefix}last_active']),
online: online: const BoolType()
boolType.mapFromDatabaseResponse(data['${effectivePrefix}online'])!, .mapFromDatabaseResponse(data['${effectivePrefix}online'])!,
banned: banned: const BoolType()
boolType.mapFromDatabaseResponse(data['${effectivePrefix}banned'])!, .mapFromDatabaseResponse(data['${effectivePrefix}banned'])!,
extraData: $UsersTable.$converter0.mapToDart(stringType extraData: $UsersTable.$converter0.mapToDart(const StringType()
.mapFromDatabaseResponse(data['${effectivePrefix}extra_data']))!, .mapFromDatabaseResponse(data['${effectivePrefix}extra_data']))!,
); );
} }
@@ -3513,7 +3509,7 @@ class UserEntity extends DataClass implements Insertable<UserEntity> {
$mrjc(online.hashCode, $mrjc(online.hashCode,
$mrjc(banned.hashCode, extraData.hashCode)))))))); $mrjc(banned.hashCode, extraData.hashCode))))))));
@override @override
bool operator ==(dynamic other) => bool operator ==(Object other) =>
identical(this, other) || identical(this, other) ||
(other is UserEntity && (other is UserEntity &&
other.id == this.id && other.id == this.id &&
@@ -3554,7 +3550,7 @@ class UsersCompanion extends UpdateCompanion<UserEntity> {
this.online = const Value.absent(), this.online = const Value.absent(),
this.banned = const Value.absent(), this.banned = const Value.absent(),
required Map<String, Object?> extraData, required Map<String, Object?> extraData,
}) : id = Value(id), }) : id = Value(id),
extraData = Value(extraData); extraData = Value(extraData);
static Insertable<UserEntity> custom({ static Insertable<UserEntity> custom({
Expression<String>? id, Expression<String>? id,
@@ -3841,30 +3837,28 @@ class MemberEntity extends DataClass implements Insertable<MemberEntity> {
factory MemberEntity.fromData(Map<String, dynamic> data, GeneratedDatabase db, factory MemberEntity.fromData(Map<String, dynamic> data, GeneratedDatabase db,
{String? prefix}) { {String? prefix}) {
final effectivePrefix = prefix ?? ''; final effectivePrefix = prefix ?? '';
final stringType = db.typeSystem.forDartType<String>();
final dateTimeType = db.typeSystem.forDartType<DateTime>();
final boolType = db.typeSystem.forDartType<bool>();
return MemberEntity( return MemberEntity(
userId: stringType userId: const StringType()
.mapFromDatabaseResponse(data['${effectivePrefix}user_id'])!, .mapFromDatabaseResponse(data['${effectivePrefix}user_id'])!,
channelCid: stringType channelCid: const StringType()
.mapFromDatabaseResponse(data['${effectivePrefix}channel_cid'])!, .mapFromDatabaseResponse(data['${effectivePrefix}channel_cid'])!,
role: stringType.mapFromDatabaseResponse(data['${effectivePrefix}role']), role: const StringType()
inviteAcceptedAt: dateTimeType.mapFromDatabaseResponse( .mapFromDatabaseResponse(data['${effectivePrefix}role']),
inviteAcceptedAt: const DateTimeType().mapFromDatabaseResponse(
data['${effectivePrefix}invite_accepted_at']), data['${effectivePrefix}invite_accepted_at']),
inviteRejectedAt: dateTimeType.mapFromDatabaseResponse( inviteRejectedAt: const DateTimeType().mapFromDatabaseResponse(
data['${effectivePrefix}invite_rejected_at']), data['${effectivePrefix}invite_rejected_at']),
invited: invited: const BoolType()
boolType.mapFromDatabaseResponse(data['${effectivePrefix}invited'])!, .mapFromDatabaseResponse(data['${effectivePrefix}invited'])!,
banned: banned: const BoolType()
boolType.mapFromDatabaseResponse(data['${effectivePrefix}banned'])!, .mapFromDatabaseResponse(data['${effectivePrefix}banned'])!,
shadowBanned: boolType shadowBanned: const BoolType()
.mapFromDatabaseResponse(data['${effectivePrefix}shadow_banned'])!, .mapFromDatabaseResponse(data['${effectivePrefix}shadow_banned'])!,
isModerator: boolType isModerator: const BoolType()
.mapFromDatabaseResponse(data['${effectivePrefix}is_moderator'])!, .mapFromDatabaseResponse(data['${effectivePrefix}is_moderator'])!,
createdAt: dateTimeType createdAt: const DateTimeType()
.mapFromDatabaseResponse(data['${effectivePrefix}created_at'])!, .mapFromDatabaseResponse(data['${effectivePrefix}created_at'])!,
updatedAt: dateTimeType updatedAt: const DateTimeType()
.mapFromDatabaseResponse(data['${effectivePrefix}updated_at'])!, .mapFromDatabaseResponse(data['${effectivePrefix}updated_at'])!,
); );
} }
@@ -3997,7 +3991,7 @@ class MemberEntity extends DataClass implements Insertable<MemberEntity> {
$mrjc(createdAt.hashCode, $mrjc(createdAt.hashCode,
updatedAt.hashCode))))))))))); updatedAt.hashCode)))))))))));
@override @override
bool operator ==(dynamic other) => bool operator ==(Object other) =>
identical(this, other) || identical(this, other) ||
(other is MemberEntity && (other is MemberEntity &&
other.userId == this.userId && other.userId == this.userId &&
@@ -4396,17 +4390,14 @@ class ReadEntity extends DataClass implements Insertable<ReadEntity> {
factory ReadEntity.fromData(Map<String, dynamic> data, GeneratedDatabase db, factory ReadEntity.fromData(Map<String, dynamic> data, GeneratedDatabase db,
{String? prefix}) { {String? prefix}) {
final effectivePrefix = prefix ?? ''; final effectivePrefix = prefix ?? '';
final dateTimeType = db.typeSystem.forDartType<DateTime>();
final stringType = db.typeSystem.forDartType<String>();
final intType = db.typeSystem.forDartType<int>();
return ReadEntity( return ReadEntity(
lastRead: dateTimeType lastRead: const DateTimeType()
.mapFromDatabaseResponse(data['${effectivePrefix}last_read'])!, .mapFromDatabaseResponse(data['${effectivePrefix}last_read'])!,
userId: stringType userId: const StringType()
.mapFromDatabaseResponse(data['${effectivePrefix}user_id'])!, .mapFromDatabaseResponse(data['${effectivePrefix}user_id'])!,
channelCid: stringType channelCid: const StringType()
.mapFromDatabaseResponse(data['${effectivePrefix}channel_cid'])!, .mapFromDatabaseResponse(data['${effectivePrefix}channel_cid'])!,
unreadMessages: intType unreadMessages: const IntType()
.mapFromDatabaseResponse(data['${effectivePrefix}unread_messages'])!, .mapFromDatabaseResponse(data['${effectivePrefix}unread_messages'])!,
); );
} }
@@ -4469,7 +4460,7 @@ class ReadEntity extends DataClass implements Insertable<ReadEntity> {
$mrjc(userId.hashCode, $mrjc(userId.hashCode,
$mrjc(channelCid.hashCode, unreadMessages.hashCode)))); $mrjc(channelCid.hashCode, unreadMessages.hashCode))));
@override @override
bool operator ==(dynamic other) => bool operator ==(Object other) =>
identical(this, other) || identical(this, other) ||
(other is ReadEntity && (other is ReadEntity &&
other.lastRead == this.lastRead && other.lastRead == this.lastRead &&
@@ -4666,11 +4657,10 @@ class ChannelQueryEntity extends DataClass
Map<String, dynamic> data, GeneratedDatabase db, Map<String, dynamic> data, GeneratedDatabase db,
{String? prefix}) { {String? prefix}) {
final effectivePrefix = prefix ?? ''; final effectivePrefix = prefix ?? '';
final stringType = db.typeSystem.forDartType<String>();
return ChannelQueryEntity( return ChannelQueryEntity(
queryHash: stringType queryHash: const StringType()
.mapFromDatabaseResponse(data['${effectivePrefix}query_hash'])!, .mapFromDatabaseResponse(data['${effectivePrefix}query_hash'])!,
channelCid: stringType channelCid: const StringType()
.mapFromDatabaseResponse(data['${effectivePrefix}channel_cid'])!, .mapFromDatabaseResponse(data['${effectivePrefix}channel_cid'])!,
); );
} }
@@ -4716,7 +4706,7 @@ class ChannelQueryEntity extends DataClass
@override @override
int get hashCode => $mrjf($mrjc(queryHash.hashCode, channelCid.hashCode)); int get hashCode => $mrjf($mrjc(queryHash.hashCode, channelCid.hashCode));
@override @override
bool operator ==(dynamic other) => bool operator ==(Object other) =>
identical(this, other) || identical(this, other) ||
(other is ChannelQueryEntity && (other is ChannelQueryEntity &&
other.queryHash == this.queryHash && other.queryHash == this.queryHash &&
@@ -4733,7 +4723,7 @@ class ChannelQueriesCompanion extends UpdateCompanion<ChannelQueryEntity> {
ChannelQueriesCompanion.insert({ ChannelQueriesCompanion.insert({
required String queryHash, required String queryHash,
required String channelCid, required String channelCid,
}) : queryHash = Value(queryHash), }) : queryHash = Value(queryHash),
channelCid = Value(channelCid); channelCid = Value(channelCid);
static Insertable<ChannelQueryEntity> custom({ static Insertable<ChannelQueryEntity> custom({
Expression<String>? queryHash, Expression<String>? queryHash,
@@ -4876,20 +4866,18 @@ class ConnectionEventEntity extends DataClass
Map<String, dynamic> data, GeneratedDatabase db, Map<String, dynamic> data, GeneratedDatabase db,
{String? prefix}) { {String? prefix}) {
final effectivePrefix = prefix ?? ''; final effectivePrefix = prefix ?? '';
final intType = db.typeSystem.forDartType<int>();
final stringType = db.typeSystem.forDartType<String>();
final dateTimeType = db.typeSystem.forDartType<DateTime>();
return ConnectionEventEntity( return ConnectionEventEntity(
id: intType.mapFromDatabaseResponse(data['${effectivePrefix}id'])!, id: const IntType()
ownUser: $ConnectionEventsTable.$converter0.mapToDart(stringType .mapFromDatabaseResponse(data['${effectivePrefix}id'])!,
ownUser: $ConnectionEventsTable.$converter0.mapToDart(const StringType()
.mapFromDatabaseResponse(data['${effectivePrefix}own_user'])), .mapFromDatabaseResponse(data['${effectivePrefix}own_user'])),
totalUnreadCount: intType.mapFromDatabaseResponse( totalUnreadCount: const IntType().mapFromDatabaseResponse(
data['${effectivePrefix}total_unread_count']), data['${effectivePrefix}total_unread_count']),
unreadChannels: intType unreadChannels: const IntType()
.mapFromDatabaseResponse(data['${effectivePrefix}unread_channels']), .mapFromDatabaseResponse(data['${effectivePrefix}unread_channels']),
lastEventAt: dateTimeType lastEventAt: const DateTimeType()
.mapFromDatabaseResponse(data['${effectivePrefix}last_event_at']), .mapFromDatabaseResponse(data['${effectivePrefix}last_event_at']),
lastSyncAt: dateTimeType lastSyncAt: const DateTimeType()
.mapFromDatabaseResponse(data['${effectivePrefix}last_sync_at']), .mapFromDatabaseResponse(data['${effectivePrefix}last_sync_at']),
); );
} }
@@ -4982,7 +4970,7 @@ class ConnectionEventEntity extends DataClass
$mrjc(unreadChannels.hashCode, $mrjc(unreadChannels.hashCode,
$mrjc(lastEventAt.hashCode, lastSyncAt.hashCode)))))); $mrjc(lastEventAt.hashCode, lastSyncAt.hashCode))))));
@override @override
bool operator ==(dynamic other) => bool operator ==(Object other) =>
identical(this, other) || identical(this, other) ||
(other is ConnectionEventEntity && (other is ConnectionEventEntity &&
other.id == this.id && other.id == this.id &&
@@ -1,7 +1,7 @@
name: stream_chat_persistence name: stream_chat_persistence
homepage: https://github.com/GetStream/stream-chat-flutter homepage: https://github.com/GetStream/stream-chat-flutter
description: Official Stream Chat Persistence library. Build your own chat experience using Dart and Flutter. description: Official Stream Chat Persistence library. Build your own chat experience using Dart and Flutter.
version: 2.0.0-nullsafety.1 version: 2.0.0-nullsafety.2
repository: https://github.com/GetStream/stream-chat-flutter repository: https://github.com/GetStream/stream-chat-flutter
issue_tracker: https://github.com/GetStream/stream-chat-flutter/issues issue_tracker: https://github.com/GetStream/stream-chat-flutter/issues
@@ -17,8 +17,8 @@ dependencies:
mutex: ^3.0.0 mutex: ^3.0.0
path: ^1.8.0 path: ^1.8.0
path_provider: ^2.0.1 path_provider: ^2.0.1
sqlite3_flutter_libs: ^0.4.1 sqlite3_flutter_libs: ^0.4.2
stream_chat: ^2.0.0-nullsafety.0 stream_chat: ^2.0.0-nullsafety.2
dev_dependencies: dev_dependencies:
build_runner: ^2.0.1 build_runner: ^2.0.1
@@ -3,12 +3,14 @@ import 'package:stream_chat_persistence/src/dao/channel_dao.dart';
import 'package:stream_chat_persistence/src/db/moor_chat_database.dart'; import 'package:stream_chat_persistence/src/db/moor_chat_database.dart';
import 'package:test/test.dart'; import 'package:test/test.dart';
import '../../stream_chat_persistence_client_test.dart';
void main() { void main() {
late ChannelDao channelDao; late ChannelDao channelDao;
late MoorChatDatabase database; late MoorChatDatabase database;
setUp(() { setUp(() {
database = MoorChatDatabase.testable('testUserId'); database = testDatabaseProvider('testUserId');
channelDao = database.channelDao; channelDao = database.channelDao;
}); });
@@ -5,6 +5,7 @@ import 'package:stream_chat_persistence/src/dao/channel_query_dao.dart';
import 'package:stream_chat_persistence/src/db/moor_chat_database.dart'; import 'package:stream_chat_persistence/src/db/moor_chat_database.dart';
import 'package:test/test.dart'; import 'package:test/test.dart';
import '../../stream_chat_persistence_client_test.dart';
import '../utils/date_matcher.dart'; import '../utils/date_matcher.dart';
void main() { void main() {
@@ -12,7 +13,7 @@ void main() {
late ChannelQueryDao channelQueryDao; late ChannelQueryDao channelQueryDao;
setUp(() { setUp(() {
database = MoorChatDatabase.testable('testUserId'); database = testDatabaseProvider('testUserId');
channelQueryDao = database.channelQueryDao; channelQueryDao = database.channelQueryDao;
}); });
@@ -3,6 +3,7 @@ import 'package:stream_chat_persistence/src/dao/connection_event_dao.dart';
import 'package:stream_chat_persistence/src/db/moor_chat_database.dart'; import 'package:stream_chat_persistence/src/db/moor_chat_database.dart';
import 'package:test/test.dart'; import 'package:test/test.dart';
import '../../stream_chat_persistence_client_test.dart';
import '../utils/date_matcher.dart'; import '../utils/date_matcher.dart';
void main() { void main() {
@@ -10,7 +11,7 @@ void main() {
late MoorChatDatabase database; late MoorChatDatabase database;
setUp(() { setUp(() {
database = MoorChatDatabase.testable('testUserId'); database = testDatabaseProvider('testUserId');
eventDao = database.connectionEventDao; eventDao = database.connectionEventDao;
}); });
@@ -5,6 +5,7 @@ import 'package:stream_chat_persistence/src/dao/dao.dart';
import 'package:stream_chat_persistence/src/db/moor_chat_database.dart'; import 'package:stream_chat_persistence/src/db/moor_chat_database.dart';
import 'package:test/test.dart'; import 'package:test/test.dart';
import '../../stream_chat_persistence_client_test.dart';
import '../utils/date_matcher.dart'; import '../utils/date_matcher.dart';
void main() { void main() {
@@ -12,7 +13,7 @@ void main() {
late MoorChatDatabase database; late MoorChatDatabase database;
setUp(() { setUp(() {
database = MoorChatDatabase.testable('testUserId'); database = testDatabaseProvider('testUserId');
memberDao = database.memberDao; memberDao = database.memberDao;
}); });
@@ -5,12 +5,14 @@ import 'package:stream_chat_persistence/src/dao/dao.dart';
import 'package:stream_chat_persistence/src/db/moor_chat_database.dart'; import 'package:stream_chat_persistence/src/db/moor_chat_database.dart';
import 'package:test/test.dart'; import 'package:test/test.dart';
import '../../stream_chat_persistence_client_test.dart';
void main() { void main() {
late MessageDao messageDao; late MessageDao messageDao;
late MoorChatDatabase database; late MoorChatDatabase database;
setUp(() { setUp(() {
database = MoorChatDatabase.testable('testUserId'); database = testDatabaseProvider('testUserId');
messageDao = database.messageDao; messageDao = database.messageDao;
}); });
@@ -5,12 +5,14 @@ import 'package:stream_chat_persistence/src/dao/dao.dart';
import 'package:stream_chat_persistence/src/db/moor_chat_database.dart'; import 'package:stream_chat_persistence/src/db/moor_chat_database.dart';
import 'package:test/test.dart'; import 'package:test/test.dart';
import '../../stream_chat_persistence_client_test.dart';
void main() { void main() {
late PinnedMessageDao pinnedMessageDao; late PinnedMessageDao pinnedMessageDao;
late MoorChatDatabase database; late MoorChatDatabase database;
setUp(() { setUp(() {
database = MoorChatDatabase.testable('testUserId'); database = testDatabaseProvider('testUserId');
pinnedMessageDao = database.pinnedMessageDao; pinnedMessageDao = database.pinnedMessageDao;
}); });
@@ -5,12 +5,14 @@ import 'package:stream_chat_persistence/src/dao/reaction_dao.dart';
import 'package:stream_chat_persistence/src/db/moor_chat_database.dart'; import 'package:stream_chat_persistence/src/db/moor_chat_database.dart';
import 'package:test/test.dart'; import 'package:test/test.dart';
import '../../stream_chat_persistence_client_test.dart';
void main() { void main() {
late ReactionDao reactionDao; late ReactionDao reactionDao;
late MoorChatDatabase database; late MoorChatDatabase database;
setUp(() { setUp(() {
database = MoorChatDatabase.testable('testUserId'); database = testDatabaseProvider('testUserId');
reactionDao = database.reactionDao; reactionDao = database.reactionDao;
}); });
@@ -3,6 +3,7 @@ import 'package:stream_chat_persistence/src/dao/dao.dart';
import 'package:stream_chat_persistence/src/db/moor_chat_database.dart'; import 'package:stream_chat_persistence/src/db/moor_chat_database.dart';
import 'package:test/test.dart'; import 'package:test/test.dart';
import '../../stream_chat_persistence_client_test.dart';
import '../utils/date_matcher.dart'; import '../utils/date_matcher.dart';
void main() { void main() {
@@ -10,7 +11,7 @@ void main() {
late MoorChatDatabase database; late MoorChatDatabase database;
setUp(() { setUp(() {
database = MoorChatDatabase.testable('testUserId'); database = testDatabaseProvider('testUserId');
readDao = database.readDao; readDao = database.readDao;
}); });
@@ -5,12 +5,14 @@ import 'package:stream_chat_persistence/src/db/moor_chat_database.dart';
import 'package:test/test.dart'; import 'package:test/test.dart';
import 'package:stream_chat/stream_chat.dart'; import 'package:stream_chat/stream_chat.dart';
import '../../stream_chat_persistence_client_test.dart';
void main() { void main() {
late UserDao userDao; late UserDao userDao;
late MoorChatDatabase database; late MoorChatDatabase database;
setUp(() { setUp(() {
database = MoorChatDatabase.testable('testUserId'); database = testDatabaseProvider('testUserId');
userDao = database.userDao; userDao = database.userDao;
}); });
@@ -1,4 +1,5 @@
import 'package:mocktail/mocktail.dart'; import 'package:mocktail/mocktail.dart';
import 'package:moor/ffi.dart';
import 'package:stream_chat/stream_chat.dart'; import 'package:stream_chat/stream_chat.dart';
import 'package:stream_chat_persistence/src/db/moor_chat_database.dart'; import 'package:stream_chat_persistence/src/db/moor_chat_database.dart';
import 'package:stream_chat_persistence/src/stream_chat_persistence_client.dart'; import 'package:stream_chat_persistence/src/stream_chat_persistence_client.dart';
@@ -6,8 +7,8 @@ import 'package:test/test.dart';
import 'mock_chat_database.dart'; import 'mock_chat_database.dart';
import 'src/utils/date_matcher.dart'; import 'src/utils/date_matcher.dart';
MoorChatDatabase _testDatabaseProvider(String userId, ConnectionMode mode) => MoorChatDatabase testDatabaseProvider(String userId, [ConnectionMode? mode]) =>
MoorChatDatabase.testable(userId); MoorChatDatabase(userId, VmDatabase.memory());
void main() { void main() {
group('connect', () { group('connect', () {
@@ -15,7 +16,7 @@ void main() {
test('successfully connects with the Database', () async { test('successfully connects with the Database', () async {
final client = StreamChatPersistenceClient(logLevel: Level.ALL); final client = StreamChatPersistenceClient(logLevel: Level.ALL);
expect(client.db, isNull); expect(client.db, isNull);
await client.connect(userId, databaseProvider: _testDatabaseProvider); await client.connect(userId, databaseProvider: testDatabaseProvider);
expect(client.db, isNotNull); expect(client.db, isNotNull);
expect(client.db, isA<MoorChatDatabase>()); expect(client.db, isA<MoorChatDatabase>());
expect(client.db!.userId, userId); expect(client.db!.userId, userId);
@@ -28,13 +29,13 @@ void main() {
test('throws if already connected', () async { test('throws if already connected', () async {
final client = StreamChatPersistenceClient(logLevel: Level.ALL); final client = StreamChatPersistenceClient(logLevel: Level.ALL);
expect(client.db, isNull); expect(client.db, isNull);
await client.connect(userId, databaseProvider: _testDatabaseProvider); await client.connect(userId, databaseProvider: testDatabaseProvider);
expect(client.db, isNotNull); expect(client.db, isNotNull);
expect(client.db, isNotNull); expect(client.db, isNotNull);
expect(client.db, isA<MoorChatDatabase>()); expect(client.db, isA<MoorChatDatabase>());
expect(client.db!.userId, userId); expect(client.db!.userId, userId);
expect( expect(
() => client.connect(userId, databaseProvider: _testDatabaseProvider), () => client.connect(userId, databaseProvider: testDatabaseProvider),
throwsException, throwsException,
); );
@@ -47,7 +48,7 @@ void main() {
test('disconnect', () async { test('disconnect', () async {
const userId = 'testUserId'; const userId = 'testUserId';
final client = StreamChatPersistenceClient(logLevel: Level.ALL); final client = StreamChatPersistenceClient(logLevel: Level.ALL);
await client.connect(userId, databaseProvider: _testDatabaseProvider); await client.connect(userId, databaseProvider: testDatabaseProvider);
expect(client.db, isNotNull); expect(client.db, isNotNull);
await client.disconnect(flush: true); await client.disconnect(flush: true);
expect(client.db, isNull); expect(client.db, isNull);