added lint changes, started migrating
This commit is contained in:
@@ -13,52 +13,138 @@ linter:
|
|||||||
# these rules are documented on and in the same order as
|
# these rules are documented on and in the same order as
|
||||||
# the Dart Lint rules page to make maintenance easier
|
# the Dart Lint rules page to make maintenance easier
|
||||||
# https://github.com/dart-lang/linter/blob/master/example/all.yaml
|
# https://github.com/dart-lang/linter/blob/master/example/all.yaml
|
||||||
# - always_declare_return_types
|
- always_use_package_imports
|
||||||
# - always_specify_types
|
|
||||||
# - annotate_overrides
|
|
||||||
# - avoid_as
|
|
||||||
- avoid_empty_else
|
- avoid_empty_else
|
||||||
- avoid_init_to_null
|
- avoid_relative_lib_imports
|
||||||
- avoid_return_types_on_setters
|
- avoid_slow_async_io
|
||||||
- avoid_web_libraries_in_flutter
|
- avoid_types_as_parameter_names
|
||||||
- await_only_futures
|
|
||||||
- camel_case_types
|
|
||||||
- cancel_subscriptions
|
- cancel_subscriptions
|
||||||
- close_sinks
|
- close_sinks
|
||||||
# - comment_references # we do not presume as to what people want to reference in their dartdocs
|
|
||||||
# - constant_identifier_names # https://github.com/dart-lang/linter/issues/204
|
|
||||||
- control_flow_in_finally
|
- control_flow_in_finally
|
||||||
- empty_constructor_bodies
|
|
||||||
- empty_statements
|
- empty_statements
|
||||||
- hash_and_equals
|
- hash_and_equals
|
||||||
- implementation_imports
|
- invariant_booleans
|
||||||
# - invariant_booleans
|
- iterable_contains_unrelated_type
|
||||||
# - iterable_contains_unrelated_type
|
- list_remove_unrelated_type
|
||||||
- library_names
|
- literal_only_boolean_expressions
|
||||||
# - library_prefixes
|
- no_adjacent_strings_in_list
|
||||||
# - list_remove_unrelated_type
|
- no_duplicate_case_values
|
||||||
# - literal_only_boolean_expressions
|
- no_logic_in_create_state
|
||||||
- non_constant_identifier_names
|
- prefer_void_to_null
|
||||||
# - one_member_abstracts
|
|
||||||
# - only_throw_errors
|
|
||||||
# - overridden_fields
|
|
||||||
# - package_api_docs
|
|
||||||
- package_names
|
|
||||||
- package_prefixed_library_names
|
|
||||||
- prefer_is_not_empty
|
|
||||||
# - prefer_mixin # https://github.com/dart-lang/language/issues/32
|
|
||||||
# - public_member_api_docs
|
|
||||||
- slash_for_doc_comments
|
|
||||||
# - sort_constructors_first
|
|
||||||
# - sort_unnamed_constructors_first
|
|
||||||
# - super_goes_last # no longer needed w/ Dart 2
|
|
||||||
- test_types_in_equals
|
- test_types_in_equals
|
||||||
- throw_in_finally
|
- throw_in_finally
|
||||||
# - type_annotate_public_apis # subset of always_specify_types
|
|
||||||
- type_init_formals
|
|
||||||
# - unawaited_futures
|
|
||||||
- unnecessary_brace_in_string_interps
|
|
||||||
- unnecessary_getters_setters
|
|
||||||
- unnecessary_statements
|
- unnecessary_statements
|
||||||
- unrelated_type_equality_checks
|
- unrelated_type_equality_checks
|
||||||
|
- omit_local_variable_types
|
||||||
|
- use_key_in_widget_constructors
|
||||||
- valid_regexps
|
- 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,7 +1,7 @@
|
|||||||
|
export 'attachment_upload_state_builder.dart';
|
||||||
|
export 'attachment_widget.dart'
|
||||||
|
show AttachmentError, AttachmentSource, AttachmentSourceX;
|
||||||
export 'file_attachment.dart';
|
export 'file_attachment.dart';
|
||||||
export 'giphy_attachment.dart';
|
export 'giphy_attachment.dart';
|
||||||
export 'image_attachment.dart';
|
export 'image_attachment.dart';
|
||||||
export 'video_attachment.dart';
|
export 'video_attachment.dart';
|
||||||
export 'attachment_upload_state_builder.dart';
|
|
||||||
export 'attachment_widget.dart'
|
|
||||||
show AttachmentError, AttachmentSource, AttachmentSourceX;
|
|
||||||
|
|||||||
@@ -1,57 +1,59 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:stream_chat_flutter/stream_chat_flutter.dart';
|
||||||
import 'package:stream_chat_flutter_core/stream_chat_flutter_core.dart';
|
import 'package:stream_chat_flutter_core/stream_chat_flutter_core.dart';
|
||||||
|
|
||||||
import '../stream_chat_theme.dart';
|
/// Title for attachments
|
||||||
import '../utils.dart';
|
|
||||||
|
|
||||||
class AttachmentTitle extends StatelessWidget {
|
class AttachmentTitle extends StatelessWidget {
|
||||||
|
/// Supply attachment and theme for constructing title
|
||||||
const AttachmentTitle({
|
const AttachmentTitle({
|
||||||
Key? key,
|
Key? key,
|
||||||
required this.attachment,
|
required this.attachment,
|
||||||
required this.messageTheme,
|
required this.messageTheme,
|
||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
|
|
||||||
|
/// Theme to apply to text
|
||||||
final MessageTheme messageTheme;
|
final MessageTheme messageTheme;
|
||||||
|
|
||||||
|
/// Attachment data to display
|
||||||
final Attachment attachment;
|
final Attachment attachment;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) => GestureDetector(
|
||||||
return GestureDetector(
|
onTap: () {
|
||||||
onTap: () {
|
if (attachment.titleLink != null) {
|
||||||
if (attachment.titleLink != null) {
|
launchURL(context, attachment.titleLink);
|
||||||
launchURL(context, attachment.titleLink!);
|
}
|
||||||
}
|
},
|
||||||
},
|
child: Padding(
|
||||||
child: Padding(
|
padding: const EdgeInsets.all(8),
|
||||||
padding: const EdgeInsets.all(8.0),
|
child: Column(
|
||||||
child: Column(
|
mainAxisSize: MainAxisSize.min,
|
||||||
mainAxisSize: MainAxisSize.min,
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
children: <Widget>[
|
||||||
children: <Widget>[
|
if (attachment.title != null)
|
||||||
if (attachment.title != null)
|
Text(
|
||||||
Text(
|
attachment.title!,
|
||||||
attachment.title!,
|
overflow: TextOverflow.ellipsis,
|
||||||
overflow: TextOverflow.ellipsis,
|
style: messageTheme.messageText?.copyWith(
|
||||||
style: messageTheme.messageText?.copyWith(
|
color: StreamChatTheme.of(context).colorTheme.accentBlue,
|
||||||
color: StreamChatTheme.of(context).colorTheme.accentBlue,
|
fontWeight: FontWeight.bold,
|
||||||
fontWeight: FontWeight.bold,
|
),
|
||||||
),
|
),
|
||||||
),
|
if (attachment.titleLink != null ||
|
||||||
if (attachment.titleLink != null || attachment.ogScrapeUrl != null)
|
attachment.ogScrapeUrl != null)
|
||||||
Text(
|
Text(
|
||||||
Uri.parse(attachment.titleLink ?? attachment.ogScrapeUrl!)
|
Uri.parse(attachment.titleLink ?? attachment.ogScrapeUrl!)
|
||||||
.authority
|
.authority
|
||||||
.split('.')
|
.split('.')
|
||||||
.reversed
|
.reversed
|
||||||
.take(2)
|
.take(2)
|
||||||
.toList()
|
.toList()
|
||||||
.reversed
|
.reversed
|
||||||
.join('.'),
|
.join('.'),
|
||||||
style: messageTheme.messageText,
|
style: messageTheme.messageText,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
);
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-2
@@ -2,9 +2,13 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:stream_chat_flutter/src/upload_progress_indicator.dart';
|
import 'package:stream_chat_flutter/src/upload_progress_indicator.dart';
|
||||||
import 'package:stream_chat_flutter/stream_chat_flutter.dart';
|
import 'package:stream_chat_flutter/stream_chat_flutter.dart';
|
||||||
|
|
||||||
|
/// Widget to build in progress
|
||||||
typedef InProgressBuilder = Widget Function(BuildContext, int, int);
|
typedef InProgressBuilder = Widget Function(BuildContext, int, int);
|
||||||
|
|
||||||
|
/// Widget to build on failure
|
||||||
typedef FailedBuilder = Widget Function(BuildContext, String);
|
typedef FailedBuilder = Widget Function(BuildContext, String);
|
||||||
|
|
||||||
|
/// Widget to display attachment upload state
|
||||||
class AttachmentUploadStateBuilder extends StatelessWidget {
|
class AttachmentUploadStateBuilder extends StatelessWidget {
|
||||||
final Message message;
|
final Message message;
|
||||||
final Attachment attachment;
|
final Attachment attachment;
|
||||||
@@ -87,7 +91,6 @@ class _IconButton extends StatelessWidget {
|
|||||||
elevation: 0,
|
elevation: 0,
|
||||||
highlightElevation: 0,
|
highlightElevation: 0,
|
||||||
focusElevation: 0,
|
focusElevation: 0,
|
||||||
disabledElevation: 0,
|
|
||||||
hoverElevation: 0,
|
hoverElevation: 0,
|
||||||
onPressed: onPressed,
|
onPressed: onPressed,
|
||||||
fillColor:
|
fillColor:
|
||||||
@@ -237,7 +240,7 @@ class _SuccessState extends StatelessWidget {
|
|||||||
alignment: Alignment.topRight,
|
alignment: Alignment.topRight,
|
||||||
child: CircleAvatar(
|
child: CircleAvatar(
|
||||||
backgroundColor: StreamChatTheme.of(context).colorTheme.overlayDark,
|
backgroundColor: StreamChatTheme.of(context).colorTheme.overlayDark,
|
||||||
maxRadius: 12.0,
|
maxRadius: 12,
|
||||||
child: StreamSvgIcon.check(
|
child: StreamSvgIcon.check(
|
||||||
color: StreamChatTheme.of(context).colorTheme.white,
|
color: StreamChatTheme.of(context).colorTheme.white,
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ class FileAttachment extends AttachmentWidget {
|
|||||||
onTap: onAttachmentTap,
|
onTap: onAttachmentTap,
|
||||||
child: Container(
|
child: Container(
|
||||||
width: size?.width ?? 100,
|
width: size?.width ?? 100,
|
||||||
height: 56.0,
|
height: 56,
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: colorTheme.white,
|
color: colorTheme.white,
|
||||||
borderRadius: BorderRadius.circular(12),
|
borderRadius: BorderRadius.circular(12),
|
||||||
@@ -54,12 +54,12 @@ class FileAttachment extends AttachmentWidget {
|
|||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Container(
|
Container(
|
||||||
height: 40.0,
|
height: 40,
|
||||||
width: 33.33,
|
width: 33.33,
|
||||||
margin: EdgeInsets.all(8.0),
|
margin: EdgeInsets.all(8),
|
||||||
child: _getFileTypeImage(context),
|
child: _getFileTypeImage(context),
|
||||||
),
|
),
|
||||||
SizedBox(width: 8.0),
|
SizedBox(width: 8),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Column(
|
child: Column(
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
@@ -71,12 +71,12 @@ class FileAttachment extends AttachmentWidget {
|
|||||||
maxLines: 1,
|
maxLines: 1,
|
||||||
overflow: TextOverflow.ellipsis,
|
overflow: TextOverflow.ellipsis,
|
||||||
),
|
),
|
||||||
SizedBox(height: 3.0),
|
SizedBox(height: 3),
|
||||||
_buildSubtitle(context),
|
_buildSubtitle(context),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
SizedBox(width: 8.0),
|
SizedBox(width: 8),
|
||||||
_buildTrailing(context),
|
_buildTrailing(context),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@@ -87,7 +87,7 @@ class FileAttachment extends AttachmentWidget {
|
|||||||
|
|
||||||
ShapeBorder _getDefaultShape(BuildContext context) {
|
ShapeBorder _getDefaultShape(BuildContext context) {
|
||||||
return RoundedRectangleBorder(
|
return RoundedRectangleBorder(
|
||||||
side: BorderSide(width: 0.0, color: Colors.transparent),
|
side: BorderSide(width: 0, color: Colors.transparent),
|
||||||
borderRadius: BorderRadius.circular(8),
|
borderRadius: BorderRadius.circular(8),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -159,8 +159,8 @@ class FileAttachment extends AttachmentWidget {
|
|||||||
placeholderBuilder: (_) {
|
placeholderBuilder: (_) {
|
||||||
return Center(
|
return Center(
|
||||||
child: Container(
|
child: Container(
|
||||||
width: 20.0,
|
width: 20,
|
||||||
height: 20.0,
|
height: 20,
|
||||||
child: const CircularProgressIndicator(),
|
child: const CircularProgressIndicator(),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
@@ -171,8 +171,8 @@ class FileAttachment extends AttachmentWidget {
|
|||||||
placeholderBuilder: (_) {
|
placeholderBuilder: (_) {
|
||||||
return Center(
|
return Center(
|
||||||
child: Container(
|
child: Container(
|
||||||
width: 20.0,
|
width: 20,
|
||||||
height: 20.0,
|
height: 20,
|
||||||
child: const CircularProgressIndicator(),
|
child: const CircularProgressIndicator(),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
@@ -197,7 +197,6 @@ class FileAttachment extends AttachmentWidget {
|
|||||||
elevation: 0,
|
elevation: 0,
|
||||||
highlightElevation: 0,
|
highlightElevation: 0,
|
||||||
focusElevation: 0,
|
focusElevation: 0,
|
||||||
disabledElevation: 0,
|
|
||||||
hoverElevation: 0,
|
hoverElevation: 0,
|
||||||
onPressed: onPressed,
|
onPressed: onPressed,
|
||||||
fillColor: fillColor,
|
fillColor: fillColor,
|
||||||
@@ -214,7 +213,7 @@ class FileAttachment extends AttachmentWidget {
|
|||||||
var trailingWidget = trailing;
|
var trailingWidget = trailing;
|
||||||
trailingWidget ??= attachment.uploadState.when(
|
trailingWidget ??= attachment.uploadState.when(
|
||||||
preparing: () => Padding(
|
preparing: () => Padding(
|
||||||
padding: const EdgeInsets.all(8.0),
|
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,
|
||||||
@@ -222,7 +221,7 @@ class FileAttachment extends AttachmentWidget {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
inProgress: (_, __) => Padding(
|
inProgress: (_, __) => Padding(
|
||||||
padding: const EdgeInsets.all(8.0),
|
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,
|
||||||
@@ -230,15 +229,15 @@ class FileAttachment extends AttachmentWidget {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
success: () => Padding(
|
success: () => Padding(
|
||||||
padding: const EdgeInsets.all(8.0),
|
padding: const EdgeInsets.all(8),
|
||||||
child: CircleAvatar(
|
child: CircleAvatar(
|
||||||
backgroundColor: theme.colorTheme.accentBlue,
|
backgroundColor: theme.colorTheme.accentBlue,
|
||||||
maxRadius: 12.0,
|
maxRadius: 12,
|
||||||
child: StreamSvgIcon.check(color: theme.colorTheme.white),
|
child: StreamSvgIcon.check(color: theme.colorTheme.white),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
failed: (_) => Padding(
|
failed: (_) => Padding(
|
||||||
padding: const EdgeInsets.all(8.0),
|
padding: const EdgeInsets.all(8),
|
||||||
child: _buildButton(
|
child: _buildButton(
|
||||||
icon: StreamSvgIcon.retry(color: theme.colorTheme.white),
|
icon: StreamSvgIcon.retry(color: theme.colorTheme.white),
|
||||||
fillColor: theme.colorTheme.overlayDark,
|
fillColor: theme.colorTheme.overlayDark,
|
||||||
@@ -251,7 +250,6 @@ class FileAttachment extends AttachmentWidget {
|
|||||||
) ??
|
) ??
|
||||||
IconButton(
|
IconButton(
|
||||||
icon: StreamSvgIcon.cloudDownload(color: theme.colorTheme.black),
|
icon: StreamSvgIcon.cloudDownload(color: theme.colorTheme.black),
|
||||||
padding: const EdgeInsets.all(8),
|
|
||||||
visualDensity: VisualDensity.compact,
|
visualDensity: VisualDensity.compact,
|
||||||
splashRadius: 16,
|
splashRadius: 16,
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
@@ -262,7 +260,6 @@ class FileAttachment extends AttachmentWidget {
|
|||||||
if (message.status == MessageSendingStatus.sent) {
|
if (message.status == MessageSendingStatus.sent) {
|
||||||
trailingWidget = IconButton(
|
trailingWidget = IconButton(
|
||||||
icon: StreamSvgIcon.cloudDownload(color: theme.colorTheme.black),
|
icon: StreamSvgIcon.cloudDownload(color: theme.colorTheme.black),
|
||||||
padding: const EdgeInsets.all(8),
|
|
||||||
visualDensity: VisualDensity.compact,
|
visualDensity: VisualDensity.compact,
|
||||||
splashRadius: 16,
|
splashRadius: 16,
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
@@ -304,9 +301,9 @@ class FileAttachment extends AttachmentWidget {
|
|||||||
progressIndicatorColor: theme.colorTheme.accentBlue,
|
progressIndicatorColor: theme.colorTheme.accentBlue,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
success: () => Text('${fileSize(size, 2)}', style: textStyle),
|
success: () => Text(fileSize(size), style: textStyle),
|
||||||
failed: (_) => Text('UPLOAD ERROR', style: textStyle),
|
failed: (_) => Text('UPLOAD ERROR', style: textStyle),
|
||||||
) ??
|
) ??
|
||||||
Text('${fileSize(size)}', style: textStyle);
|
Text(fileSize(size), style: textStyle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -52,10 +52,10 @@ class GiphyAttachment extends AttachmentWidget {
|
|||||||
clipBehavior: Clip.antiAlias,
|
clipBehavior: Clip.antiAlias,
|
||||||
shape: RoundedRectangleBorder(
|
shape: RoundedRectangleBorder(
|
||||||
borderRadius: BorderRadius.only(
|
borderRadius: BorderRadius.only(
|
||||||
topRight: Radius.circular(16.0),
|
topRight: Radius.circular(16),
|
||||||
bottomRight: Radius.circular(0.0),
|
bottomRight: Radius.circular(0),
|
||||||
topLeft: Radius.circular(16.0),
|
topLeft: Radius.circular(16),
|
||||||
bottomLeft: Radius.circular(16.0),
|
bottomLeft: Radius.circular(16),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
child: Column(
|
child: Column(
|
||||||
@@ -63,7 +63,7 @@ class GiphyAttachment extends AttachmentWidget {
|
|||||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.all(8.0),
|
padding: const EdgeInsets.all(8),
|
||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
StreamSvgIcon.giphyIcon(),
|
StreamSvgIcon.giphyIcon(),
|
||||||
@@ -91,7 +91,7 @@ class GiphyAttachment extends AttachmentWidget {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.all(2.0),
|
padding: const EdgeInsets.all(2),
|
||||||
child: GestureDetector(
|
child: GestureDetector(
|
||||||
onTap: () => onAttachmentTap ?? _onImageTap(context),
|
onTap: () => onAttachmentTap ?? _onImageTap(context),
|
||||||
child: CachedNetworkImage(
|
child: CachedNetworkImage(
|
||||||
@@ -123,8 +123,6 @@ class GiphyAttachment extends AttachmentWidget {
|
|||||||
height: 0.5,
|
height: 0.5,
|
||||||
),
|
),
|
||||||
Row(
|
Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.start,
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
|
||||||
children: [
|
children: [
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Container(
|
child: Container(
|
||||||
@@ -156,7 +154,7 @@ class GiphyAttachment extends AttachmentWidget {
|
|||||||
.colorTheme
|
.colorTheme
|
||||||
.black
|
.black
|
||||||
.withOpacity(0.2),
|
.withOpacity(0.2),
|
||||||
height: 50.0,
|
height: 50,
|
||||||
),
|
),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Container(
|
child: Container(
|
||||||
@@ -189,7 +187,7 @@ class GiphyAttachment extends AttachmentWidget {
|
|||||||
.colorTheme
|
.colorTheme
|
||||||
.black
|
.black
|
||||||
.withOpacity(0.2),
|
.withOpacity(0.2),
|
||||||
height: 50.0,
|
height: 50,
|
||||||
),
|
),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Container(
|
child: Container(
|
||||||
@@ -217,11 +215,11 @@ class GiphyAttachment extends AttachmentWidget {
|
|||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
SizedBox(height: 4.0),
|
SizedBox(height: 4),
|
||||||
Align(
|
Align(
|
||||||
alignment: Alignment.centerRight,
|
alignment: Alignment.centerRight,
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 8.0, vertical: 4.0),
|
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
|
||||||
child: Row(
|
child: Row(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: [
|
children: [
|
||||||
@@ -230,10 +228,10 @@ class GiphyAttachment extends AttachmentWidget {
|
|||||||
.colorTheme
|
.colorTheme
|
||||||
.black
|
.black
|
||||||
.withOpacity(0.5),
|
.withOpacity(0.5),
|
||||||
size: 16.0,
|
size: 16,
|
||||||
),
|
),
|
||||||
SizedBox(
|
SizedBox(
|
||||||
width: 8.0,
|
width: 8,
|
||||||
),
|
),
|
||||||
Text(
|
Text(
|
||||||
'Only visible to you',
|
'Only visible to you',
|
||||||
@@ -332,8 +330,8 @@ class GiphyAttachment extends AttachmentWidget {
|
|||||||
),
|
),
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.symmetric(
|
padding: const EdgeInsets.symmetric(
|
||||||
horizontal: 8.0,
|
horizontal: 8,
|
||||||
vertical: 4.0,
|
vertical: 4,
|
||||||
),
|
),
|
||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
|
|||||||
@@ -34,137 +34,131 @@ class ImageAttachment extends AttachmentWidget {
|
|||||||
);
|
);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) => source.when(
|
||||||
return source.when(
|
local: () {
|
||||||
local: () {
|
if (attachment.localUri == null || attachment.file?.bytes == null) {
|
||||||
if (attachment.localUri == null || attachment.file?.bytes == null) {
|
return AttachmentError(size: size);
|
||||||
return AttachmentError(size: size);
|
}
|
||||||
}
|
return _buildImageAttachment(
|
||||||
return _buildImageAttachment(
|
context,
|
||||||
context,
|
Image.memory(
|
||||||
Image.memory(
|
attachment.file!.bytes!,
|
||||||
attachment.file!.bytes!,
|
height: size?.height,
|
||||||
height: size?.height,
|
width: size?.width,
|
||||||
width: size?.width,
|
fit: BoxFit.cover,
|
||||||
fit: BoxFit.cover,
|
errorBuilder: (context, _, __) => Image.asset(
|
||||||
errorBuilder: (context, _, __) {
|
|
||||||
return Image.asset(
|
|
||||||
'images/placeholder.png',
|
'images/placeholder.png',
|
||||||
package: 'stream_chat_flutter',
|
package: 'stream_chat_flutter',
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
network: () {
|
|
||||||
var imageUrl =
|
|
||||||
attachment.thumbUrl ?? attachment.imageUrl ?? attachment.assetUrl;
|
|
||||||
|
|
||||||
if (imageUrl == null) {
|
|
||||||
return AttachmentError(size: size);
|
|
||||||
}
|
|
||||||
|
|
||||||
var imageUri = Uri.parse(imageUrl);
|
|
||||||
if (imageUri.host == 'stream-io-cdn.com') {
|
|
||||||
imageUri = imageUri.replace(queryParameters: {
|
|
||||||
...imageUri.queryParameters,
|
|
||||||
'h': '500',
|
|
||||||
'w': '500',
|
|
||||||
'crop': 'center',
|
|
||||||
'resize': 'crop',
|
|
||||||
});
|
|
||||||
} else if (imageUri.host == 'stream-cloud-uploads.imgix.net') {
|
|
||||||
imageUri = imageUri.replace(queryParameters: {
|
|
||||||
...imageUri.queryParameters,
|
|
||||||
'height': '500',
|
|
||||||
'width': '500',
|
|
||||||
'fit': 'crop',
|
|
||||||
});
|
|
||||||
}
|
|
||||||
imageUrl = imageUri.toString();
|
|
||||||
|
|
||||||
return _buildImageAttachment(
|
|
||||||
context,
|
|
||||||
CachedNetworkImage(
|
|
||||||
cacheKey: imageUri.path,
|
|
||||||
height: size?.height,
|
|
||||||
width: size?.width,
|
|
||||||
placeholder: (_, __) {
|
|
||||||
final image = Image.asset(
|
|
||||||
'images/placeholder.png',
|
|
||||||
fit: BoxFit.cover,
|
|
||||||
package: 'stream_chat_flutter',
|
|
||||||
);
|
|
||||||
final colorTheme = StreamChatTheme.of(context).colorTheme;
|
|
||||||
return Shimmer.fromColors(
|
|
||||||
baseColor: colorTheme.greyGainsboro,
|
|
||||||
highlightColor: colorTheme.whiteSmoke,
|
|
||||||
child: image,
|
|
||||||
);
|
|
||||||
},
|
|
||||||
imageUrl: imageUrl,
|
|
||||||
errorWidget: (context, url, error) {
|
|
||||||
return AttachmentError(size: size);
|
|
||||||
},
|
|
||||||
fit: BoxFit.cover,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget _buildImageAttachment(BuildContext context, Widget imageWidget) {
|
|
||||||
return ConstrainedBox(
|
|
||||||
constraints: BoxConstraints.loose(size!),
|
|
||||||
child: Column(
|
|
||||||
children: <Widget>[
|
|
||||||
Expanded(
|
|
||||||
child: Stack(
|
|
||||||
children: [
|
|
||||||
GestureDetector(
|
|
||||||
onTap: onAttachmentTap ??
|
|
||||||
() async {
|
|
||||||
final result = await Navigator.push(
|
|
||||||
context,
|
|
||||||
MaterialPageRoute(
|
|
||||||
builder: (_) {
|
|
||||||
final channel = StreamChannel.of(context).channel;
|
|
||||||
return StreamChannel(
|
|
||||||
channel: channel,
|
|
||||||
child: FullScreenMedia(
|
|
||||||
mediaAttachments: [attachment],
|
|
||||||
userName: message.user?.name,
|
|
||||||
message: message,
|
|
||||||
onShowMessage: onShowMessage,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
);
|
|
||||||
if (result != null) onReturnAction?.call(result);
|
|
||||||
},
|
|
||||||
child: imageWidget,
|
|
||||||
),
|
|
||||||
Padding(
|
|
||||||
padding: const EdgeInsets.all(8.0),
|
|
||||||
child: AttachmentUploadStateBuilder(
|
|
||||||
message: message,
|
|
||||||
attachment: attachment,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
if (showTitle && attachment.title != null)
|
|
||||||
Material(
|
|
||||||
color: messageTheme.messageBackgroundColor,
|
|
||||||
child: AttachmentTitle(
|
|
||||||
messageTheme: messageTheme,
|
|
||||||
attachment: attachment,
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
);
|
||||||
),
|
},
|
||||||
);
|
network: () {
|
||||||
}
|
var imageUrl =
|
||||||
|
attachment.thumbUrl ?? attachment.imageUrl ?? attachment.assetUrl;
|
||||||
|
|
||||||
|
if (imageUrl == null) {
|
||||||
|
return AttachmentError(size: size);
|
||||||
|
}
|
||||||
|
|
||||||
|
var imageUri = Uri.parse(imageUrl);
|
||||||
|
if (imageUri.host == 'stream-io-cdn.com') {
|
||||||
|
imageUri = imageUri.replace(queryParameters: {
|
||||||
|
...imageUri.queryParameters,
|
||||||
|
'h': '500',
|
||||||
|
'w': '500',
|
||||||
|
'crop': 'center',
|
||||||
|
'resize': 'crop',
|
||||||
|
});
|
||||||
|
} else if (imageUri.host == 'stream-cloud-uploads.imgix.net') {
|
||||||
|
imageUri = imageUri.replace(queryParameters: {
|
||||||
|
...imageUri.queryParameters,
|
||||||
|
'height': '500',
|
||||||
|
'width': '500',
|
||||||
|
'fit': 'crop',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
imageUrl = imageUri.toString();
|
||||||
|
|
||||||
|
return _buildImageAttachment(
|
||||||
|
context,
|
||||||
|
CachedNetworkImage(
|
||||||
|
cacheKey: imageUri.path,
|
||||||
|
height: size?.height,
|
||||||
|
width: size?.width,
|
||||||
|
placeholder: (_, __) {
|
||||||
|
final image = Image.asset(
|
||||||
|
'images/placeholder.png',
|
||||||
|
fit: BoxFit.cover,
|
||||||
|
package: 'stream_chat_flutter',
|
||||||
|
);
|
||||||
|
final colorTheme = StreamChatTheme.of(context).colorTheme;
|
||||||
|
return Shimmer.fromColors(
|
||||||
|
baseColor: colorTheme.greyGainsboro,
|
||||||
|
highlightColor: colorTheme.whiteSmoke,
|
||||||
|
child: image,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
imageUrl: imageUrl,
|
||||||
|
errorWidget: (context, url, error) => AttachmentError(size: size),
|
||||||
|
fit: BoxFit.cover,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
Widget _buildImageAttachment(BuildContext context, Widget imageWidget) =>
|
||||||
|
ConstrainedBox(
|
||||||
|
constraints: BoxConstraints.loose(size!),
|
||||||
|
child: Column(
|
||||||
|
children: <Widget>[
|
||||||
|
Expanded(
|
||||||
|
child: Stack(
|
||||||
|
children: [
|
||||||
|
GestureDetector(
|
||||||
|
onTap: onAttachmentTap ??
|
||||||
|
() async {
|
||||||
|
final result = await Navigator.push(
|
||||||
|
context,
|
||||||
|
MaterialPageRoute(
|
||||||
|
builder: (_) {
|
||||||
|
final channel =
|
||||||
|
StreamChannel.of(context).channel;
|
||||||
|
return StreamChannel(
|
||||||
|
channel: channel,
|
||||||
|
child: FullScreenMedia(
|
||||||
|
mediaAttachments: [attachment],
|
||||||
|
userName: message.user?.name,
|
||||||
|
message: message,
|
||||||
|
onShowMessage: onShowMessage,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
if (result != null) onReturnAction?.call(result);
|
||||||
|
},
|
||||||
|
child: imageWidget,
|
||||||
|
),
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.all(8),
|
||||||
|
child: AttachmentUploadStateBuilder(
|
||||||
|
message: message,
|
||||||
|
attachment: attachment,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
if (showTitle && attachment.title != null)
|
||||||
|
Material(
|
||||||
|
color: messageTheme.messageBackgroundColor,
|
||||||
|
child: AttachmentTitle(
|
||||||
|
messageTheme: messageTheme,
|
||||||
|
attachment: attachment,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,100 +30,97 @@ class VideoAttachment extends AttachmentWidget {
|
|||||||
);
|
);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) => source.when(
|
||||||
return source.when(
|
local: () {
|
||||||
local: () {
|
if (attachment.file == null) {
|
||||||
if (attachment.file == null) {
|
return AttachmentError(size: size);
|
||||||
return AttachmentError(size: size);
|
}
|
||||||
}
|
return _buildVideoAttachment(
|
||||||
return _buildVideoAttachment(
|
context,
|
||||||
context,
|
VideoThumbnailImage(
|
||||||
VideoThumbnailImage(
|
video: attachment.file!.path!,
|
||||||
video: attachment.file!.path!,
|
height: size?.height,
|
||||||
height: size?.height,
|
width: size?.width,
|
||||||
width: size?.width,
|
fit: BoxFit.cover,
|
||||||
fit: BoxFit.cover,
|
errorBuilder: (_, __) => AttachmentError(size: size),
|
||||||
errorBuilder: (_, __) => AttachmentError(size: size),
|
),
|
||||||
),
|
);
|
||||||
);
|
},
|
||||||
},
|
network: () {
|
||||||
network: () {
|
if (attachment.assetUrl == null) {
|
||||||
if (attachment.assetUrl == null) {
|
return AttachmentError(size: size);
|
||||||
return AttachmentError(size: size);
|
}
|
||||||
}
|
return _buildVideoAttachment(
|
||||||
return _buildVideoAttachment(
|
context,
|
||||||
context,
|
VideoThumbnailImage(
|
||||||
VideoThumbnailImage(
|
video: attachment.assetUrl!,
|
||||||
video: attachment.assetUrl!,
|
height: size?.height,
|
||||||
height: size?.height,
|
width: size?.width,
|
||||||
width: size?.width,
|
fit: BoxFit.cover,
|
||||||
fit: BoxFit.cover,
|
errorBuilder: (_, __) => AttachmentError(size: size),
|
||||||
errorBuilder: (_, __) => AttachmentError(size: size),
|
),
|
||||||
),
|
);
|
||||||
);
|
},
|
||||||
},
|
);
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget _buildVideoAttachment(BuildContext context, Widget videoWidget) {
|
Widget _buildVideoAttachment(BuildContext context, Widget videoWidget) =>
|
||||||
return ConstrainedBox(
|
ConstrainedBox(
|
||||||
constraints: BoxConstraints.loose(size ?? Size.infinite),
|
constraints: BoxConstraints.loose(size ?? Size.infinite),
|
||||||
child: Column(
|
child: Column(
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
Expanded(
|
Expanded(
|
||||||
child: GestureDetector(
|
child: GestureDetector(
|
||||||
onTap: onAttachmentTap ??
|
onTap: onAttachmentTap ??
|
||||||
() async {
|
() async {
|
||||||
final channel = StreamChannel.of(context).channel;
|
final channel = StreamChannel.of(context).channel;
|
||||||
final res = await Navigator.push(
|
final res = await Navigator.push(
|
||||||
context,
|
context,
|
||||||
MaterialPageRoute(
|
MaterialPageRoute(
|
||||||
builder: (_) => StreamChannel(
|
builder: (_) => StreamChannel(
|
||||||
channel: channel,
|
channel: channel,
|
||||||
child: FullScreenMedia(
|
child: FullScreenMedia(
|
||||||
mediaAttachments: [attachment],
|
mediaAttachments: [attachment],
|
||||||
userName: message.user?.name,
|
userName: message.user?.name,
|
||||||
message: message,
|
message: message,
|
||||||
onShowMessage: onShowMessage,
|
onShowMessage: onShowMessage,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
);
|
||||||
);
|
if (res != null) onReturnAction?.call(res);
|
||||||
if (res != null) onReturnAction?.call(res);
|
},
|
||||||
},
|
child: Stack(
|
||||||
child: Stack(
|
children: [
|
||||||
children: [
|
videoWidget,
|
||||||
videoWidget,
|
const Center(
|
||||||
Center(
|
child: Material(
|
||||||
child: Material(
|
shape: CircleBorder(),
|
||||||
shape: CircleBorder(),
|
child: Padding(
|
||||||
child: Padding(
|
padding: EdgeInsets.all(16),
|
||||||
padding: const EdgeInsets.all(16.0),
|
child: Icon(Icons.play_arrow),
|
||||||
child: Icon(Icons.play_arrow),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
Padding(
|
||||||
Padding(
|
padding: const EdgeInsets.all(8),
|
||||||
padding: const EdgeInsets.all(8.0),
|
child: AttachmentUploadStateBuilder(
|
||||||
child: AttachmentUploadStateBuilder(
|
message: message,
|
||||||
message: message,
|
attachment: attachment,
|
||||||
attachment: attachment,
|
),
|
||||||
),
|
),
|
||||||
),
|
],
|
||||||
],
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
if (attachment.title != null)
|
||||||
if (attachment.title != null)
|
Material(
|
||||||
Material(
|
color: messageTheme.messageBackgroundColor,
|
||||||
color: messageTheme.messageBackgroundColor,
|
child: AttachmentTitle(
|
||||||
child: AttachmentTitle(
|
messageTheme: messageTheme,
|
||||||
messageTheme: messageTheme,
|
attachment: attachment,
|
||||||
attachment: attachment,
|
),
|
||||||
),
|
),
|
||||||
),
|
],
|
||||||
],
|
),
|
||||||
),
|
);
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,27 +42,25 @@ class AttachmentActionsModal extends StatelessWidget {
|
|||||||
});
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) => GestureDetector(
|
||||||
return GestureDetector(
|
behavior: HitTestBehavior.translucent,
|
||||||
behavior: HitTestBehavior.translucent,
|
onTap: () => Navigator.maybePop(context),
|
||||||
onTap: () => Navigator.maybePop(context),
|
child: _buildPage(context),
|
||||||
child: _buildPage(context),
|
);
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget _buildPage(context) {
|
Widget _buildPage(context) {
|
||||||
final theme = StreamChatTheme.of(context);
|
final theme = StreamChatTheme.of(context);
|
||||||
return Column(
|
return Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.end,
|
crossAxisAlignment: CrossAxisAlignment.end,
|
||||||
children: [
|
children: [
|
||||||
SizedBox(height: kToolbarHeight),
|
const SizedBox(height: kToolbarHeight),
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.only(right: 8.0),
|
padding: const EdgeInsets.only(right: 8),
|
||||||
child: Container(
|
child: Container(
|
||||||
width: MediaQuery.of(context).size.width * 0.5,
|
width: MediaQuery.of(context).size.width * 0.5,
|
||||||
clipBehavior: Clip.hardEdge,
|
clipBehavior: Clip.hardEdge,
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
borderRadius: BorderRadius.circular(16.0),
|
borderRadius: BorderRadius.circular(16),
|
||||||
),
|
),
|
||||||
child: Container(
|
child: Container(
|
||||||
child: Column(
|
child: Column(
|
||||||
@@ -73,7 +71,7 @@ class AttachmentActionsModal extends StatelessWidget {
|
|||||||
context,
|
context,
|
||||||
'Reply',
|
'Reply',
|
||||||
StreamSvgIcon.iconCurveLineLeftUp(
|
StreamSvgIcon.iconCurveLineLeftUp(
|
||||||
size: 24.0,
|
size: 24,
|
||||||
color: theme.colorTheme.grey,
|
color: theme.colorTheme.grey,
|
||||||
),
|
),
|
||||||
() {
|
() {
|
||||||
@@ -84,7 +82,7 @@ class AttachmentActionsModal extends StatelessWidget {
|
|||||||
context,
|
context,
|
||||||
'Show in Chat',
|
'Show in Chat',
|
||||||
StreamSvgIcon.eye(
|
StreamSvgIcon.eye(
|
||||||
size: 24.0,
|
size: 24,
|
||||||
color: theme.colorTheme.black,
|
color: theme.colorTheme.black,
|
||||||
),
|
),
|
||||||
onShowMessage,
|
onShowMessage,
|
||||||
@@ -93,7 +91,7 @@ class AttachmentActionsModal extends StatelessWidget {
|
|||||||
context,
|
context,
|
||||||
'Save ${message.attachments[currentIndex].type == 'video' ? 'Video' : 'Image'}',
|
'Save ${message.attachments[currentIndex].type == 'video' ? 'Video' : 'Image'}',
|
||||||
StreamSvgIcon.iconSave(
|
StreamSvgIcon.iconSave(
|
||||||
size: 24.0,
|
size: 24,
|
||||||
color: theme.colorTheme.grey,
|
color: theme.colorTheme.grey,
|
||||||
),
|
),
|
||||||
() {
|
() {
|
||||||
@@ -144,7 +142,7 @@ class AttachmentActionsModal extends StatelessWidget {
|
|||||||
context,
|
context,
|
||||||
'Delete',
|
'Delete',
|
||||||
StreamSvgIcon.delete(
|
StreamSvgIcon.delete(
|
||||||
size: 24.0,
|
size: 24,
|
||||||
color: theme.colorTheme.accentRed,
|
color: theme.colorTheme.accentRed,
|
||||||
),
|
),
|
||||||
() {
|
() {
|
||||||
@@ -201,7 +199,7 @@ class AttachmentActionsModal extends StatelessWidget {
|
|||||||
child: InkWell(
|
child: InkWell(
|
||||||
onTap: onTap,
|
onTap: onTap,
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.symmetric(vertical: 8.0, horizontal: 16.0),
|
padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 16),
|
||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
icon,
|
icon,
|
||||||
@@ -271,7 +269,7 @@ class AttachmentActionsModal extends StatelessWidget {
|
|||||||
children: [
|
children: [
|
||||||
CircularProgressIndicator(
|
CircularProgressIndicator(
|
||||||
value: progress.toProgressIndicatorValue,
|
value: progress.toProgressIndicatorValue,
|
||||||
strokeWidth: 8.0,
|
strokeWidth: 8,
|
||||||
valueColor: AlwaysStoppedAnimation(
|
valueColor: AlwaysStoppedAnimation(
|
||||||
theme.colorTheme.accentBlue,
|
theme.colorTheme.accentBlue,
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -30,7 +30,6 @@ class StreamBackButton extends StatelessWidget {
|
|||||||
elevation: 0,
|
elevation: 0,
|
||||||
highlightElevation: 0,
|
highlightElevation: 0,
|
||||||
focusElevation: 0,
|
focusElevation: 0,
|
||||||
disabledElevation: 0,
|
|
||||||
hoverElevation: 0,
|
hoverElevation: 0,
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
if (onPressed != null) {
|
if (onPressed != null) {
|
||||||
@@ -39,7 +38,7 @@ class StreamBackButton extends StatelessWidget {
|
|||||||
Navigator.maybePop(context);
|
Navigator.maybePop(context);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
padding: const EdgeInsets.all(14.0),
|
padding: const EdgeInsets.all(14),
|
||||||
child: StreamSvgIcon.left(
|
child: StreamSvgIcon.left(
|
||||||
size: 24,
|
size: 24,
|
||||||
color: StreamChatTheme.of(context).colorTheme.black,
|
color: StreamChatTheme.of(context).colorTheme.black,
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import 'option_list_tile.dart';
|
|||||||
class ChannelBottomSheet extends StatefulWidget {
|
class ChannelBottomSheet extends StatefulWidget {
|
||||||
final VoidCallback? onViewInfoTap;
|
final VoidCallback? onViewInfoTap;
|
||||||
|
|
||||||
ChannelBottomSheet({this.onViewInfoTap});
|
const ChannelBottomSheet({this.onViewInfoTap});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
_ChannelBottomSheetState createState() => _ChannelBottomSheetState();
|
_ChannelBottomSheetState createState() => _ChannelBottomSheetState();
|
||||||
@@ -31,29 +31,29 @@ class _ChannelBottomSheetState extends State<ChannelBottomSheet> {
|
|||||||
clipBehavior: Clip.antiAlias,
|
clipBehavior: Clip.antiAlias,
|
||||||
shape: RoundedRectangleBorder(
|
shape: RoundedRectangleBorder(
|
||||||
borderRadius: BorderRadius.only(
|
borderRadius: BorderRadius.only(
|
||||||
topLeft: Radius.circular(16.0),
|
topLeft: Radius.circular(16),
|
||||||
topRight: Radius.circular(16.0),
|
topRight: Radius.circular(16),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
child: !_showActions
|
child: !_showActions
|
||||||
? SizedBox()
|
? const SizedBox()
|
||||||
: ListView(
|
: ListView(
|
||||||
shrinkWrap: true,
|
shrinkWrap: true,
|
||||||
children: [
|
children: [
|
||||||
SizedBox(
|
const SizedBox(
|
||||||
height: 24.0,
|
height: 24,
|
||||||
),
|
),
|
||||||
Center(
|
Center(
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 16.0),
|
padding: const EdgeInsets.symmetric(horizontal: 16),
|
||||||
child: ChannelName(
|
child: ChannelName(
|
||||||
textStyle:
|
textStyle:
|
||||||
StreamChatTheme.of(context).textTheme.headlineBold,
|
StreamChatTheme.of(context).textTheme.headlineBold,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
SizedBox(
|
const SizedBox(
|
||||||
height: 5.0,
|
height: 5,
|
||||||
),
|
),
|
||||||
Center(
|
Center(
|
||||||
child: ChannelInfo(
|
child: ChannelInfo(
|
||||||
@@ -64,8 +64,8 @@ class _ChannelBottomSheetState extends State<ChannelBottomSheet> {
|
|||||||
.subtitle,
|
.subtitle,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
SizedBox(
|
const SizedBox(
|
||||||
height: 17.0,
|
height: 17,
|
||||||
),
|
),
|
||||||
if (channel.isDistinct && channel.memberCount == 2)
|
if (channel.isDistinct && channel.memberCount == 2)
|
||||||
Column(
|
Column(
|
||||||
@@ -75,16 +75,16 @@ class _ChannelBottomSheetState extends State<ChannelBottomSheet> {
|
|||||||
.firstWhere(
|
.firstWhere(
|
||||||
(e) => e.user?.id != userAsMember.user?.id)
|
(e) => e.user?.id != userAsMember.user?.id)
|
||||||
.user!,
|
.user!,
|
||||||
constraints: BoxConstraints(
|
constraints: const BoxConstraints(
|
||||||
maxHeight: 64.0,
|
maxHeight: 64,
|
||||||
maxWidth: 64.0,
|
maxWidth: 64,
|
||||||
),
|
),
|
||||||
borderRadius: BorderRadius.circular(32.0),
|
borderRadius: BorderRadius.circular(32),
|
||||||
onlineIndicatorConstraints:
|
onlineIndicatorConstraints:
|
||||||
BoxConstraints.tight(Size(12.0, 12.0)),
|
BoxConstraints.tight(const Size(12, 12)),
|
||||||
),
|
),
|
||||||
SizedBox(
|
const SizedBox(
|
||||||
height: 6.0,
|
height: 6,
|
||||||
),
|
),
|
||||||
Text(
|
Text(
|
||||||
members
|
members
|
||||||
@@ -102,50 +102,48 @@ class _ChannelBottomSheetState extends State<ChannelBottomSheet> {
|
|||||||
),
|
),
|
||||||
if (!(channel.isDistinct && channel.memberCount == 2))
|
if (!(channel.isDistinct && channel.memberCount == 2))
|
||||||
Container(
|
Container(
|
||||||
height: 94.0,
|
height: 94,
|
||||||
alignment: Alignment.center,
|
alignment: Alignment.center,
|
||||||
child: ListView.builder(
|
child: ListView.builder(
|
||||||
scrollDirection: Axis.horizontal,
|
scrollDirection: Axis.horizontal,
|
||||||
itemCount: members.length,
|
itemCount: members.length,
|
||||||
shrinkWrap: true,
|
shrinkWrap: true,
|
||||||
itemBuilder: (context, index) {
|
itemBuilder: (context, index) => Padding(
|
||||||
return Padding(
|
padding: const EdgeInsets.symmetric(horizontal: 8),
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 8.0),
|
child: Column(
|
||||||
child: Column(
|
children: [
|
||||||
children: [
|
UserAvatar(
|
||||||
UserAvatar(
|
user: members[index].user!,
|
||||||
user: members[index].user!,
|
constraints: const BoxConstraints.tightFor(
|
||||||
constraints: BoxConstraints.tightFor(
|
height: 64,
|
||||||
height: 64.0,
|
width: 64,
|
||||||
width: 64.0,
|
|
||||||
),
|
|
||||||
borderRadius: BorderRadius.circular(32.0),
|
|
||||||
onlineIndicatorConstraints:
|
|
||||||
BoxConstraints.tight(Size(12.0, 12.0)),
|
|
||||||
),
|
),
|
||||||
SizedBox(
|
borderRadius: BorderRadius.circular(32),
|
||||||
height: 6.0,
|
onlineIndicatorConstraints:
|
||||||
),
|
BoxConstraints.tight(Size(12, 12)),
|
||||||
Text(
|
),
|
||||||
members[index].user?.name ?? '',
|
const SizedBox(
|
||||||
style: StreamChatTheme.of(context)
|
height: 6,
|
||||||
.textTheme
|
),
|
||||||
.footnoteBold,
|
Text(
|
||||||
maxLines: 1,
|
members[index].user?.name ?? '',
|
||||||
overflow: TextOverflow.ellipsis,
|
style: StreamChatTheme.of(context)
|
||||||
),
|
.textTheme
|
||||||
],
|
.footnoteBold,
|
||||||
),
|
maxLines: 1,
|
||||||
);
|
overflow: TextOverflow.ellipsis,
|
||||||
},
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
SizedBox(
|
const SizedBox(
|
||||||
height: 24.0,
|
height: 24,
|
||||||
),
|
),
|
||||||
OptionListTile(
|
OptionListTile(
|
||||||
leading: Padding(
|
leading: Padding(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 16.0),
|
padding: const EdgeInsets.symmetric(horizontal: 16),
|
||||||
child: StreamSvgIcon.user(
|
child: StreamSvgIcon.user(
|
||||||
color: StreamChatTheme.of(context).colorTheme.grey,
|
color: StreamChatTheme.of(context).colorTheme.grey,
|
||||||
),
|
),
|
||||||
@@ -156,7 +154,7 @@ class _ChannelBottomSheetState extends State<ChannelBottomSheet> {
|
|||||||
if (!channel.isDistinct)
|
if (!channel.isDistinct)
|
||||||
OptionListTile(
|
OptionListTile(
|
||||||
leading: Padding(
|
leading: Padding(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 16.0),
|
padding: const EdgeInsets.symmetric(horizontal: 16),
|
||||||
child: StreamSvgIcon.userRemove(
|
child: StreamSvgIcon.userRemove(
|
||||||
color: StreamChatTheme.of(context).colorTheme.grey,
|
color: StreamChatTheme.of(context).colorTheme.grey,
|
||||||
),
|
),
|
||||||
@@ -175,7 +173,7 @@ class _ChannelBottomSheetState extends State<ChannelBottomSheet> {
|
|||||||
if (isOwner)
|
if (isOwner)
|
||||||
OptionListTile(
|
OptionListTile(
|
||||||
leading: Padding(
|
leading: Padding(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 16.0),
|
padding: const EdgeInsets.symmetric(horizontal: 16),
|
||||||
child: StreamSvgIcon.delete(
|
child: StreamSvgIcon.delete(
|
||||||
color: StreamChatTheme.of(context).colorTheme.accentRed,
|
color: StreamChatTheme.of(context).colorTheme.accentRed,
|
||||||
),
|
),
|
||||||
@@ -195,7 +193,7 @@ class _ChannelBottomSheetState extends State<ChannelBottomSheet> {
|
|||||||
),
|
),
|
||||||
OptionListTile(
|
OptionListTile(
|
||||||
leading: Padding(
|
leading: Padding(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 16.0),
|
padding: const EdgeInsets.symmetric(horizontal: 16),
|
||||||
child: StreamSvgIcon.closeSmall(
|
child: StreamSvgIcon.closeSmall(
|
||||||
color: StreamChatTheme.of(context).colorTheme.grey,
|
color: StreamChatTheme.of(context).colorTheme.grey,
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -144,7 +144,7 @@ class ChannelHeader extends StatelessWidget implements PreferredSizeWidget {
|
|||||||
actions: actions ??
|
actions: actions ??
|
||||||
<Widget>[
|
<Widget>[
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.only(right: 10.0),
|
padding: const EdgeInsets.only(right: 10),
|
||||||
child: Center(
|
child: Center(
|
||||||
child: ChannelImage(
|
child: ChannelImage(
|
||||||
borderRadius: StreamChatTheme.of(context)
|
borderRadius: StreamChatTheme.of(context)
|
||||||
@@ -169,7 +169,6 @@ class ChannelHeader extends StatelessWidget implements PreferredSizeWidget {
|
|||||||
height: preferredSize.height,
|
height: preferredSize.height,
|
||||||
width: preferredSize.width,
|
width: preferredSize.width,
|
||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
title ??
|
title ??
|
||||||
|
|||||||
@@ -158,30 +158,29 @@ class ChannelImage extends StatelessWidget {
|
|||||||
alignment: Alignment.center,
|
alignment: Alignment.center,
|
||||||
fit: StackFit.expand,
|
fit: StackFit.expand,
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
image != null
|
if (image != null)
|
||||||
? CachedNetworkImage(
|
CachedNetworkImage(
|
||||||
imageUrl: image,
|
imageUrl: image,
|
||||||
errorWidget: (_, __, ___) {
|
errorWidget: (_, __, ___) {
|
||||||
return Center(
|
return Center(
|
||||||
child: Text(
|
child: Text(
|
||||||
snapshot.data?.containsKey('name') ?? false
|
snapshot.data?.containsKey('name') ?? false
|
||||||
? snapshot.data!['name'][0]
|
? snapshot.data!['name'][0]
|
||||||
: '',
|
: '',
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: StreamChatTheme.of(context)
|
color: StreamChatTheme.of(context).colorTheme.white,
|
||||||
.colorTheme
|
fontWeight: FontWeight.bold,
|
||||||
.white,
|
),
|
||||||
fontWeight: FontWeight.bold,
|
),
|
||||||
),
|
);
|
||||||
),
|
},
|
||||||
);
|
fit: BoxFit.cover,
|
||||||
},
|
)
|
||||||
fit: BoxFit.cover,
|
else
|
||||||
)
|
StreamChatTheme.of(context).defaultChannelImage(
|
||||||
: StreamChatTheme.of(context).defaultChannelImage(
|
context,
|
||||||
context,
|
channel,
|
||||||
channel,
|
),
|
||||||
),
|
|
||||||
Material(
|
Material(
|
||||||
color: Colors.transparent,
|
color: Colors.transparent,
|
||||||
child: InkWell(
|
child: InkWell(
|
||||||
|
|||||||
@@ -27,28 +27,26 @@ class ChannelInfo extends StatelessWidget {
|
|||||||
return StreamBuilder<List<Member>>(
|
return StreamBuilder<List<Member>>(
|
||||||
stream: channel.state?.membersStream,
|
stream: channel.state?.membersStream,
|
||||||
initialData: channel.state?.members,
|
initialData: channel.state?.members,
|
||||||
builder: (context, snapshot) {
|
builder: (context, snapshot) => ConnectionStatusBuilder(
|
||||||
return ConnectionStatusBuilder(
|
statusBuilder: (context, status) {
|
||||||
statusBuilder: (context, status) {
|
switch (status) {
|
||||||
switch (status) {
|
case ConnectionStatus.connected:
|
||||||
case ConnectionStatus.connected:
|
return _buildConnectedTitleState(context, snapshot.data);
|
||||||
return _buildConnectedTitleState(context, snapshot.data);
|
case ConnectionStatus.connecting:
|
||||||
case ConnectionStatus.connecting:
|
return _buildConnectingTitleState(context);
|
||||||
return _buildConnectingTitleState(context);
|
case ConnectionStatus.disconnected:
|
||||||
case ConnectionStatus.disconnected:
|
return _buildDisconnectedTitleState(context, client);
|
||||||
return _buildDisconnectedTitleState(context, client);
|
default:
|
||||||
default:
|
return const Offstage();
|
||||||
return Offstage();
|
}
|
||||||
}
|
},
|
||||||
},
|
),
|
||||||
);
|
|
||||||
},
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildConnectedTitleState(
|
Widget _buildConnectedTitleState(
|
||||||
BuildContext context, List<Member>? members) {
|
BuildContext context, List<Member>? members) {
|
||||||
var alternativeWidget;
|
Widget? alternativeWidget;
|
||||||
|
|
||||||
if (channel.memberCount != null && channel.memberCount! > 2) {
|
if (channel.memberCount != null && channel.memberCount! > 2) {
|
||||||
var text = '${channel.memberCount} Members';
|
var text = '${channel.memberCount} Members';
|
||||||
@@ -82,7 +80,7 @@ class ChannelInfo extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!showTypingIndicator) {
|
if (!showTypingIndicator) {
|
||||||
return alternativeWidget ?? Offstage();
|
return alternativeWidget ?? const Offstage();
|
||||||
}
|
}
|
||||||
|
|
||||||
return TypingIndicator(
|
return TypingIndicator(
|
||||||
@@ -92,58 +90,55 @@ class ChannelInfo extends StatelessWidget {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildConnectingTitleState(BuildContext context) {
|
Widget _buildConnectingTitleState(BuildContext context) => Row(
|
||||||
return Row(
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
children: [
|
||||||
children: [
|
Container(
|
||||||
Container(
|
height: 16,
|
||||||
height: 16,
|
width: 16,
|
||||||
width: 16,
|
child: const Center(
|
||||||
child: Center(
|
child: CircularProgressIndicator(),
|
||||||
child: CircularProgressIndicator(),
|
),
|
||||||
),
|
),
|
||||||
),
|
SizedBox(width: 10),
|
||||||
SizedBox(width: 10),
|
Text(
|
||||||
Text(
|
'Searching for Network',
|
||||||
'Searching for Network',
|
style: textStyle,
|
||||||
style: textStyle,
|
),
|
||||||
),
|
],
|
||||||
],
|
);
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget _buildDisconnectedTitleState(
|
Widget _buildDisconnectedTitleState(
|
||||||
BuildContext context,
|
BuildContext context,
|
||||||
StreamChatClient client,
|
StreamChatClient client,
|
||||||
) {
|
) =>
|
||||||
return Row(
|
Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
'Offline...',
|
'Offline...',
|
||||||
style: textStyle,
|
style: textStyle,
|
||||||
),
|
),
|
||||||
TextButton(
|
TextButton(
|
||||||
style: TextButton.styleFrom(
|
style: TextButton.styleFrom(
|
||||||
padding: const EdgeInsets.all(0),
|
padding: const EdgeInsets.all(0),
|
||||||
tapTargetSize: MaterialTapTargetSize.shrinkWrap,
|
tapTargetSize: MaterialTapTargetSize.shrinkWrap,
|
||||||
visualDensity: VisualDensity(
|
visualDensity: const VisualDensity(
|
||||||
horizontal: VisualDensity.minimumDensity,
|
horizontal: VisualDensity.minimumDensity,
|
||||||
vertical: VisualDensity.minimumDensity,
|
vertical: VisualDensity.minimumDensity,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
onPressed: () async {
|
||||||
|
await client.disconnect();
|
||||||
|
await client.connect();
|
||||||
|
},
|
||||||
|
child: Text(
|
||||||
|
'Try Again',
|
||||||
|
style: textStyle?.copyWith(
|
||||||
|
color: StreamChatTheme.of(context).colorTheme.accentBlue,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
onPressed: () async {
|
],
|
||||||
await client.disconnect();
|
);
|
||||||
await client.connect();
|
|
||||||
},
|
|
||||||
child: Text(
|
|
||||||
'Try Again',
|
|
||||||
style: textStyle?.copyWith(
|
|
||||||
color: StreamChatTheme.of(context).colorTheme.accentBlue,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -168,8 +168,8 @@ class ChannelListHeader extends StatelessWidget implements PreferredSizeWidget {
|
|||||||
return SvgPicture.asset(
|
return SvgPicture.asset(
|
||||||
'svgs/icon_pen_write.svg',
|
'svgs/icon_pen_write.svg',
|
||||||
package: 'stream_chat_flutter',
|
package: 'stream_chat_flutter',
|
||||||
width: 24.0,
|
width: 24,
|
||||||
height: 24.0,
|
height: 24,
|
||||||
color: color,
|
color: color,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ typedef ViewInfoCallback = void Function(Channel);
|
|||||||
/// Modify it to change the widget appearance.
|
/// Modify it to change the widget appearance.
|
||||||
class ChannelListView extends StatefulWidget {
|
class ChannelListView extends StatefulWidget {
|
||||||
/// Instantiate a new ChannelListView
|
/// Instantiate a new ChannelListView
|
||||||
ChannelListView({
|
const ChannelListView({
|
||||||
Key? key,
|
Key? key,
|
||||||
this.filter,
|
this.filter,
|
||||||
this.options,
|
this.options,
|
||||||
@@ -248,7 +248,7 @@ class _ChannelListViewState extends State<ChannelListView> {
|
|||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.all(8.0),
|
padding: const EdgeInsets.all(8),
|
||||||
child: StreamSvgIcon.message(
|
child: StreamSvgIcon.message(
|
||||||
size: 136,
|
size: 136,
|
||||||
color: StreamChatTheme.of(context)
|
color: StreamChatTheme.of(context)
|
||||||
@@ -257,7 +257,7 @@ class _ChannelListViewState extends State<ChannelListView> {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.all(8.0),
|
padding: const EdgeInsets.all(8),
|
||||||
child: Text(
|
child: Text(
|
||||||
'Let’s start chatting!',
|
'Let’s start chatting!',
|
||||||
style: StreamChatTheme.of(context).textTheme.headline,
|
style: StreamChatTheme.of(context).textTheme.headline,
|
||||||
@@ -265,7 +265,7 @@ class _ChannelListViewState extends State<ChannelListView> {
|
|||||||
),
|
),
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.symmetric(
|
padding: const EdgeInsets.symmetric(
|
||||||
vertical: 8.0,
|
vertical: 8,
|
||||||
horizontal: 52,
|
horizontal: 52,
|
||||||
),
|
),
|
||||||
child: Text(
|
child: Text(
|
||||||
@@ -340,7 +340,7 @@ class _ChannelListViewState extends State<ChannelListView> {
|
|||||||
highlightColor: StreamChatTheme.of(context).colorTheme.whiteSmoke,
|
highlightColor: StreamChatTheme.of(context).colorTheme.whiteSmoke,
|
||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
SizedBox(height: 4.0),
|
SizedBox(height: 4),
|
||||||
Row(
|
Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||||
children: [
|
children: [
|
||||||
@@ -358,7 +358,7 @@ class _ChannelListViewState extends State<ChannelListView> {
|
|||||||
],
|
],
|
||||||
),
|
),
|
||||||
SizedBox(
|
SizedBox(
|
||||||
height: 16.0,
|
height: 16,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@@ -441,7 +441,7 @@ class _ChannelListViewState extends State<ChannelListView> {
|
|||||||
WidgetSpan(
|
WidgetSpan(
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.only(
|
padding: const EdgeInsets.only(
|
||||||
right: 2.0,
|
right: 2,
|
||||||
),
|
),
|
||||||
child: Icon(Icons.error_outline),
|
child: Icon(Icons.error_outline),
|
||||||
),
|
),
|
||||||
@@ -477,7 +477,6 @@ class _ChannelListViewState extends State<ChannelListView> {
|
|||||||
enabled: widget.swipeToAction,
|
enabled: widget.swipeToAction,
|
||||||
actionPane: SlidableBehindActionPane(),
|
actionPane: SlidableBehindActionPane(),
|
||||||
actionExtentRatio: 0.12,
|
actionExtentRatio: 0.12,
|
||||||
closeOnScroll: true,
|
|
||||||
secondaryActions: <Widget>[
|
secondaryActions: <Widget>[
|
||||||
IconSlideAction(
|
IconSlideAction(
|
||||||
color: backgroundColor,
|
color: backgroundColor,
|
||||||
@@ -589,7 +588,6 @@ class _ChannelListViewState extends State<ChannelListView> {
|
|||||||
key: ValueKey<String>('CHANNEL-${channel.id}'),
|
key: ValueKey<String>('CHANNEL-${channel.id}'),
|
||||||
child: Column(
|
child: Column(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
|
||||||
children: [
|
children: [
|
||||||
ChannelImage(
|
ChannelImage(
|
||||||
channel: channel,
|
channel: channel,
|
||||||
@@ -634,7 +632,7 @@ class _ChannelListViewState extends State<ChannelListView> {
|
|||||||
.accentRed
|
.accentRed
|
||||||
.withOpacity(.2),
|
.withOpacity(.2),
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.symmetric(vertical: 16.0),
|
padding: const EdgeInsets.symmetric(vertical: 16),
|
||||||
child: Center(
|
child: Center(
|
||||||
child: Text('Error loading channels'),
|
child: Text('Error loading channels'),
|
||||||
),
|
),
|
||||||
@@ -644,7 +642,7 @@ class _ChannelListViewState extends State<ChannelListView> {
|
|||||||
return snapshot.data!
|
return snapshot.data!
|
||||||
? Center(
|
? Center(
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.all(16.0),
|
padding: const EdgeInsets.all(16),
|
||||||
child: const CircularProgressIndicator(),
|
child: const CircularProgressIndicator(),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
@@ -653,7 +651,7 @@ class _ChannelListViewState extends State<ChannelListView> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Widget _separatorBuilder(context, i) {
|
Widget _separatorBuilder(context, i) {
|
||||||
var effect = StreamChatTheme.of(context).colorTheme.borderBottom;
|
final effect = StreamChatTheme.of(context).colorTheme.borderBottom;
|
||||||
|
|
||||||
return Container(
|
return Container(
|
||||||
height: 1,
|
height: 1,
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ class ChannelPreview extends StatelessWidget {
|
|||||||
/// Widget rendering the sending indicator, by default it uses the [SendingIndicator] widget
|
/// Widget rendering the sending indicator, by default it uses the [SendingIndicator] widget
|
||||||
final Widget? sendingIndicator;
|
final Widget? sendingIndicator;
|
||||||
|
|
||||||
ChannelPreview({
|
const ChannelPreview({
|
||||||
required this.channel,
|
required this.channel,
|
||||||
Key? key,
|
Key? key,
|
||||||
this.onTap,
|
this.onTap,
|
||||||
@@ -128,7 +128,7 @@ class ChannelPreview extends StatelessWidget {
|
|||||||
if (lastMessage?.user?.id ==
|
if (lastMessage?.user?.id ==
|
||||||
StreamChat.of(context).user?.id) {
|
StreamChat.of(context).user?.id) {
|
||||||
return Padding(
|
return Padding(
|
||||||
padding: const EdgeInsets.only(right: 4.0),
|
padding: const EdgeInsets.only(right: 4),
|
||||||
child: SendingIndicator(
|
child: SendingIndicator(
|
||||||
message: lastMessage!,
|
message: lastMessage!,
|
||||||
size: channelPreviewTheme.indicatorIconSize,
|
size: channelPreviewTheme.indicatorIconSize,
|
||||||
@@ -167,7 +167,7 @@ class ChannelPreview extends StatelessWidget {
|
|||||||
String stringDate;
|
String stringDate;
|
||||||
final now = DateTime.now();
|
final now = DateTime.now();
|
||||||
|
|
||||||
var startOfDay = DateTime(now.year, now.month, now.day);
|
final startOfDay = DateTime(now.year, now.month, now.day);
|
||||||
|
|
||||||
if (lastMessageAt.millisecondsSinceEpoch >=
|
if (lastMessageAt.millisecondsSinceEpoch >=
|
||||||
startOfDay.millisecondsSinceEpoch) {
|
startOfDay.millisecondsSinceEpoch) {
|
||||||
@@ -298,7 +298,7 @@ class ChannelPreview extends StatelessWidget {
|
|||||||
));
|
));
|
||||||
} else {
|
} else {
|
||||||
resList.add(TextSpan(
|
resList.add(TextSpan(
|
||||||
text: e == textList.last ? '$e' : '$e ',
|
text: e == textList.last ? e : '$e ',
|
||||||
style: normalTextStyle,
|
style: normalTextStyle,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ class DeletedMessage extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.symmetric(
|
padding: const EdgeInsets.symmetric(
|
||||||
vertical: 8.0,
|
vertical: 8,
|
||||||
horizontal: 16,
|
horizontal: 16,
|
||||||
),
|
),
|
||||||
child: Transform(
|
child: Transform(
|
||||||
|
|||||||
@@ -150,7 +150,7 @@ class _FullScreenMediaState extends State<FullScreenMedia>
|
|||||||
},
|
},
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.symmetric(
|
padding: const EdgeInsets.symmetric(
|
||||||
vertical: 50.0,
|
vertical: 50,
|
||||||
),
|
),
|
||||||
child: Chewie(
|
child: Chewie(
|
||||||
controller: controller.chewieController!,
|
controller: controller.chewieController!,
|
||||||
|
|||||||
@@ -113,8 +113,8 @@ class GroupImage extends StatelessWidget {
|
|||||||
child: Container(
|
child: Container(
|
||||||
color: selectionColor ??
|
color: selectionColor ??
|
||||||
StreamChatTheme.of(context).colorTheme.accentBlue,
|
StreamChatTheme.of(context).colorTheme.accentBlue,
|
||||||
height: 64.0,
|
height: 64,
|
||||||
width: 64.0,
|
width: 64,
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: EdgeInsets.all(selectionThickness),
|
padding: EdgeInsets.all(selectionThickness),
|
||||||
child: avatar,
|
child: avatar,
|
||||||
|
|||||||
@@ -82,47 +82,45 @@ class _ImageFooterState extends State<ImageFooter> {
|
|||||||
child: Row(
|
child: Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
children: [
|
children: [
|
||||||
!showShareButton
|
if (!showShareButton)
|
||||||
? Container(
|
Container(
|
||||||
width: 48,
|
width: 48,
|
||||||
)
|
)
|
||||||
: IconButton(
|
else
|
||||||
icon: StreamSvgIcon.iconShare(
|
IconButton(
|
||||||
size: 24.0,
|
icon: StreamSvgIcon.iconShare(
|
||||||
color: StreamChatTheme.of(context).colorTheme.black,
|
size: 24,
|
||||||
),
|
color: StreamChatTheme.of(context).colorTheme.black,
|
||||||
onPressed: () async {
|
),
|
||||||
final attachment =
|
onPressed: () async {
|
||||||
widget.mediaAttachments[widget.currentPage];
|
final attachment =
|
||||||
final url = attachment.imageUrl ??
|
widget.mediaAttachments[widget.currentPage];
|
||||||
attachment.assetUrl ??
|
final url = attachment.imageUrl ??
|
||||||
attachment.thumbUrl!;
|
attachment.assetUrl ??
|
||||||
final type = attachment.type == 'image'
|
attachment.thumbUrl!;
|
||||||
? 'jpg'
|
final type = attachment.type == 'image'
|
||||||
: url.split('?').first.split('.').last;
|
? 'jpg'
|
||||||
final request =
|
: url.split('?').first.split('.').last;
|
||||||
await HttpClient().getUrl(Uri.parse(url));
|
final request = await HttpClient().getUrl(Uri.parse(url));
|
||||||
final response = await request.close();
|
final response = await request.close();
|
||||||
final bytes =
|
final bytes =
|
||||||
await consolidateHttpClientResponseBytes(response);
|
await consolidateHttpClientResponseBytes(response);
|
||||||
final tmpPath = await getTemporaryDirectory();
|
final tmpPath = await getTemporaryDirectory();
|
||||||
final filePath =
|
final filePath = '${tmpPath.path}/${attachment.id}.$type';
|
||||||
'${tmpPath.path}/${attachment.id}.$type';
|
final file = File(filePath);
|
||||||
final file = File(filePath);
|
await file.writeAsBytes(bytes);
|
||||||
await file.writeAsBytes(bytes);
|
await Share.shareFiles(
|
||||||
await Share.shareFiles(
|
[filePath],
|
||||||
[filePath],
|
mimeTypes: [
|
||||||
mimeTypes: [
|
'image/$type',
|
||||||
'image/$type',
|
],
|
||||||
],
|
);
|
||||||
);
|
},
|
||||||
},
|
),
|
||||||
),
|
|
||||||
InkWell(
|
InkWell(
|
||||||
onTap: widget.onTitleTap,
|
onTap: widget.onTitleTap,
|
||||||
child: Container(
|
child: Container(
|
||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
@@ -156,12 +154,12 @@ class _ImageFooterState extends State<ImageFooter> {
|
|||||||
isScrollControlled: true,
|
isScrollControlled: true,
|
||||||
shape: const RoundedRectangleBorder(
|
shape: const RoundedRectangleBorder(
|
||||||
borderRadius: BorderRadius.only(
|
borderRadius: BorderRadius.only(
|
||||||
topLeft: Radius.circular(16.0),
|
topLeft: Radius.circular(16),
|
||||||
topRight: Radius.circular(16.0),
|
topRight: Radius.circular(16),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
builder: (context) {
|
builder: (context) {
|
||||||
final crossAxisCount = 3;
|
const crossAxisCount = 3;
|
||||||
final noOfRowToShowInitially =
|
final noOfRowToShowInitially =
|
||||||
widget.mediaAttachments.length > crossAxisCount ? 2 : 1;
|
widget.mediaAttachments.length > crossAxisCount ? 2 : 1;
|
||||||
final size = MediaQuery.of(context).size;
|
final size = MediaQuery.of(context).size;
|
||||||
@@ -181,7 +179,7 @@ class _ImageFooterState extends State<ImageFooter> {
|
|||||||
children: [
|
children: [
|
||||||
Center(
|
Center(
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.all(16.0),
|
padding: const EdgeInsets.all(16),
|
||||||
child: Text(
|
child: Text(
|
||||||
'Photos',
|
'Photos',
|
||||||
style: StreamChatTheme.of(context)
|
style: StreamChatTheme.of(context)
|
||||||
@@ -209,8 +207,8 @@ class _ImageFooterState extends State<ImageFooter> {
|
|||||||
padding: const EdgeInsets.all(1),
|
padding: const EdgeInsets.all(1),
|
||||||
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
|
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
|
||||||
crossAxisCount: crossAxisCount,
|
crossAxisCount: crossAxisCount,
|
||||||
mainAxisSpacing: 2.0,
|
mainAxisSpacing: 2,
|
||||||
crossAxisSpacing: 2.0,
|
crossAxisSpacing: 2,
|
||||||
),
|
),
|
||||||
itemBuilder: (context, index) {
|
itemBuilder: (context, index) {
|
||||||
Widget media;
|
Widget media;
|
||||||
@@ -230,7 +228,7 @@ class _ImageFooterState extends State<ImageFooter> {
|
|||||||
media = InkWell(
|
media = InkWell(
|
||||||
onTap: () => widget.mediaSelectedCallBack!(index),
|
onTap: () => widget.mediaSelectedCallBack!(index),
|
||||||
child: AspectRatio(
|
child: AspectRatio(
|
||||||
aspectRatio: 1.0,
|
aspectRatio: 1,
|
||||||
child: CachedNetworkImage(
|
child: CachedNetworkImage(
|
||||||
imageUrl: attachment.imageUrl ??
|
imageUrl: attachment.imageUrl ??
|
||||||
attachment.assetUrl ??
|
attachment.assetUrl ??
|
||||||
@@ -246,7 +244,7 @@ class _ImageFooterState extends State<ImageFooter> {
|
|||||||
media,
|
media,
|
||||||
if (widget.message.user != null)
|
if (widget.message.user != null)
|
||||||
Padding(
|
Padding(
|
||||||
padding: EdgeInsets.all(8.0),
|
padding: EdgeInsets.all(8),
|
||||||
child: Container(
|
child: Container(
|
||||||
clipBehavior: Clip.antiAlias,
|
clipBehavior: Clip.antiAlias,
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
@@ -254,7 +252,7 @@ class _ImageFooterState extends State<ImageFooter> {
|
|||||||
color: Colors.white.withOpacity(0.6),
|
color: Colors.white.withOpacity(0.6),
|
||||||
boxShadow: [
|
boxShadow: [
|
||||||
BoxShadow(
|
BoxShadow(
|
||||||
blurRadius: 8.0,
|
blurRadius: 8,
|
||||||
color: StreamChatTheme.of(context)
|
color: StreamChatTheme.of(context)
|
||||||
.colorTheme
|
.colorTheme
|
||||||
.black
|
.black
|
||||||
@@ -287,7 +285,7 @@ class _ImageFooterState extends State<ImageFooter> {
|
|||||||
|
|
||||||
/// Sends the current message
|
/// Sends the current message
|
||||||
Future sendMessage() async {
|
Future sendMessage() async {
|
||||||
var text = _messageController.text.trim();
|
final text = _messageController.text.trim();
|
||||||
|
|
||||||
final attachments = widget.message.attachments;
|
final attachments = widget.message.attachments;
|
||||||
|
|
||||||
@@ -311,10 +309,10 @@ class _ImageFooterState extends State<ImageFooter> {
|
|||||||
class IconClipper extends CustomClipper<Path> {
|
class IconClipper extends CustomClipper<Path> {
|
||||||
@override
|
@override
|
||||||
Path getClip(Size size) {
|
Path getClip(Size size) {
|
||||||
var leftX = size.width / 5;
|
final leftX = size.width / 5;
|
||||||
var rightX = 4 * size.width / 5;
|
final rightX = 4 * size.width / 5;
|
||||||
var topY = size.height / 5;
|
final topY = size.height / 5;
|
||||||
var bottomY = 4 * size.height / 5;
|
final bottomY = 4 * size.height / 5;
|
||||||
|
|
||||||
final path = Path();
|
final path = Path();
|
||||||
path.moveTo(leftX, topY);
|
path.moveTo(leftX, topY);
|
||||||
@@ -322,7 +320,7 @@ class IconClipper extends CustomClipper<Path> {
|
|||||||
path.lineTo(rightX, bottomY);
|
path.lineTo(rightX, bottomY);
|
||||||
path.lineTo(rightX, topY);
|
path.lineTo(rightX, topY);
|
||||||
path.lineTo(leftX, topY);
|
path.lineTo(leftX, topY);
|
||||||
path.lineTo(0.0, 0.0);
|
path.lineTo(0, 0);
|
||||||
path.close();
|
path.close();
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,22 +27,19 @@ class ImageGroup extends StatelessWidget {
|
|||||||
direction: Axis.vertical,
|
direction: Axis.vertical,
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
Flexible(
|
Flexible(
|
||||||
flex: 1,
|
|
||||||
fit: FlexFit.tight,
|
fit: FlexFit.tight,
|
||||||
child: Flex(
|
child: Flex(
|
||||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||||
direction: Axis.horizontal,
|
direction: Axis.horizontal,
|
||||||
children: [
|
children: [
|
||||||
Flexible(
|
Flexible(
|
||||||
flex: 1,
|
|
||||||
fit: FlexFit.tight,
|
fit: FlexFit.tight,
|
||||||
child: _buildImage(context, 0),
|
child: _buildImage(context, 0),
|
||||||
),
|
),
|
||||||
Flexible(
|
Flexible(
|
||||||
flex: 1,
|
|
||||||
fit: FlexFit.tight,
|
fit: FlexFit.tight,
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.only(left: 2.0),
|
padding: const EdgeInsets.only(left: 2),
|
||||||
child: _buildImage(context, 1),
|
child: _buildImage(context, 1),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -52,24 +49,21 @@ class ImageGroup extends StatelessWidget {
|
|||||||
if (images.length >= 3)
|
if (images.length >= 3)
|
||||||
Flexible(
|
Flexible(
|
||||||
fit: FlexFit.tight,
|
fit: FlexFit.tight,
|
||||||
flex: 1,
|
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.only(top: 2.0),
|
padding: const EdgeInsets.only(top: 2),
|
||||||
child: Flex(
|
child: Flex(
|
||||||
direction: Axis.horizontal,
|
direction: Axis.horizontal,
|
||||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
Flexible(
|
Flexible(
|
||||||
fit: FlexFit.tight,
|
fit: FlexFit.tight,
|
||||||
flex: 1,
|
|
||||||
child: _buildImage(context, 2),
|
child: _buildImage(context, 2),
|
||||||
),
|
),
|
||||||
if (images.length >= 4)
|
if (images.length >= 4)
|
||||||
Flexible(
|
Flexible(
|
||||||
fit: FlexFit.tight,
|
fit: FlexFit.tight,
|
||||||
flex: 1,
|
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.only(left: 2.0),
|
padding: const EdgeInsets.only(left: 2),
|
||||||
child: Stack(
|
child: Stack(
|
||||||
fit: StackFit.expand,
|
fit: StackFit.expand,
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ class ImageHeader extends StatelessWidget implements PreferredSizeWidget {
|
|||||||
? IconButton(
|
? IconButton(
|
||||||
icon: StreamSvgIcon.close(
|
icon: StreamSvgIcon.close(
|
||||||
color: StreamChatTheme.of(context).colorTheme.black,
|
color: StreamChatTheme.of(context).colorTheme.black,
|
||||||
size: 24.0,
|
size: 24,
|
||||||
),
|
),
|
||||||
onPressed: onBackPressed,
|
onPressed: onBackPressed,
|
||||||
)
|
)
|
||||||
@@ -79,7 +79,6 @@ class ImageHeader extends StatelessWidget implements PreferredSizeWidget {
|
|||||||
height: preferredSize.height,
|
height: preferredSize.height,
|
||||||
width: preferredSize.width,
|
width: preferredSize.width,
|
||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ class InfoTile extends StatelessWidget {
|
|||||||
final TextStyle? textStyle;
|
final TextStyle? textStyle;
|
||||||
final Color? backgroundColor;
|
final Color? backgroundColor;
|
||||||
|
|
||||||
InfoTile({
|
const InfoTile({
|
||||||
required this.message,
|
required this.message,
|
||||||
required this.child,
|
required this.child,
|
||||||
required this.showMessage,
|
required this.showMessage,
|
||||||
@@ -28,7 +28,7 @@ class InfoTile extends StatelessWidget {
|
|||||||
portalAnchor: tileAnchor ?? Alignment.topCenter,
|
portalAnchor: tileAnchor ?? Alignment.topCenter,
|
||||||
childAnchor: childAnchor ?? Alignment.bottomCenter,
|
childAnchor: childAnchor ?? Alignment.bottomCenter,
|
||||||
portal: Container(
|
portal: Container(
|
||||||
height: 25.0,
|
height: 25,
|
||||||
color: backgroundColor ??
|
color: backgroundColor ??
|
||||||
StreamChatTheme.of(context).colorTheme.grey.withOpacity(0.9),
|
StreamChatTheme.of(context).colorTheme.grey.withOpacity(0.9),
|
||||||
child: Center(
|
child: Center(
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ class _MediaListViewState extends State<MediaListView> {
|
|||||||
) {
|
) {
|
||||||
final media = _media.elementAt(position);
|
final media = _media.elementAt(position);
|
||||||
return Padding(
|
return Padding(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 1.0, vertical: 1.0),
|
padding: const EdgeInsets.symmetric(horizontal: 1, vertical: 1),
|
||||||
child: InkWell(
|
child: InkWell(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
if (widget.onSelect != null) {
|
if (widget.onSelect != null) {
|
||||||
@@ -64,7 +64,7 @@ class _MediaListViewState extends State<MediaListView> {
|
|||||||
child: Stack(
|
child: Stack(
|
||||||
children: [
|
children: [
|
||||||
AspectRatio(
|
AspectRatio(
|
||||||
aspectRatio: 1.0,
|
aspectRatio: 1,
|
||||||
child: FadeInImage(
|
child: FadeInImage(
|
||||||
fadeInDuration: Duration(milliseconds: 300),
|
fadeInDuration: Duration(milliseconds: 300),
|
||||||
placeholder: AssetImage(
|
placeholder: AssetImage(
|
||||||
@@ -144,9 +144,7 @@ class _MediaListViewState extends State<MediaListView> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void _getMedia() async {
|
void _getMedia() async {
|
||||||
final assetList = await PhotoManager.getAssetPathList(
|
final assetList = await PhotoManager.getAssetPathList().then((value) {
|
||||||
hasAll: true,
|
|
||||||
).then((value) {
|
|
||||||
if (value.isNotEmpty == true) {
|
if (value.isNotEmpty == true) {
|
||||||
return value.singleWhere((element) => element.isAll);
|
return value.singleWhere((element) => element.isAll);
|
||||||
}
|
}
|
||||||
@@ -178,7 +176,7 @@ class MediaThumbnailProvider extends ImageProvider<MediaThumbnailProvider> {
|
|||||||
ImageStreamCompleter load(key, decode) {
|
ImageStreamCompleter load(key, decode) {
|
||||||
return MultiFrameImageStreamCompleter(
|
return MultiFrameImageStreamCompleter(
|
||||||
codec: _loadAsync(key, decode),
|
codec: _loadAsync(key, decode),
|
||||||
scale: 1.0,
|
scale: 1,
|
||||||
informationCollector: () sync* {
|
informationCollector: () sync* {
|
||||||
yield ErrorDescription('Id: ${media.id}');
|
yield ErrorDescription('Id: ${media.id}');
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ class MentionTile extends StatelessWidget {
|
|||||||
/// Widget at the end of tile
|
/// Widget at the end of tile
|
||||||
final Widget? trailing;
|
final Widget? trailing;
|
||||||
|
|
||||||
MentionTile(
|
const MentionTile(
|
||||||
this.member, {
|
this.member, {
|
||||||
this.title,
|
this.title,
|
||||||
this.subtitle,
|
this.subtitle,
|
||||||
@@ -31,12 +31,11 @@ class MentionTile extends StatelessWidget {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Container(
|
return Container(
|
||||||
height: 56.0,
|
height: 56,
|
||||||
child: Row(
|
child: Row(
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
|
||||||
children: [
|
children: [
|
||||||
SizedBox(
|
SizedBox(
|
||||||
width: 16.0,
|
width: 16,
|
||||||
),
|
),
|
||||||
leading ??
|
leading ??
|
||||||
UserAvatar(
|
UserAvatar(
|
||||||
@@ -49,7 +48,7 @@ class MentionTile extends StatelessWidget {
|
|||||||
user: member.user!,
|
user: member.user!,
|
||||||
),
|
),
|
||||||
SizedBox(
|
SizedBox(
|
||||||
width: 8.0,
|
width: 8,
|
||||||
),
|
),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Align(
|
child: Align(
|
||||||
@@ -60,13 +59,13 @@ class MentionTile extends StatelessWidget {
|
|||||||
children: [
|
children: [
|
||||||
title ??
|
title ??
|
||||||
Text(
|
Text(
|
||||||
'${member.user!.name}',
|
member.user!.name,
|
||||||
maxLines: 1,
|
maxLines: 1,
|
||||||
overflow: TextOverflow.ellipsis,
|
overflow: TextOverflow.ellipsis,
|
||||||
style: StreamChatTheme.of(context).textTheme.bodyBold,
|
style: StreamChatTheme.of(context).textTheme.bodyBold,
|
||||||
),
|
),
|
||||||
SizedBox(
|
SizedBox(
|
||||||
height: 2.0,
|
height: 2,
|
||||||
),
|
),
|
||||||
subtitle ??
|
subtitle ??
|
||||||
Text(
|
Text(
|
||||||
@@ -88,8 +87,8 @@ class MentionTile extends StatelessWidget {
|
|||||||
trailing ??
|
trailing ??
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.only(
|
padding: const EdgeInsets.only(
|
||||||
right: 18.0,
|
right: 18,
|
||||||
left: 8.0,
|
left: 8,
|
||||||
),
|
),
|
||||||
child: StreamSvgIcon.mentions(
|
child: StreamSvgIcon.mentions(
|
||||||
color: StreamChatTheme.of(context).colorTheme.accentBlue,
|
color: StreamChatTheme.of(context).colorTheme.accentBlue,
|
||||||
|
|||||||
@@ -119,7 +119,7 @@ class _MessageActionsModalState extends State<MessageActionsModal> {
|
|||||||
),
|
),
|
||||||
if (_showActions)
|
if (_showActions)
|
||||||
TweenAnimationBuilder<double>(
|
TweenAnimationBuilder<double>(
|
||||||
tween: Tween(begin: 0.0, end: 1.0),
|
tween: Tween(begin: 0, end: 1),
|
||||||
duration: Duration(milliseconds: 300),
|
duration: Duration(milliseconds: 300),
|
||||||
curve: Curves.easeInOutBack,
|
curve: Curves.easeInOutBack,
|
||||||
builder: (context, val, snapshot) {
|
builder: (context, val, snapshot) {
|
||||||
@@ -128,7 +128,7 @@ class _MessageActionsModalState extends State<MessageActionsModal> {
|
|||||||
child: Center(
|
child: Center(
|
||||||
child: SingleChildScrollView(
|
child: SingleChildScrollView(
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.all(8.0),
|
padding: const EdgeInsets.all(8),
|
||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: widget.reverse
|
crossAxisAlignment: widget.reverse
|
||||||
? CrossAxisAlignment.end
|
? CrossAxisAlignment.end
|
||||||
@@ -146,7 +146,7 @@ class _MessageActionsModalState extends State<MessageActionsModal> {
|
|||||||
: (divFactor > 1.0
|
: (divFactor > 1.0
|
||||||
? 0.0
|
? 0.0
|
||||||
: -(1.0 - divFactor)),
|
: -(1.0 - divFactor)),
|
||||||
0.0),
|
0),
|
||||||
child: ReactionPicker(
|
child: ReactionPicker(
|
||||||
message: widget.message,
|
message: widget.message,
|
||||||
),
|
),
|
||||||
@@ -166,7 +166,6 @@ class _MessageActionsModalState extends State<MessageActionsModal> {
|
|||||||
messageTheme: widget.messageTheme,
|
messageTheme: widget.messageTheme,
|
||||||
showReactions: false,
|
showReactions: false,
|
||||||
showUsername: false,
|
showUsername: false,
|
||||||
showThreadReplyIndicator: false,
|
|
||||||
showReplyMessage: false,
|
showReplyMessage: false,
|
||||||
showUserAvatar: widget.showUserAvatar,
|
showUserAvatar: widget.showUserAvatar,
|
||||||
attachmentPadding: EdgeInsets.all(
|
attachmentPadding: EdgeInsets.all(
|
||||||
@@ -176,7 +175,7 @@ class _MessageActionsModalState extends State<MessageActionsModal> {
|
|||||||
translateUserAvatar: false,
|
translateUserAvatar: false,
|
||||||
padding: const EdgeInsets.all(0),
|
padding: const EdgeInsets.all(0),
|
||||||
textPadding: EdgeInsets.symmetric(
|
textPadding: EdgeInsets.symmetric(
|
||||||
vertical: 8.0,
|
vertical: 8,
|
||||||
horizontal: widget.message.text!.isOnlyEmoji
|
horizontal: widget.message.text!.isOnlyEmoji
|
||||||
? 0
|
? 0
|
||||||
: 16.0,
|
: 16.0,
|
||||||
@@ -185,7 +184,6 @@ class _MessageActionsModalState extends State<MessageActionsModal> {
|
|||||||
widget.showReactions &&
|
widget.showReactions &&
|
||||||
(widget.message.status ==
|
(widget.message.status ==
|
||||||
MessageSendingStatus.sent),
|
MessageSendingStatus.sent),
|
||||||
showInChannelIndicator: false,
|
|
||||||
showSendingIndicator: false,
|
showSendingIndicator: false,
|
||||||
shape: widget.messageShape,
|
shape: widget.messageShape,
|
||||||
attachmentShape: widget.attachmentShape,
|
attachmentShape: widget.attachmentShape,
|
||||||
@@ -269,7 +267,7 @@ class _MessageActionsModalState extends State<MessageActionsModal> {
|
|||||||
messageAction.onTap?.call(widget.message);
|
messageAction.onTap?.call(widget.message);
|
||||||
},
|
},
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.symmetric(vertical: 11.0, horizontal: 16.0),
|
padding: const EdgeInsets.symmetric(vertical: 11, horizontal: 16),
|
||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
messageAction.leading ?? Offstage(),
|
messageAction.leading ?? Offstage(),
|
||||||
@@ -289,7 +287,7 @@ class _MessageActionsModalState extends State<MessageActionsModal> {
|
|||||||
title: 'Flag Message',
|
title: 'Flag Message',
|
||||||
icon: StreamSvgIcon.flag(
|
icon: StreamSvgIcon.flag(
|
||||||
color: StreamChatTheme.of(context).colorTheme.accentRed,
|
color: StreamChatTheme.of(context).colorTheme.accentRed,
|
||||||
size: 24.0,
|
size: 24,
|
||||||
),
|
),
|
||||||
question:
|
question:
|
||||||
'Do you want to send a copy of this message to a\nmoderator for further investigation?',
|
'Do you want to send a copy of this message to a\nmoderator for further investigation?',
|
||||||
@@ -305,7 +303,7 @@ class _MessageActionsModalState extends State<MessageActionsModal> {
|
|||||||
context,
|
context,
|
||||||
icon: StreamSvgIcon.flag(
|
icon: StreamSvgIcon.flag(
|
||||||
color: theme.colorTheme.accentRed,
|
color: theme.colorTheme.accentRed,
|
||||||
size: 24.0,
|
size: 24,
|
||||||
),
|
),
|
||||||
details: 'The message has been reported to a moderator.',
|
details: 'The message has been reported to a moderator.',
|
||||||
title: 'Message flagged',
|
title: 'Message flagged',
|
||||||
@@ -317,7 +315,7 @@ class _MessageActionsModalState extends State<MessageActionsModal> {
|
|||||||
context,
|
context,
|
||||||
icon: StreamSvgIcon.flag(
|
icon: StreamSvgIcon.flag(
|
||||||
color: theme.colorTheme.accentRed,
|
color: theme.colorTheme.accentRed,
|
||||||
size: 24.0,
|
size: 24,
|
||||||
),
|
),
|
||||||
details: 'The message has been reported to a moderator.',
|
details: 'The message has been reported to a moderator.',
|
||||||
title: 'Message flagged',
|
title: 'Message flagged',
|
||||||
@@ -339,7 +337,7 @@ class _MessageActionsModalState extends State<MessageActionsModal> {
|
|||||||
title: 'Delete message',
|
title: 'Delete message',
|
||||||
icon: StreamSvgIcon.flag(
|
icon: StreamSvgIcon.flag(
|
||||||
color: StreamChatTheme.of(context).colorTheme.accentRed,
|
color: StreamChatTheme.of(context).colorTheme.accentRed,
|
||||||
size: 24.0,
|
size: 24,
|
||||||
),
|
),
|
||||||
question: 'Are you sure you want to permanently delete this\nmessage?',
|
question: 'Are you sure you want to permanently delete this\nmessage?',
|
||||||
okText: 'DELETE',
|
okText: 'DELETE',
|
||||||
@@ -365,7 +363,7 @@ class _MessageActionsModalState extends State<MessageActionsModal> {
|
|||||||
context,
|
context,
|
||||||
icon: StreamSvgIcon.error(
|
icon: StreamSvgIcon.error(
|
||||||
color: StreamChatTheme.of(context).colorTheme.accentRed,
|
color: StreamChatTheme.of(context).colorTheme.accentRed,
|
||||||
size: 24.0,
|
size: 24,
|
||||||
),
|
),
|
||||||
details: 'The operation couldn\'t be completed.',
|
details: 'The operation couldn\'t be completed.',
|
||||||
title: 'Something went wrong',
|
title: 'Something went wrong',
|
||||||
@@ -382,7 +380,7 @@ class _MessageActionsModalState extends State<MessageActionsModal> {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.symmetric(vertical: 11.0, horizontal: 16.0),
|
padding: const EdgeInsets.symmetric(vertical: 11, horizontal: 16),
|
||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
StreamSvgIcon.reply(
|
StreamSvgIcon.reply(
|
||||||
@@ -401,9 +399,9 @@ class _MessageActionsModalState extends State<MessageActionsModal> {
|
|||||||
|
|
||||||
Widget _buildFlagButton(BuildContext context) {
|
Widget _buildFlagButton(BuildContext context) {
|
||||||
return InkWell(
|
return InkWell(
|
||||||
onTap: () => _showFlagDialog(),
|
onTap: _showFlagDialog,
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.symmetric(vertical: 11.0, horizontal: 16.0),
|
padding: const EdgeInsets.symmetric(vertical: 11, horizontal: 16),
|
||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
StreamSvgIcon.iconFlag(
|
StreamSvgIcon.iconFlag(
|
||||||
@@ -424,9 +422,9 @@ class _MessageActionsModalState extends State<MessageActionsModal> {
|
|||||||
final isDeleteFailed =
|
final isDeleteFailed =
|
||||||
widget.message.status == MessageSendingStatus.failed_delete;
|
widget.message.status == MessageSendingStatus.failed_delete;
|
||||||
return InkWell(
|
return InkWell(
|
||||||
onTap: () => _showDeleteDialog(),
|
onTap: _showDeleteDialog,
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.symmetric(vertical: 11.0, horizontal: 16.0),
|
padding: const EdgeInsets.symmetric(vertical: 11, horizontal: 16),
|
||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
StreamSvgIcon.delete(
|
StreamSvgIcon.delete(
|
||||||
@@ -453,7 +451,7 @@ class _MessageActionsModalState extends State<MessageActionsModal> {
|
|||||||
Navigator.pop(context);
|
Navigator.pop(context);
|
||||||
},
|
},
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.symmetric(vertical: 11.0, horizontal: 16.0),
|
padding: const EdgeInsets.symmetric(vertical: 11, horizontal: 16),
|
||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
StreamSvgIcon.copy(
|
StreamSvgIcon.copy(
|
||||||
@@ -478,7 +476,7 @@ class _MessageActionsModalState extends State<MessageActionsModal> {
|
|||||||
_showEditBottomSheet(context);
|
_showEditBottomSheet(context);
|
||||||
},
|
},
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.symmetric(vertical: 11.0, horizontal: 16.0),
|
padding: const EdgeInsets.symmetric(vertical: 11, horizontal: 16),
|
||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
StreamSvgIcon.edit(
|
StreamSvgIcon.edit(
|
||||||
@@ -509,7 +507,7 @@ class _MessageActionsModalState extends State<MessageActionsModal> {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.symmetric(vertical: 11.0, horizontal: 16.0),
|
padding: const EdgeInsets.symmetric(vertical: 11, horizontal: 16),
|
||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
StreamSvgIcon.circleUp(
|
StreamSvgIcon.circleUp(
|
||||||
@@ -555,7 +553,7 @@ class _MessageActionsModalState extends State<MessageActionsModal> {
|
|||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.all(8.0),
|
padding: const EdgeInsets.all(8),
|
||||||
child: StreamSvgIcon.edit(
|
child: StreamSvgIcon.edit(
|
||||||
color: StreamChatTheme.of(context)
|
color: StreamChatTheme.of(context)
|
||||||
.colorTheme
|
.colorTheme
|
||||||
@@ -574,16 +572,17 @@ class _MessageActionsModalState extends State<MessageActionsModal> {
|
|||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
widget.editMessageInputBuilder != null
|
if (widget.editMessageInputBuilder != null)
|
||||||
? widget.editMessageInputBuilder!(context, widget.message)
|
widget.editMessageInputBuilder!(context, widget.message)
|
||||||
: MessageInput(
|
else
|
||||||
editMessage: widget.message,
|
MessageInput(
|
||||||
preMessageSending: (m) {
|
editMessage: widget.message,
|
||||||
FocusScope.of(context).unfocus();
|
preMessageSending: (m) {
|
||||||
Navigator.pop(context);
|
FocusScope.of(context).unfocus();
|
||||||
return m;
|
Navigator.pop(context);
|
||||||
},
|
return m;
|
||||||
),
|
},
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
@@ -600,7 +599,7 @@ class _MessageActionsModalState extends State<MessageActionsModal> {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.symmetric(vertical: 11.0, horizontal: 16.0),
|
padding: const EdgeInsets.symmetric(vertical: 11, horizontal: 16),
|
||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
StreamSvgIcon.thread(
|
StreamSvgIcon.thread(
|
||||||
|
|||||||
@@ -109,7 +109,7 @@ const _kMaxAttachmentSize = 20971520; // 20MB in Bytes
|
|||||||
/// Modify it to change the widget appearance.
|
/// Modify it to change the widget appearance.
|
||||||
class MessageInput extends StatefulWidget {
|
class MessageInput extends StatefulWidget {
|
||||||
/// Instantiate a new MessageInput
|
/// Instantiate a new MessageInput
|
||||||
MessageInput({
|
const MessageInput({
|
||||||
Key? key,
|
Key? key,
|
||||||
this.onMessageSent,
|
this.onMessageSent,
|
||||||
this.preMessageSending,
|
this.preMessageSending,
|
||||||
@@ -306,7 +306,7 @@ class MessageInputState extends State<MessageInput> {
|
|||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
children: [
|
children: [
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.all(8.0),
|
padding: const EdgeInsets.all(8),
|
||||||
child: StreamSvgIcon.reply(
|
child: StreamSvgIcon.reply(
|
||||||
color: StreamChatTheme.of(context)
|
color: StreamChatTheme.of(context)
|
||||||
.colorTheme
|
.colorTheme
|
||||||
@@ -326,15 +326,15 @@ class MessageInputState extends State<MessageInput> {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.symmetric(vertical: 8.0),
|
padding: const EdgeInsets.symmetric(vertical: 8),
|
||||||
child: _buildTextField(context),
|
child: _buildTextField(context),
|
||||||
),
|
),
|
||||||
if (widget.parentMessage != null && !widget.hideSendAsDm)
|
if (widget.parentMessage != null && !widget.hideSendAsDm)
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.only(
|
padding: const EdgeInsets.only(
|
||||||
right: 12.0,
|
right: 12,
|
||||||
left: 12.0,
|
left: 12,
|
||||||
bottom: 12.0,
|
bottom: 12,
|
||||||
),
|
),
|
||||||
child: _buildDmCheckbox(),
|
child: _buildDmCheckbox(),
|
||||||
),
|
),
|
||||||
@@ -356,7 +356,6 @@ class MessageInputState extends State<MessageInput> {
|
|||||||
Flex _buildTextField(BuildContext context) {
|
Flex _buildTextField(BuildContext context) {
|
||||||
return Flex(
|
return Flex(
|
||||||
direction: Axis.horizontal,
|
direction: Axis.horizontal,
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
if (!_commandEnabled && widget.actionsLocation == ActionsLocation.left)
|
if (!_commandEnabled && widget.actionsLocation == ActionsLocation.left)
|
||||||
_buildExpandActionsButton(),
|
_buildExpandActionsButton(),
|
||||||
@@ -371,7 +370,6 @@ class MessageInputState extends State<MessageInput> {
|
|||||||
|
|
||||||
Widget _buildDmCheckbox() {
|
Widget _buildDmCheckbox() {
|
||||||
return Row(
|
return Row(
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
|
||||||
children: [
|
children: [
|
||||||
Container(
|
Container(
|
||||||
height: 16,
|
height: 16,
|
||||||
@@ -407,7 +405,7 @@ class MessageInputState extends State<MessageInput> {
|
|||||||
? CrossFadeState.showFirst
|
? CrossFadeState.showFirst
|
||||||
: CrossFadeState.showSecond,
|
: CrossFadeState.showSecond,
|
||||||
firstChild: StreamSvgIcon.check(
|
firstChild: StreamSvgIcon.check(
|
||||||
size: 16.0,
|
size: 16,
|
||||||
color: StreamChatTheme.of(context).colorTheme.white,
|
color: StreamChatTheme.of(context).colorTheme.white,
|
||||||
),
|
),
|
||||||
secondChild: SizedBox(
|
secondChild: SizedBox(
|
||||||
@@ -420,7 +418,7 @@ class MessageInputState extends State<MessageInput> {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 12.0),
|
padding: const EdgeInsets.symmetric(horizontal: 12),
|
||||||
child: Text(
|
child: Text(
|
||||||
'Also send as direct message',
|
'Also send as direct message',
|
||||||
style: StreamChatTheme.of(context).textTheme.footnote.copyWith(
|
style: StreamChatTheme.of(context).textTheme.footnote.copyWith(
|
||||||
@@ -456,7 +454,7 @@ class MessageInputState extends State<MessageInput> {
|
|||||||
|
|
||||||
Widget _buildExpandActionsButton() {
|
Widget _buildExpandActionsButton() {
|
||||||
return Padding(
|
return Padding(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 8.0),
|
padding: const EdgeInsets.symmetric(horizontal: 8),
|
||||||
child: AnimatedCrossFade(
|
child: AnimatedCrossFade(
|
||||||
crossFadeState: _actionsShrunk
|
crossFadeState: _actionsShrunk
|
||||||
? CrossFadeState.showFirst
|
? CrossFadeState.showFirst
|
||||||
@@ -464,7 +462,6 @@ class MessageInputState extends State<MessageInput> {
|
|||||||
firstChild: IconButton(
|
firstChild: IconButton(
|
||||||
onPressed: () => setState(() => _actionsShrunk = false),
|
onPressed: () => setState(() => _actionsShrunk = false),
|
||||||
icon: Transform.rotate(
|
icon: Transform.rotate(
|
||||||
alignment: Alignment.center,
|
|
||||||
angle: (widget.actionsLocation == ActionsLocation.right ||
|
angle: (widget.actionsLocation == ActionsLocation.right ||
|
||||||
widget.actionsLocation == ActionsLocation.rightInside)
|
widget.actionsLocation == ActionsLocation.rightInside)
|
||||||
? pi
|
? pi
|
||||||
@@ -484,7 +481,6 @@ class MessageInputState extends State<MessageInput> {
|
|||||||
),
|
),
|
||||||
secondChild: FittedBox(
|
secondChild: FittedBox(
|
||||||
child: Row(
|
child: Row(
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
if (!widget.disableAttachments) _buildAttachmentButton(),
|
if (!widget.disableAttachments) _buildAttachmentButton(),
|
||||||
@@ -510,10 +506,10 @@ class MessageInputState extends State<MessageInput> {
|
|||||||
Expanded _buildTextInput(BuildContext context) {
|
Expanded _buildTextInput(BuildContext context) {
|
||||||
final theme = StreamChatTheme.of(context);
|
final theme = StreamChatTheme.of(context);
|
||||||
final margin = (widget.sendButtonLocation == SendButtonLocation.inside
|
final margin = (widget.sendButtonLocation == SendButtonLocation.inside
|
||||||
? const EdgeInsets.only(right: 8.0)
|
? const EdgeInsets.only(right: 8)
|
||||||
: EdgeInsets.zero) +
|
: EdgeInsets.zero) +
|
||||||
(widget.actionsLocation != ActionsLocation.left
|
(widget.actionsLocation != ActionsLocation.left
|
||||||
? const EdgeInsets.only(left: 8.0)
|
? const EdgeInsets.only(left: 8)
|
||||||
: EdgeInsets.zero);
|
: EdgeInsets.zero);
|
||||||
return Expanded(
|
return Expanded(
|
||||||
child: Center(
|
child: Center(
|
||||||
@@ -545,7 +541,6 @@ class MessageInputState extends State<MessageInput> {
|
|||||||
child: TextField(
|
child: TextField(
|
||||||
key: Key('messageInputText'),
|
key: Key('messageInputText'),
|
||||||
enabled: _inputEnabled,
|
enabled: _inputEnabled,
|
||||||
minLines: null,
|
|
||||||
maxLines: null,
|
maxLines: null,
|
||||||
onSubmitted: (_) => sendMessage(),
|
onSubmitted: (_) => sendMessage(),
|
||||||
keyboardType: widget.keyboardType,
|
keyboardType: widget.keyboardType,
|
||||||
@@ -607,7 +602,7 @@ class MessageInputState extends State<MessageInput> {
|
|||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: [
|
children: [
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.all(8.0),
|
padding: const EdgeInsets.all(8),
|
||||||
child: Container(
|
child: Container(
|
||||||
constraints: BoxConstraints.tight(Size(64, 24)),
|
constraints: BoxConstraints.tight(Size(64, 24)),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
@@ -620,7 +615,7 @@ class MessageInputState extends State<MessageInput> {
|
|||||||
children: [
|
children: [
|
||||||
StreamSvgIcon.lightning(
|
StreamSvgIcon.lightning(
|
||||||
color: Colors.white,
|
color: Colors.white,
|
||||||
size: 16.0,
|
size: 16,
|
||||||
),
|
),
|
||||||
Text(
|
Text(
|
||||||
_chosenCommand?.name.toUpperCase() ?? '',
|
_chosenCommand?.name.toUpperCase() ?? '',
|
||||||
@@ -640,7 +635,6 @@ class MessageInputState extends State<MessageInput> {
|
|||||||
: (widget.actionsLocation == ActionsLocation.leftInside
|
: (widget.actionsLocation == ActionsLocation.leftInside
|
||||||
? Row(
|
? Row(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
|
||||||
children: [
|
children: [
|
||||||
_buildExpandActionsButton(),
|
_buildExpandActionsButton(),
|
||||||
],
|
],
|
||||||
@@ -650,11 +644,10 @@ class MessageInputState extends State<MessageInput> {
|
|||||||
prefixIconConstraints: BoxConstraints.tightFor(height: 40),
|
prefixIconConstraints: BoxConstraints.tightFor(height: 40),
|
||||||
suffixIcon: Row(
|
suffixIcon: Row(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
|
||||||
children: [
|
children: [
|
||||||
if (_commandEnabled)
|
if (_commandEnabled)
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.only(right: 8.0),
|
padding: const EdgeInsets.only(right: 8),
|
||||||
child: IconButton(
|
child: IconButton(
|
||||||
icon: StreamSvgIcon.closeSmall(),
|
icon: StreamSvgIcon.closeSmall(),
|
||||||
splashRadius: 24,
|
splashRadius: 24,
|
||||||
@@ -776,7 +769,7 @@ class MessageInputState extends State<MessageInput> {
|
|||||||
|
|
||||||
void _checkCommands(String s, BuildContext context) {
|
void _checkCommands(String s, BuildContext context) {
|
||||||
if (s.startsWith('/')) {
|
if (s.startsWith('/')) {
|
||||||
var matchedCommandsList = StreamChannel.of(context)
|
final matchedCommandsList = StreamChannel.of(context)
|
||||||
.channel
|
.channel
|
||||||
.config
|
.config
|
||||||
?.commands
|
?.commands
|
||||||
@@ -825,19 +818,18 @@ class MessageInputState extends State<MessageInput> {
|
|||||||
left: 0,
|
left: 0,
|
||||||
right: 0,
|
right: 0,
|
||||||
child: TweenAnimationBuilder<double>(
|
child: TweenAnimationBuilder<double>(
|
||||||
tween: Tween(begin: 0.0, end: 1.0),
|
tween: Tween(begin: 0, end: 1),
|
||||||
duration: Duration(milliseconds: 300),
|
duration: Duration(milliseconds: 300),
|
||||||
curve: Curves.easeInOutExpo,
|
curve: Curves.easeInOutExpo,
|
||||||
builder: (context, val, wid) {
|
builder: (context, val, wid) {
|
||||||
return Transform.scale(
|
return Transform.scale(
|
||||||
alignment: Alignment.center,
|
|
||||||
scale: val,
|
scale: val,
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.all(8.0),
|
padding: const EdgeInsets.all(8),
|
||||||
child: Card(
|
child: Card(
|
||||||
elevation: 2.0,
|
elevation: 2,
|
||||||
shape: RoundedRectangleBorder(
|
shape: RoundedRectangleBorder(
|
||||||
borderRadius: BorderRadius.circular(8.0),
|
borderRadius: BorderRadius.circular(8),
|
||||||
),
|
),
|
||||||
color: StreamChatTheme.of(context).colorTheme.white,
|
color: StreamChatTheme.of(context).colorTheme.white,
|
||||||
clipBehavior: Clip.antiAlias,
|
clipBehavior: Clip.antiAlias,
|
||||||
@@ -845,20 +837,19 @@ class MessageInputState extends State<MessageInput> {
|
|||||||
constraints: BoxConstraints.loose(Size.fromHeight(400)),
|
constraints: BoxConstraints.loose(Size.fromHeight(400)),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: StreamChatTheme.of(context).colorTheme.white,
|
color: StreamChatTheme.of(context).colorTheme.white,
|
||||||
borderRadius: BorderRadius.circular(8.0)),
|
borderRadius: BorderRadius.circular(8)),
|
||||||
child: ListView(
|
child: ListView(
|
||||||
padding: const EdgeInsets.all(0),
|
padding: const EdgeInsets.all(0),
|
||||||
shrinkWrap: true,
|
shrinkWrap: true,
|
||||||
children: [
|
children: [
|
||||||
if (commands.isNotEmpty)
|
if (commands.isNotEmpty)
|
||||||
Padding(
|
Padding(
|
||||||
padding:
|
padding: const EdgeInsets.only(top: 8),
|
||||||
const EdgeInsets.only(left: 0.0, top: 8.0),
|
|
||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.symmetric(
|
padding: const EdgeInsets.symmetric(
|
||||||
horizontal: 8.0,
|
horizontal: 8,
|
||||||
),
|
),
|
||||||
child: StreamSvgIcon.lightning(
|
child: StreamSvgIcon.lightning(
|
||||||
color: StreamChatTheme.of(context)
|
color: StreamChatTheme.of(context)
|
||||||
@@ -879,7 +870,7 @@ class MessageInputState extends State<MessageInput> {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
SizedBox(
|
SizedBox(
|
||||||
height: 10.0,
|
height: 10,
|
||||||
),
|
),
|
||||||
...commands
|
...commands
|
||||||
.map(
|
.map(
|
||||||
@@ -888,19 +879,19 @@ class MessageInputState extends State<MessageInput> {
|
|||||||
_setCommand(c);
|
_setCommand(c);
|
||||||
},
|
},
|
||||||
child: Container(
|
child: Container(
|
||||||
height: 40.0,
|
height: 40,
|
||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
SizedBox(
|
SizedBox(
|
||||||
width: 16.0,
|
width: 16,
|
||||||
),
|
),
|
||||||
_buildCommandIcon(c.name),
|
_buildCommandIcon(c.name),
|
||||||
SizedBox(
|
SizedBox(
|
||||||
width: 8.0,
|
width: 8,
|
||||||
),
|
),
|
||||||
Text.rich(
|
Text.rich(
|
||||||
TextSpan(
|
TextSpan(
|
||||||
text: '${c.name.capitalize()}',
|
text: c.name.capitalize(),
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontWeight: FontWeight.bold),
|
fontWeight: FontWeight.bold),
|
||||||
children: [
|
children: [
|
||||||
@@ -987,10 +978,8 @@ class MessageInputState extends State<MessageInput> {
|
|||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: [
|
children: [
|
||||||
Row(
|
Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.start,
|
|
||||||
children: [
|
children: [
|
||||||
IconButton(
|
IconButton(
|
||||||
iconSize: 24,
|
|
||||||
icon: StreamSvgIcon.pictures(
|
icon: StreamSvgIcon.pictures(
|
||||||
color: _getIconColor(0),
|
color: _getIconColor(0),
|
||||||
),
|
),
|
||||||
@@ -1010,11 +999,10 @@ class MessageInputState extends State<MessageInput> {
|
|||||||
onPressed: !_attachmentContainsFile && _attachments.isNotEmpty
|
onPressed: !_attachmentContainsFile && _attachments.isNotEmpty
|
||||||
? null
|
? null
|
||||||
: () {
|
: () {
|
||||||
pickFile(DefaultAttachmentTypes.file, false);
|
pickFile(DefaultAttachmentTypes.file);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
IconButton(
|
IconButton(
|
||||||
iconSize: 24,
|
|
||||||
icon: StreamSvgIcon.camera(
|
icon: StreamSvgIcon.camera(
|
||||||
color: _getIconColor(2),
|
color: _getIconColor(2),
|
||||||
),
|
),
|
||||||
@@ -1026,7 +1014,6 @@ class MessageInputState extends State<MessageInput> {
|
|||||||
),
|
),
|
||||||
IconButton(
|
IconButton(
|
||||||
padding: const EdgeInsets.all(0),
|
padding: const EdgeInsets.all(0),
|
||||||
iconSize: 24,
|
|
||||||
icon: StreamSvgIcon.record(
|
icon: StreamSvgIcon.record(
|
||||||
color: _getIconColor(3),
|
color: _getIconColor(3),
|
||||||
),
|
),
|
||||||
@@ -1052,22 +1039,22 @@ class MessageInputState extends State<MessageInput> {
|
|||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: StreamChatTheme.of(context).colorTheme.white,
|
color: StreamChatTheme.of(context).colorTheme.white,
|
||||||
borderRadius: BorderRadius.only(
|
borderRadius: BorderRadius.only(
|
||||||
topLeft: Radius.circular(16.0),
|
topLeft: Radius.circular(16),
|
||||||
topRight: Radius.circular(16.0),
|
topRight: Radius.circular(16),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
child: Container(
|
child: Container(
|
||||||
width: double.infinity,
|
width: double.infinity,
|
||||||
child: Center(
|
child: Center(
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.all(8.0),
|
padding: const EdgeInsets.all(8),
|
||||||
child: Container(
|
child: Container(
|
||||||
width: 40.0,
|
width: 40,
|
||||||
height: 4.0,
|
height: 4,
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color:
|
color:
|
||||||
StreamChatTheme.of(context).colorTheme.whiteSmoke,
|
StreamChatTheme.of(context).colorTheme.whiteSmoke,
|
||||||
borderRadius: BorderRadius.circular(4.0),
|
borderRadius: BorderRadius.circular(4),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -1080,7 +1067,7 @@ class MessageInputState extends State<MessageInput> {
|
|||||||
child: Container(
|
child: Container(
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: StreamChatTheme.of(context).colorTheme.white,
|
color: StreamChatTheme.of(context).colorTheme.white,
|
||||||
borderRadius: BorderRadius.circular(8.0),
|
borderRadius: BorderRadius.circular(8),
|
||||||
),
|
),
|
||||||
child: _PickerWidget(
|
child: _PickerWidget(
|
||||||
filePickerIndex: _filePickerIndex,
|
filePickerIndex: _filePickerIndex,
|
||||||
@@ -1159,7 +1146,7 @@ class MessageInputState extends State<MessageInput> {
|
|||||||
return CircleAvatar(
|
return CircleAvatar(
|
||||||
radius: 12,
|
radius: 12,
|
||||||
child: StreamSvgIcon.giphyIcon(
|
child: StreamSvgIcon.giphyIcon(
|
||||||
size: 24.0,
|
size: 24,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
case 'ban':
|
case 'ban':
|
||||||
@@ -1167,7 +1154,7 @@ class MessageInputState extends State<MessageInput> {
|
|||||||
backgroundColor: StreamChatTheme.of(context).colorTheme.accentBlue,
|
backgroundColor: StreamChatTheme.of(context).colorTheme.accentBlue,
|
||||||
radius: 12,
|
radius: 12,
|
||||||
child: StreamSvgIcon.iconUserDelete(
|
child: StreamSvgIcon.iconUserDelete(
|
||||||
size: 16.0,
|
size: 16,
|
||||||
color: Colors.white,
|
color: Colors.white,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
@@ -1176,7 +1163,7 @@ class MessageInputState extends State<MessageInput> {
|
|||||||
backgroundColor: StreamChatTheme.of(context).colorTheme.accentBlue,
|
backgroundColor: StreamChatTheme.of(context).colorTheme.accentBlue,
|
||||||
radius: 12,
|
radius: 12,
|
||||||
child: StreamSvgIcon.flag(
|
child: StreamSvgIcon.flag(
|
||||||
size: 14.0,
|
size: 14,
|
||||||
color: Colors.white,
|
color: Colors.white,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
@@ -1186,7 +1173,7 @@ class MessageInputState extends State<MessageInput> {
|
|||||||
radius: 12,
|
radius: 12,
|
||||||
child: ClipOval(
|
child: ClipOval(
|
||||||
child: StreamSvgIcon.imgur(
|
child: StreamSvgIcon.imgur(
|
||||||
size: 24.0,
|
size: 24,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
@@ -1195,7 +1182,7 @@ class MessageInputState extends State<MessageInput> {
|
|||||||
backgroundColor: StreamChatTheme.of(context).colorTheme.accentBlue,
|
backgroundColor: StreamChatTheme.of(context).colorTheme.accentBlue,
|
||||||
radius: 12,
|
radius: 12,
|
||||||
child: StreamSvgIcon.mute(
|
child: StreamSvgIcon.mute(
|
||||||
size: 16.0,
|
size: 16,
|
||||||
color: Colors.white,
|
color: Colors.white,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
@@ -1204,7 +1191,7 @@ class MessageInputState extends State<MessageInput> {
|
|||||||
backgroundColor: StreamChatTheme.of(context).colorTheme.accentBlue,
|
backgroundColor: StreamChatTheme.of(context).colorTheme.accentBlue,
|
||||||
radius: 12,
|
radius: 12,
|
||||||
child: StreamSvgIcon.userAdd(
|
child: StreamSvgIcon.userAdd(
|
||||||
size: 16.0,
|
size: 16,
|
||||||
color: Colors.white,
|
color: Colors.white,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
@@ -1213,7 +1200,7 @@ class MessageInputState extends State<MessageInput> {
|
|||||||
backgroundColor: StreamChatTheme.of(context).colorTheme.accentBlue,
|
backgroundColor: StreamChatTheme.of(context).colorTheme.accentBlue,
|
||||||
radius: 12,
|
radius: 12,
|
||||||
child: StreamSvgIcon.volumeUp(
|
child: StreamSvgIcon.volumeUp(
|
||||||
size: 16.0,
|
size: 16,
|
||||||
color: Colors.white,
|
color: Colors.white,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
@@ -1222,7 +1209,7 @@ class MessageInputState extends State<MessageInput> {
|
|||||||
backgroundColor: StreamChatTheme.of(context).colorTheme.accentBlue,
|
backgroundColor: StreamChatTheme.of(context).colorTheme.accentBlue,
|
||||||
radius: 12,
|
radius: 12,
|
||||||
child: StreamSvgIcon.lightning(
|
child: StreamSvgIcon.lightning(
|
||||||
size: 16.0,
|
size: 16,
|
||||||
color: Colors.white,
|
color: Colors.white,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
@@ -1263,18 +1250,18 @@ class MessageInputState extends State<MessageInput> {
|
|||||||
left: 0,
|
left: 0,
|
||||||
right: 0,
|
right: 0,
|
||||||
child: TweenAnimationBuilder<double>(
|
child: TweenAnimationBuilder<double>(
|
||||||
tween: Tween(begin: 0.0, end: 1.0),
|
tween: Tween(begin: 0, end: 1),
|
||||||
duration: Duration(milliseconds: 300),
|
duration: Duration(milliseconds: 300),
|
||||||
curve: Curves.easeInOutExpo,
|
curve: Curves.easeInOutExpo,
|
||||||
builder: (context, val, wid) {
|
builder: (context, val, wid) {
|
||||||
return Transform.scale(
|
return Transform.scale(
|
||||||
scale: val,
|
scale: val,
|
||||||
child: Card(
|
child: Card(
|
||||||
margin: EdgeInsets.all(8.0),
|
margin: EdgeInsets.all(8),
|
||||||
elevation: 2.0,
|
elevation: 2,
|
||||||
color: StreamChatTheme.of(context).colorTheme.white,
|
color: StreamChatTheme.of(context).colorTheme.white,
|
||||||
shape: RoundedRectangleBorder(
|
shape: RoundedRectangleBorder(
|
||||||
borderRadius: BorderRadius.circular(8.0),
|
borderRadius: BorderRadius.circular(8),
|
||||||
),
|
),
|
||||||
clipBehavior: Clip.antiAlias,
|
clipBehavior: Clip.antiAlias,
|
||||||
child: Container(
|
child: Container(
|
||||||
@@ -1291,7 +1278,7 @@ class MessageInputState extends State<MessageInput> {
|
|||||||
shrinkWrap: true,
|
shrinkWrap: true,
|
||||||
children: [
|
children: [
|
||||||
SizedBox(
|
SizedBox(
|
||||||
height: 8.0,
|
height: 8,
|
||||||
),
|
),
|
||||||
...snapshot.data!
|
...snapshot.data!
|
||||||
.where((it) => it.user != null)
|
.where((it) => it.user != null)
|
||||||
@@ -1333,7 +1320,7 @@ class MessageInputState extends State<MessageInput> {
|
|||||||
},
|
},
|
||||||
).toList(),
|
).toList(),
|
||||||
SizedBox(
|
SizedBox(
|
||||||
height: 8.0,
|
height: 8,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
@@ -1361,7 +1348,7 @@ class MessageInputState extends State<MessageInput> {
|
|||||||
|
|
||||||
final emojis = _emojiNames
|
final emojis = _emojiNames
|
||||||
.where((e) => e.contains(query))
|
.where((e) => e.contains(query))
|
||||||
.map((e) => Emoji.byName(e))
|
.map(Emoji.byName)
|
||||||
.where((e) => e != null);
|
.where((e) => e != null);
|
||||||
|
|
||||||
if (emojis.isEmpty) {
|
if (emojis.isEmpty) {
|
||||||
@@ -1377,11 +1364,11 @@ class MessageInputState extends State<MessageInput> {
|
|||||||
left: 0,
|
left: 0,
|
||||||
right: 0,
|
right: 0,
|
||||||
child: Card(
|
child: Card(
|
||||||
margin: EdgeInsets.all(8.0),
|
margin: EdgeInsets.all(8),
|
||||||
elevation: 2.0,
|
elevation: 2,
|
||||||
color: StreamChatTheme.of(context).colorTheme.white,
|
color: StreamChatTheme.of(context).colorTheme.white,
|
||||||
shape: RoundedRectangleBorder(
|
shape: RoundedRectangleBorder(
|
||||||
borderRadius: BorderRadius.circular(8.0),
|
borderRadius: BorderRadius.circular(8),
|
||||||
),
|
),
|
||||||
clipBehavior: Clip.antiAlias,
|
clipBehavior: Clip.antiAlias,
|
||||||
child: Container(
|
child: Container(
|
||||||
@@ -1390,7 +1377,7 @@ class MessageInputState extends State<MessageInput> {
|
|||||||
boxShadow: [
|
boxShadow: [
|
||||||
BoxShadow(
|
BoxShadow(
|
||||||
spreadRadius: -8,
|
spreadRadius: -8,
|
||||||
blurRadius: 5.0,
|
blurRadius: 5,
|
||||||
offset: Offset(0, -4),
|
offset: Offset(0, -4),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@@ -1403,12 +1390,11 @@ class MessageInputState extends State<MessageInput> {
|
|||||||
itemBuilder: (context, i) {
|
itemBuilder: (context, i) {
|
||||||
if (i == 0) {
|
if (i == 0) {
|
||||||
return Padding(
|
return Padding(
|
||||||
padding: const EdgeInsets.only(left: 8.0, top: 8.0),
|
padding: const EdgeInsets.only(left: 8, top: 8),
|
||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
Padding(
|
Padding(
|
||||||
padding:
|
padding: const EdgeInsets.symmetric(horizontal: 8),
|
||||||
const EdgeInsets.symmetric(horizontal: 8.0),
|
|
||||||
child: StreamSvgIcon.smile(
|
child: StreamSvgIcon.smile(
|
||||||
color: StreamChatTheme.of(context)
|
color: StreamChatTheme.of(context)
|
||||||
.colorTheme
|
.colorTheme
|
||||||
@@ -1516,7 +1502,7 @@ class MessageInputState extends State<MessageInput> {
|
|||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.fromLTRB(8, 8, 8, 0),
|
padding: const EdgeInsets.fromLTRB(8, 8, 8, 0),
|
||||||
child: LimitedBox(
|
child: LimitedBox(
|
||||||
maxHeight: 136.0,
|
maxHeight: 136,
|
||||||
child: ListView(
|
child: ListView(
|
||||||
reverse: true,
|
reverse: true,
|
||||||
shrinkWrap: true,
|
shrinkWrap: true,
|
||||||
@@ -1524,16 +1510,15 @@ class MessageInputState extends State<MessageInput> {
|
|||||||
.map<Widget>(
|
.map<Widget>(
|
||||||
(e) => ClipRRect(
|
(e) => ClipRRect(
|
||||||
borderRadius: BorderRadius.circular(10),
|
borderRadius: BorderRadius.circular(10),
|
||||||
clipBehavior: Clip.antiAlias,
|
|
||||||
child: FileAttachment(
|
child: FileAttachment(
|
||||||
message: Message(), // dummy message
|
message: Message(), // dummy message
|
||||||
attachment: e,
|
attachment: e,
|
||||||
size: Size(
|
size: Size(
|
||||||
MediaQuery.of(context).size.width * 0.65,
|
MediaQuery.of(context).size.width * 0.65,
|
||||||
56.0,
|
56,
|
||||||
),
|
),
|
||||||
trailing: Padding(
|
trailing: Padding(
|
||||||
padding: const EdgeInsets.all(8.0),
|
padding: const EdgeInsets.all(8),
|
||||||
child: _buildRemoveButton(e),
|
child: _buildRemoveButton(e),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -1547,18 +1532,17 @@ class MessageInputState extends State<MessageInput> {
|
|||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.fromLTRB(8, 8, 8, 0),
|
padding: const EdgeInsets.fromLTRB(8, 8, 8, 0),
|
||||||
child: LimitedBox(
|
child: LimitedBox(
|
||||||
maxHeight: 104.0,
|
maxHeight: 104,
|
||||||
child: ListView(
|
child: ListView(
|
||||||
scrollDirection: Axis.horizontal,
|
scrollDirection: Axis.horizontal,
|
||||||
children: remainingAttachments
|
children: remainingAttachments
|
||||||
.map<Widget>(
|
.map<Widget>(
|
||||||
(attachment) => ClipRRect(
|
(attachment) => ClipRRect(
|
||||||
borderRadius: BorderRadius.circular(10),
|
borderRadius: BorderRadius.circular(10),
|
||||||
clipBehavior: Clip.antiAlias,
|
|
||||||
child: Stack(
|
child: Stack(
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
AspectRatio(
|
AspectRatio(
|
||||||
aspectRatio: 1.0,
|
aspectRatio: 1,
|
||||||
child: Container(
|
child: Container(
|
||||||
height: 104,
|
height: 104,
|
||||||
width: 104,
|
width: 104,
|
||||||
@@ -1593,7 +1577,6 @@ class MessageInputState extends State<MessageInput> {
|
|||||||
elevation: 0,
|
elevation: 0,
|
||||||
highlightElevation: 0,
|
highlightElevation: 0,
|
||||||
focusElevation: 0,
|
focusElevation: 0,
|
||||||
disabledElevation: 0,
|
|
||||||
hoverElevation: 0,
|
hoverElevation: 0,
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
setState(() => _attachments.remove(attachment.id));
|
setState(() => _attachments.remove(attachment.id));
|
||||||
@@ -1803,7 +1786,7 @@ class MessageInputState extends State<MessageInput> {
|
|||||||
leading: Icon(Icons.image),
|
leading: Icon(Icons.image),
|
||||||
title: Text('Upload a photo'),
|
title: Text('Upload a photo'),
|
||||||
onTap: () {
|
onTap: () {
|
||||||
pickFile(DefaultAttachmentTypes.image, false);
|
pickFile(DefaultAttachmentTypes.image);
|
||||||
Navigator.pop(context);
|
Navigator.pop(context);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
@@ -1811,7 +1794,7 @@ class MessageInputState extends State<MessageInput> {
|
|||||||
leading: Icon(Icons.video_library),
|
leading: Icon(Icons.video_library),
|
||||||
title: Text('Upload a video'),
|
title: Text('Upload a video'),
|
||||||
onTap: () {
|
onTap: () {
|
||||||
pickFile(DefaultAttachmentTypes.video, false);
|
pickFile(DefaultAttachmentTypes.video);
|
||||||
Navigator.pop(context);
|
Navigator.pop(context);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
@@ -1837,7 +1820,7 @@ class MessageInputState extends State<MessageInput> {
|
|||||||
leading: Icon(Icons.insert_drive_file),
|
leading: Icon(Icons.insert_drive_file),
|
||||||
title: Text('Upload a file'),
|
title: Text('Upload a file'),
|
||||||
onTap: () {
|
onTap: () {
|
||||||
pickFile(DefaultAttachmentTypes.file, false);
|
pickFile(DefaultAttachmentTypes.file);
|
||||||
Navigator.pop(context);
|
Navigator.pop(context);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
@@ -1967,7 +1950,7 @@ class MessageInputState extends State<MessageInput> {
|
|||||||
|
|
||||||
Widget _buildIdleSendButton(BuildContext context) {
|
Widget _buildIdleSendButton(BuildContext context) {
|
||||||
return Padding(
|
return Padding(
|
||||||
padding: const EdgeInsets.all(8.0),
|
padding: const EdgeInsets.all(8),
|
||||||
child: StreamSvgIcon(
|
child: StreamSvgIcon(
|
||||||
assetName: _getIdleSendIcon(),
|
assetName: _getIdleSendIcon(),
|
||||||
color:
|
color:
|
||||||
@@ -1978,7 +1961,7 @@ class MessageInputState extends State<MessageInput> {
|
|||||||
|
|
||||||
Widget _buildSendButton(BuildContext context) {
|
Widget _buildSendButton(BuildContext context) {
|
||||||
return Padding(
|
return Padding(
|
||||||
padding: const EdgeInsets.all(8.0),
|
padding: const EdgeInsets.all(8),
|
||||||
child: IconButton(
|
child: IconButton(
|
||||||
onPressed: sendMessage,
|
onPressed: sendMessage,
|
||||||
padding: const EdgeInsets.all(0),
|
padding: const EdgeInsets.all(0),
|
||||||
@@ -2112,44 +2095,44 @@ class MessageInputState extends State<MessageInput> {
|
|||||||
context: context,
|
context: context,
|
||||||
shape: RoundedRectangleBorder(
|
shape: RoundedRectangleBorder(
|
||||||
borderRadius: BorderRadius.only(
|
borderRadius: BorderRadius.only(
|
||||||
topLeft: Radius.circular(16.0),
|
topLeft: Radius.circular(16),
|
||||||
topRight: Radius.circular(16.0),
|
topRight: Radius.circular(16),
|
||||||
)),
|
)),
|
||||||
builder: (context) {
|
builder: (context) {
|
||||||
return Column(
|
return Column(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: [
|
children: [
|
||||||
SizedBox(
|
SizedBox(
|
||||||
height: 26.0,
|
height: 26,
|
||||||
),
|
),
|
||||||
StreamSvgIcon.error(
|
StreamSvgIcon.error(
|
||||||
color: StreamChatTheme.of(context).colorTheme.accentRed,
|
color: StreamChatTheme.of(context).colorTheme.accentRed,
|
||||||
size: 24.0,
|
size: 24,
|
||||||
),
|
),
|
||||||
SizedBox(
|
SizedBox(
|
||||||
height: 26.0,
|
height: 26,
|
||||||
),
|
),
|
||||||
Text(
|
Text(
|
||||||
'Something went wrong',
|
'Something went wrong',
|
||||||
style: StreamChatTheme.of(context).textTheme.headlineBold,
|
style: StreamChatTheme.of(context).textTheme.headlineBold,
|
||||||
),
|
),
|
||||||
SizedBox(
|
SizedBox(
|
||||||
height: 7.0,
|
height: 7,
|
||||||
),
|
),
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 16.0),
|
padding: const EdgeInsets.symmetric(horizontal: 16),
|
||||||
child: Text(
|
child: Text(
|
||||||
description,
|
description,
|
||||||
textAlign: TextAlign.center,
|
textAlign: TextAlign.center,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
SizedBox(
|
SizedBox(
|
||||||
height: 36.0,
|
height: 36,
|
||||||
),
|
),
|
||||||
Container(
|
Container(
|
||||||
color:
|
color:
|
||||||
StreamChatTheme.of(context).colorTheme.black.withOpacity(.08),
|
StreamChatTheme.of(context).colorTheme.black.withOpacity(.08),
|
||||||
height: 1.0,
|
height: 1,
|
||||||
),
|
),
|
||||||
Row(
|
Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
@@ -2345,7 +2328,7 @@ class __PickerWidgetState extends State<_PickerWidget> {
|
|||||||
color: StreamChatTheme.of(context).colorTheme.grey),
|
color: StreamChatTheme.of(context).colorTheme.grey),
|
||||||
textAlign: TextAlign.center,
|
textAlign: TextAlign.center,
|
||||||
),
|
),
|
||||||
SizedBox(height: 6.0),
|
SizedBox(height: 6),
|
||||||
Center(
|
Center(
|
||||||
child: Text(
|
child: Text(
|
||||||
'Allow access to your gallery',
|
'Allow access to your gallery',
|
||||||
|
|||||||
@@ -111,7 +111,7 @@ class MessageDetails {
|
|||||||
/// Modify it to change the widget appearance.
|
/// Modify it to change the widget appearance.
|
||||||
class MessageListView extends StatefulWidget {
|
class MessageListView extends StatefulWidget {
|
||||||
/// Instantiate a new MessageListView
|
/// Instantiate a new MessageListView
|
||||||
MessageListView({
|
const MessageListView({
|
||||||
Key? key,
|
Key? key,
|
||||||
this.showScrollToBottom = true,
|
this.showScrollToBottom = true,
|
||||||
this.messageBuilder,
|
this.messageBuilder,
|
||||||
@@ -418,7 +418,6 @@ class _MessageListViewState extends State<MessageListView> {
|
|||||||
child: ScrollablePositionedList.separated(
|
child: ScrollablePositionedList.separated(
|
||||||
key: ValueKey(initialIndex! + initialAlignment!),
|
key: ValueKey(initialIndex! + initialAlignment!),
|
||||||
itemPositionsListener: _itemPositionListener,
|
itemPositionsListener: _itemPositionListener,
|
||||||
addAutomaticKeepAlives: true,
|
|
||||||
initialScrollIndex: initialIndex ?? 0,
|
initialScrollIndex: initialIndex ?? 0,
|
||||||
initialAlignment: initialAlignment ?? 0,
|
initialAlignment: initialAlignment ?? 0,
|
||||||
physics: widget.scrollPhysics,
|
physics: widget.scrollPhysics,
|
||||||
@@ -437,7 +436,7 @@ class _MessageListViewState extends State<MessageListView> {
|
|||||||
StreamChatTheme.of(context).colorTheme.bgGradient,
|
StreamChatTheme.of(context).colorTheme.bgGradient,
|
||||||
),
|
),
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.all(8.0),
|
padding: const EdgeInsets.all(8),
|
||||||
child: Text(
|
child: Text(
|
||||||
'$replyCount ${replyCount == 1 ? 'Reply' : 'Replies'}',
|
'$replyCount ${replyCount == 1 ? 'Reply' : 'Replies'}',
|
||||||
textAlign: TextAlign.center,
|
textAlign: TextAlign.center,
|
||||||
@@ -464,7 +463,7 @@ class _MessageListViewState extends State<MessageListView> {
|
|||||||
dateTime: nextMessage.createdAt.toLocal(),
|
dateTime: nextMessage.createdAt.toLocal(),
|
||||||
);
|
);
|
||||||
return Padding(
|
return Padding(
|
||||||
padding: const EdgeInsets.symmetric(vertical: 12.0),
|
padding: const EdgeInsets.symmetric(vertical: 12),
|
||||||
child: divider,
|
child: divider,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -554,7 +553,7 @@ class _MessageListViewState extends State<MessageListView> {
|
|||||||
),
|
),
|
||||||
if (widget.showScrollToBottom) _buildScrollToBottom(),
|
if (widget.showScrollToBottom) _buildScrollToBottom(),
|
||||||
Positioned(
|
Positioned(
|
||||||
top: 20.0,
|
top: 20,
|
||||||
child: ValueListenableBuilder<Iterable<ItemPosition>>(
|
child: ValueListenableBuilder<Iterable<ItemPosition>>(
|
||||||
valueListenable: _itemPositionListener.itemPositions,
|
valueListenable: _itemPositionListener.itemPositions,
|
||||||
builder: (context, values, _) {
|
builder: (context, values, _) {
|
||||||
@@ -660,7 +659,7 @@ class _MessageListViewState extends State<MessageListView> {
|
|||||||
top: -10,
|
top: -10,
|
||||||
child: CircleAvatar(
|
child: CircleAvatar(
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.all(3.0),
|
padding: const EdgeInsets.all(3),
|
||||||
child: Text(
|
child: Text(
|
||||||
'$unreadCount',
|
'$unreadCount',
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
@@ -712,7 +711,7 @@ class _MessageListViewState extends State<MessageListView> {
|
|||||||
}
|
}
|
||||||
return Center(
|
return Center(
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.all(8.0),
|
padding: const EdgeInsets.all(8),
|
||||||
child: const CircularProgressIndicator(),
|
child: const CircularProgressIndicator(),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
@@ -799,8 +798,6 @@ class _MessageListViewState extends State<MessageListView> {
|
|||||||
final isOnlyEmoji = message.text!.isOnlyEmoji;
|
final isOnlyEmoji = message.text!.isOnlyEmoji;
|
||||||
|
|
||||||
return MessageWidget(
|
return MessageWidget(
|
||||||
showThreadReplyIndicator: false,
|
|
||||||
showInChannelIndicator: false,
|
|
||||||
showReplyMessage: false,
|
showReplyMessage: false,
|
||||||
showResendMessage: false,
|
showResendMessage: false,
|
||||||
showThreadReplyMessage: false,
|
showThreadReplyMessage: false,
|
||||||
@@ -810,7 +807,7 @@ class _MessageListViewState extends State<MessageListView> {
|
|||||||
message: message,
|
message: message,
|
||||||
reverse: isMyMessage,
|
reverse: isMyMessage,
|
||||||
showUsername: !isMyMessage,
|
showUsername: !isMyMessage,
|
||||||
padding: const EdgeInsets.all(8.0),
|
padding: const EdgeInsets.all(8),
|
||||||
showSendingIndicator: false,
|
showSendingIndicator: false,
|
||||||
onThreadTap: _onThreadTap as void Function(Message)?,
|
onThreadTap: _onThreadTap as void Function(Message)?,
|
||||||
borderRadiusGeometry: BorderRadius.only(
|
borderRadiusGeometry: BorderRadius.only(
|
||||||
@@ -820,7 +817,7 @@ class _MessageListViewState extends State<MessageListView> {
|
|||||||
bottomRight: Radius.circular(16),
|
bottomRight: Radius.circular(16),
|
||||||
),
|
),
|
||||||
textPadding: EdgeInsets.symmetric(
|
textPadding: EdgeInsets.symmetric(
|
||||||
vertical: 8.0,
|
vertical: 8,
|
||||||
horizontal: isOnlyEmoji ? 0 : 16.0,
|
horizontal: isOnlyEmoji ? 0 : 16.0,
|
||||||
),
|
),
|
||||||
borderSide: isMyMessage || isOnlyEmoji ? BorderSide.none : null,
|
borderSide: isMyMessage || isOnlyEmoji ? BorderSide.none : null,
|
||||||
@@ -940,7 +937,7 @@ class _MessageListViewState extends State<MessageListView> {
|
|||||||
message: message,
|
message: message,
|
||||||
reverse: isMyMessage,
|
reverse: isMyMessage,
|
||||||
showReactions: !message.isDeleted,
|
showReactions: !message.isDeleted,
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 8.0),
|
padding: const EdgeInsets.symmetric(horizontal: 8),
|
||||||
showInChannelIndicator: showInChannelIndicator,
|
showInChannelIndicator: showInChannelIndicator,
|
||||||
showThreadReplyIndicator: showThreadReplyIndicator,
|
showThreadReplyIndicator: showThreadReplyIndicator,
|
||||||
showUsername: showUsername,
|
showUsername: showUsername,
|
||||||
@@ -997,7 +994,7 @@ class _MessageListViewState extends State<MessageListView> {
|
|||||||
bottomRight: Radius.circular(16),
|
bottomRight: Radius.circular(16),
|
||||||
),
|
),
|
||||||
textPadding: EdgeInsets.symmetric(
|
textPadding: EdgeInsets.symmetric(
|
||||||
vertical: 8.0,
|
vertical: 8,
|
||||||
horizontal: isOnlyEmoji ? 0 : 16.0,
|
horizontal: isOnlyEmoji ? 0 : 16.0,
|
||||||
),
|
),
|
||||||
messageTheme: isMyMessage
|
messageTheme: isMyMessage
|
||||||
@@ -1069,7 +1066,7 @@ class _MessageListViewState extends State<MessageListView> {
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.only(top: 4.0),
|
padding: const EdgeInsets.only(top: 4),
|
||||||
child: child,
|
child: child,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ class MessageReactionsModal extends StatelessWidget {
|
|||||||
: (roughSentenceSize == 0 ? 1 : (roughSentenceSize / roughMaxSize));
|
: (roughSentenceSize == 0 ? 1 : (roughSentenceSize / roughMaxSize));
|
||||||
|
|
||||||
return TweenAnimationBuilder<double>(
|
return TweenAnimationBuilder<double>(
|
||||||
tween: Tween(begin: 0.0, end: 1.0),
|
tween: Tween(begin: 0, end: 1),
|
||||||
duration: Duration(milliseconds: 300),
|
duration: Duration(milliseconds: 300),
|
||||||
curve: Curves.easeInOutBack,
|
curve: Curves.easeInOutBack,
|
||||||
builder: (context, val, snapshot) {
|
builder: (context, val, snapshot) {
|
||||||
@@ -86,7 +86,7 @@ class MessageReactionsModal extends StatelessWidget {
|
|||||||
child: Center(
|
child: Center(
|
||||||
child: SingleChildScrollView(
|
child: SingleChildScrollView(
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.all(8.0),
|
padding: const EdgeInsets.all(8),
|
||||||
child: Column(
|
child: Column(
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||||
@@ -102,7 +102,7 @@ class MessageReactionsModal extends StatelessWidget {
|
|||||||
: (divFactor > 1.0
|
: (divFactor > 1.0
|
||||||
? 0.0
|
? 0.0
|
||||||
: -(1.0 - divFactor)),
|
: -(1.0 - divFactor)),
|
||||||
0.0),
|
0),
|
||||||
child: ReactionPicker(
|
child: ReactionPicker(
|
||||||
message: message,
|
message: message,
|
||||||
),
|
),
|
||||||
@@ -121,7 +121,6 @@ class MessageReactionsModal extends StatelessWidget {
|
|||||||
showReactions: false,
|
showReactions: false,
|
||||||
showUsername: false,
|
showUsername: false,
|
||||||
showUserAvatar: showUserAvatar,
|
showUserAvatar: showUserAvatar,
|
||||||
showThreadReplyIndicator: false,
|
|
||||||
showTimestamp: false,
|
showTimestamp: false,
|
||||||
translateUserAvatar: false,
|
translateUserAvatar: false,
|
||||||
showSendingIndicator: false,
|
showSendingIndicator: false,
|
||||||
@@ -133,9 +132,8 @@ class MessageReactionsModal extends StatelessWidget {
|
|||||||
attachmentPadding: EdgeInsets.all(
|
attachmentPadding: EdgeInsets.all(
|
||||||
hasFileAttachment ? 4 : 2,
|
hasFileAttachment ? 4 : 2,
|
||||||
),
|
),
|
||||||
showInChannelIndicator: false,
|
|
||||||
textPadding: EdgeInsets.symmetric(
|
textPadding: EdgeInsets.symmetric(
|
||||||
vertical: 8.0,
|
vertical: 8,
|
||||||
horizontal:
|
horizontal:
|
||||||
message.text!.isOnlyEmoji ? 0 : 16.0,
|
message.text!.isOnlyEmoji ? 0 : 16.0,
|
||||||
),
|
),
|
||||||
@@ -184,7 +182,6 @@ class MessageReactionsModal extends StatelessWidget {
|
|||||||
child: Wrap(
|
child: Wrap(
|
||||||
spacing: 16,
|
spacing: 16,
|
||||||
runSpacing: 16,
|
runSpacing: 16,
|
||||||
alignment: WrapAlignment.start,
|
|
||||||
children: message.latestReactions!
|
children: message.latestReactions!
|
||||||
.map((e) => _buildReaction(
|
.map((e) => _buildReaction(
|
||||||
e,
|
e,
|
||||||
@@ -214,8 +211,6 @@ class MessageReactionsModal extends StatelessWidget {
|
|||||||
)),
|
)),
|
||||||
child: Column(
|
child: Column(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
mainAxisAlignment: MainAxisAlignment.start,
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
|
||||||
children: [
|
children: [
|
||||||
Stack(
|
Stack(
|
||||||
clipBehavior: Clip.none,
|
clipBehavior: Clip.none,
|
||||||
|
|||||||
@@ -147,8 +147,8 @@ class MessageSearchItem extends StatelessWidget {
|
|||||||
List<Attachment> attachments,
|
List<Attachment> attachments,
|
||||||
TextStyle? normalTextStyle,
|
TextStyle? normalTextStyle,
|
||||||
TextStyle? mentionsTextStyle) {
|
TextStyle? mentionsTextStyle) {
|
||||||
var textList = text.split(' ');
|
final textList = text.split(' ');
|
||||||
var resList = <TextSpan>[];
|
final resList = <TextSpan>[];
|
||||||
for (var e in textList) {
|
for (var e in textList) {
|
||||||
if (mentions.isNotEmpty &&
|
if (mentions.isNotEmpty &&
|
||||||
mentions.any((element) => '@${element.name}' == e)) {
|
mentions.any((element) => '@${element.name}' == e)) {
|
||||||
@@ -166,7 +166,7 @@ class MessageSearchItem extends StatelessWidget {
|
|||||||
));
|
));
|
||||||
} else {
|
} else {
|
||||||
resList.add(TextSpan(
|
resList.add(TextSpan(
|
||||||
text: e == textList.last ? '$e' : '$e ',
|
text: e == textList.last ? e : '$e ',
|
||||||
style: normalTextStyle,
|
style: normalTextStyle,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -189,10 +189,7 @@ class _MessageSearchListViewState extends State<MessageSearchListView> {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
childBuilder: widget.childBuilder ??
|
childBuilder: widget.childBuilder ?? _buildListView,
|
||||||
(list) {
|
|
||||||
return _buildListView(list);
|
|
||||||
},
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -228,7 +225,7 @@ class _MessageSearchListViewState extends State<MessageSearchListView> {
|
|||||||
.accentRed
|
.accentRed
|
||||||
.withOpacity(.2),
|
.withOpacity(.2),
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.symmetric(vertical: 16.0),
|
padding: const EdgeInsets.symmetric(vertical: 16),
|
||||||
child: Center(
|
child: Center(
|
||||||
child: Text('Error loading messages'),
|
child: Text('Error loading messages'),
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -201,8 +201,8 @@ class MessageWidget extends StatefulWidget {
|
|||||||
this.readList,
|
this.readList,
|
||||||
this.padding,
|
this.padding,
|
||||||
this.textPadding = const EdgeInsets.symmetric(
|
this.textPadding = const EdgeInsets.symmetric(
|
||||||
horizontal: 16.0,
|
horizontal: 16,
|
||||||
vertical: 8.0,
|
vertical: 8,
|
||||||
),
|
),
|
||||||
this.attachmentPadding = EdgeInsets.zero,
|
this.attachmentPadding = EdgeInsets.zero,
|
||||||
this.allRead = false,
|
this.allRead = false,
|
||||||
@@ -211,8 +211,7 @@ class MessageWidget extends StatefulWidget {
|
|||||||
this.onAttachmentTap,
|
this.onAttachmentTap,
|
||||||
}) : attachmentBuilders = {
|
}) : attachmentBuilders = {
|
||||||
'image': (context, message, attachments) {
|
'image': (context, message, attachments) {
|
||||||
var border = RoundedRectangleBorder(
|
final border = RoundedRectangleBorder(
|
||||||
side: BorderSide.none,
|
|
||||||
borderRadius: attachmentBorderRadiusGeometry ?? BorderRadius.zero,
|
borderRadius: attachmentBorderRadiusGeometry ?? BorderRadius.zero,
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -267,8 +266,7 @@ class MessageWidget extends StatefulWidget {
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
'video': (context, message, attachments) {
|
'video': (context, message, attachments) {
|
||||||
var border = RoundedRectangleBorder(
|
final border = RoundedRectangleBorder(
|
||||||
side: BorderSide.none,
|
|
||||||
borderRadius: attachmentBorderRadiusGeometry ?? BorderRadius.zero,
|
borderRadius: attachmentBorderRadiusGeometry ?? BorderRadius.zero,
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -302,7 +300,6 @@ class MessageWidget extends StatefulWidget {
|
|||||||
},
|
},
|
||||||
'giphy': (context, message, attachments) {
|
'giphy': (context, message, attachments) {
|
||||||
final border = RoundedRectangleBorder(
|
final border = RoundedRectangleBorder(
|
||||||
side: BorderSide.none,
|
|
||||||
borderRadius: attachmentBorderRadiusGeometry ?? BorderRadius.zero,
|
borderRadius: attachmentBorderRadiusGeometry ?? BorderRadius.zero,
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -329,7 +326,7 @@ class MessageWidget extends StatefulWidget {
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
'file': (context, message, attachments) {
|
'file': (context, message, attachments) {
|
||||||
var border = RoundedRectangleBorder(
|
final border = RoundedRectangleBorder(
|
||||||
side: attachmentBorderSide ??
|
side: attachmentBorderSide ??
|
||||||
BorderSide(
|
BorderSide(
|
||||||
color: StreamChatTheme.of(context).colorTheme.greyWhisper,
|
color: StreamChatTheme.of(context).colorTheme.greyWhisper,
|
||||||
@@ -426,7 +423,7 @@ class _MessageWidgetState extends State<MessageWidget>
|
|||||||
super.build(context);
|
super.build(context);
|
||||||
final avatarWidth =
|
final avatarWidth =
|
||||||
widget.messageTheme.avatarTheme?.constraints.maxWidth ?? 40;
|
widget.messageTheme.avatarTheme?.constraints.maxWidth ?? 40;
|
||||||
var leftPadding =
|
final leftPadding =
|
||||||
widget.showUserAvatar != DisplayWidget.gone ? avatarWidth + 8.5 : 0.5;
|
widget.showUserAvatar != DisplayWidget.gone ? avatarWidth + 8.5 : 0.5;
|
||||||
|
|
||||||
return Material(
|
return Material(
|
||||||
@@ -460,7 +457,6 @@ class _MessageWidgetState extends State<MessageWidget>
|
|||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: [
|
children: [
|
||||||
Row(
|
Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.start,
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.end,
|
crossAxisAlignment: CrossAxisAlignment.end,
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
@@ -481,8 +477,8 @@ class _MessageWidgetState extends State<MessageWidget>
|
|||||||
BoxConstraints(maxWidth: 22 * 6.0),
|
BoxConstraints(maxWidth: 22 * 6.0),
|
||||||
child: _buildReactionIndicator(context),
|
child: _buildReactionIndicator(context),
|
||||||
),
|
),
|
||||||
portalAnchor: Alignment(-1.0, -1.0),
|
portalAnchor: Alignment(-1, -1),
|
||||||
childAnchor: Alignment(1, -1.0),
|
childAnchor: Alignment(1, -1),
|
||||||
child: Stack(
|
child: Stack(
|
||||||
clipBehavior: Clip.none,
|
clipBehavior: Clip.none,
|
||||||
children: [
|
children: [
|
||||||
@@ -526,7 +522,7 @@ class _MessageWidgetState extends State<MessageWidget>
|
|||||||
)
|
)
|
||||||
: Card(
|
: Card(
|
||||||
clipBehavior: Clip.antiAlias,
|
clipBehavior: Clip.antiAlias,
|
||||||
elevation: 0.0,
|
elevation: 0,
|
||||||
margin: EdgeInsets.symmetric(
|
margin: EdgeInsets.symmetric(
|
||||||
horizontal: (isFailedState
|
horizontal: (isFailedState
|
||||||
? 15.0
|
? 15.0
|
||||||
@@ -650,9 +646,9 @@ class _MessageWidgetState extends State<MessageWidget>
|
|||||||
children: [
|
children: [
|
||||||
StreamSvgIcon.eye(
|
StreamSvgIcon.eye(
|
||||||
color: StreamChatTheme.of(context).colorTheme.grey,
|
color: StreamChatTheme.of(context).colorTheme.grey,
|
||||||
size: 16.0,
|
size: 16,
|
||||||
),
|
),
|
||||||
SizedBox(width: 8.0),
|
SizedBox(width: 8),
|
||||||
Text(
|
Text(
|
||||||
'Only visible to you',
|
'Only visible to you',
|
||||||
style: StreamChatTheme.of(context)
|
style: StreamChatTheme.of(context)
|
||||||
@@ -665,7 +661,7 @@ class _MessageWidgetState extends State<MessageWidget>
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
var children = <Widget>[];
|
final children = <Widget>[];
|
||||||
|
|
||||||
final threadParticipants = widget.message.threadParticipants?.take(2);
|
final threadParticipants = widget.message.threadParticipants?.take(2);
|
||||||
final showThreadParticipants = threadParticipants?.isNotEmpty == true;
|
final showThreadParticipants = threadParticipants?.isNotEmpty == true;
|
||||||
@@ -757,18 +753,18 @@ class _MessageWidgetState extends State<MessageWidget>
|
|||||||
return mappedChild;
|
return mappedChild;
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
].insertBetween(const SizedBox(width: 8.0)),
|
].insertBetween(const SizedBox(width: 8)),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildUrlAttachment() {
|
Widget _buildUrlAttachment() {
|
||||||
var urlAttachment = widget.message.attachments
|
final urlAttachment = widget.message.attachments
|
||||||
.firstWhere((element) => element.ogScrapeUrl != null);
|
.firstWhere((element) => element.ogScrapeUrl != null);
|
||||||
|
|
||||||
var host = Uri.parse(urlAttachment.ogScrapeUrl!).host;
|
final host = Uri.parse(urlAttachment.ogScrapeUrl!).host;
|
||||||
var splitList = host.split('.');
|
final splitList = host.split('.');
|
||||||
var hostName = splitList.length == 3 ? splitList[1] : splitList[0];
|
final hostName = splitList.length == 3 ? splitList[1] : splitList[0];
|
||||||
var hostDisplayName = urlAttachment.authorName?.capitalize() ??
|
final hostDisplayName = urlAttachment.authorName?.capitalize() ??
|
||||||
getWebsiteName(hostName.toLowerCase()) ??
|
getWebsiteName(hostName.toLowerCase()) ??
|
||||||
hostName.capitalize();
|
hostName.capitalize();
|
||||||
|
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ class OptionListTile extends StatelessWidget {
|
|||||||
final Color? separatorColor;
|
final Color? separatorColor;
|
||||||
final TextStyle? titleTextStyle;
|
final TextStyle? titleTextStyle;
|
||||||
|
|
||||||
OptionListTile({
|
const OptionListTile({
|
||||||
this.title,
|
this.title,
|
||||||
this.leading,
|
this.leading,
|
||||||
this.trailing,
|
this.trailing,
|
||||||
@@ -29,12 +29,12 @@ class OptionListTile extends StatelessWidget {
|
|||||||
Container(
|
Container(
|
||||||
color: separatorColor ??
|
color: separatorColor ??
|
||||||
StreamChatTheme.of(context).colorTheme.greyGainsboro,
|
StreamChatTheme.of(context).colorTheme.greyGainsboro,
|
||||||
height: 1.0,
|
height: 1,
|
||||||
),
|
),
|
||||||
Material(
|
Material(
|
||||||
color: tileColor ?? StreamChatTheme.of(context).colorTheme.white,
|
color: tileColor ?? StreamChatTheme.of(context).colorTheme.white,
|
||||||
child: Container(
|
child: Container(
|
||||||
height: 63.0,
|
height: 63,
|
||||||
child: InkWell(
|
child: InkWell(
|
||||||
onTap: onTap,
|
onTap: onTap,
|
||||||
child: Row(
|
child: Row(
|
||||||
@@ -42,7 +42,7 @@ class OptionListTile extends StatelessWidget {
|
|||||||
if (leading != null) Center(child: leading),
|
if (leading != null) Center(child: leading),
|
||||||
if (leading == null)
|
if (leading == null)
|
||||||
SizedBox(
|
SizedBox(
|
||||||
width: 16.0,
|
width: 16,
|
||||||
),
|
),
|
||||||
Expanded(
|
Expanded(
|
||||||
flex: 4,
|
flex: 4,
|
||||||
@@ -62,7 +62,7 @@ class OptionListTile extends StatelessWidget {
|
|||||||
Expanded(
|
Expanded(
|
||||||
flex: 2,
|
flex: 2,
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.only(right: 16.0),
|
padding: const EdgeInsets.only(right: 16),
|
||||||
child: Align(
|
child: Align(
|
||||||
alignment: Alignment.centerRight,
|
alignment: Alignment.centerRight,
|
||||||
child: trailing ?? Container(),
|
child: trailing ?? Container(),
|
||||||
|
|||||||
@@ -87,7 +87,7 @@ class QuotedMessageWidget extends StatelessWidget {
|
|||||||
final GestureTapCallback? onTap;
|
final GestureTapCallback? onTap;
|
||||||
|
|
||||||
///
|
///
|
||||||
QuotedMessageWidget({
|
const QuotedMessageWidget({
|
||||||
Key? key,
|
Key? key,
|
||||||
required this.message,
|
required this.message,
|
||||||
required this.messageTheme,
|
required this.messageTheme,
|
||||||
@@ -237,7 +237,7 @@ class QuotedMessageWidget extends StatelessWidget {
|
|||||||
|
|
||||||
ShapeBorder _getDefaultShape(BuildContext context) {
|
ShapeBorder _getDefaultShape(BuildContext context) {
|
||||||
return RoundedRectangleBorder(
|
return RoundedRectangleBorder(
|
||||||
side: BorderSide(width: 0.0, color: Colors.transparent),
|
side: BorderSide(width: 0, color: Colors.transparent),
|
||||||
borderRadius: BorderRadius.circular(8),
|
borderRadius: BorderRadius.circular(8),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,7 +40,6 @@ class ReactionBubble extends StatelessWidget {
|
|||||||
alignment: Alignment.center,
|
alignment: Alignment.center,
|
||||||
child: Stack(
|
child: Stack(
|
||||||
alignment: Alignment.center,
|
alignment: Alignment.center,
|
||||||
fit: StackFit.loose,
|
|
||||||
children: [
|
children: [
|
||||||
Transform.translate(
|
Transform.translate(
|
||||||
offset: Offset(reverse ? offset : -offset, 0),
|
offset: Offset(reverse ? offset : -offset, 0),
|
||||||
@@ -115,7 +114,7 @@ class ReactionBubble extends StatelessWidget {
|
|||||||
|
|
||||||
return Padding(
|
return Padding(
|
||||||
padding: const EdgeInsets.symmetric(
|
padding: const EdgeInsets.symmetric(
|
||||||
horizontal: 4.0,
|
horizontal: 4,
|
||||||
),
|
),
|
||||||
child: reactionIcon != null
|
child: reactionIcon != null
|
||||||
? StreamSvgIcon(
|
? StreamSvgIcon(
|
||||||
@@ -239,9 +238,9 @@ class ReactionBubblePainter extends CustomPainter {
|
|||||||
..strokeWidth = 1
|
..strokeWidth = 1
|
||||||
..style = PaintingStyle.stroke;
|
..style = PaintingStyle.stroke;
|
||||||
|
|
||||||
final dy = -2.2;
|
const dy = -2.2;
|
||||||
final startAngle = 1.1;
|
const startAngle = 1.1;
|
||||||
final sweepAngle = 1.2;
|
const sweepAngle = 1.2;
|
||||||
final path = Path();
|
final path = Path();
|
||||||
path.addArc(
|
path.addArc(
|
||||||
Rect.fromCircle(
|
Rect.fromCircle(
|
||||||
@@ -259,9 +258,9 @@ class ReactionBubblePainter extends CustomPainter {
|
|||||||
..color = color
|
..color = color
|
||||||
..strokeWidth = 1;
|
..strokeWidth = 1;
|
||||||
|
|
||||||
final dy = -2.2;
|
const dy = -2.2;
|
||||||
final startAngle = 1;
|
const startAngle = 1;
|
||||||
final sweepAngle = 1.3;
|
const sweepAngle = 1.3;
|
||||||
final path = Path();
|
final path = Path();
|
||||||
path.addArc(
|
path.addArc(
|
||||||
Rect.fromCircle(
|
Rect.fromCircle(
|
||||||
@@ -280,9 +279,9 @@ class ReactionBubblePainter extends CustomPainter {
|
|||||||
..strokeWidth = 1
|
..strokeWidth = 1
|
||||||
..style = PaintingStyle.fill;
|
..style = PaintingStyle.fill;
|
||||||
|
|
||||||
final dy = -2.2;
|
const dy = -2.2;
|
||||||
final startAngle = 1.1;
|
const startAngle = 1.1;
|
||||||
final sweepAngle = 1.2;
|
const sweepAngle = 1.2;
|
||||||
final path = Path();
|
final path = Path();
|
||||||
path.addArc(
|
path.addArc(
|
||||||
Rect.fromCircle(
|
Rect.fromCircle(
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ class _ReactionPickerState extends State<ReactionPicker>
|
|||||||
}
|
}
|
||||||
|
|
||||||
return TweenAnimationBuilder<double>(
|
return TweenAnimationBuilder<double>(
|
||||||
tween: Tween(begin: 0.0, end: 1.0),
|
tween: Tween(begin: 0, end: 1),
|
||||||
curve: Curves.easeInOutBack,
|
curve: Curves.easeInOutBack,
|
||||||
duration: Duration(milliseconds: 500),
|
duration: Duration(milliseconds: 500),
|
||||||
builder: (context, val, wid) {
|
builder: (context, val, wid) {
|
||||||
@@ -61,8 +61,8 @@ class _ReactionPickerState extends State<ReactionPicker>
|
|||||||
clipBehavior: Clip.hardEdge,
|
clipBehavior: Clip.hardEdge,
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.symmetric(
|
padding: const EdgeInsets.symmetric(
|
||||||
horizontal: 16.0,
|
horizontal: 16,
|
||||||
vertical: 8.0,
|
vertical: 8,
|
||||||
),
|
),
|
||||||
child: Row(
|
child: Row(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
@@ -74,7 +74,7 @@ class _ReactionPickerState extends State<ReactionPicker>
|
|||||||
?.indexWhere((reaction) =>
|
?.indexWhere((reaction) =>
|
||||||
reaction.type == reactionIcon.type) ??
|
reaction.type == reactionIcon.type) ??
|
||||||
-1;
|
-1;
|
||||||
var index = reactionIcons.indexOf(reactionIcon);
|
final index = reactionIcons.indexOf(reactionIcon);
|
||||||
|
|
||||||
return ConstrainedBox(
|
return ConstrainedBox(
|
||||||
constraints: BoxConstraints.tightFor(
|
constraints: BoxConstraints.tightFor(
|
||||||
@@ -83,8 +83,6 @@ class _ReactionPickerState extends State<ReactionPicker>
|
|||||||
),
|
),
|
||||||
child: RawMaterialButton(
|
child: RawMaterialButton(
|
||||||
elevation: 0,
|
elevation: 0,
|
||||||
padding: const EdgeInsets.all(0),
|
|
||||||
clipBehavior: Clip.none,
|
|
||||||
shape: ContinuousRectangleBorder(
|
shape: ContinuousRectangleBorder(
|
||||||
borderRadius: BorderRadius.circular(16),
|
borderRadius: BorderRadius.circular(16),
|
||||||
),
|
),
|
||||||
@@ -110,7 +108,6 @@ class _ReactionPickerState extends State<ReactionPicker>
|
|||||||
animation: animations[index],
|
animation: animations[index],
|
||||||
builder: (context, val) {
|
builder: (context, val) {
|
||||||
return Transform.scale(
|
return Transform.scale(
|
||||||
alignment: Alignment.center,
|
|
||||||
scale: animations[index].value,
|
scale: animations[index].value,
|
||||||
child: StreamSvgIcon(
|
child: StreamSvgIcon(
|
||||||
assetName: reactionIcon.assetName,
|
assetName: reactionIcon.assetName,
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ class StreamChat extends StatefulWidget {
|
|||||||
/// upon the [Event.type]
|
/// upon the [Event.type]
|
||||||
final EventHandler? onBackgroundEventReceived;
|
final EventHandler? onBackgroundEventReceived;
|
||||||
|
|
||||||
StreamChat({
|
const StreamChat({
|
||||||
Key? key,
|
Key? key,
|
||||||
required this.client,
|
required this.client,
|
||||||
required this.child,
|
required this.child,
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ import 'package:stream_chat_flutter_core/stream_chat_flutter_core.dart';
|
|||||||
class StreamChatTheme extends InheritedWidget {
|
class StreamChatTheme extends InheritedWidget {
|
||||||
final StreamChatThemeData data;
|
final StreamChatThemeData data;
|
||||||
|
|
||||||
StreamChatTheme({
|
const StreamChatTheme({
|
||||||
Key? key,
|
Key? key,
|
||||||
required this.data,
|
required this.data,
|
||||||
required Widget child,
|
required Widget child,
|
||||||
@@ -237,7 +237,7 @@ class StreamChatThemeData {
|
|||||||
lastMessageAt: textTheme.footnote.copyWith(
|
lastMessageAt: textTheme.footnote.copyWith(
|
||||||
color: colorTheme.black.withOpacity(.5),
|
color: colorTheme.black.withOpacity(.5),
|
||||||
),
|
),
|
||||||
indicatorIconSize: 16.0),
|
indicatorIconSize: 16),
|
||||||
channelListHeaderTheme: ChannelListHeaderTheme(
|
channelListHeaderTheme: ChannelListHeaderTheme(
|
||||||
avatarTheme: AvatarTheme(
|
avatarTheme: AvatarTheme(
|
||||||
borderRadius: BorderRadius.circular(20),
|
borderRadius: BorderRadius.circular(20),
|
||||||
@@ -543,17 +543,13 @@ class ColorTheme {
|
|||||||
stops: [0, 1],
|
stops: [0, 1],
|
||||||
),
|
),
|
||||||
this.borderTop = const Effect(
|
this.borderTop = const Effect(
|
||||||
sigmaX: 0,
|
sigmaX: 0, sigmaY: -1, color: Color(0xff000000), blur: 0, alpha: 0.08),
|
||||||
sigmaY: -1,
|
|
||||||
color: Color(0xff000000),
|
|
||||||
blur: 0.0,
|
|
||||||
alpha: 0.08),
|
|
||||||
this.borderBottom = const Effect(
|
this.borderBottom = const Effect(
|
||||||
sigmaX: 0, sigmaY: 1, color: Color(0xff000000), blur: 0.0, alpha: 0.08),
|
sigmaX: 0, sigmaY: 1, color: Color(0xff000000), blur: 0, alpha: 0.08),
|
||||||
this.shadowIconButton = const Effect(
|
this.shadowIconButton = const Effect(
|
||||||
sigmaX: 0, sigmaY: 2, color: Color(0xff000000), alpha: 0.5, blur: 4.0),
|
sigmaX: 0, sigmaY: 2, color: Color(0xff000000), alpha: 0.5, blur: 4),
|
||||||
this.modalShadow = const Effect(
|
this.modalShadow = const Effect(
|
||||||
sigmaX: 0, sigmaY: 0, color: Color(0xff000000), alpha: 1, blur: 8.0),
|
sigmaX: 0, sigmaY: 0, color: Color(0xff000000), alpha: 1, blur: 8),
|
||||||
}) : brightness = Brightness.light;
|
}) : brightness = Brightness.light;
|
||||||
|
|
||||||
ColorTheme.dark({
|
ColorTheme.dark({
|
||||||
@@ -572,28 +568,28 @@ class ColorTheme {
|
|||||||
sigmaX: 0,
|
sigmaX: 0,
|
||||||
sigmaY: -1,
|
sigmaY: -1,
|
||||||
color: Color(0xff141924),
|
color: Color(0xff141924),
|
||||||
blur: 0.0,
|
blur: 0,
|
||||||
),
|
),
|
||||||
this.borderBottom = const Effect(
|
this.borderBottom = const Effect(
|
||||||
sigmaX: 0,
|
sigmaX: 0,
|
||||||
sigmaY: 1,
|
sigmaY: 1,
|
||||||
color: Color(0xff141924),
|
color: Color(0xff141924),
|
||||||
blur: 0.0,
|
blur: 0,
|
||||||
alpha: 1.0,
|
alpha: 1,
|
||||||
),
|
),
|
||||||
this.shadowIconButton = const Effect(
|
this.shadowIconButton = const Effect(
|
||||||
sigmaX: 0,
|
sigmaX: 0,
|
||||||
sigmaY: 2,
|
sigmaY: 2,
|
||||||
color: Color(0xff000000),
|
color: Color(0xff000000),
|
||||||
alpha: 0.5,
|
alpha: 0.5,
|
||||||
blur: 4.0,
|
blur: 4,
|
||||||
),
|
),
|
||||||
this.modalShadow = const Effect(
|
this.modalShadow = const Effect(
|
||||||
sigmaX: 0,
|
sigmaX: 0,
|
||||||
sigmaY: 0,
|
sigmaY: 0,
|
||||||
color: Color(0xff000000),
|
color: Color(0xff000000),
|
||||||
alpha: 1,
|
alpha: 1,
|
||||||
blur: 8.0,
|
blur: 8,
|
||||||
),
|
),
|
||||||
this.highlight = const Color(0xff302d22),
|
this.highlight = const Color(0xff302d22),
|
||||||
this.overlay = const Color.fromRGBO(0, 0, 0, 0.4),
|
this.overlay = const Color.fromRGBO(0, 0, 0, 0.4),
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ class StreamNeumorphicButton extends StatelessWidget {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Container(
|
return Container(
|
||||||
margin: EdgeInsets.all(8.0),
|
margin: EdgeInsets.all(8),
|
||||||
height: 40,
|
height: 40,
|
||||||
width: 40,
|
width: 40,
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
@@ -22,15 +22,12 @@ class StreamNeumorphicButton extends StatelessWidget {
|
|||||||
boxShadow: [
|
boxShadow: [
|
||||||
BoxShadow(
|
BoxShadow(
|
||||||
color: Colors.grey.shade700,
|
color: Colors.grey.shade700,
|
||||||
offset: Offset(0, 1.0),
|
offset: Offset(0, 1),
|
||||||
blurRadius: 0.5,
|
blurRadius: 0.5,
|
||||||
spreadRadius: 0,
|
|
||||||
),
|
),
|
||||||
BoxShadow(
|
BoxShadow(
|
||||||
color: Colors.white,
|
color: Colors.white,
|
||||||
offset: Offset.zero,
|
|
||||||
blurRadius: 0.5,
|
blurRadius: 0.5,
|
||||||
spreadRadius: 0,
|
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -25,7 +25,6 @@ class StreamSvgIcon extends StatelessWidget {
|
|||||||
width: width,
|
width: width,
|
||||||
height: height,
|
height: height,
|
||||||
color: color,
|
color: color,
|
||||||
alignment: Alignment.center,
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ class Swipeable extends StatefulWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class _SwipeableState extends State<Swipeable> with TickerProviderStateMixin {
|
class _SwipeableState extends State<Swipeable> with TickerProviderStateMixin {
|
||||||
double _dragExtent = 0.0;
|
double _dragExtent = 0;
|
||||||
late AnimationController _moveController;
|
late AnimationController _moveController;
|
||||||
late AnimationController _iconMoveController;
|
late AnimationController _iconMoveController;
|
||||||
late Animation<Offset> _moveAnimation;
|
late Animation<Offset> _moveAnimation;
|
||||||
@@ -45,15 +45,15 @@ class _SwipeableState extends State<Swipeable> with TickerProviderStateMixin {
|
|||||||
AnimationController(duration: _animationDuration, vsync: this);
|
AnimationController(duration: _animationDuration, vsync: this);
|
||||||
_iconMoveController =
|
_iconMoveController =
|
||||||
AnimationController(duration: _animationDuration, vsync: this);
|
AnimationController(duration: _animationDuration, vsync: this);
|
||||||
_moveAnimation = Tween<Offset>(begin: Offset.zero, end: Offset(1.0, 0.0))
|
_moveAnimation = Tween<Offset>(begin: Offset.zero, end: Offset(1, 0))
|
||||||
.animate(_moveController);
|
.animate(_moveController);
|
||||||
_iconTransitionAnimation =
|
_iconTransitionAnimation =
|
||||||
Tween<Offset>(begin: Offset(-0.1, 0.0), end: Offset(0.4, 0.0))
|
Tween<Offset>(begin: Offset(-0.1, 0), end: Offset(0.4, 0))
|
||||||
.animate(_moveController);
|
.animate(_moveController);
|
||||||
_iconFadeAnimation =
|
_iconFadeAnimation =
|
||||||
Tween<double>(begin: 0.7, end: 1.0).animate(_iconMoveController);
|
Tween<double>(begin: 0.7, end: 1).animate(_iconMoveController);
|
||||||
|
|
||||||
final controllerValue = 0.0;
|
const controllerValue = 0.0;
|
||||||
_moveController.animateTo(controllerValue);
|
_moveController.animateTo(controllerValue);
|
||||||
_iconMoveController.animateTo(controllerValue);
|
_iconMoveController.animateTo(controllerValue);
|
||||||
}
|
}
|
||||||
@@ -77,19 +77,19 @@ class _SwipeableState extends State<Swipeable> with TickerProviderStateMixin {
|
|||||||
|
|
||||||
if (_dragExtent.isNegative) return;
|
if (_dragExtent.isNegative) return;
|
||||||
|
|
||||||
var movePastThresholdPixels = widget.threshold;
|
final movePastThresholdPixels = widget.threshold;
|
||||||
var newPos = _dragExtent.abs() / context.size!.width;
|
var newPos = _dragExtent.abs() / context.size!.width;
|
||||||
|
|
||||||
if (_dragExtent.abs() > movePastThresholdPixels) {
|
if (_dragExtent.abs() > movePastThresholdPixels) {
|
||||||
// how many "thresholds" past the threshold we are. 1 = the threshold 2
|
// how many "thresholds" past the threshold we are. 1 = the threshold 2
|
||||||
// = two thresholds.
|
// = two thresholds.
|
||||||
var n = _dragExtent.abs() / movePastThresholdPixels;
|
final n = _dragExtent.abs() / movePastThresholdPixels;
|
||||||
|
|
||||||
// Take the number of thresholds past the threshold, and reduce this
|
// Take the number of thresholds past the threshold, and reduce this
|
||||||
// number
|
// number
|
||||||
var reducedThreshold = math.pow(n, 0.3);
|
final reducedThreshold = math.pow(n, 0.3);
|
||||||
|
|
||||||
var adjustedPixelPos = movePastThresholdPixels * reducedThreshold;
|
final adjustedPixelPos = movePastThresholdPixels * reducedThreshold;
|
||||||
newPos = adjustedPixelPos / context.size!.width;
|
newPos = adjustedPixelPos / context.size!.width;
|
||||||
|
|
||||||
if (_dragExtent > 0 && !_pastThreshold) {
|
if (_dragExtent > 0 && !_pastThreshold) {
|
||||||
@@ -111,8 +111,8 @@ class _SwipeableState extends State<Swipeable> with TickerProviderStateMixin {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void _handleDragEnd(DragEndDetails details) {
|
void _handleDragEnd(DragEndDetails details) {
|
||||||
_moveController.animateTo(0.0, duration: _animationDuration);
|
_moveController.animateTo(0, duration: _animationDuration);
|
||||||
_iconMoveController.animateTo(0.0, duration: _animationDuration);
|
_iconMoveController.animateTo(0, duration: _animationDuration);
|
||||||
_dragExtent = 0.0;
|
_dragExtent = 0.0;
|
||||||
if (_pastThreshold && widget.onSwipeEnd != null) {
|
if (_pastThreshold && widget.onSwipeEnd != null) {
|
||||||
widget.onSwipeEnd!();
|
widget.onSwipeEnd!();
|
||||||
|
|||||||
@@ -118,7 +118,6 @@ class ThreadHeader extends StatelessWidget implements PreferredSizeWidget {
|
|||||||
child: Container(
|
child: Container(
|
||||||
height: preferredSize.height,
|
height: preferredSize.height,
|
||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
title ??
|
title ??
|
||||||
@@ -133,7 +132,6 @@ class ThreadHeader extends StatelessWidget implements PreferredSizeWidget {
|
|||||||
subtitle ??
|
subtitle ??
|
||||||
Row(
|
Row(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
|
|||||||
@@ -33,8 +33,8 @@ class UnreadIndicator extends StatelessWidget {
|
|||||||
.unreadCounterColor,
|
.unreadCounterColor,
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.only(
|
padding: const EdgeInsets.only(
|
||||||
left: 5.0,
|
left: 5,
|
||||||
right: 5.0,
|
right: 5,
|
||||||
top: 2,
|
top: 2,
|
||||||
bottom: 1,
|
bottom: 1,
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ class UploadProgressIndicator extends StatelessWidget {
|
|||||||
final bool showBackground;
|
final bool showBackground;
|
||||||
final TextStyle? textStyle;
|
final TextStyle? textStyle;
|
||||||
|
|
||||||
UploadProgressIndicator({
|
const UploadProgressIndicator({
|
||||||
Key? key,
|
Key? key,
|
||||||
required this.uploaded,
|
required this.uploaded,
|
||||||
required this.total,
|
required this.total,
|
||||||
|
|||||||
@@ -8,12 +8,12 @@ class UrlAttachment extends StatelessWidget {
|
|||||||
final String hostDisplayName;
|
final String hostDisplayName;
|
||||||
final EdgeInsets textPadding;
|
final EdgeInsets textPadding;
|
||||||
|
|
||||||
UrlAttachment({
|
const UrlAttachment({
|
||||||
required this.urlAttachment,
|
required this.urlAttachment,
|
||||||
required this.hostDisplayName,
|
required this.hostDisplayName,
|
||||||
this.textPadding = const EdgeInsets.symmetric(
|
this.textPadding = const EdgeInsets.symmetric(
|
||||||
horizontal: 16.0,
|
horizontal: 16,
|
||||||
vertical: 8.0,
|
vertical: 8,
|
||||||
),
|
),
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -32,9 +32,9 @@ class UrlAttachment extends StatelessWidget {
|
|||||||
if (urlAttachment.imageUrl != null)
|
if (urlAttachment.imageUrl != null)
|
||||||
Container(
|
Container(
|
||||||
clipBehavior: Clip.antiAliasWithSaveLayer,
|
clipBehavior: Clip.antiAliasWithSaveLayer,
|
||||||
margin: EdgeInsets.symmetric(horizontal: 8.0),
|
margin: EdgeInsets.symmetric(horizontal: 8),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
borderRadius: BorderRadius.circular(8.0),
|
borderRadius: BorderRadius.circular(8),
|
||||||
),
|
),
|
||||||
child: Stack(
|
child: Stack(
|
||||||
children: [
|
children: [
|
||||||
@@ -44,20 +44,20 @@ class UrlAttachment extends StatelessWidget {
|
|||||||
fit: BoxFit.cover,
|
fit: BoxFit.cover,
|
||||||
),
|
),
|
||||||
Positioned(
|
Positioned(
|
||||||
left: 0.0,
|
left: 0,
|
||||||
bottom: -1,
|
bottom: -1,
|
||||||
child: Container(
|
child: Container(
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
borderRadius: BorderRadius.only(
|
borderRadius: BorderRadius.only(
|
||||||
topRight: Radius.circular(16.0),
|
topRight: Radius.circular(16),
|
||||||
),
|
),
|
||||||
color: StreamChatTheme.of(context).colorTheme.blueAlice,
|
color: StreamChatTheme.of(context).colorTheme.blueAlice,
|
||||||
),
|
),
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.only(
|
padding: const EdgeInsets.only(
|
||||||
top: 8.0,
|
top: 8,
|
||||||
left: 8.0,
|
left: 8,
|
||||||
right: 8.0,
|
right: 8,
|
||||||
),
|
),
|
||||||
child: Text(
|
child: Text(
|
||||||
hostDisplayName,
|
hostDisplayName,
|
||||||
|
|||||||
@@ -42,7 +42,6 @@ class UserAvatar extends StatelessWidget {
|
|||||||
Widget avatar = FittedBox(
|
Widget avatar = FittedBox(
|
||||||
fit: BoxFit.cover,
|
fit: BoxFit.cover,
|
||||||
child: ClipRRect(
|
child: ClipRRect(
|
||||||
clipBehavior: Clip.antiAlias,
|
|
||||||
borderRadius: borderRadius ??
|
borderRadius: borderRadius ??
|
||||||
streamChatTheme.ownMessageTheme.avatarTheme?.borderRadius,
|
streamChatTheme.ownMessageTheme.avatarTheme?.borderRadius,
|
||||||
child: Container(
|
child: Container(
|
||||||
@@ -97,7 +96,7 @@ class UserAvatar extends StatelessWidget {
|
|||||||
type: MaterialType.circle,
|
type: MaterialType.circle,
|
||||||
color: streamChatTheme.colorTheme.white,
|
color: streamChatTheme.colorTheme.white,
|
||||||
child: Container(
|
child: Container(
|
||||||
margin: const EdgeInsets.all(2.0),
|
margin: const EdgeInsets.all(2),
|
||||||
constraints: onlineIndicatorConstraints ??
|
constraints: onlineIndicatorConstraints ??
|
||||||
BoxConstraints.tightFor(
|
BoxConstraints.tightFor(
|
||||||
width: 8,
|
width: 8,
|
||||||
|
|||||||
@@ -61,7 +61,6 @@ class UserItem extends StatelessWidget {
|
|||||||
},
|
},
|
||||||
leading: UserAvatar(
|
leading: UserAvatar(
|
||||||
user: user,
|
user: user,
|
||||||
showOnlineStatus: true,
|
|
||||||
onTap: (user) {
|
onTap: (user) {
|
||||||
if (onImageTap != null) {
|
if (onImageTap != null) {
|
||||||
onImageTap!(user);
|
onImageTap!(user);
|
||||||
|
|||||||
@@ -151,7 +151,7 @@ class _UserListViewState extends State<UserListView>
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
var child = UserListCore(
|
final child = UserListCore(
|
||||||
errorBuilder: widget.errorBuilder as Widget Function(Object)? ??
|
errorBuilder: widget.errorBuilder as Widget Function(Object)? ??
|
||||||
(err) {
|
(err) {
|
||||||
return _buildError(err as Error);
|
return _buildError(err as Error);
|
||||||
@@ -225,7 +225,7 @@ class _UserListViewState extends State<UserListView>
|
|||||||
WidgetSpan(
|
WidgetSpan(
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.only(
|
padding: const EdgeInsets.only(
|
||||||
right: 2.0,
|
right: 2,
|
||||||
),
|
),
|
||||||
child: Icon(Icons.error_outline),
|
child: Icon(Icons.error_outline),
|
||||||
),
|
),
|
||||||
@@ -237,7 +237,7 @@ class _UserListViewState extends State<UserListView>
|
|||||||
),
|
),
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.only(
|
padding: const EdgeInsets.only(
|
||||||
top: 16.0,
|
top: 16,
|
||||||
),
|
),
|
||||||
child: Text(message),
|
child: Text(message),
|
||||||
),
|
),
|
||||||
@@ -313,7 +313,7 @@ class _UserListViewState extends State<UserListView>
|
|||||||
color:
|
color:
|
||||||
StreamChatTheme.of(context).colorTheme.black.withOpacity(0.05),
|
StreamChatTheme.of(context).colorTheme.black.withOpacity(0.05),
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 8.0, vertical: 6),
|
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 6),
|
||||||
child: Text(
|
child: Text(
|
||||||
header,
|
header,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
@@ -360,7 +360,6 @@ class _UserListViewState extends State<UserListView>
|
|||||||
? widget.userItemBuilder!(context, user, selected)
|
? widget.userItemBuilder!(context, user, selected)
|
||||||
: Column(
|
: Column(
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
|
||||||
children: [
|
children: [
|
||||||
UserAvatar(
|
UserAvatar(
|
||||||
user: user,
|
user: user,
|
||||||
@@ -414,7 +413,7 @@ class _UserListViewState extends State<UserListView>
|
|||||||
.accentRed
|
.accentRed
|
||||||
.withOpacity(.2),
|
.withOpacity(.2),
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.symmetric(vertical: 16.0),
|
padding: const EdgeInsets.symmetric(vertical: 16),
|
||||||
child: Center(
|
child: Center(
|
||||||
child: Text('Error loading users'),
|
child: Text('Error loading users'),
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ class UserReactionDisplay extends StatelessWidget {
|
|||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: reactionToEmoji.keys.map((reactionType) {
|
children: reactionToEmoji.keys.map((reactionType) {
|
||||||
var firstUserReaction = message.latestReactions!
|
final firstUserReaction = message.latestReactions!
|
||||||
.firstWhere((element) => element.type == reactionType,
|
.firstWhere((element) => element.type == reactionType,
|
||||||
orElse: () {
|
orElse: () {
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
@@ -33,8 +33,8 @@ Future<bool?> showConfirmationDialog(
|
|||||||
context: context,
|
context: context,
|
||||||
shape: RoundedRectangleBorder(
|
shape: RoundedRectangleBorder(
|
||||||
borderRadius: BorderRadius.only(
|
borderRadius: BorderRadius.only(
|
||||||
topLeft: Radius.circular(16.0),
|
topLeft: Radius.circular(16),
|
||||||
topRight: Radius.circular(16.0),
|
topRight: Radius.circular(16),
|
||||||
)),
|
)),
|
||||||
builder: (context) {
|
builder: (context) {
|
||||||
final effect = StreamChatTheme.of(context).colorTheme.borderTop;
|
final effect = StreamChatTheme.of(context).colorTheme.borderTop;
|
||||||
@@ -42,20 +42,20 @@ Future<bool?> showConfirmationDialog(
|
|||||||
child: Column(
|
child: Column(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: [
|
children: [
|
||||||
SizedBox(height: 26.0),
|
SizedBox(height: 26),
|
||||||
if (icon != null) icon,
|
if (icon != null) icon,
|
||||||
SizedBox(height: 26.0),
|
SizedBox(height: 26),
|
||||||
Text(
|
Text(
|
||||||
title,
|
title,
|
||||||
style: StreamChatTheme.of(context).textTheme.headlineBold,
|
style: StreamChatTheme.of(context).textTheme.headlineBold,
|
||||||
),
|
),
|
||||||
SizedBox(height: 7.0),
|
SizedBox(height: 7),
|
||||||
if (question != null)
|
if (question != null)
|
||||||
Text(
|
Text(
|
||||||
question,
|
question,
|
||||||
textAlign: TextAlign.center,
|
textAlign: TextAlign.center,
|
||||||
),
|
),
|
||||||
SizedBox(height: 36.0),
|
SizedBox(height: 36),
|
||||||
Container(
|
Container(
|
||||||
color: effect.color!.withOpacity(effect.alpha ?? 1),
|
color: effect.color!.withOpacity(effect.alpha ?? 1),
|
||||||
height: 1,
|
height: 1,
|
||||||
@@ -126,8 +126,8 @@ Future<bool?> showInfoDialog(
|
|||||||
context: context,
|
context: context,
|
||||||
shape: RoundedRectangleBorder(
|
shape: RoundedRectangleBorder(
|
||||||
borderRadius: BorderRadius.only(
|
borderRadius: BorderRadius.only(
|
||||||
topLeft: Radius.circular(16.0),
|
topLeft: Radius.circular(16),
|
||||||
topRight: Radius.circular(16.0),
|
topRight: Radius.circular(16),
|
||||||
)),
|
)),
|
||||||
builder: (context) {
|
builder: (context) {
|
||||||
return SafeArea(
|
return SafeArea(
|
||||||
@@ -135,11 +135,11 @@ Future<bool?> showInfoDialog(
|
|||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: [
|
children: [
|
||||||
SizedBox(
|
SizedBox(
|
||||||
height: 26.0,
|
height: 26,
|
||||||
),
|
),
|
||||||
if (icon != null) icon,
|
if (icon != null) icon,
|
||||||
SizedBox(
|
SizedBox(
|
||||||
height: 26.0,
|
height: 26,
|
||||||
),
|
),
|
||||||
Text(
|
Text(
|
||||||
title,
|
title,
|
||||||
@@ -147,16 +147,16 @@ Future<bool?> showInfoDialog(
|
|||||||
StreamChatTheme.of(context).textTheme.headlineBold,
|
StreamChatTheme.of(context).textTheme.headlineBold,
|
||||||
),
|
),
|
||||||
SizedBox(
|
SizedBox(
|
||||||
height: 7.0,
|
height: 7,
|
||||||
),
|
),
|
||||||
if (details != null) Text(details),
|
if (details != null) Text(details),
|
||||||
SizedBox(
|
SizedBox(
|
||||||
height: 36.0,
|
height: 36,
|
||||||
),
|
),
|
||||||
Container(
|
Container(
|
||||||
color: theme?.colorTheme.black.withOpacity(.08) ??
|
color: theme?.colorTheme.black.withOpacity(.08) ??
|
||||||
StreamChatTheme.of(context).colorTheme.black.withOpacity(.08),
|
StreamChatTheme.of(context).colorTheme.black.withOpacity(.08),
|
||||||
height: 1.0,
|
height: 1,
|
||||||
),
|
),
|
||||||
Center(
|
Center(
|
||||||
child: TextButton(
|
child: TextButton(
|
||||||
@@ -236,7 +236,7 @@ String fileSize(dynamic size, [int round = 2]) {
|
|||||||
* the optional parameter [round] specifies the number
|
* the optional parameter [round] specifies the number
|
||||||
* of digits after comma/point (default is 2)
|
* of digits after comma/point (default is 2)
|
||||||
*/
|
*/
|
||||||
final divider = 1024;
|
const divider = 1024;
|
||||||
int _size;
|
int _size;
|
||||||
try {
|
try {
|
||||||
_size = int.parse(size.toString());
|
_size = int.parse(size.toString());
|
||||||
@@ -274,21 +274,21 @@ String fileSize(dynamic size, [int round = 2]) {
|
|||||||
|
|
||||||
if (_size < divider * divider * divider * divider * divider &&
|
if (_size < divider * divider * divider * divider * divider &&
|
||||||
_size % divider == 0) {
|
_size % divider == 0) {
|
||||||
num r = _size / divider / divider / divider / divider;
|
final num r = _size / divider / divider / divider / divider;
|
||||||
return '${r.toStringAsFixed(0)} TB';
|
return '${r.toStringAsFixed(0)} TB';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_size < divider * divider * divider * divider * divider) {
|
if (_size < divider * divider * divider * divider * divider) {
|
||||||
num r = _size / divider / divider / divider / divider;
|
final num r = _size / divider / divider / divider / divider;
|
||||||
return '${r.toStringAsFixed(round)} TB';
|
return '${r.toStringAsFixed(round)} TB';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_size < divider * divider * divider * divider * divider * divider &&
|
if (_size < divider * divider * divider * divider * divider * divider &&
|
||||||
_size % divider == 0) {
|
_size % divider == 0) {
|
||||||
num r = _size / divider / divider / divider / divider / divider;
|
final num r = _size / divider / divider / divider / divider / divider;
|
||||||
return '${r.toStringAsFixed(0)} PB';
|
return '${r.toStringAsFixed(0)} PB';
|
||||||
} else {
|
} else {
|
||||||
num r = _size / divider / divider / divider / divider / divider;
|
final num r = _size / divider / divider / divider / divider / divider;
|
||||||
return '${r.toStringAsFixed(round)} PB';
|
return '${r.toStringAsFixed(round)} PB';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -239,7 +239,7 @@ void main() {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
await tester.tap(find.text('Show in Chat'));
|
await tester.tap(find.text('Show in Chat'));
|
||||||
verify(() => onShowMessage.call()).called(1);
|
verify(onShowMessage.call).called(1);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -26,8 +26,8 @@ void main() {
|
|||||||
child: Container(
|
child: Container(
|
||||||
child: FileAttachment(
|
child: FileAttachment(
|
||||||
size: Size(
|
size: Size(
|
||||||
300.0,
|
300,
|
||||||
300.0,
|
300,
|
||||||
),
|
),
|
||||||
message: Message(),
|
message: Message(),
|
||||||
attachment: Attachment(
|
attachment: Attachment(
|
||||||
|
|||||||
@@ -318,7 +318,6 @@ void main() {
|
|||||||
body: ChannelHeader(
|
body: ChannelHeader(
|
||||||
showTypingIndicator: false,
|
showTypingIndicator: false,
|
||||||
showBackButton: false,
|
showBackButton: false,
|
||||||
showConnectionStateTile: false,
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -224,7 +224,6 @@ void main() {
|
|||||||
borderColor: Colors.red,
|
borderColor: Colors.red,
|
||||||
backgroundColor: Colors.blue,
|
backgroundColor: Colors.blue,
|
||||||
maskColor: Colors.green,
|
maskColor: Colors.green,
|
||||||
highlightOwnReactions: true,
|
|
||||||
reverse: true,
|
reverse: true,
|
||||||
flipTail: true,
|
flipTail: true,
|
||||||
tailCirclesSpacing: 4,
|
tailCirclesSpacing: 4,
|
||||||
|
|||||||
Reference in New Issue
Block a user