add offline attachment rendering
This commit is contained in:
@@ -573,6 +573,10 @@ class _MessageInputState extends State<MessageInput> {
|
|||||||
file = await FilePicker.getFile(type: type);
|
file = await FilePicker.getFile(type: type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (file == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
final channel = StreamChannel.of(context).channel;
|
final channel = StreamChannel.of(context).channel;
|
||||||
|
|
||||||
final bytes = await file.readAsBytes();
|
final bytes = await file.readAsBytes();
|
||||||
@@ -717,6 +721,7 @@ class _MessageInputState extends State<MessageInput> {
|
|||||||
imageUrl: attachment.type == FileType.IMAGE ? attachment.url : null,
|
imageUrl: attachment.type == FileType.IMAGE ? attachment.url : null,
|
||||||
assetUrl: attachment.url,
|
assetUrl: attachment.url,
|
||||||
type: type,
|
type: type,
|
||||||
|
localUri: attachment.file.uri,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
+107
-86
@@ -1,3 +1,4 @@
|
|||||||
|
import 'dart:io';
|
||||||
import 'dart:math';
|
import 'dart:math';
|
||||||
|
|
||||||
import 'package:cached_network_image/cached_network_image.dart';
|
import 'package:cached_network_image/cached_network_image.dart';
|
||||||
@@ -450,6 +451,32 @@ class _MessageWidgetState extends State<MessageWidget>
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Widget _buildSendingError(Widget child) {
|
||||||
|
return Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: <Widget>[
|
||||||
|
if (widget.message.status == MessageSendingStatus.FAILED)
|
||||||
|
Text(
|
||||||
|
'MESSAGE FAILED · CLICK TO TRY AGAIN',
|
||||||
|
style: _messageTheme.messageText.copyWith(
|
||||||
|
color: Colors.black.withOpacity(.5),
|
||||||
|
fontSize: 11,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
if (widget.message.status == MessageSendingStatus.FAILED_UPDATE)
|
||||||
|
Text(
|
||||||
|
'MESSAGE UPDATE FAILED · CLICK TO TRY AGAIN',
|
||||||
|
style: _messageTheme.messageText.copyWith(
|
||||||
|
color: Colors.black.withOpacity(.5),
|
||||||
|
fontSize: 11,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child,
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
Padding _buildMessageText(
|
Padding _buildMessageText(
|
||||||
int nOfAttachmentWidgets,
|
int nOfAttachmentWidgets,
|
||||||
String text,
|
String text,
|
||||||
@@ -465,62 +492,41 @@ class _MessageWidgetState extends State<MessageWidget>
|
|||||||
_buildBoxDecoration(_isLastUser || nOfAttachmentWidgets > 0),
|
_buildBoxDecoration(_isLastUser || nOfAttachmentWidgets > 0),
|
||||||
padding: EdgeInsets.all(10),
|
padding: EdgeInsets.all(10),
|
||||||
constraints: BoxConstraints.loose(Size.fromWidth(300)),
|
constraints: BoxConstraints.loose(Size.fromWidth(300)),
|
||||||
child: Column(
|
child: _buildSendingError(
|
||||||
mainAxisSize: MainAxisSize.min,
|
MarkdownBody(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
data: text,
|
||||||
children: <Widget>[
|
onTapLink: (link) {
|
||||||
if (widget.message.status == MessageSendingStatus.FAILED)
|
if (link.startsWith('@')) {
|
||||||
Text(
|
final mentionedUser = widget.message.mentionedUsers.firstWhere(
|
||||||
'MESSAGE FAILED · CLICK TO TRY AGAIN',
|
(u) => '@${u.name.replaceAll(' ', '')}' == link,
|
||||||
style: _messageTheme.messageText.copyWith(
|
orElse: () => null,
|
||||||
color: Colors.black.withOpacity(.5),
|
);
|
||||||
fontSize: 11,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
if (widget.message.status == MessageSendingStatus.FAILED_UPDATE)
|
|
||||||
Text(
|
|
||||||
'MESSAGE UPDATE FAILED · CLICK TO TRY AGAIN',
|
|
||||||
style: _messageTheme.messageText.copyWith(
|
|
||||||
color: Colors.black.withOpacity(.5),
|
|
||||||
fontSize: 11,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
MarkdownBody(
|
|
||||||
data: text,
|
|
||||||
onTapLink: (link) {
|
|
||||||
if (link.startsWith('@')) {
|
|
||||||
final mentionedUser =
|
|
||||||
widget.message.mentionedUsers.firstWhere(
|
|
||||||
(u) => '@${u.name.replaceAll(' ', '')}' == link,
|
|
||||||
orElse: () => null,
|
|
||||||
);
|
|
||||||
|
|
||||||
if (widget.onMentionTap != null) {
|
if (widget.onMentionTap != null) {
|
||||||
widget.onMentionTap(mentionedUser);
|
widget.onMentionTap(mentionedUser);
|
||||||
} else {
|
|
||||||
print('tap on ${mentionedUser.name}');
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
_launchURL(link);
|
print('tap on ${mentionedUser.name}');
|
||||||
}
|
}
|
||||||
},
|
} else {
|
||||||
styleSheet: MarkdownStyleSheet.fromTheme(
|
_launchURL(link);
|
||||||
Theme.of(context).copyWith(
|
}
|
||||||
textTheme: Theme.of(context).textTheme.apply(
|
},
|
||||||
bodyColor: _messageTheme.messageText.color,
|
styleSheet: MarkdownStyleSheet.fromTheme(
|
||||||
decoration: _messageTheme.messageText.decoration,
|
Theme.of(context).copyWith(
|
||||||
decorationColor:
|
textTheme: Theme.of(context).textTheme.apply(
|
||||||
_messageTheme.messageText.decorationColor,
|
bodyColor: _messageTheme.messageText.color,
|
||||||
decorationStyle:
|
decoration: _messageTheme.messageText.decoration,
|
||||||
_messageTheme.messageText.decorationStyle,
|
decorationColor:
|
||||||
fontFamily: _messageTheme.messageText.fontFamily,
|
_messageTheme.messageText.decorationColor,
|
||||||
),
|
decorationStyle:
|
||||||
),
|
_messageTheme.messageText.decorationStyle,
|
||||||
).copyWith(
|
fontFamily: _messageTheme.messageText.fontFamily,
|
||||||
p: _messageTheme.messageText,
|
),
|
||||||
),
|
),
|
||||||
|
).copyWith(
|
||||||
|
p: _messageTheme.messageText,
|
||||||
),
|
),
|
||||||
],
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
@@ -896,42 +902,54 @@ class _MessageWidgetState extends State<MessageWidget>
|
|||||||
Widget _buildImage(
|
Widget _buildImage(
|
||||||
Attachment attachment,
|
Attachment attachment,
|
||||||
) {
|
) {
|
||||||
return GestureDetector(
|
return Hero(
|
||||||
onTap: () {
|
tag: attachment.imageUrl ?? attachment.assetUrl ?? attachment.thumbUrl,
|
||||||
print(attachment.toJson());
|
child: CachedNetworkImage(
|
||||||
Navigator.push(context, MaterialPageRoute(builder: (_) {
|
imageBuilder: (context, provider) {
|
||||||
return FullScreenImage(
|
return GestureDetector(
|
||||||
url: attachment.imageUrl ??
|
child: Image(image: provider),
|
||||||
attachment.assetUrl ??
|
onTap: () {
|
||||||
attachment.thumbUrl,
|
print(attachment.toJson());
|
||||||
|
Navigator.push(context, MaterialPageRoute(builder: (_) {
|
||||||
|
return FullScreenImage(
|
||||||
|
url: attachment.imageUrl ??
|
||||||
|
attachment.assetUrl ??
|
||||||
|
attachment.thumbUrl,
|
||||||
|
);
|
||||||
|
}));
|
||||||
|
},
|
||||||
);
|
);
|
||||||
}));
|
},
|
||||||
},
|
placeholder: (_, __) {
|
||||||
child: Hero(
|
return Container(
|
||||||
tag: attachment.imageUrl ?? attachment.assetUrl ?? attachment.thumbUrl,
|
width: 200,
|
||||||
child: CachedNetworkImage(
|
height: 140,
|
||||||
placeholder: (_, __) {
|
);
|
||||||
return Container(
|
},
|
||||||
width: 200,
|
imageUrl:
|
||||||
height: 140,
|
attachment.thumbUrl ?? attachment.imageUrl ?? attachment.assetUrl,
|
||||||
);
|
errorWidget: (context, url, error) => _buildErrorImage(attachment),
|
||||||
},
|
fit: BoxFit.cover,
|
||||||
imageUrl:
|
),
|
||||||
attachment.thumbUrl ?? attachment.imageUrl ?? attachment.assetUrl,
|
);
|
||||||
errorWidget: (context, url, error) {
|
}
|
||||||
return Container(
|
|
||||||
width: 200,
|
Widget _buildErrorImage(Attachment attachment) {
|
||||||
height: 140,
|
if (attachment.localUri != null) {
|
||||||
color: Color(0xffd0021B).withAlpha(26),
|
return Image.file(
|
||||||
child: Center(
|
File(attachment.localUri.path),
|
||||||
child: Icon(
|
);
|
||||||
Icons.error_outline,
|
}
|
||||||
color: Colors.white,
|
return Center(
|
||||||
),
|
child: Container(
|
||||||
),
|
width: 200,
|
||||||
);
|
height: 140,
|
||||||
},
|
color: Color(0xffd0021B).withAlpha(26),
|
||||||
fit: BoxFit.cover,
|
child: Center(
|
||||||
|
child: Icon(
|
||||||
|
Icons.error_outline,
|
||||||
|
color: Colors.white,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
@@ -956,6 +974,9 @@ class _MessageWidgetState extends State<MessageWidget>
|
|||||||
videoPlayerController: videoController,
|
videoPlayerController: videoController,
|
||||||
autoInitialize: true,
|
autoInitialize: true,
|
||||||
errorBuilder: (_, e) {
|
errorBuilder: (_, e) {
|
||||||
|
if (attachment.thumbUrl == null) {
|
||||||
|
return _buildErrorImage(attachment);
|
||||||
|
}
|
||||||
return Stack(
|
return Stack(
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
Container(
|
Container(
|
||||||
|
|||||||
Reference in New Issue
Block a user