fix reaction bubble ui
This commit is contained in:
@@ -237,13 +237,13 @@
|
|||||||
0BC14C4C242B5A7A0028DE94 = {
|
0BC14C4C242B5A7A0028DE94 = {
|
||||||
CreatedOnToolsVersion = 11.4;
|
CreatedOnToolsVersion = 11.4;
|
||||||
DevelopmentTeam = EHV7XZLAHA;
|
DevelopmentTeam = EHV7XZLAHA;
|
||||||
ProvisioningStyle = Manual;
|
ProvisioningStyle = Automatic;
|
||||||
};
|
};
|
||||||
97C146ED1CF9000F007C117D = {
|
97C146ED1CF9000F007C117D = {
|
||||||
CreatedOnToolsVersion = 7.3.1;
|
CreatedOnToolsVersion = 7.3.1;
|
||||||
DevelopmentTeam = EHV7XZLAHA;
|
DevelopmentTeam = EHV7XZLAHA;
|
||||||
LastSwiftMigration = 1100;
|
LastSwiftMigration = 1100;
|
||||||
ProvisioningStyle = Manual;
|
ProvisioningStyle = Automatic;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
@@ -412,9 +412,9 @@
|
|||||||
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||||
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
||||||
CODE_SIGN_ENTITLEMENTS = Notifications/Notifications.entitlements;
|
CODE_SIGN_ENTITLEMENTS = Notifications/Notifications.entitlements;
|
||||||
CODE_SIGN_IDENTITY = "iPhone Distribution";
|
CODE_SIGN_IDENTITY = "Apple Development";
|
||||||
CODE_SIGN_STYLE = Manual;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
DEVELOPMENT_TEAM = EHV7XZLAHA;
|
DEVELOPMENT_TEAM = "";
|
||||||
ENABLE_BITCODE = NO;
|
ENABLE_BITCODE = NO;
|
||||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||||
INFOPLIST_FILE = Notifications/Info.plist;
|
INFOPLIST_FILE = Notifications/Info.plist;
|
||||||
@@ -424,7 +424,7 @@
|
|||||||
MTL_FAST_MATH = YES;
|
MTL_FAST_MATH = YES;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = io.getstream.flutter.Notifications;
|
PRODUCT_BUNDLE_IDENTIFIER = io.getstream.flutter.Notifications;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
PROVISIONING_PROFILE_SPECIFIER = "flutter example notifications";
|
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||||
SKIP_INSTALL = YES;
|
SKIP_INSTALL = YES;
|
||||||
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
|
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
|
||||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||||
@@ -442,9 +442,9 @@
|
|||||||
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||||
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
||||||
CODE_SIGN_ENTITLEMENTS = Notifications/Notifications.entitlements;
|
CODE_SIGN_ENTITLEMENTS = Notifications/Notifications.entitlements;
|
||||||
CODE_SIGN_IDENTITY = "iPhone Distribution";
|
CODE_SIGN_IDENTITY = "Apple Development";
|
||||||
CODE_SIGN_STYLE = Manual;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
DEVELOPMENT_TEAM = EHV7XZLAHA;
|
DEVELOPMENT_TEAM = "";
|
||||||
ENABLE_BITCODE = NO;
|
ENABLE_BITCODE = NO;
|
||||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||||
INFOPLIST_FILE = Notifications/Info.plist;
|
INFOPLIST_FILE = Notifications/Info.plist;
|
||||||
@@ -453,7 +453,7 @@
|
|||||||
MTL_FAST_MATH = YES;
|
MTL_FAST_MATH = YES;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = io.getstream.flutter.Notifications;
|
PRODUCT_BUNDLE_IDENTIFIER = io.getstream.flutter.Notifications;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
PROVISIONING_PROFILE_SPECIFIER = "flutter example notifications";
|
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||||
SKIP_INSTALL = YES;
|
SKIP_INSTALL = YES;
|
||||||
SWIFT_VERSION = 5.0;
|
SWIFT_VERSION = 5.0;
|
||||||
TARGETED_DEVICE_FAMILY = "1,2";
|
TARGETED_DEVICE_FAMILY = "1,2";
|
||||||
@@ -469,9 +469,9 @@
|
|||||||
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||||
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
||||||
CODE_SIGN_ENTITLEMENTS = Notifications/Notifications.entitlements;
|
CODE_SIGN_ENTITLEMENTS = Notifications/Notifications.entitlements;
|
||||||
CODE_SIGN_IDENTITY = "iPhone Distribution";
|
CODE_SIGN_IDENTITY = "Apple Development";
|
||||||
CODE_SIGN_STYLE = Manual;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
DEVELOPMENT_TEAM = EHV7XZLAHA;
|
DEVELOPMENT_TEAM = "";
|
||||||
ENABLE_BITCODE = NO;
|
ENABLE_BITCODE = NO;
|
||||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||||
INFOPLIST_FILE = Notifications/Info.plist;
|
INFOPLIST_FILE = Notifications/Info.plist;
|
||||||
@@ -480,7 +480,7 @@
|
|||||||
MTL_FAST_MATH = YES;
|
MTL_FAST_MATH = YES;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = io.getstream.flutter.Notifications;
|
PRODUCT_BUNDLE_IDENTIFIER = io.getstream.flutter.Notifications;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
PROVISIONING_PROFILE_SPECIFIER = "flutter example notifications";
|
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||||
SKIP_INSTALL = YES;
|
SKIP_INSTALL = YES;
|
||||||
SWIFT_VERSION = 5.0;
|
SWIFT_VERSION = 5.0;
|
||||||
TARGETED_DEVICE_FAMILY = "1,2";
|
TARGETED_DEVICE_FAMILY = "1,2";
|
||||||
@@ -546,10 +546,10 @@
|
|||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
CLANG_ENABLE_MODULES = YES;
|
CLANG_ENABLE_MODULES = YES;
|
||||||
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
|
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
|
||||||
CODE_SIGN_IDENTITY = "iPhone Distribution";
|
CODE_SIGN_IDENTITY = "Apple Development";
|
||||||
CODE_SIGN_STYLE = Manual;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
|
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
|
||||||
DEVELOPMENT_TEAM = EHV7XZLAHA;
|
DEVELOPMENT_TEAM = "";
|
||||||
ENABLE_BITCODE = NO;
|
ENABLE_BITCODE = NO;
|
||||||
FRAMEWORK_SEARCH_PATHS = (
|
FRAMEWORK_SEARCH_PATHS = (
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
@@ -564,7 +564,7 @@
|
|||||||
);
|
);
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = io.getstream.flutter;
|
PRODUCT_BUNDLE_IDENTIFIER = io.getstream.flutter;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
PROVISIONING_PROFILE_SPECIFIER = "flutter example";
|
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||||
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
||||||
SWIFT_VERSION = 5.0;
|
SWIFT_VERSION = 5.0;
|
||||||
VERSIONING_SYSTEM = "apple-generic";
|
VERSIONING_SYSTEM = "apple-generic";
|
||||||
@@ -687,10 +687,10 @@
|
|||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
CLANG_ENABLE_MODULES = YES;
|
CLANG_ENABLE_MODULES = YES;
|
||||||
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
|
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
|
||||||
CODE_SIGN_IDENTITY = "iPhone Distribution";
|
CODE_SIGN_IDENTITY = "Apple Development";
|
||||||
CODE_SIGN_STYLE = Manual;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
|
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
|
||||||
DEVELOPMENT_TEAM = EHV7XZLAHA;
|
DEVELOPMENT_TEAM = "";
|
||||||
ENABLE_BITCODE = NO;
|
ENABLE_BITCODE = NO;
|
||||||
FRAMEWORK_SEARCH_PATHS = (
|
FRAMEWORK_SEARCH_PATHS = (
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
@@ -705,7 +705,7 @@
|
|||||||
);
|
);
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = io.getstream.flutter;
|
PRODUCT_BUNDLE_IDENTIFIER = io.getstream.flutter;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
PROVISIONING_PROFILE_SPECIFIER = "flutter example";
|
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||||
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
||||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||||
SWIFT_VERSION = 5.0;
|
SWIFT_VERSION = 5.0;
|
||||||
@@ -721,10 +721,10 @@
|
|||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
CLANG_ENABLE_MODULES = YES;
|
CLANG_ENABLE_MODULES = YES;
|
||||||
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
|
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
|
||||||
CODE_SIGN_IDENTITY = "iPhone Distribution";
|
CODE_SIGN_IDENTITY = "Apple Development";
|
||||||
CODE_SIGN_STYLE = Manual;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
|
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
|
||||||
DEVELOPMENT_TEAM = EHV7XZLAHA;
|
DEVELOPMENT_TEAM = "";
|
||||||
ENABLE_BITCODE = NO;
|
ENABLE_BITCODE = NO;
|
||||||
FRAMEWORK_SEARCH_PATHS = (
|
FRAMEWORK_SEARCH_PATHS = (
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
@@ -739,7 +739,7 @@
|
|||||||
);
|
);
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = io.getstream.flutter;
|
PRODUCT_BUNDLE_IDENTIFIER = io.getstream.flutter;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
PROVISIONING_PROFILE_SPECIFIER = "flutter example";
|
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||||
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
||||||
SWIFT_VERSION = 5.0;
|
SWIFT_VERSION = 5.0;
|
||||||
VERSIONING_SYSTEM = "apple-generic";
|
VERSIONING_SYSTEM = "apple-generic";
|
||||||
|
|||||||
+161
-113
@@ -34,7 +34,7 @@ enum DisplayWidget {
|
|||||||
///
|
///
|
||||||
/// The widget components render the ui based on the first ancestor of type [StreamChatTheme].
|
/// The widget components render the ui based on the first ancestor of type [StreamChatTheme].
|
||||||
/// Modify it to change the widget appearance.
|
/// Modify it to change the widget appearance.
|
||||||
class MessageWidget extends StatelessWidget {
|
class MessageWidget extends StatefulWidget {
|
||||||
/// Function called on mention tap
|
/// Function called on mention tap
|
||||||
final void Function(User) onMentionTap;
|
final void Function(User) onMentionTap;
|
||||||
|
|
||||||
@@ -104,15 +104,6 @@ class MessageWidget extends StatelessWidget {
|
|||||||
final bool showEditMessage;
|
final bool showEditMessage;
|
||||||
final Map<String, AttachmentBuilder> attachmentBuilders;
|
final Map<String, AttachmentBuilder> attachmentBuilders;
|
||||||
|
|
||||||
final Map<String, String> _reactionToEmoji = {
|
|
||||||
'love': '❤️️',
|
|
||||||
'haha': '😂',
|
|
||||||
'like': '👍',
|
|
||||||
'sad': '😕',
|
|
||||||
'angry': '😡',
|
|
||||||
'wow': '😲',
|
|
||||||
};
|
|
||||||
|
|
||||||
MessageWidget({
|
MessageWidget({
|
||||||
Key key,
|
Key key,
|
||||||
@required this.message,
|
@required this.message,
|
||||||
@@ -186,20 +177,37 @@ class MessageWidget extends StatelessWidget {
|
|||||||
}..addAll(customAttachmentBuilders ?? {}),
|
}..addAll(customAttachmentBuilders ?? {}),
|
||||||
super(key: key);
|
super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
_MessageWidgetState createState() => _MessageWidgetState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _MessageWidgetState extends State<MessageWidget> {
|
||||||
|
final Map<String, String> _reactionToEmoji = {
|
||||||
|
'love': '❤️️',
|
||||||
|
'haha': '😂',
|
||||||
|
'like': '👍',
|
||||||
|
'sad': '😕',
|
||||||
|
'angry': '😡',
|
||||||
|
'wow': '😲',
|
||||||
|
};
|
||||||
|
|
||||||
|
final GlobalKey _reactionPickerKey = GlobalKey();
|
||||||
|
double _reactionPadding = 0;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
var leftPadding = showUserAvatar != DisplayWidget.gone
|
var leftPadding = widget.showUserAvatar != DisplayWidget.gone
|
||||||
? messageTheme.avatarTheme.constraints.maxWidth + 23.0
|
? widget.messageTheme.avatarTheme.constraints.maxWidth + 23.0
|
||||||
: 12.0;
|
: 12.0;
|
||||||
if (showSendingIndicator == DisplayWidget.gone) {
|
if (widget.showSendingIndicator == DisplayWidget.gone) {
|
||||||
leftPadding -= 7;
|
leftPadding -= 7;
|
||||||
}
|
}
|
||||||
return Portal(
|
return Portal(
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: padding ?? EdgeInsets.all(8),
|
padding: widget.padding ?? EdgeInsets.all(8),
|
||||||
child: Transform(
|
child: Transform(
|
||||||
alignment: Alignment.center,
|
alignment: Alignment.center,
|
||||||
transform: Matrix4.rotationY(reverse ? pi : 0),
|
transform: Matrix4.rotationY(widget.reverse ? pi : 0),
|
||||||
child: Container(
|
child: Container(
|
||||||
alignment: Alignment.centerLeft,
|
alignment: Alignment.centerLeft,
|
||||||
child: Container(
|
child: Container(
|
||||||
@@ -220,31 +228,31 @@ class MessageWidget extends StatelessWidget {
|
|||||||
crossAxisAlignment: CrossAxisAlignment.end,
|
crossAxisAlignment: CrossAxisAlignment.end,
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
if (showSendingIndicator == DisplayWidget.show)
|
if (widget.showSendingIndicator ==
|
||||||
|
DisplayWidget.show)
|
||||||
_buildSendingIndicator(),
|
_buildSendingIndicator(),
|
||||||
SizedBox(
|
SizedBox(
|
||||||
width: 2,
|
width: 2,
|
||||||
),
|
),
|
||||||
if (showSendingIndicator == DisplayWidget.hide)
|
if (widget.showSendingIndicator ==
|
||||||
|
DisplayWidget.hide)
|
||||||
SizedBox(
|
SizedBox(
|
||||||
width: 6,
|
width: 6,
|
||||||
),
|
),
|
||||||
if (showUserAvatar == DisplayWidget.show)
|
if (widget.showUserAvatar == DisplayWidget.show)
|
||||||
_buildUserAvatar(),
|
_buildUserAvatar(),
|
||||||
SizedBox(
|
SizedBox(
|
||||||
width: 6,
|
width: 6,
|
||||||
),
|
),
|
||||||
if (showUserAvatar == DisplayWidget.hide)
|
if (widget.showUserAvatar == DisplayWidget.hide)
|
||||||
SizedBox(
|
SizedBox(
|
||||||
width: messageTheme
|
width: widget.messageTheme.avatarTheme
|
||||||
.avatarTheme.constraints.maxWidth +
|
.constraints.maxWidth +
|
||||||
8,
|
8,
|
||||||
),
|
),
|
||||||
Flexible(
|
Flexible(
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: (message.reactionCounts?.isNotEmpty ==
|
padding: widget.showReactions
|
||||||
true &&
|
|
||||||
showReactions)
|
|
||||||
? EdgeInsets.only(
|
? EdgeInsets.only(
|
||||||
top: _getReactionsTopPadding(),
|
top: _getReactionsTopPadding(),
|
||||||
)
|
)
|
||||||
@@ -253,16 +261,16 @@ class MessageWidget extends StatelessWidget {
|
|||||||
portalAnchor: Alignment(0, 1),
|
portalAnchor: Alignment(0, 1),
|
||||||
childAnchor: Alignment.topRight,
|
childAnchor: Alignment.topRight,
|
||||||
portal: _buildReactionIndicator(context),
|
portal: _buildReactionIndicator(context),
|
||||||
child: (message.isDeleted &&
|
child: (widget.message.isDeleted &&
|
||||||
message.status !=
|
widget.message.status !=
|
||||||
MessageSendingStatus
|
MessageSendingStatus
|
||||||
.FAILED_DELETE)
|
.FAILED_DELETE)
|
||||||
? Transform(
|
? Transform(
|
||||||
alignment: Alignment.center,
|
alignment: Alignment.center,
|
||||||
transform: Matrix4.rotationY(
|
transform: Matrix4.rotationY(
|
||||||
reverse ? pi : 0),
|
widget.reverse ? pi : 0),
|
||||||
child: DeletedMessage(
|
child: DeletedMessage(
|
||||||
messageTheme: messageTheme,
|
messageTheme: widget.messageTheme,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
: Column(
|
: Column(
|
||||||
@@ -270,7 +278,9 @@ class MessageWidget extends StatelessWidget {
|
|||||||
CrossAxisAlignment.start,
|
CrossAxisAlignment.start,
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
..._parseAttachments(context),
|
..._parseAttachments(context),
|
||||||
if (message.text.trim().isNotEmpty)
|
if (widget.message.text
|
||||||
|
.trim()
|
||||||
|
.isNotEmpty)
|
||||||
_buildTextBubble(context),
|
_buildTextBubble(context),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@@ -279,13 +289,15 @@ class MessageWidget extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
if (showReplyIndicator && message.replyCount > 0)
|
if (widget.showReplyIndicator &&
|
||||||
|
widget.message.replyCount > 0)
|
||||||
_buildReplyIndicator(leftPadding),
|
_buildReplyIndicator(leftPadding),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
if ((message.createdAt != null && showTimestamp) ||
|
if ((widget.message.createdAt != null &&
|
||||||
showUsername)
|
widget.showTimestamp) ||
|
||||||
|
widget.showUsername)
|
||||||
_buildUsernameAndTimestamp(leftPadding),
|
_buildUsernameAndTimestamp(leftPadding),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@@ -297,18 +309,49 @@ class MessageWidget extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
double _getReactionsTopPadding() {
|
double _getReactionsTopPadding() {
|
||||||
|
return _reactionPadding;
|
||||||
return 36.0 *
|
return 36.0 *
|
||||||
((message.reactionCounts.values
|
((widget.message.reactionCounts.values
|
||||||
.where((element) => element > 0)
|
.where((element) => element > 0)
|
||||||
.length ~/
|
.length ~/
|
||||||
5) +
|
5) +
|
||||||
1);
|
1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void didUpdateWidget(MessageWidget oldWidget) {
|
||||||
|
super.didUpdateWidget(oldWidget);
|
||||||
|
_updateReactionPadding();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
_updateReactionPadding();
|
||||||
|
}
|
||||||
|
|
||||||
|
void _updateReactionPadding() {
|
||||||
|
WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
|
||||||
|
if (_reactionPickerKey.currentContext != null &&
|
||||||
|
widget.message.reactionCounts.values
|
||||||
|
.where((element) => element > 0)
|
||||||
|
.length >
|
||||||
|
0) {
|
||||||
|
setState(() {
|
||||||
|
_reactionPadding = _reactionPickerKey.currentContext.size.height;
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
setState(() {
|
||||||
|
_reactionPadding = 0;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
Widget _buildReactionsTail(BuildContext context) {
|
Widget _buildReactionsTail(BuildContext context) {
|
||||||
return AnimatedSwitcher(
|
return AnimatedSwitcher(
|
||||||
duration: Duration(milliseconds: 300),
|
duration: Duration(milliseconds: 300),
|
||||||
child: message.reactionCounts?.isNotEmpty == true
|
child: widget.message.reactionCounts?.isNotEmpty == true
|
||||||
? Transform.translate(
|
? Transform.translate(
|
||||||
offset: Offset(4, 0),
|
offset: Offset(4, 0),
|
||||||
child: CustomPaint(
|
child: CustomPaint(
|
||||||
@@ -331,19 +374,20 @@ class MessageWidget extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
child: Transform(
|
child: Transform(
|
||||||
alignment: Alignment.center,
|
alignment: Alignment.center,
|
||||||
transform: Matrix4.rotationY(reverse ? pi : 0),
|
transform: Matrix4.rotationY(widget.reverse ? pi : 0),
|
||||||
child: RichText(
|
child: RichText(
|
||||||
text: TextSpan(
|
text: TextSpan(
|
||||||
style: messageTheme.createdAt,
|
style: widget.messageTheme.createdAt,
|
||||||
children: <TextSpan>[
|
children: <TextSpan>[
|
||||||
if (showUsername)
|
if (widget.showUsername)
|
||||||
TextSpan(
|
TextSpan(
|
||||||
text: message.user.name,
|
text: widget.message.user.name,
|
||||||
style: TextStyle(fontWeight: FontWeight.bold),
|
style: TextStyle(fontWeight: FontWeight.bold),
|
||||||
),
|
),
|
||||||
if (message.createdAt != null && showTimestamp)
|
if (widget.message.createdAt != null && widget.showTimestamp)
|
||||||
TextSpan(
|
TextSpan(
|
||||||
text: Jiffy(message.createdAt.toLocal()).format(' HH:mm'),
|
text: Jiffy(widget.message.createdAt.toLocal())
|
||||||
|
.format(' HH:mm'),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@@ -354,10 +398,11 @@ class MessageWidget extends StatelessWidget {
|
|||||||
|
|
||||||
Widget _buildReactionIndicator(BuildContext context) {
|
Widget _buildReactionIndicator(BuildContext context) {
|
||||||
return AnimatedSwitcher(
|
return AnimatedSwitcher(
|
||||||
|
key: _reactionPickerKey,
|
||||||
duration: Duration(milliseconds: 300),
|
duration: Duration(milliseconds: 300),
|
||||||
child: (showReactions &&
|
child: (widget.showReactions &&
|
||||||
message.reactionCounts?.isNotEmpty == true &&
|
widget.message.reactionCounts?.isNotEmpty == true &&
|
||||||
!message.isDeleted)
|
!widget.message.isDeleted)
|
||||||
? Container(
|
? Container(
|
||||||
child: GestureDetector(
|
child: GestureDetector(
|
||||||
onTap: () => onLongPress(context),
|
onTap: () => onLongPress(context),
|
||||||
@@ -371,7 +416,7 @@ class MessageWidget extends StatelessWidget {
|
|||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
Transform(
|
Transform(
|
||||||
transform: Matrix4.rotationY(reverse ? pi : 0),
|
transform: Matrix4.rotationY(widget.reverse ? pi : 0),
|
||||||
alignment: Alignment.center,
|
alignment: Alignment.center,
|
||||||
child: Container(
|
child: Container(
|
||||||
padding: const EdgeInsets.all(8),
|
padding: const EdgeInsets.all(8),
|
||||||
@@ -397,10 +442,10 @@ class MessageWidget extends StatelessWidget {
|
|||||||
|
|
||||||
Text _buildReactionsText(BuildContext context) {
|
Text _buildReactionsText(BuildContext context) {
|
||||||
return Text(
|
return Text(
|
||||||
message.reactionCounts.keys.map((reactionType) {
|
widget.message.reactionCounts.keys.map((reactionType) {
|
||||||
return _reactionToEmoji[reactionType] ?? '?';
|
return _reactionToEmoji[reactionType] ?? '?';
|
||||||
}).join(' ') +
|
}).join(' ') +
|
||||||
' ${message.reactionCounts.values.fold(0, (t, v) => v + t).toString()}',
|
' ${widget.message.reactionCounts.values.fold(0, (t, v) => v + t).toString()}',
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: Theme.of(context).brightness == Brightness.dark
|
color: Theme.of(context).brightness == Brightness.dark
|
||||||
? Colors.black
|
? Colors.black
|
||||||
@@ -425,21 +470,22 @@ class MessageWidget extends StatelessWidget {
|
|||||||
return StreamChannel(
|
return StreamChannel(
|
||||||
channel: channel,
|
channel: channel,
|
||||||
child: MessageActionsBottomSheet(
|
child: MessageActionsBottomSheet(
|
||||||
showDeleteMessage: showDeleteMessage,
|
showDeleteMessage: widget.showDeleteMessage,
|
||||||
message: message,
|
message: widget.message,
|
||||||
editMessageInputBuilder: editMessageInputBuilder,
|
editMessageInputBuilder: widget.editMessageInputBuilder,
|
||||||
onThreadTap: onThreadTap,
|
onThreadTap: widget.onThreadTap,
|
||||||
showEditMessage: showEditMessage,
|
showEditMessage: widget.showEditMessage,
|
||||||
showReactions: showReactions,
|
showReactions: widget.showReactions,
|
||||||
showReply: showReplyIndicator && onThreadTap != null,
|
showReply:
|
||||||
|
widget.showReplyIndicator && widget.onThreadTap != null,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
List<Widget> _parseAttachments(BuildContext context) {
|
List<Widget> _parseAttachments(BuildContext context) {
|
||||||
return message.attachments?.map((attachment) {
|
return widget.message.attachments?.map((attachment) {
|
||||||
final attachmentBuilder = attachmentBuilders[attachment.type];
|
final attachmentBuilder = widget.attachmentBuilders[attachment.type];
|
||||||
|
|
||||||
if (attachmentBuilder == null) {
|
if (attachmentBuilder == null) {
|
||||||
return SizedBox();
|
return SizedBox();
|
||||||
@@ -455,27 +501,28 @@ class MessageWidget extends StatelessWidget {
|
|||||||
child: Material(
|
child: Material(
|
||||||
color: _getBackgroundColor(),
|
color: _getBackgroundColor(),
|
||||||
clipBehavior: Clip.hardEdge,
|
clipBehavior: Clip.hardEdge,
|
||||||
shape: attachmentShape ??
|
shape: widget.attachmentShape ??
|
||||||
shape ??
|
widget.shape ??
|
||||||
ContinuousRectangleBorder(
|
ContinuousRectangleBorder(
|
||||||
side: attachmentBorderSide ??
|
side: widget.attachmentBorderSide ??
|
||||||
borderSide ??
|
widget.borderSide ??
|
||||||
BorderSide(
|
BorderSide(
|
||||||
color:
|
color:
|
||||||
Theme.of(context).brightness == Brightness.dark
|
Theme.of(context).brightness == Brightness.dark
|
||||||
? Colors.white.withAlpha(24)
|
? Colors.white.withAlpha(24)
|
||||||
: Colors.black.withAlpha(24),
|
: Colors.black.withAlpha(24),
|
||||||
),
|
),
|
||||||
borderRadius: attachmentBorderRadiusGeometry ??
|
borderRadius: widget.attachmentBorderRadiusGeometry ??
|
||||||
borderRadiusGeometry ??
|
widget.borderRadiusGeometry ??
|
||||||
BorderRadius.zero,
|
BorderRadius.zero,
|
||||||
),
|
),
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: attachmentPadding,
|
padding: widget.attachmentPadding,
|
||||||
child: Transform(
|
child: Transform(
|
||||||
transform: Matrix4.rotationY(reverse ? pi : 0),
|
transform: Matrix4.rotationY(widget.reverse ? pi : 0),
|
||||||
alignment: Alignment.center,
|
alignment: Alignment.center,
|
||||||
child: Column(
|
child: Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
crossAxisAlignment: CrossAxisAlignment.end,
|
crossAxisAlignment: CrossAxisAlignment.end,
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
getFailedMessageWidget(
|
getFailedMessageWidget(
|
||||||
@@ -484,7 +531,7 @@ class MessageWidget extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
attachmentBuilder(
|
attachmentBuilder(
|
||||||
context,
|
context,
|
||||||
message,
|
widget.message,
|
||||||
attachment,
|
attachment,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@@ -499,12 +546,13 @@ class MessageWidget extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void onLongPress(BuildContext context) {
|
void onLongPress(BuildContext context) {
|
||||||
if (message.isEphemeral || message.status == MessageSendingStatus.SENDING) {
|
if (widget.message.isEphemeral ||
|
||||||
|
widget.message.status == MessageSendingStatus.SENDING) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (onMessageActions != null) {
|
if (widget.onMessageActions != null) {
|
||||||
onMessageActions(context, message);
|
widget.onMessageActions(context, widget.message);
|
||||||
} else {
|
} else {
|
||||||
_showMessageBottomSheet(context);
|
_showMessageBottomSheet(context);
|
||||||
}
|
}
|
||||||
@@ -517,15 +565,15 @@ class MessageWidget extends StatelessWidget {
|
|||||||
left: leftPadding,
|
left: leftPadding,
|
||||||
),
|
),
|
||||||
child: Transform(
|
child: Transform(
|
||||||
transform: Matrix4.rotationY(reverse ? pi : 0),
|
transform: Matrix4.rotationY(widget.reverse ? pi : 0),
|
||||||
alignment: Alignment.center,
|
alignment: Alignment.center,
|
||||||
child: ReplyIndicator(
|
child: ReplyIndicator(
|
||||||
message: message,
|
message: widget.message,
|
||||||
reversed: reverse,
|
reversed: widget.reverse,
|
||||||
messageTheme: messageTheme,
|
messageTheme: widget.messageTheme,
|
||||||
onTap: onThreadTap != null
|
onTap: widget.onThreadTap != null
|
||||||
? () {
|
? () {
|
||||||
onThreadTap(message);
|
widget.onThreadTap(widget.message);
|
||||||
}
|
}
|
||||||
: null,
|
: null,
|
||||||
),
|
),
|
||||||
@@ -540,27 +588,27 @@ class MessageWidget extends StatelessWidget {
|
|||||||
4,
|
4,
|
||||||
),
|
),
|
||||||
child: Transform(
|
child: Transform(
|
||||||
transform: Matrix4.rotationY(reverse ? pi : 0),
|
transform: Matrix4.rotationY(widget.reverse ? pi : 0),
|
||||||
alignment: Alignment.center,
|
alignment: Alignment.center,
|
||||||
child: SendingIndicator(
|
child: SendingIndicator(
|
||||||
message: message,
|
message: widget.message,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildUserAvatar() => Transform(
|
Widget _buildUserAvatar() => Transform(
|
||||||
transform: Matrix4.rotationY(reverse ? pi : 0),
|
transform: Matrix4.rotationY(widget.reverse ? pi : 0),
|
||||||
alignment: Alignment.center,
|
alignment: Alignment.center,
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 4.0),
|
padding: const EdgeInsets.symmetric(horizontal: 4.0),
|
||||||
child: Transform.translate(
|
child: Transform.translate(
|
||||||
offset:
|
offset: Offset(
|
||||||
Offset(0, messageTheme.avatarTheme.constraints.maxHeight / 2),
|
0, widget.messageTheme.avatarTheme.constraints.maxHeight / 2),
|
||||||
child: UserAvatar(
|
child: UserAvatar(
|
||||||
user: message.user,
|
user: widget.message.user,
|
||||||
onTap: onUserAvatarTap,
|
onTap: widget.onUserAvatarTap,
|
||||||
constraints: messageTheme.avatarTheme.constraints,
|
constraints: widget.messageTheme.avatarTheme.constraints,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -570,31 +618,31 @@ class MessageWidget extends StatelessWidget {
|
|||||||
BuildContext context, {
|
BuildContext context, {
|
||||||
EdgeInsetsGeometry padding,
|
EdgeInsetsGeometry padding,
|
||||||
}) {
|
}) {
|
||||||
Widget widget;
|
Widget failedWidget;
|
||||||
if (message.status == MessageSendingStatus.FAILED)
|
if (widget.message.status == MessageSendingStatus.FAILED)
|
||||||
widget = Text(
|
failedWidget = Text(
|
||||||
'MESSAGE FAILED · CLICK TO TRY AGAIN',
|
'MESSAGE FAILED · CLICK TO TRY AGAIN',
|
||||||
style: messageTheme.messageText.copyWith(
|
style: widget.messageTheme.messageText.copyWith(
|
||||||
color: Theme.of(context).brightness == Brightness.dark
|
color: Theme.of(context).brightness == Brightness.dark
|
||||||
? Colors.white.withOpacity(.5)
|
? Colors.white.withOpacity(.5)
|
||||||
: Colors.black.withOpacity(.5),
|
: Colors.black.withOpacity(.5),
|
||||||
fontSize: 11,
|
fontSize: 11,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
if (message.status == MessageSendingStatus.FAILED_UPDATE)
|
if (widget.message.status == MessageSendingStatus.FAILED_UPDATE)
|
||||||
widget = Text(
|
failedWidget = Text(
|
||||||
'MESSAGE UPDATE FAILED · CLICK TO TRY AGAIN',
|
'MESSAGE UPDATE FAILED · CLICK TO TRY AGAIN',
|
||||||
style: messageTheme.messageText.copyWith(
|
style: widget.messageTheme.messageText.copyWith(
|
||||||
color: Theme.of(context).brightness == Brightness.dark
|
color: Theme.of(context).brightness == Brightness.dark
|
||||||
? Colors.white.withOpacity(.5)
|
? Colors.white.withOpacity(.5)
|
||||||
: Colors.black.withOpacity(.5),
|
: Colors.black.withOpacity(.5),
|
||||||
fontSize: 11,
|
fontSize: 11,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
if (message.status == MessageSendingStatus.FAILED_DELETE)
|
if (widget.message.status == MessageSendingStatus.FAILED_DELETE)
|
||||||
widget = Text(
|
failedWidget = Text(
|
||||||
'MESSAGE DELETE FAILED · CLICK TO TRY AGAIN',
|
'MESSAGE DELETE FAILED · CLICK TO TRY AGAIN',
|
||||||
style: messageTheme.messageText.copyWith(
|
style: widget.messageTheme.messageText.copyWith(
|
||||||
color: Theme.of(context).brightness == Brightness.dark
|
color: Theme.of(context).brightness == Brightness.dark
|
||||||
? Colors.white.withOpacity(.5)
|
? Colors.white.withOpacity(.5)
|
||||||
: Colors.black.withOpacity(.5),
|
: Colors.black.withOpacity(.5),
|
||||||
@@ -602,10 +650,10 @@ class MessageWidget extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
if (widget != null) {
|
if (failedWidget != null) {
|
||||||
return Padding(
|
return Padding(
|
||||||
padding: padding ?? EdgeInsets.zero,
|
padding: padding ?? EdgeInsets.zero,
|
||||||
child: widget,
|
child: failedWidget,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -617,22 +665,22 @@ class MessageWidget extends StatelessWidget {
|
|||||||
onTap: () => retryMessage(context),
|
onTap: () => retryMessage(context),
|
||||||
onLongPress: () => onLongPress(context),
|
onLongPress: () => onLongPress(context),
|
||||||
child: Material(
|
child: Material(
|
||||||
shape: shape ??
|
shape: widget.shape ??
|
||||||
ContinuousRectangleBorder(
|
ContinuousRectangleBorder(
|
||||||
side: borderSide ??
|
side: widget.borderSide ??
|
||||||
BorderSide(
|
BorderSide(
|
||||||
color: Theme.of(context).brightness == Brightness.dark
|
color: Theme.of(context).brightness == Brightness.dark
|
||||||
? Colors.white.withAlpha(24)
|
? Colors.white.withAlpha(24)
|
||||||
: Colors.black.withAlpha(24),
|
: Colors.black.withAlpha(24),
|
||||||
),
|
),
|
||||||
borderRadius: borderRadiusGeometry ?? BorderRadius.zero,
|
borderRadius: widget.borderRadiusGeometry ?? BorderRadius.zero,
|
||||||
),
|
),
|
||||||
color: _getBackgroundColor(),
|
color: _getBackgroundColor(),
|
||||||
child: Transform(
|
child: Transform(
|
||||||
transform: Matrix4.rotationY(reverse ? pi : 0),
|
transform: Matrix4.rotationY(widget.reverse ? pi : 0),
|
||||||
alignment: Alignment.center,
|
alignment: Alignment.center,
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: textPadding,
|
padding: widget.textPadding,
|
||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.end,
|
crossAxisAlignment: CrossAxisAlignment.end,
|
||||||
children: [
|
children: [
|
||||||
@@ -647,30 +695,30 @@ class MessageWidget extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Color _getBackgroundColor() {
|
Color _getBackgroundColor() {
|
||||||
return (message.status == MessageSendingStatus.FAILED ||
|
return (widget.message.status == MessageSendingStatus.FAILED ||
|
||||||
message.status == MessageSendingStatus.FAILED_UPDATE ||
|
widget.message.status == MessageSendingStatus.FAILED_UPDATE ||
|
||||||
message.status == MessageSendingStatus.FAILED_DELETE)
|
widget.message.status == MessageSendingStatus.FAILED_DELETE)
|
||||||
? Color(0xffd0021B).withOpacity(.1)
|
? Color(0xffd0021B).withOpacity(.1)
|
||||||
: messageTheme.messageBackgroundColor;
|
: widget.messageTheme.messageBackgroundColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
void retryMessage(BuildContext context) {
|
void retryMessage(BuildContext context) {
|
||||||
final channel = StreamChannel.of(context).channel;
|
final channel = StreamChannel.of(context).channel;
|
||||||
if (message.status == MessageSendingStatus.FAILED) {
|
if (widget.message.status == MessageSendingStatus.FAILED) {
|
||||||
channel.sendMessage(message);
|
channel.sendMessage(widget.message);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (message.status == MessageSendingStatus.FAILED_UPDATE) {
|
if (widget.message.status == MessageSendingStatus.FAILED_UPDATE) {
|
||||||
StreamChat.of(context).client.updateMessage(
|
StreamChat.of(context).client.updateMessage(
|
||||||
message,
|
widget.message,
|
||||||
channel.cid,
|
channel.cid,
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (message.status == MessageSendingStatus.FAILED_DELETE) {
|
if (widget.message.status == MessageSendingStatus.FAILED_DELETE) {
|
||||||
StreamChat.of(context).client.deleteMessage(
|
StreamChat.of(context).client.deleteMessage(
|
||||||
message,
|
widget.message,
|
||||||
channel.cid,
|
channel.cid,
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
@@ -678,12 +726,12 @@ class MessageWidget extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildText(BuildContext context) {
|
Widget _buildText(BuildContext context) {
|
||||||
return textBuilder != null
|
return widget.textBuilder != null
|
||||||
? textBuilder(context, message)
|
? widget.textBuilder(context, widget.message)
|
||||||
: MessageText(
|
: MessageText(
|
||||||
message: message,
|
message: widget.message,
|
||||||
onMentionTap: onMentionTap,
|
onMentionTap: widget.onMentionTap,
|
||||||
messageTheme: messageTheme,
|
messageTheme: widget.messageTheme,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user