migrate ui
This commit is contained in:
@@ -6,12 +6,12 @@ import '../utils.dart';
|
||||
|
||||
class AttachmentTitle extends StatelessWidget {
|
||||
const AttachmentTitle({
|
||||
Key key,
|
||||
@required this.attachment,
|
||||
@required this.messageTheme,
|
||||
Key? key,
|
||||
required this.attachment,
|
||||
required this.messageTheme,
|
||||
}) : super(key: key);
|
||||
|
||||
final MessageTheme messageTheme;
|
||||
final MessageTheme? messageTheme;
|
||||
final Attachment attachment;
|
||||
|
||||
@override
|
||||
@@ -19,7 +19,7 @@ class AttachmentTitle extends StatelessWidget {
|
||||
return GestureDetector(
|
||||
onTap: () {
|
||||
if (attachment.titleLink != null) {
|
||||
launchURL(context, attachment.titleLink);
|
||||
launchURL(context, attachment.titleLink!);
|
||||
}
|
||||
},
|
||||
child: Padding(
|
||||
@@ -28,17 +28,18 @@ class AttachmentTitle extends StatelessWidget {
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: <Widget>[
|
||||
Text(
|
||||
attachment.title,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: messageTheme.messageText.copyWith(
|
||||
color: StreamChatTheme.of(context).colorTheme.accentBlue,
|
||||
fontWeight: FontWeight.bold,
|
||||
if (attachment.title != null)
|
||||
Text(
|
||||
attachment.title!,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: messageTheme?.messageText?.copyWith(
|
||||
color: StreamChatTheme.of(context).colorTheme.accentBlue,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
),
|
||||
if (attachment.titleLink != null || attachment.ogScrapeUrl != null)
|
||||
Text(
|
||||
Uri.parse(attachment.titleLink ?? attachment.ogScrapeUrl)
|
||||
Uri.parse(attachment.titleLink ?? attachment.ogScrapeUrl!)
|
||||
.authority
|
||||
.split('.')
|
||||
.reversed
|
||||
@@ -46,7 +47,7 @@ class AttachmentTitle extends StatelessWidget {
|
||||
.toList()
|
||||
.reversed
|
||||
.join('.'),
|
||||
style: messageTheme.messageText,
|
||||
style: messageTheme?.messageText,
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
+50
-48
@@ -8,55 +8,52 @@ typedef FailedBuilder = Widget Function(BuildContext, String);
|
||||
class AttachmentUploadStateBuilder extends StatelessWidget {
|
||||
final Message message;
|
||||
final Attachment attachment;
|
||||
final FailedBuilder failedBuilder;
|
||||
final WidgetBuilder successBuilder;
|
||||
final InProgressBuilder inProgressBuilder;
|
||||
final WidgetBuilder preparingBuilder;
|
||||
final FailedBuilder? failedBuilder;
|
||||
final WidgetBuilder? successBuilder;
|
||||
final InProgressBuilder? inProgressBuilder;
|
||||
final WidgetBuilder? preparingBuilder;
|
||||
|
||||
const AttachmentUploadStateBuilder({
|
||||
Key key,
|
||||
@required this.message,
|
||||
@required this.attachment,
|
||||
Key? key,
|
||||
required this.message,
|
||||
required this.attachment,
|
||||
this.failedBuilder,
|
||||
this.successBuilder,
|
||||
this.inProgressBuilder,
|
||||
this.preparingBuilder,
|
||||
}) : assert(message != null),
|
||||
assert(attachment != null),
|
||||
super(key: key);
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
if (message.status == null || message.status == MessageSendingStatus.sent) {
|
||||
if (message.status == MessageSendingStatus.sent) {
|
||||
return Offstage();
|
||||
}
|
||||
|
||||
final messageId = message.id;
|
||||
final attachmentId = attachment.id;
|
||||
|
||||
var inProgress = inProgressBuilder;
|
||||
inProgress ??= (context, int sent, int total) {
|
||||
return _InProgressState(
|
||||
sent: sent,
|
||||
total: total,
|
||||
attachmentId: attachmentId,
|
||||
);
|
||||
};
|
||||
final inProgress = inProgressBuilder ??
|
||||
(context, int sent, int total) {
|
||||
return _InProgressState(
|
||||
sent: sent,
|
||||
total: total,
|
||||
attachmentId: attachmentId,
|
||||
);
|
||||
};
|
||||
|
||||
var failed = failedBuilder;
|
||||
failed ??= (context, error) {
|
||||
return _FailedState(
|
||||
error: error,
|
||||
messageId: messageId,
|
||||
attachmentId: attachmentId,
|
||||
);
|
||||
};
|
||||
final failed = failedBuilder ??
|
||||
(context, error) {
|
||||
return _FailedState(
|
||||
error: error,
|
||||
messageId: messageId,
|
||||
attachmentId: attachmentId,
|
||||
);
|
||||
};
|
||||
|
||||
var success = successBuilder;
|
||||
success ??= (context) => _SuccessState();
|
||||
final success = successBuilder ?? (context) => _SuccessState();
|
||||
|
||||
var preparing = preparingBuilder;
|
||||
preparing ??= (context) => _PreparingState(attachmentId: attachmentId);
|
||||
final preparing = preparingBuilder ??
|
||||
(context) => _PreparingState(attachmentId: attachmentId);
|
||||
|
||||
return attachment.uploadState.when(
|
||||
preparing: () => preparing(context),
|
||||
@@ -68,13 +65,13 @@ class AttachmentUploadStateBuilder extends StatelessWidget {
|
||||
}
|
||||
|
||||
class _IconButton extends StatelessWidget {
|
||||
final Widget icon;
|
||||
final Widget? icon;
|
||||
final double iconSize;
|
||||
final VoidCallback onPressed;
|
||||
final Color fillColor;
|
||||
final VoidCallback? onPressed;
|
||||
final Color? fillColor;
|
||||
|
||||
const _IconButton({
|
||||
Key key,
|
||||
Key? key,
|
||||
this.icon,
|
||||
this.iconSize = 24.0,
|
||||
this.onPressed,
|
||||
@@ -95,7 +92,9 @@ class _IconButton extends StatelessWidget {
|
||||
onPressed: onPressed,
|
||||
fillColor:
|
||||
fillColor ?? StreamChatTheme.of(context).colorTheme.overlayDark,
|
||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(16)),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
),
|
||||
child: icon,
|
||||
),
|
||||
);
|
||||
@@ -106,8 +105,8 @@ class _PreparingState extends StatelessWidget {
|
||||
final String attachmentId;
|
||||
|
||||
const _PreparingState({
|
||||
Key key,
|
||||
@required this.attachmentId,
|
||||
Key? key,
|
||||
required this.attachmentId,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
@@ -144,10 +143,10 @@ class _InProgressState extends StatelessWidget {
|
||||
final String attachmentId;
|
||||
|
||||
const _InProgressState({
|
||||
Key key,
|
||||
@required this.sent,
|
||||
@required this.total,
|
||||
@required this.attachmentId,
|
||||
Key? key,
|
||||
required this.sent,
|
||||
required this.total,
|
||||
required this.attachmentId,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
@@ -179,15 +178,15 @@ class _InProgressState extends StatelessWidget {
|
||||
}
|
||||
|
||||
class _FailedState extends StatelessWidget {
|
||||
final String error;
|
||||
final String? error;
|
||||
final String messageId;
|
||||
final String attachmentId;
|
||||
|
||||
const _FailedState({
|
||||
Key key,
|
||||
Key? key,
|
||||
this.error,
|
||||
@required this.messageId,
|
||||
@required this.attachmentId,
|
||||
required this.messageId,
|
||||
required this.attachmentId,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
@@ -203,7 +202,7 @@ class _FailedState extends StatelessWidget {
|
||||
color: theme.colorTheme.white,
|
||||
),
|
||||
onPressed: () {
|
||||
return channel.retryAttachmentUpload(messageId, attachmentId);
|
||||
channel.retryAttachmentUpload(messageId, attachmentId);
|
||||
},
|
||||
),
|
||||
Center(
|
||||
@@ -213,7 +212,10 @@ class _FailedState extends StatelessWidget {
|
||||
color: theme.colorTheme.overlayDark.withOpacity(0.6),
|
||||
),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 6, horizontal: 12),
|
||||
padding: const EdgeInsets.symmetric(
|
||||
vertical: 6,
|
||||
horizontal: 12,
|
||||
),
|
||||
child: Text(
|
||||
'UPLOAD ERROR',
|
||||
style: theme.textTheme.footnote.copyWith(
|
||||
|
||||
@@ -13,15 +13,9 @@ extension AttachmentSourceX on AttachmentSource {
|
||||
/// Its prototype depends on the AttachmentSource defined.
|
||||
// ignore: missing_return
|
||||
T when<T>({
|
||||
@required T Function() local,
|
||||
@required T Function() network,
|
||||
required T Function() local,
|
||||
required T Function() network,
|
||||
}) {
|
||||
assert(() {
|
||||
if (local == null || network == null) {
|
||||
throw 'check for all possible cases';
|
||||
}
|
||||
return true;
|
||||
}());
|
||||
switch (this) {
|
||||
case AttachmentSource.local:
|
||||
return local();
|
||||
@@ -32,30 +26,32 @@ extension AttachmentSourceX on AttachmentSource {
|
||||
}
|
||||
|
||||
abstract class AttachmentWidget extends StatelessWidget {
|
||||
final Size size;
|
||||
final Size? size;
|
||||
final AttachmentSource? _source;
|
||||
final Message message;
|
||||
final Attachment attachment;
|
||||
final AttachmentSource _source;
|
||||
|
||||
AttachmentSource get source => _source ?? attachment.file != null
|
||||
? AttachmentSource.local
|
||||
: AttachmentSource.network;
|
||||
AttachmentSource get source =>
|
||||
_source ??
|
||||
(attachment.file != null
|
||||
? AttachmentSource.local
|
||||
: AttachmentSource.network);
|
||||
|
||||
const AttachmentWidget({
|
||||
Key key,
|
||||
@required this.message,
|
||||
@required this.attachment,
|
||||
Key? key,
|
||||
required this.message,
|
||||
required this.attachment,
|
||||
this.size,
|
||||
AttachmentSource source,
|
||||
AttachmentSource? source,
|
||||
}) : _source = source,
|
||||
super(key: key);
|
||||
}
|
||||
|
||||
class AttachmentError extends StatelessWidget {
|
||||
final Size size;
|
||||
final Size? size;
|
||||
|
||||
const AttachmentError({
|
||||
Key key,
|
||||
Key? key,
|
||||
this.size,
|
||||
}) : super(key: key);
|
||||
|
||||
|
||||
@@ -11,19 +11,24 @@ import '../upload_progress_indicator.dart';
|
||||
import 'attachment_widget.dart';
|
||||
|
||||
class FileAttachment extends AttachmentWidget {
|
||||
final Widget title;
|
||||
final Widget trailing;
|
||||
final VoidCallback onAttachmentTap;
|
||||
final Widget? title;
|
||||
final Widget? trailing;
|
||||
final VoidCallback? onAttachmentTap;
|
||||
|
||||
const FileAttachment({
|
||||
Key key,
|
||||
@required Message message,
|
||||
@required Attachment attachment,
|
||||
Size size,
|
||||
Key? key,
|
||||
required Message message,
|
||||
required Attachment attachment,
|
||||
Size? size,
|
||||
this.title,
|
||||
this.trailing,
|
||||
this.onAttachmentTap,
|
||||
}) : super(key: key, message: message, attachment: attachment, size: size);
|
||||
}) : super(
|
||||
key: key,
|
||||
message: message,
|
||||
attachment: attachment,
|
||||
size: size,
|
||||
);
|
||||
|
||||
bool get isVideoAttachment => attachment.title?.mimeType?.type == 'video';
|
||||
|
||||
@@ -31,6 +36,7 @@ class FileAttachment extends AttachmentWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final colorTheme = StreamChatTheme.of(context).colorTheme;
|
||||
return Material(
|
||||
child: GestureDetector(
|
||||
onTap: onAttachmentTap,
|
||||
@@ -38,10 +44,10 @@ class FileAttachment extends AttachmentWidget {
|
||||
width: size?.width ?? 100,
|
||||
height: 56.0,
|
||||
decoration: BoxDecoration(
|
||||
color: StreamChatTheme.of(context).colorTheme.white,
|
||||
color: colorTheme.white,
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
border: Border.all(
|
||||
color: StreamChatTheme.of(context).colorTheme.greyWhisper,
|
||||
color: colorTheme.greyWhisper,
|
||||
),
|
||||
),
|
||||
child: Row(
|
||||
@@ -60,7 +66,7 @@ class FileAttachment extends AttachmentWidget {
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
attachment?.title ?? 'File',
|
||||
attachment.title ?? 'File',
|
||||
style: StreamChatTheme.of(context).textTheme.bodyBold,
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
@@ -93,34 +99,51 @@ class FileAttachment extends AttachmentWidget {
|
||||
type: MaterialType.transparency,
|
||||
shape: _getDefaultShape(context),
|
||||
child: source.when(
|
||||
local: () => Image.memory(
|
||||
attachment.file.bytes,
|
||||
fit: BoxFit.cover,
|
||||
errorBuilder: (_, obj, trace) {
|
||||
return getFileTypeImage(attachment.extraData['other']);
|
||||
},
|
||||
),
|
||||
network: () => CachedNetworkImage(
|
||||
imageUrl: attachment.imageUrl ??
|
||||
attachment.assetUrl ??
|
||||
attachment.thumbUrl,
|
||||
fit: BoxFit.cover,
|
||||
errorWidget: (_, obj, trace) {
|
||||
return getFileTypeImage(attachment.extraData['other']);
|
||||
},
|
||||
placeholder: (_, __) {
|
||||
return Shimmer.fromColors(
|
||||
baseColor: StreamChatTheme.of(context).colorTheme.greyGainsboro,
|
||||
highlightColor:
|
||||
StreamChatTheme.of(context).colorTheme.whiteSmoke,
|
||||
child: Image.asset(
|
||||
local: () {
|
||||
if (attachment.file?.bytes == null) {
|
||||
return getFileTypeImage(attachment.extraData['other'] as String?);
|
||||
}
|
||||
return Image.memory(
|
||||
attachment.file!.bytes!,
|
||||
fit: BoxFit.cover,
|
||||
errorBuilder: (_, obj, trace) {
|
||||
return getFileTypeImage(
|
||||
attachment.extraData['other'] as String?);
|
||||
},
|
||||
);
|
||||
},
|
||||
network: () {
|
||||
if ((attachment.imageUrl ??
|
||||
attachment.assetUrl ??
|
||||
attachment.thumbUrl) ==
|
||||
null) {
|
||||
return getFileTypeImage(attachment.extraData['other'] as String?);
|
||||
}
|
||||
return CachedNetworkImage(
|
||||
imageUrl: attachment.imageUrl ??
|
||||
attachment.assetUrl ??
|
||||
attachment.thumbUrl!,
|
||||
fit: BoxFit.cover,
|
||||
errorWidget: (_, obj, trace) {
|
||||
return getFileTypeImage(
|
||||
attachment.extraData['other'] as String?);
|
||||
},
|
||||
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,
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
@@ -132,7 +155,7 @@ class FileAttachment extends AttachmentWidget {
|
||||
shape: _getDefaultShape(context),
|
||||
child: source.when(
|
||||
local: () => VideoThumbnailImage(
|
||||
video: attachment.file.path,
|
||||
video: attachment.file?.path,
|
||||
placeholderBuilder: (_) {
|
||||
return Center(
|
||||
child: Container(
|
||||
@@ -158,14 +181,14 @@ class FileAttachment extends AttachmentWidget {
|
||||
),
|
||||
);
|
||||
}
|
||||
return getFileTypeImage(attachment.extraData['mime_type']);
|
||||
return getFileTypeImage(attachment.extraData['mime_type'] as String?);
|
||||
}
|
||||
|
||||
Widget _buildButton({
|
||||
Widget icon,
|
||||
Widget? icon,
|
||||
double iconSize = 24.0,
|
||||
VoidCallback onPressed,
|
||||
Color fillColor,
|
||||
VoidCallback? onPressed,
|
||||
Color? fillColor,
|
||||
}) {
|
||||
return Container(
|
||||
height: iconSize,
|
||||
@@ -189,7 +212,7 @@ class FileAttachment extends AttachmentWidget {
|
||||
final channel = StreamChannel.of(context).channel;
|
||||
final attachmentId = attachment.id;
|
||||
var trailingWidget = trailing;
|
||||
trailingWidget ??= attachment.uploadState?.when(
|
||||
trailingWidget ??= attachment.uploadState.when(
|
||||
preparing: () => Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: _buildButton(
|
||||
@@ -220,7 +243,7 @@ class FileAttachment extends AttachmentWidget {
|
||||
icon: StreamSvgIcon.retry(color: theme.colorTheme.white),
|
||||
fillColor: theme.colorTheme.overlayDark,
|
||||
onPressed: () => channel.retryAttachmentUpload(
|
||||
message?.id,
|
||||
message.id,
|
||||
attachmentId,
|
||||
),
|
||||
),
|
||||
@@ -236,9 +259,7 @@ class FileAttachment extends AttachmentWidget {
|
||||
},
|
||||
);
|
||||
|
||||
if (message != null &&
|
||||
(message.status == null ||
|
||||
message.status == MessageSendingStatus.sent)) {
|
||||
if (message.status == MessageSendingStatus.sent) {
|
||||
trailingWidget = IconButton(
|
||||
icon: StreamSvgIcon.cloudDownload(color: theme.colorTheme.black),
|
||||
padding: const EdgeInsets.all(8),
|
||||
@@ -262,11 +283,8 @@ class FileAttachment extends AttachmentWidget {
|
||||
final textStyle = theme.textTheme.footnote.copyWith(
|
||||
color: theme.colorTheme.grey,
|
||||
);
|
||||
return attachment.uploadState?.when(
|
||||
return attachment.uploadState.when(
|
||||
preparing: () {
|
||||
if (message == null) {
|
||||
return Text('${fileSize(size, 2)}', style: textStyle);
|
||||
}
|
||||
return UploadProgressIndicator(
|
||||
uploaded: 0,
|
||||
total: double.maxFinite.toInt(),
|
||||
|
||||
@@ -9,17 +9,15 @@ import '../stream_svg_icon.dart';
|
||||
import 'attachment_widget.dart';
|
||||
|
||||
class GiphyAttachment extends AttachmentWidget {
|
||||
final MessageTheme messageTheme;
|
||||
final ShowMessageCallback onShowMessage;
|
||||
final ValueChanged<ReturnActionType> onReturnAction;
|
||||
final VoidCallback onAttachmentTap;
|
||||
final ShowMessageCallback? onShowMessage;
|
||||
final ValueChanged<ReturnActionType>? onReturnAction;
|
||||
final VoidCallback? onAttachmentTap;
|
||||
|
||||
const GiphyAttachment({
|
||||
Key key,
|
||||
@required Message message,
|
||||
@required Attachment attachment,
|
||||
Size size,
|
||||
this.messageTheme,
|
||||
Key? key,
|
||||
required Message message,
|
||||
required Attachment attachment,
|
||||
Size? size,
|
||||
this.onShowMessage,
|
||||
this.onReturnAction,
|
||||
this.onAttachmentTap,
|
||||
@@ -29,10 +27,10 @@ class GiphyAttachment extends AttachmentWidget {
|
||||
Widget build(BuildContext context) {
|
||||
final imageUrl =
|
||||
attachment.thumbUrl ?? attachment.imageUrl ?? attachment.assetUrl;
|
||||
if (imageUrl == null && source == AttachmentSource.network) {
|
||||
if (imageUrl == null) {
|
||||
return AttachmentError();
|
||||
}
|
||||
if (attachment.actions != null) {
|
||||
if (attachment.actions.isNotEmpty) {
|
||||
return _buildSendingAttachment(context, imageUrl);
|
||||
}
|
||||
return _buildSentAttachment(context, imageUrl);
|
||||
@@ -73,7 +71,7 @@ class GiphyAttachment extends AttachmentWidget {
|
||||
if (attachment.title != null)
|
||||
Flexible(
|
||||
child: Text(
|
||||
attachment.title,
|
||||
attachment.title!,
|
||||
style: TextStyle(
|
||||
color: StreamChatTheme.of(context)
|
||||
.colorTheme
|
||||
@@ -199,10 +197,11 @@ class GiphyAttachment extends AttachmentWidget {
|
||||
child: Text(
|
||||
'Send',
|
||||
style: TextStyle(
|
||||
color: StreamChatTheme.of(context)
|
||||
.colorTheme
|
||||
.accentBlue,
|
||||
fontWeight: FontWeight.bold),
|
||||
color: StreamChatTheme.of(context)
|
||||
.colorTheme
|
||||
.accentBlue,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -259,8 +258,7 @@ class GiphyAttachment extends AttachmentWidget {
|
||||
channel: channel,
|
||||
child: FullScreenMedia(
|
||||
mediaAttachments: [attachment],
|
||||
userName: message.user.name,
|
||||
sentAt: message.createdAt,
|
||||
userName: message.user?.name,
|
||||
message: message,
|
||||
onShowMessage: onShowMessage,
|
||||
),
|
||||
@@ -268,7 +266,7 @@ class GiphyAttachment extends AttachmentWidget {
|
||||
},
|
||||
),
|
||||
);
|
||||
if (res != null) onReturnAction(res);
|
||||
if (res != null) onReturnAction?.call(res);
|
||||
}
|
||||
|
||||
Widget _buildSentAttachment(BuildContext context, String imageUrl) {
|
||||
@@ -282,14 +280,13 @@ class GiphyAttachment extends AttachmentWidget {
|
||||
channel: channel,
|
||||
child: FullScreenMedia(
|
||||
mediaAttachments: [attachment],
|
||||
userName: message.user.name,
|
||||
sentAt: message.createdAt,
|
||||
userName: message.user?.name,
|
||||
message: message,
|
||||
onShowMessage: onShowMessage,
|
||||
),
|
||||
);
|
||||
}));
|
||||
if (res != null) onReturnAction(res);
|
||||
if (res != null) onReturnAction!(res);
|
||||
},
|
||||
child: Stack(
|
||||
children: [
|
||||
@@ -297,16 +294,17 @@ class GiphyAttachment extends AttachmentWidget {
|
||||
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:
|
||||
StreamChatTheme.of(context).colorTheme.greyGainsboro,
|
||||
highlightColor:
|
||||
StreamChatTheme.of(context).colorTheme.whiteSmoke,
|
||||
child: Image.asset(
|
||||
'images/placeholder.png',
|
||||
fit: BoxFit.cover,
|
||||
package: 'stream_chat_flutter',
|
||||
),
|
||||
baseColor: colorTheme.greyGainsboro,
|
||||
highlightColor: colorTheme.whiteSmoke,
|
||||
child: image,
|
||||
);
|
||||
},
|
||||
imageUrl: imageUrl,
|
||||
|
||||
@@ -10,35 +10,40 @@ import 'attachment_title.dart';
|
||||
import 'attachment_widget.dart';
|
||||
|
||||
class ImageAttachment extends AttachmentWidget {
|
||||
final MessageTheme messageTheme;
|
||||
final MessageTheme? messageTheme;
|
||||
final bool showTitle;
|
||||
final ShowMessageCallback onShowMessage;
|
||||
final ValueChanged<ReturnActionType> onReturnAction;
|
||||
final VoidCallback onAttachmentTap;
|
||||
final ShowMessageCallback? onShowMessage;
|
||||
final ValueChanged<ReturnActionType>? onReturnAction;
|
||||
final VoidCallback? onAttachmentTap;
|
||||
|
||||
const ImageAttachment({
|
||||
Key key,
|
||||
@required Message message,
|
||||
@required Attachment attachment,
|
||||
Size size,
|
||||
Key? key,
|
||||
required Message message,
|
||||
required Attachment attachment,
|
||||
Size? size,
|
||||
this.messageTheme,
|
||||
this.showTitle = false,
|
||||
this.onShowMessage,
|
||||
this.onReturnAction,
|
||||
this.onAttachmentTap,
|
||||
}) : super(key: key, message: message, attachment: attachment, size: size);
|
||||
}) : super(
|
||||
key: key,
|
||||
message: message,
|
||||
attachment: attachment,
|
||||
size: size,
|
||||
);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return source.when(
|
||||
local: () {
|
||||
if (attachment.localUri == null) {
|
||||
if (attachment.localUri == null || attachment.file?.bytes == null) {
|
||||
return AttachmentError(size: size);
|
||||
}
|
||||
return _buildImageAttachment(
|
||||
context,
|
||||
Image.memory(
|
||||
attachment.file.bytes,
|
||||
attachment.file!.bytes!,
|
||||
height: size?.height,
|
||||
width: size?.width,
|
||||
fit: BoxFit.cover,
|
||||
@@ -85,15 +90,16 @@ class ImageAttachment extends AttachmentWidget {
|
||||
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: StreamChatTheme.of(context).colorTheme.greyGainsboro,
|
||||
highlightColor:
|
||||
StreamChatTheme.of(context).colorTheme.whiteSmoke,
|
||||
child: Image.asset(
|
||||
'images/placeholder.png',
|
||||
fit: BoxFit.cover,
|
||||
package: 'stream_chat_flutter',
|
||||
),
|
||||
baseColor: colorTheme.greyGainsboro,
|
||||
highlightColor: colorTheme.whiteSmoke,
|
||||
child: image,
|
||||
);
|
||||
},
|
||||
imageUrl: imageUrl,
|
||||
@@ -109,7 +115,7 @@ class ImageAttachment extends AttachmentWidget {
|
||||
|
||||
Widget _buildImageAttachment(BuildContext context, Widget imageWidget) {
|
||||
return ConstrainedBox(
|
||||
constraints: BoxConstraints.loose(size),
|
||||
constraints: BoxConstraints.loose(size!),
|
||||
child: Column(
|
||||
children: <Widget>[
|
||||
Expanded(
|
||||
@@ -127,8 +133,7 @@ class ImageAttachment extends AttachmentWidget {
|
||||
channel: channel,
|
||||
child: FullScreenMedia(
|
||||
mediaAttachments: [attachment],
|
||||
userName: message.user.name,
|
||||
sentAt: message.createdAt,
|
||||
userName: message.user?.name,
|
||||
message: message,
|
||||
onShowMessage: onShowMessage,
|
||||
),
|
||||
@@ -136,7 +141,7 @@ class ImageAttachment extends AttachmentWidget {
|
||||
},
|
||||
),
|
||||
);
|
||||
if (result != null) onReturnAction(result);
|
||||
if (result != null) onReturnAction?.call(result);
|
||||
},
|
||||
child: imageWidget,
|
||||
),
|
||||
@@ -152,7 +157,7 @@ class ImageAttachment extends AttachmentWidget {
|
||||
),
|
||||
if (showTitle && attachment.title != null)
|
||||
Material(
|
||||
color: messageTheme.messageBackgroundColor,
|
||||
color: messageTheme?.messageBackgroundColor,
|
||||
child: AttachmentTitle(
|
||||
messageTheme: messageTheme,
|
||||
attachment: attachment,
|
||||
|
||||
@@ -8,21 +8,26 @@ import 'attachment_upload_state_builder.dart';
|
||||
import 'attachment_widget.dart';
|
||||
|
||||
class VideoAttachment extends AttachmentWidget {
|
||||
final MessageTheme messageTheme;
|
||||
final ShowMessageCallback onShowMessage;
|
||||
final ValueChanged<ReturnActionType> onReturnAction;
|
||||
final VoidCallback onAttachmentTap;
|
||||
final MessageTheme? messageTheme;
|
||||
final ShowMessageCallback? onShowMessage;
|
||||
final ValueChanged<ReturnActionType>? onReturnAction;
|
||||
final VoidCallback? onAttachmentTap;
|
||||
|
||||
const VideoAttachment({
|
||||
Key key,
|
||||
@required Message message,
|
||||
@required Attachment attachment,
|
||||
Size size,
|
||||
Key? key,
|
||||
required Message message,
|
||||
required Attachment attachment,
|
||||
Size? size,
|
||||
this.messageTheme,
|
||||
this.onShowMessage,
|
||||
this.onReturnAction,
|
||||
this.onAttachmentTap,
|
||||
}) : super(key: key, message: message, attachment: attachment, size: size);
|
||||
}) : super(
|
||||
key: key,
|
||||
message: message,
|
||||
attachment: attachment,
|
||||
size: size,
|
||||
);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
@@ -34,7 +39,7 @@ class VideoAttachment extends AttachmentWidget {
|
||||
return _buildVideoAttachment(
|
||||
context,
|
||||
VideoThumbnailImage(
|
||||
video: attachment.file.path,
|
||||
video: attachment.file?.path,
|
||||
height: size?.height,
|
||||
width: size?.width,
|
||||
fit: BoxFit.cover,
|
||||
@@ -62,7 +67,7 @@ class VideoAttachment extends AttachmentWidget {
|
||||
|
||||
Widget _buildVideoAttachment(BuildContext context, Widget videoWidget) {
|
||||
return ConstrainedBox(
|
||||
constraints: BoxConstraints.loose(size),
|
||||
constraints: BoxConstraints.loose(size ?? Size.infinite),
|
||||
child: Column(
|
||||
children: <Widget>[
|
||||
Expanded(
|
||||
@@ -77,15 +82,14 @@ class VideoAttachment extends AttachmentWidget {
|
||||
channel: channel,
|
||||
child: FullScreenMedia(
|
||||
mediaAttachments: [attachment],
|
||||
userName: message.user.name,
|
||||
sentAt: message.createdAt,
|
||||
userName: message.user?.name,
|
||||
message: message,
|
||||
onShowMessage: onShowMessage,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
if (res != null) onReturnAction(res);
|
||||
if (res != null) onReturnAction?.call(res);
|
||||
},
|
||||
child: Stack(
|
||||
children: [
|
||||
@@ -112,7 +116,7 @@ class VideoAttachment extends AttachmentWidget {
|
||||
),
|
||||
if (attachment.title != null)
|
||||
Material(
|
||||
color: messageTheme.messageBackgroundColor,
|
||||
color: messageTheme?.messageBackgroundColor,
|
||||
child: AttachmentTitle(
|
||||
messageTheme: messageTheme,
|
||||
attachment: attachment,
|
||||
|
||||
Reference in New Issue
Block a user