fix attachment size

This commit is contained in:
Salvatore Giordano
2020-05-12 15:27:16 +02:00
parent 18ded607a8
commit 073f21dc5d
10 changed files with 267 additions and 137 deletions
+5 -5
View File
@@ -111,11 +111,11 @@ class ChannelListPage extends StatelessWidget {
return Scaffold( return Scaffold(
body: ChannelsBloc( body: ChannelsBloc(
child: ChannelListView( child: ChannelListView(
// filter: { filter: {
// 'members': { 'members': {
// '\$in': [StreamChat.of(context).user.id], '\$in': [StreamChat.of(context).user.id],
// } }
// }, },
sort: [SortOption('last_message_at')], sort: [SortOption('last_message_at')],
pagination: PaginationParams( pagination: PaginationParams(
limit: 20, limit: 20,
+19 -24
View File
@@ -15,42 +15,37 @@ class AttachmentActions extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
final streamChannel = StreamChannel.of(context); final streamChannel = StreamChannel.of(context);
return Row( return Row(
mainAxisAlignment: MainAxisAlignment.end, mainAxisAlignment: MainAxisAlignment.spaceBetween,
mainAxisSize: MainAxisSize.min,
children: attachment.actions?.map((action) { children: attachment.actions?.map((action) {
if (action.style == 'primary') { if (action.style == 'primary') {
return Padding( return FlatButton(
padding: const EdgeInsets.symmetric(horizontal: 4.0),
child: FlatButton(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16),
),
child: Text('${action.text}'),
color: action.style == 'primary'
? StreamChatTheme.of(context).accentColor
: null,
textColor: Colors.white,
onPressed: () {
streamChannel.channel.sendAction(message, {
action.name: action.value,
});
},
),
);
}
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 4.0),
child: OutlineButton(
shape: RoundedRectangleBorder( shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16), borderRadius: BorderRadius.circular(16),
), ),
child: Text('${action.text}'), child: Text('${action.text}'),
color: StreamChatTheme.of(context).accentColor, color: action.style == 'primary'
? StreamChatTheme.of(context).accentColor
: null,
textColor: Colors.white,
onPressed: () { onPressed: () {
streamChannel.channel.sendAction(message, { streamChannel.channel.sendAction(message, {
action.name: action.value, action.name: action.value,
}); });
}, },
);
}
return OutlineButton(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16),
), ),
child: Text('${action.text}'),
color: StreamChatTheme.of(context).accentColor,
onPressed: () {
streamChannel.channel.sendAction(message, {
action.name: action.value,
});
},
); );
})?.toList(), })?.toList(),
); );
+4 -2
View File
@@ -5,10 +5,12 @@ import 'package:stream_chat/stream_chat.dart';
class AttachmentError extends StatelessWidget { class AttachmentError extends StatelessWidget {
final Attachment attachment; final Attachment attachment;
final Size size;
const AttachmentError({ const AttachmentError({
Key key, Key key,
@required this.attachment, @required this.attachment,
this.size,
}) : super(key: key); }) : super(key: key);
@override @override
@@ -20,8 +22,8 @@ class AttachmentError extends StatelessWidget {
} }
return Center( return Center(
child: Container( child: Container(
width: 200, width: size?.width,
height: 140, height: size?.height,
color: Color(0xffd0021B).withOpacity(.1), color: Color(0xffd0021B).withOpacity(.1),
child: Center( child: Center(
child: Icon( child: Icon(
+1 -1
View File
@@ -26,7 +26,7 @@ class AttachmentTitle extends StatelessWidget {
padding: const EdgeInsets.all(8.0), padding: const EdgeInsets.all(8.0),
child: Column( child: Column(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[ children: <Widget>[
Text( Text(
attachment.title, attachment.title,
+4 -2
View File
@@ -4,10 +4,12 @@ import 'package:stream_chat_flutter/src/utils.dart';
class FileAttachment extends StatelessWidget { class FileAttachment extends StatelessWidget {
final Attachment attachment; final Attachment attachment;
final Size size;
const FileAttachment({ const FileAttachment({
Key key, Key key,
@required this.attachment, @required this.attachment,
this.size,
}) : super(key: key); }) : super(key: key);
@override @override
@@ -18,8 +20,8 @@ class FileAttachment extends StatelessWidget {
launchURL(context, attachment.assetUrl); launchURL(context, attachment.assetUrl);
}, },
child: Container( child: Container(
width: 100, width: size?.width ?? 100,
height: 100, height: size?.height ?? 100,
child: Center( child: Center(
child: Icon(Icons.attach_file), child: Icon(Icons.attach_file),
), ),
+76
View File
@@ -0,0 +1,76 @@
import 'package:chewie/chewie.dart';
import 'package:flutter/material.dart';
import 'package:stream_chat_flutter/stream_chat_flutter.dart';
import 'package:video_player/video_player.dart';
import 'utils.dart';
class FullScreenVideo extends StatefulWidget {
final Attachment attachment;
FullScreenVideo({
Key key,
@required this.attachment,
}) : super(key: key);
@override
_FullScreenVideoState createState() => _FullScreenVideoState();
}
class _FullScreenVideoState extends State<FullScreenVideo> {
ChewieController _chewieController;
VideoPlayerController _videoPlayerController;
bool initialized = false;
@override
Widget build(BuildContext context) {
return Scaffold(
body: Builder(
builder: (context) {
if (!initialized) {
return Center(
child: CircularProgressIndicator(),
);
}
return Chewie(
controller: _chewieController,
);
},
),
);
}
@override
void initState() {
super.initState();
_videoPlayerController =
VideoPlayerController.network(widget.attachment.assetUrl);
_videoPlayerController.initialize().whenComplete(() {
setState(() {
initialized = true;
});
});
_chewieController = ChewieController(
videoPlayerController: _videoPlayerController,
autoInitialize: false,
aspectRatio: _videoPlayerController.value.aspectRatio,
);
_videoPlayerController.addListener(() {
if (_videoPlayerController.value.hasError) {
WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
Navigator.pop(context);
launchURL(context, widget.attachment.titleLink);
});
}
});
}
@override
void dispose() {
_videoPlayerController.dispose();
_chewieController.dispose();
super.dispose();
}
}
+29 -36
View File
@@ -5,19 +5,20 @@ import 'package:stream_chat_flutter/src/attachment_actions.dart';
import '../stream_chat_flutter.dart'; import '../stream_chat_flutter.dart';
import 'attachment_error.dart'; import 'attachment_error.dart';
import 'attachment_title.dart'; import 'attachment_title.dart';
import 'full_screen_image.dart';
import 'utils.dart'; import 'utils.dart';
class GiphyAttachment extends StatelessWidget { class GiphyAttachment extends StatelessWidget {
final Attachment attachment; final Attachment attachment;
final MessageTheme messageTheme; final MessageTheme messageTheme;
final Message message; final Message message;
final Size size;
const GiphyAttachment({ const GiphyAttachment({
Key key, Key key,
this.attachment, this.attachment,
this.messageTheme, this.messageTheme,
this.message, this.message,
this.size,
}) : super(key: key); }) : super(key: key);
@override @override
@@ -36,39 +37,26 @@ class GiphyAttachment extends StatelessWidget {
children: <Widget>[ children: <Widget>[
Stack( Stack(
children: <Widget>[ children: <Widget>[
Hero( CachedNetworkImage(
tag: attachment.imageUrl ?? height: size?.height,
attachment.assetUrl ?? width: size?.width,
attachment.thumbUrl, placeholder: (_, __) {
child: CachedNetworkImage( return Container(
imageBuilder: (context, provider) { width: size?.width,
return GestureDetector( height: size?.height,
child: Image(image: provider), child: Center(
onTap: () { child: CircularProgressIndicator(),
Navigator.push(context, MaterialPageRoute(builder: (_) { ),
return FullScreenImage( );
url: attachment.imageUrl ?? },
attachment.assetUrl ?? imageUrl: attachment.thumbUrl ??
attachment.thumbUrl, attachment.imageUrl ??
); attachment.assetUrl,
})); errorWidget: (context, url, error) => AttachmentError(
}, attachment: attachment,
); size: size,
},
placeholder: (_, __) {
return Container(
width: 200,
height: 140,
);
},
imageUrl: attachment.thumbUrl ??
attachment.imageUrl ??
attachment.assetUrl,
errorWidget: (context, url, error) => AttachmentError(
attachment: attachment,
),
fit: BoxFit.cover,
), ),
fit: BoxFit.cover,
), ),
if (attachment.titleLink != null || attachment.ogScrapeUrl != null) if (attachment.titleLink != null || attachment.ogScrapeUrl != null)
Positioned.fill( Positioned.fill(
@@ -85,9 +73,14 @@ class GiphyAttachment extends StatelessWidget {
], ],
), ),
if (attachment.title != null) if (attachment.title != null)
AttachmentTitle( Container(
messageTheme: messageTheme, alignment: Alignment.bottomCenter,
attachment: attachment, child: Material(
child: AttachmentTitle(
messageTheme: messageTheme,
attachment: attachment,
),
),
), ),
if (attachment.actions != null) if (attachment.actions != null)
AttachmentActions( AttachmentActions(
+51 -45
View File
@@ -10,11 +10,13 @@ import 'utils.dart';
class ImageAttachment extends StatelessWidget { class ImageAttachment extends StatelessWidget {
final Attachment attachment; final Attachment attachment;
final MessageTheme messageTheme; final MessageTheme messageTheme;
final Size size;
const ImageAttachment({ const ImageAttachment({
Key key, Key key,
this.attachment, this.attachment,
this.messageTheme, this.messageTheme,
this.size,
}) : super(key: key); }) : super(key: key);
@override @override
@@ -26,38 +28,34 @@ class ImageAttachment extends StatelessWidget {
attachment: attachment, attachment: attachment,
); );
} }
return Column( return SizedBox.fromSize(
mainAxisSize: MainAxisSize.min, size: size,
crossAxisAlignment: CrossAxisAlignment.start, child: Stack(
children: <Widget>[ children: <Widget>[
Stack( Hero(
children: <Widget>[ tag: attachment.imageUrl ??
Hero( attachment.assetUrl ??
tag: attachment.imageUrl ?? attachment.thumbUrl,
attachment.assetUrl ?? child: GestureDetector(
attachment.thumbUrl, onTap: () {
child: CachedNetworkImage( Navigator.push(context, MaterialPageRoute(builder: (_) {
imageBuilder: (context, provider) { return FullScreenImage(
return GestureDetector( url: attachment.imageUrl ??
child: Image( attachment.assetUrl ??
image: provider, attachment.thumbUrl,
fit: BoxFit.cover,
),
onTap: () {
Navigator.push(context, MaterialPageRoute(builder: (_) {
return FullScreenImage(
url: attachment.imageUrl ??
attachment.assetUrl ??
attachment.thumbUrl,
);
}));
},
); );
}, }));
},
child: CachedNetworkImage(
height: size?.height,
width: size?.width,
placeholder: (_, __) { placeholder: (_, __) {
return Container( return Container(
width: 200, width: size?.width,
height: 140, height: size?.height,
child: Center(
child: CircularProgressIndicator(),
),
); );
}, },
imageUrl: attachment.thumbUrl ?? imageUrl: attachment.thumbUrl ??
@@ -65,30 +63,38 @@ class ImageAttachment extends StatelessWidget {
attachment.assetUrl, attachment.assetUrl,
errorWidget: (context, url, error) => AttachmentError( errorWidget: (context, url, error) => AttachmentError(
attachment: attachment, attachment: attachment,
size: size,
), ),
fit: BoxFit.cover, fit: BoxFit.cover,
), ),
), ),
if (attachment.titleLink != null || attachment.ogScrapeUrl != null) ),
Positioned.fill( if (attachment.title != null)
Positioned.fill(
child: Align(
alignment: Alignment.bottomCenter,
child: Material( child: Material(
color: Colors.transparent, child: AttachmentTitle(
child: InkWell( messageTheme: messageTheme,
onTap: () => launchURL( attachment: attachment,
context,
attachment.titleLink ?? attachment.ogScrapeUrl,
),
), ),
), ),
), ),
], ),
), if (attachment.titleLink != null || attachment.ogScrapeUrl != null)
if (attachment.title != null) Positioned.fill(
AttachmentTitle( child: Material(
messageTheme: messageTheme, color: Colors.transparent,
attachment: attachment, child: InkWell(
), onTap: () => launchURL(
], context,
attachment.titleLink ?? attachment.ogScrapeUrl,
),
),
),
),
],
),
); );
} }
} }
+18 -5
View File
@@ -43,7 +43,6 @@ class MessageWidget extends StatelessWidget {
final bool showReplyIndicator; final bool showReplyIndicator;
final bool isParent; final bool isParent;
final bool showUsername; final bool showUsername;
final bool showVideoFullScreen;
final bool showTimestamp; final bool showTimestamp;
final bool showDeleteMessage; final bool showDeleteMessage;
final bool showEditMessage; final bool showEditMessage;
@@ -83,7 +82,6 @@ class MessageWidget extends StatelessWidget {
this.editMessageInputBuilder, this.editMessageInputBuilder,
this.textBuilder, this.textBuilder,
Map<String, AttachmentBuilder> customAttachmentBuilders, Map<String, AttachmentBuilder> customAttachmentBuilders,
this.showVideoFullScreen = true,
this.padding, this.padding,
this.textPadding = const EdgeInsets.all(8.0), this.textPadding = const EdgeInsets.all(8.0),
this.attachmentPadding = EdgeInsets.zero, this.attachmentPadding = EdgeInsets.zero,
@@ -92,13 +90,20 @@ class MessageWidget extends StatelessWidget {
return ImageAttachment( return ImageAttachment(
attachment: attachment, attachment: attachment,
messageTheme: messageTheme, messageTheme: messageTheme,
size: Size(
MediaQuery.of(context).size.width * 0.8,
MediaQuery.of(context).size.height * 0.3,
),
); );
}, },
'video': (context, message, attachment) { 'video': (context, message, attachment) {
return VideoAttachment( return VideoAttachment(
enableFullScreen: showVideoFullScreen,
attachment: attachment, attachment: attachment,
messageTheme: messageTheme, messageTheme: messageTheme,
size: Size(
MediaQuery.of(context).size.width * 0.8,
MediaQuery.of(context).size.height * 0.3,
),
); );
}, },
'giphy': (context, message, attachment) { 'giphy': (context, message, attachment) {
@@ -106,11 +111,19 @@ class MessageWidget extends StatelessWidget {
attachment: attachment, attachment: attachment,
messageTheme: messageTheme, messageTheme: messageTheme,
message: message, message: message,
size: Size(
MediaQuery.of(context).size.width * 0.8,
MediaQuery.of(context).size.height * 0.3,
),
); );
}, },
'file': (context, message, attachment) { 'file': (context, message, attachment) {
return FileAttachment( return FileAttachment(
attachment: attachment, attachment: attachment,
size: Size(
MediaQuery.of(context).size.width * 0.8,
MediaQuery.of(context).size.height * 0.3,
),
); );
}, },
}..addAll(customAttachmentBuilders ?? {}), }..addAll(customAttachmentBuilders ?? {}),
@@ -165,7 +178,7 @@ class MessageWidget extends StatelessWidget {
SizedBox( SizedBox(
width: messageTheme width: messageTheme
.avatarTheme.constraints.maxWidth + .avatarTheme.constraints.maxWidth +
10, 8,
), ),
Flexible( Flexible(
child: Padding( child: Padding(
@@ -228,7 +241,7 @@ class MessageWidget extends StatelessWidget {
((message.reactionCounts.values ((message.reactionCounts.values
.where((element) => element > 0) .where((element) => element > 0)
.length ~/ .length ~/
4) + 5) +
1); 1);
} }
+60 -17
View File
@@ -1,6 +1,7 @@
import 'package:cached_network_image/cached_network_image.dart'; import 'package:cached_network_image/cached_network_image.dart';
import 'package:chewie/chewie.dart'; import 'package:chewie/chewie.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:stream_chat_flutter/src/full_screen_video.dart';
import 'package:stream_chat_flutter/src/utils.dart'; import 'package:stream_chat_flutter/src/utils.dart';
import 'package:stream_chat_flutter/stream_chat_flutter.dart'; import 'package:stream_chat_flutter/stream_chat_flutter.dart';
import 'package:video_player/video_player.dart'; import 'package:video_player/video_player.dart';
@@ -10,14 +11,14 @@ import 'attachment_title.dart';
class VideoAttachment extends StatefulWidget { class VideoAttachment extends StatefulWidget {
final Attachment attachment; final Attachment attachment;
final bool enableFullScreen;
final MessageTheme messageTheme; final MessageTheme messageTheme;
final Size size;
VideoAttachment({ VideoAttachment({
Key key, Key key,
@required this.attachment, @required this.attachment,
@required this.messageTheme, @required this.messageTheme,
this.enableFullScreen = true, this.size,
}) : super(key: key); }) : super(key: key);
@override @override
@@ -33,23 +34,25 @@ class _VideoAttachmentState extends State<VideoAttachment> {
Widget build(BuildContext context) { Widget build(BuildContext context) {
if (!initialized) { if (!initialized) {
return Container( return Container(
height: 100, height: widget.size?.height ?? 100,
width: 100, width: widget.size?.width ?? 100,
child: Center( child: Center(
child: CircularProgressIndicator(), child: CircularProgressIndicator(),
), ),
); );
} }
_chewieController = ChewieController( _chewieController = ChewieController(
allowFullScreen: widget.enableFullScreen,
videoPlayerController: _videoPlayerController, videoPlayerController: _videoPlayerController,
autoInitialize: false, autoInitialize: false,
showControls: false,
aspectRatio: _videoPlayerController.value.aspectRatio, aspectRatio: _videoPlayerController.value.aspectRatio,
errorBuilder: (_, e) { errorBuilder: (_, e) {
if (widget.attachment.thumbUrl != null) { if (widget.attachment.thumbUrl != null) {
return Stack( return Stack(
children: <Widget>[ children: <Widget>[
Container( Container(
height: widget.size?.height,
width: widget.size?.width,
decoration: BoxDecoration( decoration: BoxDecoration(
image: DecorationImage( image: DecorationImage(
fit: BoxFit.cover, fit: BoxFit.cover,
@@ -72,22 +75,62 @@ class _VideoAttachmentState extends State<VideoAttachment> {
} }
return AttachmentError( return AttachmentError(
attachment: widget.attachment, attachment: widget.attachment,
size: widget.size,
); );
}); });
return Column( return GestureDetector(
mainAxisSize: MainAxisSize.min, onTap: () {
crossAxisAlignment: CrossAxisAlignment.stretch, Navigator.push(
children: <Widget>[ context,
Chewie( MaterialPageRoute(
controller: _chewieController, builder: (_) => FullScreenVideo(
), attachment: widget.attachment,
if (widget.attachment.title != null) ),
AttachmentTitle(
messageTheme: widget.messageTheme,
attachment: widget.attachment,
), ),
], );
},
child: Container(
height: widget.size?.height,
width: widget.size?.width,
child: Flex(
direction: Axis.vertical,
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Expanded(
child: FittedBox(
fit: BoxFit.cover,
child: Stack(
children: <Widget>[
Chewie(
controller: _chewieController,
),
Positioned.fill(
child: Center(
child: Material(
shape: CircleBorder(),
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Icon(Icons.play_arrow),
),
),
),
),
],
),
),
),
if (widget.attachment.title != null)
Material(
child: AttachmentTitle(
messageTheme: widget.messageTheme,
attachment: widget.attachment,
),
),
],
),
),
); );
} }