Merge pull request #221 from GetStream/hotfix/qa5.1

Hotfix/qa5.1
This commit is contained in:
Salvatore Giordano
2021-01-19 11:25:31 +01:00
committed by GitHub
6 changed files with 334 additions and 303 deletions
@@ -14,6 +14,8 @@ class ChannelBottomSheet extends StatefulWidget {
}
class _ChannelBottomSheetState extends State<ChannelBottomSheet> {
bool _showActions = true;
@override
Widget build(BuildContext context) {
var channel = StreamChannel.of(context).channel;
@@ -33,157 +35,177 @@ class _ChannelBottomSheetState extends State<ChannelBottomSheet> {
topRight: Radius.circular(16.0),
),
),
child: ListView(
shrinkWrap: true,
children: [
SizedBox(
height: 24.0,
),
Center(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 16.0),
child: ChannelName(
textStyle: StreamChatTheme.of(context).textTheme.headlineBold,
),
),
),
SizedBox(
height: 5.0,
),
Center(
child: ChannelInfo(
showTypingIndicator: false,
channel: StreamChannel.of(context).channel,
textStyle:
StreamChatTheme.of(context).channelPreviewTheme.subtitle,
),
),
SizedBox(
height: 17.0,
),
if (channel.isDistinct && channel.memberCount == 2)
Column(
child: !_showActions
? SizedBox()
: ListView(
shrinkWrap: true,
children: [
UserAvatar(
user: members
.firstWhere((e) => e.user.id != userAsMember.user.id)
.user,
constraints: BoxConstraints(
maxHeight: 64.0,
maxWidth: 64.0,
SizedBox(
height: 24.0,
),
Center(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 16.0),
child: ChannelName(
textStyle:
StreamChatTheme.of(context).textTheme.headlineBold,
),
),
borderRadius: BorderRadius.circular(32.0),
onlineIndicatorConstraints:
BoxConstraints.tight(Size(12.0, 12.0)),
),
SizedBox(
height: 6.0,
height: 5.0,
),
Text(
members
.firstWhere((e) => e.user.id != userAsMember.user.id)
.user
.name,
style: StreamChatTheme.of(context).textTheme.footnoteBold,
maxLines: 1,
overflow: TextOverflow.ellipsis,
Center(
child: ChannelInfo(
showTypingIndicator: false,
channel: StreamChannel.of(context).channel,
textStyle: StreamChatTheme.of(context)
.channelPreviewTheme
.subtitle,
),
),
SizedBox(
height: 17.0,
),
if (channel.isDistinct && channel.memberCount == 2)
Column(
children: [
UserAvatar(
user: members
.firstWhere(
(e) => e.user.id != userAsMember.user.id)
.user,
constraints: BoxConstraints(
maxHeight: 64.0,
maxWidth: 64.0,
),
borderRadius: BorderRadius.circular(32.0),
onlineIndicatorConstraints:
BoxConstraints.tight(Size(12.0, 12.0)),
),
SizedBox(
height: 6.0,
),
Text(
members
.firstWhere(
(e) => e.user.id != userAsMember.user.id)
.user
.name,
style:
StreamChatTheme.of(context).textTheme.footnoteBold,
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
],
),
if (!(channel.isDistinct && channel.memberCount == 2))
Container(
height: 94.0,
alignment: Alignment.center,
child: ListView.builder(
scrollDirection: Axis.horizontal,
itemCount: members.length,
shrinkWrap: true,
itemBuilder: (context, index) {
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 8.0),
child: Column(
children: [
UserAvatar(
user: members[index].user,
constraints: BoxConstraints(
maxHeight: 64.0,
maxWidth: 64.0,
),
borderRadius: BorderRadius.circular(32.0),
onlineIndicatorConstraints:
BoxConstraints.tight(Size(12.0, 12.0)),
),
SizedBox(
height: 6.0,
),
Text(
members[index].user.name,
style: StreamChatTheme.of(context)
.textTheme
.footnoteBold,
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
],
),
);
},
),
),
SizedBox(
height: 24.0,
),
OptionListTile(
leading: Padding(
padding: const EdgeInsets.symmetric(horizontal: 16.0),
child: StreamSvgIcon.user(
color: StreamChatTheme.of(context).colorTheme.grey,
),
),
title: 'View Info',
onTap: widget.onViewInfoTap,
),
if (!channel.isDistinct)
OptionListTile(
leading: Padding(
padding: const EdgeInsets.symmetric(horizontal: 16.0),
child: StreamSvgIcon.userRemove(
color: StreamChatTheme.of(context).colorTheme.grey,
),
),
title: 'Leave Group',
onTap: () async {
setState(() {
_showActions = false;
});
await _showLeaveDialog();
setState(() {
_showActions = true;
});
},
),
if (isOwner)
OptionListTile(
leading: Padding(
padding: const EdgeInsets.symmetric(horizontal: 16.0),
child: StreamSvgIcon.delete(
color: StreamChatTheme.of(context).colorTheme.accentRed,
),
),
title: 'Delete Conversation',
titleColor:
StreamChatTheme.of(context).colorTheme.accentRed,
onTap: () async {
setState(() {
_showActions = false;
});
await _showDeleteDialog();
setState(() {
_showActions = true;
});
},
),
OptionListTile(
leading: Padding(
padding: const EdgeInsets.symmetric(horizontal: 16.0),
child: StreamSvgIcon.close_small(
color: StreamChatTheme.of(context).colorTheme.grey,
),
),
title: 'Cancel',
onTap: () {
Navigator.pop(context);
},
),
],
),
if (!(channel.isDistinct && channel.memberCount == 2))
Container(
height: 94.0,
alignment: Alignment.center,
child: ListView.builder(
scrollDirection: Axis.horizontal,
itemCount: members.length,
shrinkWrap: true,
itemBuilder: (context, index) {
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 8.0),
child: Column(
children: [
UserAvatar(
user: members[index].user,
constraints: BoxConstraints(
maxHeight: 64.0,
maxWidth: 64.0,
),
borderRadius: BorderRadius.circular(32.0),
onlineIndicatorConstraints:
BoxConstraints.tight(Size(12.0, 12.0)),
),
SizedBox(
height: 6.0,
),
Text(
members[index].user.name,
style: StreamChatTheme.of(context)
.textTheme
.footnoteBold,
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
],
),
);
},
),
),
SizedBox(
height: 24.0,
),
OptionListTile(
leading: Padding(
padding: const EdgeInsets.symmetric(horizontal: 16.0),
child: StreamSvgIcon.user(
color: StreamChatTheme.of(context).colorTheme.grey,
),
),
title: 'View Info',
onTap: widget.onViewInfoTap,
),
if (!channel.isDistinct)
OptionListTile(
leading: Padding(
padding: const EdgeInsets.symmetric(horizontal: 16.0),
child: StreamSvgIcon.userRemove(
color: StreamChatTheme.of(context).colorTheme.grey,
),
),
title: 'Leave Group',
onTap: () async {
_showLeaveDialog();
},
),
if (isOwner)
OptionListTile(
leading: Padding(
padding: const EdgeInsets.symmetric(horizontal: 16.0),
child: StreamSvgIcon.delete(
color: StreamChatTheme.of(context).colorTheme.accentRed,
),
),
title: 'Delete Conversation',
titleColor: StreamChatTheme.of(context).colorTheme.accentRed,
onTap: () async {
_showDeleteDialog();
},
),
OptionListTile(
leading: Padding(
padding: const EdgeInsets.symmetric(horizontal: 16.0),
child: StreamSvgIcon.close_small(
color: StreamChatTheme.of(context).colorTheme.grey,
),
),
title: 'Cancel',
onTap: () {
Navigator.pop(context);
},
),
],
),
);
}
@@ -61,6 +61,8 @@ class MessageActionsModal extends StatefulWidget {
}
class _MessageActionsModalState extends State<MessageActionsModal> {
bool _showActions = true;
@override
Widget build(BuildContext context) {
return _showMessageOptionsModal();
@@ -87,160 +89,163 @@ class _MessageActionsModalState extends State<MessageActionsModal> {
? 1
: (roughSentenceSize == 0 ? 1 : (roughSentenceSize / roughMaxSize));
return TweenAnimationBuilder<double>(
tween: Tween(begin: 0.0, end: 1.0),
duration: Duration(milliseconds: 300),
curve: Curves.easeInOutBack,
builder: (context, val, snapshot) {
final hasFileAttachment =
widget.message.attachments?.any((it) => it.type == 'file') == true;
return GestureDetector(
behavior: HitTestBehavior.translucent,
onTap: () => Navigator.maybePop(context),
child: Stack(
children: [
Positioned.fill(
child: BackdropFilter(
filter: ImageFilter.blur(
sigmaX: 10,
sigmaY: 10,
),
child: Container(
color: StreamChatTheme.of(context).colorTheme.overlay,
),
),
final hasFileAttachment =
widget.message.attachments?.any((it) => it.type == 'file') == true;
return GestureDetector(
behavior: HitTestBehavior.translucent,
onTap: () => Navigator.maybePop(context),
child: Stack(
children: [
Positioned.fill(
child: BackdropFilter(
filter: ImageFilter.blur(
sigmaX: 10,
sigmaY: 10,
),
Transform.scale(
scale: val,
child: Center(
child: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
crossAxisAlignment: widget.reverse
? CrossAxisAlignment.end
: CrossAxisAlignment.start,
children: <Widget>[
if (widget.showReactions &&
(widget.message.status ==
MessageSendingStatus.SENT ||
widget.message.status == null))
Align(
alignment: Alignment(
user.id == widget.message.user.id
? (divFactor > 1.0
? 0.0
: (1.0 - divFactor))
: (divFactor > 1.0
? 0.0
: -(1.0 - divFactor)),
0.0),
child: ReactionPicker(
message: widget.message,
messageTheme: widget.messageTheme,
),
),
SizedBox(height: 8),
IgnorePointer(
child: MessageWidget(
key: Key('MessageWidget'),
reverse: widget.reverse,
message: widget.message.copyWith(
text: widget.message.text.length > 200
? '${widget.message.text.substring(0, 200)}...'
: widget.message.text,
),
messageTheme: widget.messageTheme,
showReactions: false,
showUsername: false,
showThreadReplyIndicator: false,
showReplyMessage: false,
showUserAvatar: widget.showUserAvatar,
attachmentPadding: EdgeInsets.all(
hasFileAttachment ? 4 : 2,
),
showTimestamp: false,
translateUserAvatar: false,
padding: const EdgeInsets.all(0),
textPadding: EdgeInsets.symmetric(
vertical: 8.0,
horizontal:
widget.message.text.isOnlyEmoji ? 0 : 16.0,
),
showReactionPickerIndicator:
widget.showReactions &&
(widget.message.status ==
MessageSendingStatus.SENT ||
widget.message.status == null),
showInChannelIndicator: false,
showSendingIndicator: false,
shape: widget.messageShape,
attachmentShape: widget.attachmentShape,
),
),
SizedBox(height: 8),
Padding(
padding: EdgeInsets.only(
left: widget.reverse ? 0 : 40,
),
child: SizedBox(
width: MediaQuery.of(context).size.width * 0.75,
child: Material(
color: StreamChatTheme.of(context)
.colorTheme
.whiteSnow,
clipBehavior: Clip.hardEdge,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16),
child: Container(
color: StreamChatTheme.of(context).colorTheme.overlay,
),
),
),
if (_showActions)
TweenAnimationBuilder<double>(
tween: Tween(begin: 0.0, end: 1.0),
duration: Duration(milliseconds: 300),
curve: Curves.easeInOutBack,
builder: (context, val, snapshot) {
return Transform.scale(
scale: val,
child: Center(
child: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
crossAxisAlignment: widget.reverse
? CrossAxisAlignment.end
: CrossAxisAlignment.start,
children: <Widget>[
if (widget.showReactions &&
(widget.message.status ==
MessageSendingStatus.SENT ||
widget.message.status == null))
Align(
alignment: Alignment(
user.id == widget.message.user.id
? (divFactor > 1.0
? 0.0
: (1.0 - divFactor))
: (divFactor > 1.0
? 0.0
: -(1.0 - divFactor)),
0.0),
child: ReactionPicker(
message: widget.message,
messageTheme: widget.messageTheme,
),
child: Column(
crossAxisAlignment:
CrossAxisAlignment.stretch,
children: [
if (widget.showReplyMessage &&
),
SizedBox(height: 8),
IgnorePointer(
child: MessageWidget(
key: Key('MessageWidget'),
reverse: widget.reverse,
message: widget.message.copyWith(
text: widget.message.text.length > 200
? '${widget.message.text.substring(0, 200)}...'
: widget.message.text,
),
messageTheme: widget.messageTheme,
showReactions: false,
showUsername: false,
showThreadReplyIndicator: false,
showReplyMessage: false,
showUserAvatar: widget.showUserAvatar,
attachmentPadding: EdgeInsets.all(
hasFileAttachment ? 4 : 2,
),
showTimestamp: false,
translateUserAvatar: false,
padding: const EdgeInsets.all(0),
textPadding: EdgeInsets.symmetric(
vertical: 8.0,
horizontal: widget.message.text.isOnlyEmoji
? 0
: 16.0,
),
showReactionPickerIndicator:
widget.showReactions &&
(widget.message.status ==
MessageSendingStatus.SENT ||
widget.message.status == null) &&
widget.message.parentId == null)
_buildReplyButton(context),
if (widget.showThreadReplyMessage &&
(widget.message.status ==
MessageSendingStatus.SENT ||
widget.message.status == null) &&
widget.message.parentId == null)
_buildThreadReplyButton(context),
if (widget.showResendMessage)
_buildResendMessage(context),
if (widget.showEditMessage)
_buildEditMessage(context),
if (widget.showCopyMessage)
_buildCopyButton(context),
if (widget.showFlagButton)
_buildFlagButton(context),
if (widget.showDeleteMessage)
_buildDeleteButton(context),
].insertBetween(
Container(
height: 1,
color: StreamChatTheme.of(context)
.colorTheme
.greyWhisper,
widget.message.status == null),
showInChannelIndicator: false,
showSendingIndicator: false,
shape: widget.messageShape,
attachmentShape: widget.attachmentShape,
),
),
SizedBox(height: 8),
Padding(
padding: EdgeInsets.only(
left: widget.reverse ? 0 : 40,
),
child: SizedBox(
width: MediaQuery.of(context).size.width * 0.75,
child: Material(
color: StreamChatTheme.of(context)
.colorTheme
.whiteSnow,
clipBehavior: Clip.hardEdge,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16),
),
child: Column(
crossAxisAlignment:
CrossAxisAlignment.stretch,
children: [
if (widget.showReplyMessage &&
(widget.message.status ==
MessageSendingStatus.SENT ||
widget.message.status == null) &&
widget.message.parentId == null)
_buildReplyButton(context),
if (widget.showThreadReplyMessage &&
(widget.message.status ==
MessageSendingStatus.SENT ||
widget.message.status == null) &&
widget.message.parentId == null)
_buildThreadReplyButton(context),
if (widget.showResendMessage)
_buildResendMessage(context),
if (widget.showEditMessage)
_buildEditMessage(context),
if (widget.showCopyMessage)
_buildCopyButton(context),
if (widget.showFlagButton)
_buildFlagButton(context),
if (widget.showDeleteMessage)
_buildDeleteButton(context),
].insertBetween(
Container(
height: 1,
color: StreamChatTheme.of(context)
.colorTheme
.greyWhisper,
),
),
),
),
),
),
),
],
],
),
),
),
),
),
),
],
),
);
},
);
},
),
],
),
);
}
@@ -273,6 +278,9 @@ class _MessageActionsModalState extends State<MessageActionsModal> {
}
void _showDeleteDialog() async {
setState(() {
_showActions = false;
});
var answer = await showConfirmationDialog(context,
title: 'Delete message',
icon: StreamSvgIcon.flag(
@@ -293,6 +301,10 @@ class _MessageActionsModalState extends State<MessageActionsModal> {
} catch (err) {
_showErrorAlert();
}
} else {
setState(() {
_showActions = true;
});
}
}
@@ -1026,7 +1026,11 @@ class MessageInputState extends State<MessageInput> {
setState(() {
_attachments.add(attachment);
});
final mediaFile = await medium.originFile;
final mediaFile = await medium.originFile.timeout(
Duration(seconds: 5),
onTimeout: () => medium.originFile,
);
var file = PlatformFile(
path: mediaFile.path,
@@ -813,9 +813,7 @@ class _MessageListViewState extends State<MessageListView> {
final readList = channel.state?.read?.where((read) {
if (read.user.id == userId) return false;
return (read.lastRead.isAfter(message.createdAt) ||
read.lastRead.isAtSameMomentAs(message.createdAt)) &&
(index == 0 ||
read.lastRead.isBefore(messages[index - 1].createdAt));
read.lastRead.isAtSameMomentAs(message.createdAt));
})?.toList() ??
[];
@@ -381,12 +381,14 @@ class _MessageWidgetState extends State<MessageWidget> {
clipBehavior: Clip.antiAlias,
elevation: 0.0,
margin: EdgeInsets.symmetric(
horizontal:
widget.showUserAvatar ==
horizontal: (isFailedState
? 15.0
: 0.0) +
(widget.showUserAvatar ==
DisplayWidget
.gone
? 0
: 4.0,
: 4.0),
),
shape: widget.shape ??
RoundedRectangleBorder(
@@ -453,16 +455,10 @@ class _MessageWidgetState extends State<MessageWidget> {
),
if (isFailedState)
Positioned(
left: widget.reverse ? -3 : null,
right: widget.reverse ? null : -9,
bottom: showBottomRow ? 20 : 0,
child: Container(
decoration: BoxDecoration(
color: Colors.white,
shape: BoxShape.circle,
),
child: StreamSvgIcon.error(size: 20),
),
left: widget.reverse ? 0 : null,
right: widget.reverse ? null : 0,
bottom: showBottomRow ? 18 : -2,
child: StreamSvgIcon.error(size: 20),
),
],
),
@@ -80,7 +80,6 @@ class StreamChatState extends State<StreamChat> with WidgetsBindingObserver {
primaryIconTheme: streamTheme.primaryIconTheme,
accentColor: streamTheme.colorTheme.accentBlue,
scaffoldBackgroundColor: streamTheme.colorTheme.white,
buttonTheme: streamTheme.buttonTheme,
),
child: widget.child,
);