add delete message
This commit is contained in:
@@ -40,6 +40,8 @@ class ChannelPreview extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Text _buildDate(BuildContext context, DateTime lastMessageAt) {
|
Text _buildDate(BuildContext context, DateTime lastMessageAt) {
|
||||||
|
lastMessageAt = lastMessageAt.toLocal();
|
||||||
|
|
||||||
String stringDate;
|
String stringDate;
|
||||||
final now = DateTime.now();
|
final now = DateTime.now();
|
||||||
|
|
||||||
|
|||||||
+194
-141
@@ -51,46 +51,70 @@ class _MessageWidgetState extends State<MessageWidget>
|
|||||||
final alignment =
|
final alignment =
|
||||||
isMyMessage ? Alignment.centerRight : Alignment.centerLeft;
|
isMyMessage ? Alignment.centerRight : Alignment.centerLeft;
|
||||||
|
|
||||||
var row = <Widget>[
|
Widget child;
|
||||||
Column(
|
|
||||||
crossAxisAlignment:
|
|
||||||
isMyMessage ? CrossAxisAlignment.end : CrossAxisAlignment.start,
|
|
||||||
children: <Widget>[
|
|
||||||
_buildBubble(context, isMyMessage, isLastUser),
|
|
||||||
_buildThreadIndicator(context),
|
|
||||||
isNextUser ? SizedBox() : _buildTimestamp(isMyMessage, alignment),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
isNextUser
|
|
||||||
? Container(
|
|
||||||
width: 40,
|
|
||||||
)
|
|
||||||
: Padding(
|
|
||||||
padding: EdgeInsets.only(
|
|
||||||
left: isMyMessage ? 8.0 : 0,
|
|
||||||
right: isMyMessage ? 0 : 8.0,
|
|
||||||
),
|
|
||||||
child: UserAvatar(user: widget.message.user),
|
|
||||||
),
|
|
||||||
];
|
|
||||||
|
|
||||||
if (!isMyMessage) {
|
if (widget.message.type == 'deleted') {
|
||||||
row = row.reversed.toList();
|
child = Align(
|
||||||
|
alignment: alignment,
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(
|
||||||
|
horizontal: 54,
|
||||||
|
vertical: 14,
|
||||||
|
),
|
||||||
|
child: Text(
|
||||||
|
'This message was deleted...',
|
||||||
|
style: TextStyle(fontStyle: FontStyle.italic),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
var row = <Widget>[
|
||||||
|
Column(
|
||||||
|
crossAxisAlignment:
|
||||||
|
isMyMessage ? CrossAxisAlignment.end : CrossAxisAlignment.start,
|
||||||
|
children: <Widget>[
|
||||||
|
_buildBubble(context, isMyMessage, isLastUser),
|
||||||
|
_buildThreadIndicator(context),
|
||||||
|
isNextUser ? SizedBox() : _buildTimestamp(isMyMessage, alignment),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
isNextUser
|
||||||
|
? Container(
|
||||||
|
width: 40,
|
||||||
|
)
|
||||||
|
: Padding(
|
||||||
|
padding: EdgeInsets.only(
|
||||||
|
left: isMyMessage ? 8.0 : 0,
|
||||||
|
right: isMyMessage ? 0 : 8.0,
|
||||||
|
),
|
||||||
|
child: UserAvatar(user: widget.message.user),
|
||||||
|
),
|
||||||
|
];
|
||||||
|
|
||||||
|
if (!isMyMessage) {
|
||||||
|
row = row.reversed.toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
child = AnimatedContainer(
|
||||||
|
duration: Duration(milliseconds: 300),
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 10.0),
|
||||||
|
margin: EdgeInsets.only(
|
||||||
|
top: isLastUser ? 5 : 24,
|
||||||
|
bottom: widget.nextMessage == null ? 30 : 0,
|
||||||
|
),
|
||||||
|
child: Row(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.end,
|
||||||
|
mainAxisAlignment:
|
||||||
|
isMyMessage ? MainAxisAlignment.end : MainAxisAlignment.start,
|
||||||
|
mainAxisSize: MainAxisSize.max,
|
||||||
|
children: row,
|
||||||
|
),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Container(
|
return AnimatedSwitcher(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 10.0),
|
duration: Duration(milliseconds: 300),
|
||||||
margin: EdgeInsets.only(
|
child: child,
|
||||||
top: isLastUser ? 5 : 24,
|
|
||||||
bottom: widget.nextMessage == null ? 30 : 0,
|
|
||||||
),
|
|
||||||
child: Row(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.end,
|
|
||||||
mainAxisAlignment:
|
|
||||||
isMyMessage ? MainAxisAlignment.end : MainAxisAlignment.start,
|
|
||||||
mainAxisSize: MainAxisSize.max,
|
|
||||||
children: row,
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -147,71 +171,75 @@ class _MessageWidgetState extends State<MessageWidget>
|
|||||||
if (attachmentWidget != null) {
|
if (attachmentWidget != null) {
|
||||||
final boxDecoration = _buildBoxDecoration(isMyMessage, isLastUser)
|
final boxDecoration = _buildBoxDecoration(isMyMessage, isLastUser)
|
||||||
.copyWith(color: Color(0xffebebeb));
|
.copyWith(color: Color(0xffebebeb));
|
||||||
return ClipRRect(
|
return Padding(
|
||||||
borderRadius: boxDecoration.borderRadius,
|
padding: const EdgeInsets.only(bottom: 2.0),
|
||||||
child: Container(
|
child: ClipRRect(
|
||||||
decoration: boxDecoration,
|
borderRadius: boxDecoration.borderRadius,
|
||||||
constraints: BoxConstraints.loose(Size.fromWidth(300)),
|
child: Container(
|
||||||
child: Stack(
|
decoration: boxDecoration,
|
||||||
children: <Widget>[
|
constraints: BoxConstraints.loose(Size.fromWidth(300)),
|
||||||
Column(
|
child: Stack(
|
||||||
mainAxisSize: MainAxisSize.min,
|
children: <Widget>[
|
||||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
Column(
|
||||||
children: <Widget>[
|
mainAxisSize: MainAxisSize.min,
|
||||||
attachmentWidget,
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||||
attachment.title != null
|
children: <Widget>[
|
||||||
? Container(
|
attachmentWidget,
|
||||||
constraints:
|
attachment.title != null
|
||||||
BoxConstraints.loose(Size.fromHeight(70)),
|
? Container(
|
||||||
child: Padding(
|
constraints:
|
||||||
padding: const EdgeInsets.all(8.0),
|
BoxConstraints.loose(Size.fromHeight(70)),
|
||||||
child: Column(
|
child: Padding(
|
||||||
mainAxisSize: MainAxisSize.min,
|
padding: const EdgeInsets.all(8.0),
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
child: Column(
|
||||||
children: <Widget>[
|
mainAxisSize: MainAxisSize.min,
|
||||||
Text(
|
crossAxisAlignment:
|
||||||
attachment.title,
|
CrossAxisAlignment.start,
|
||||||
overflow: TextOverflow.ellipsis,
|
children: <Widget>[
|
||||||
style: Theme.of(context)
|
Text(
|
||||||
.textTheme
|
attachment.title,
|
||||||
.subtitle
|
overflow: TextOverflow.ellipsis,
|
||||||
.copyWith(color: Colors.blue),
|
style: Theme.of(context)
|
||||||
),
|
.textTheme
|
||||||
Text(
|
.subtitle
|
||||||
Uri.parse(attachment.thumbUrl)
|
.copyWith(color: Colors.blue),
|
||||||
.authority
|
),
|
||||||
.split('.')
|
Text(
|
||||||
.reversed
|
Uri.parse(attachment.thumbUrl)
|
||||||
.take(2)
|
.authority
|
||||||
.toList()
|
.split('.')
|
||||||
.reversed
|
.reversed
|
||||||
.join('.'),
|
.take(2)
|
||||||
overflow: TextOverflow.ellipsis,
|
.toList()
|
||||||
style:
|
.reversed
|
||||||
Theme.of(context).textTheme.caption,
|
.join('.'),
|
||||||
),
|
overflow: TextOverflow.ellipsis,
|
||||||
],
|
style:
|
||||||
|
Theme.of(context).textTheme.caption,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
),
|
),
|
||||||
|
color: Color(0xffebebeb),
|
||||||
|
)
|
||||||
|
: Container(),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
attachment.type == 'image' && attachment.titleLink != null
|
||||||
|
? Positioned.fill(
|
||||||
|
child: Material(
|
||||||
|
color: Colors.transparent,
|
||||||
|
child: InkWell(
|
||||||
|
onTap: () => _launchURL(attachment.titleLink),
|
||||||
),
|
),
|
||||||
color: Color(0xffebebeb),
|
|
||||||
)
|
|
||||||
: Container(),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
attachment.type == 'image' && attachment.titleLink != null
|
|
||||||
? Positioned.fill(
|
|
||||||
child: Material(
|
|
||||||
color: Colors.transparent,
|
|
||||||
child: InkWell(
|
|
||||||
onTap: () => _launchURL(attachment.titleLink),
|
|
||||||
),
|
),
|
||||||
),
|
)
|
||||||
)
|
: SizedBox(),
|
||||||
: SizedBox(),
|
],
|
||||||
],
|
),
|
||||||
),
|
margin: EdgeInsets.only(
|
||||||
margin: EdgeInsets.only(
|
top: nOfAttachmentWidgets > 1 ? 5 : 0,
|
||||||
top: nOfAttachmentWidgets > 1 ? 5 : 0,
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
@@ -223,8 +251,6 @@ class _MessageWidgetState extends State<MessageWidget>
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (widget.message.text.trim().isNotEmpty) {
|
if (widget.message.text.trim().isNotEmpty) {
|
||||||
final topPadding =
|
|
||||||
widget.message.reactionCounts?.isNotEmpty == true ? 2.0 : 0.0;
|
|
||||||
column.children.addAll(
|
column.children.addAll(
|
||||||
<Widget>[
|
<Widget>[
|
||||||
IntrinsicWidth(
|
IntrinsicWidth(
|
||||||
@@ -246,7 +272,7 @@ class _MessageWidgetState extends State<MessageWidget>
|
|||||||
? Positioned(
|
? Positioned(
|
||||||
left: isMyMessage ? 8 : null,
|
left: isMyMessage ? 8 : null,
|
||||||
right: !isMyMessage ? 8 : null,
|
right: !isMyMessage ? 8 : null,
|
||||||
top: -4,
|
top: -6,
|
||||||
child: CustomPaint(
|
child: CustomPaint(
|
||||||
painter: ReactionBubblePainter(),
|
painter: ReactionBubblePainter(),
|
||||||
),
|
),
|
||||||
@@ -258,11 +284,6 @@ class _MessageWidgetState extends State<MessageWidget>
|
|||||||
left: isMyMessage ? 8.0 : 0.0,
|
left: isMyMessage ? 8.0 : 0.0,
|
||||||
),
|
),
|
||||||
child: Container(
|
child: Container(
|
||||||
margin: EdgeInsets.only(
|
|
||||||
top: nOfAttachmentWidgets > 0
|
|
||||||
? (topPadding)
|
|
||||||
: (topPadding),
|
|
||||||
),
|
|
||||||
decoration: _buildBoxDecoration(isMyMessage,
|
decoration: _buildBoxDecoration(isMyMessage,
|
||||||
isLastUser || nOfAttachmentWidgets > 0),
|
isLastUser || nOfAttachmentWidgets > 0),
|
||||||
padding: EdgeInsets.all(10),
|
padding: EdgeInsets.all(10),
|
||||||
@@ -289,11 +310,11 @@ class _MessageWidgetState extends State<MessageWidget>
|
|||||||
return GestureDetector(
|
return GestureDetector(
|
||||||
child: column,
|
child: column,
|
||||||
onLongPress: () {
|
onLongPress: () {
|
||||||
_showMessageBottomSheet(context);
|
_showMessageBottomSheet(context, isMyMessage);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void _showMessageBottomSheet(BuildContext context) {
|
void _showMessageBottomSheet(BuildContext context, bool isMyMessage) {
|
||||||
showModalBottomSheet(
|
showModalBottomSheet(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (context) {
|
builder: (context) {
|
||||||
@@ -301,38 +322,68 @@ class _MessageWidgetState extends State<MessageWidget>
|
|||||||
final textStyle = TextStyle(
|
final textStyle = TextStyle(
|
||||||
fontSize: fontSize,
|
fontSize: fontSize,
|
||||||
);
|
);
|
||||||
return Row(
|
return Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: reactionToEmoji.keys.map((reactionType) {
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||||
final ownReactionIndex = widget.message.ownReactions
|
children: <Widget>[
|
||||||
.indexWhere((reaction) => reaction.type == reactionType);
|
Row(
|
||||||
return Column(
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
mainAxisAlignment: MainAxisAlignment.start,
|
children: reactionToEmoji.keys.map((reactionType) {
|
||||||
children: <Widget>[
|
final ownReactionIndex = widget.message.ownReactions
|
||||||
IconButton(
|
.indexWhere((reaction) => reaction.type == reactionType);
|
||||||
iconSize: fontSize + 10,
|
return Column(
|
||||||
icon: Text(
|
mainAxisSize: MainAxisSize.min,
|
||||||
reactionToEmoji[reactionType],
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
style: textStyle,
|
children: <Widget>[
|
||||||
),
|
IconButton(
|
||||||
onPressed: () {
|
iconSize: fontSize + 10,
|
||||||
if (ownReactionIndex != -1) {
|
icon: Text(
|
||||||
removeReaction(reactionType);
|
reactionToEmoji[reactionType],
|
||||||
} else {
|
style: textStyle,
|
||||||
sendReaction(reactionType);
|
),
|
||||||
}
|
onPressed: () {
|
||||||
},
|
if (ownReactionIndex != -1) {
|
||||||
),
|
removeReaction(reactionType);
|
||||||
ownReactionIndex != -1
|
} else {
|
||||||
? Text(widget.message.ownReactions[ownReactionIndex].score
|
sendReaction(reactionType);
|
||||||
.toString())
|
}
|
||||||
: SizedBox(),
|
},
|
||||||
],
|
),
|
||||||
);
|
ownReactionIndex != -1
|
||||||
}).toList(),
|
? Padding(
|
||||||
|
padding: const EdgeInsets.only(bottom: 4.0),
|
||||||
|
child: Text(widget
|
||||||
|
.message.ownReactions[ownReactionIndex].score
|
||||||
|
.toString()),
|
||||||
|
)
|
||||||
|
: SizedBox(),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}).toList(),
|
||||||
|
),
|
||||||
|
isMyMessage
|
||||||
|
? FlatButton(
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.all(28.0),
|
||||||
|
child: Text(
|
||||||
|
'Delete message',
|
||||||
|
style: Theme.of(context)
|
||||||
|
.textTheme
|
||||||
|
.headline
|
||||||
|
.copyWith(color: Colors.red),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
onPressed: () {
|
||||||
|
StreamChat.of(context)
|
||||||
|
.client
|
||||||
|
.deleteMessage(widget.message.id);
|
||||||
|
Navigator.pop(context);
|
||||||
|
},
|
||||||
|
)
|
||||||
|
: SizedBox(),
|
||||||
|
],
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -340,10 +391,12 @@ class _MessageWidgetState extends State<MessageWidget>
|
|||||||
Widget _buildReactions(bool isMyMessage) {
|
Widget _buildReactions(bool isMyMessage) {
|
||||||
return GestureDetector(
|
return GestureDetector(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
_showMessageBottomSheet(context);
|
_showMessageBottomSheet(context, isMyMessage);
|
||||||
},
|
},
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.symmetric(vertical: 2.0),
|
padding: EdgeInsets.symmetric(
|
||||||
|
vertical:
|
||||||
|
widget.message.reactionCounts?.isNotEmpty == true ? 4.0 : 0),
|
||||||
child: AnimatedContainer(
|
child: AnimatedContainer(
|
||||||
duration: Duration(milliseconds: 300),
|
duration: Duration(milliseconds: 300),
|
||||||
curve: Curves.decelerate,
|
curve: Curves.decelerate,
|
||||||
|
|||||||
Reference in New Issue
Block a user