fix video attachment fullscreen

This commit is contained in:
Salvatore Giordano
2020-05-13 15:51:45 +02:00
parent 4dcdc457f4
commit a1a3cb177d
8 changed files with 142 additions and 69 deletions
+1 -1
View File
@@ -94,7 +94,7 @@ class MyApp extends StatelessWidget {
return MaterialApp(
theme: ThemeData.light(),
darkTheme: ThemeData.dark(),
themeMode: ThemeMode.system,
themeMode: ThemeMode.dark,
home: Container(
child: StreamChat(
client: client,
+12 -13
View File
@@ -32,7 +32,6 @@ class _FullScreenVideoState extends State<FullScreenVideo> {
child: CircularProgressIndicator(),
);
}
return Chewie(
controller: _chewieController,
);
@@ -49,28 +48,28 @@ class _FullScreenVideoState extends State<FullScreenVideo> {
_videoPlayerController.initialize().whenComplete(() {
setState(() {
initialized = true;
_chewieController = ChewieController(
videoPlayerController: _videoPlayerController,
autoInitialize: false,
aspectRatio: _videoPlayerController.value.aspectRatio,
);
});
});
_chewieController = ChewieController(
videoPlayerController: _videoPlayerController,
autoInitialize: false,
aspectRatio: _videoPlayerController.value.aspectRatio,
);
_videoPlayerController.addListener(() {
VoidCallback errorListener;
errorListener = () {
if (_videoPlayerController.value.hasError) {
WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
Navigator.pop(context);
launchURL(context, widget.attachment.titleLink);
});
Navigator.pop(context);
launchURL(context, widget.attachment.titleLink);
}
});
_videoPlayerController.removeListener(errorListener);
};
_videoPlayerController.addListener(errorListener);
}
@override
void dispose() {
_videoPlayerController.dispose();
_chewieController.dispose();
super.dispose();
}
}
+51 -45
View File
@@ -32,55 +32,61 @@ class ImageAttachment extends StatelessWidget {
size: size,
child: Stack(
children: <Widget>[
Hero(
tag: attachment.imageUrl ??
attachment.assetUrl ??
attachment.thumbUrl,
child: GestureDetector(
onTap: () {
Navigator.push(context, MaterialPageRoute(builder: (_) {
return FullScreenImage(
url: attachment.imageUrl ??
attachment.assetUrl ??
attachment.thumbUrl,
);
}));
},
child: CachedNetworkImage(
height: size?.height,
width: size?.width,
placeholder: (_, __) {
return Container(
width: size?.width,
height: size?.height,
child: Center(
child: CircularProgressIndicator(),
Column(
children: <Widget>[
Expanded(
child: Hero(
tag: attachment.imageUrl ??
attachment.assetUrl ??
attachment.thumbUrl,
child: GestureDetector(
onTap: () {
Navigator.push(context, MaterialPageRoute(builder: (_) {
return FullScreenImage(
url: attachment.imageUrl ??
attachment.assetUrl ??
attachment.thumbUrl,
);
}));
},
child: CachedNetworkImage(
height: size?.height,
width: size?.width,
placeholder: (_, __) {
return Container(
width: size?.width,
height: size?.height,
child: Center(
child: CircularProgressIndicator(),
),
);
},
imageUrl: attachment.thumbUrl ??
attachment.imageUrl ??
attachment.assetUrl,
errorWidget: (context, url, error) => AttachmentError(
attachment: attachment,
size: size,
),
fit: BoxFit.cover,
),
);
},
imageUrl: attachment.thumbUrl ??
attachment.imageUrl ??
attachment.assetUrl,
errorWidget: (context, url, error) => AttachmentError(
attachment: attachment,
size: size,
),
fit: BoxFit.cover,
),
),
),
if (attachment.title != null)
Positioned.fill(
child: Align(
alignment: Alignment.bottomCenter,
child: Material(
child: AttachmentTitle(
messageTheme: messageTheme,
attachment: attachment,
),
),
),
),
if (attachment.title != null)
Positioned.fill(
child: Align(
alignment: Alignment.bottomCenter,
child: Material(
child: AttachmentTitle(
messageTheme: messageTheme,
attachment: attachment,
),
),
),
),
],
),
if (attachment.titleLink != null || attachment.ogScrapeUrl != null)
Positioned.fill(
child: Material(
+62 -4
View File
@@ -13,41 +13,98 @@ import 'message_text.dart';
typedef AttachmentBuilder = Widget Function(BuildContext, Message, Attachment);
/// The display behaviour of a widget
enum DisplayWidget {
/// Hides the widget replacing its space with a spacer
hide,
/// Hides the widget not replacing its space
gone,
/// Shows the widget normally
show,
}
/// ![screenshot](https://raw.githubusercontent.com/GetStream/stream-chat-flutter/master/screenshots/message_widget.png)
/// ![screenshot](https://raw.githubusercontent.com/GetStream/stream-chat-flutter/master/screenshots/message_widget_paint.png)
///
/// It shows a message with reactions, replies and user avatar.
///
/// Usually you don't use this widget as it's the default message widget used by [MessageListView].
///
/// The widget components render the ui based on the first ancestor of type [StreamChatTheme].
/// Modify it to change the widget appearance.
class MessageWidget extends StatelessWidget {
/// Function called on mention tap
final void Function(User) onMentionTap;
/// The function called when tapping on replies
final void Function(Message) onThreadTap;
final Widget Function(BuildContext, Message) editMessageInputBuilder;
final Widget Function(BuildContext, Message) textBuilder;
/// Function called on long press
final void Function(BuildContext, Message) onMessageActions;
/// The message
final Message message;
/// The message theme
final MessageTheme messageTheme;
/// If true the widget will be mirrored
final bool reverse;
/// The shape of the message text
final ShapeBorder shape;
/// The shape of an attachment
final ShapeBorder attachmentShape;
/// The borderside of the message text
final BorderSide borderSide;
/// The borderside of an attachment
final BorderSide attachmentBorderSide;
/// The border radius of the message text
final BorderRadiusGeometry borderRadiusGeometry;
/// The border radius of an attachment
final BorderRadiusGeometry attachmentBorderRadiusGeometry;
/// The padding of the widget
final EdgeInsetsGeometry padding;
/// The internal padding of the message text
final EdgeInsetsGeometry textPadding;
/// The internal padding of an attachment
final EdgeInsetsGeometry attachmentPadding;
/// It controls the display behaviour of the user avatar
final DisplayWidget showUserAvatar;
/// It controls the display behaviour of the sending indicator
final DisplayWidget showSendingIndicator;
/// If true the widget will show the reactions
final bool showReactions;
/// If true the widget will show the reply indicator
final bool showReplyIndicator;
final bool isParent;
/// The function called when tapping on UserAvatar
final void Function(User) onUserAvatarTap;
/// If true show the users username next to the timestamp of the message
final bool showUsername;
final bool showTimestamp;
final bool showDeleteMessage;
final bool showEditMessage;
final Map<String, AttachmentBuilder> attachmentBuilders;
final Map<String, String> reactionToEmoji = {
final Map<String, String> _reactionToEmoji = {
'love': '❤️',
'haha': '😂',
'like': '👍',
@@ -71,13 +128,13 @@ class MessageWidget extends StatelessWidget {
this.showUserAvatar = DisplayWidget.show,
this.showSendingIndicator = DisplayWidget.show,
this.showReplyIndicator = true,
this.isParent = false,
this.onThreadTap,
this.showUsername = true,
this.showTimestamp = true,
this.showReactions = true,
this.showDeleteMessage = true,
this.showEditMessage = true,
this.onUserAvatarTap,
this.onMessageActions,
this.editMessageInputBuilder,
this.textBuilder,
@@ -338,7 +395,7 @@ class MessageWidget extends StatelessWidget {
Text _buildReactionsText(BuildContext context) {
return Text(
message.reactionCounts.keys.map((reactionType) {
return reactionToEmoji[reactionType] ?? '?';
return _reactionToEmoji[reactionType] ?? '?';
}).join(' ') +
' ${message.reactionCounts.values.fold(0, (t, v) => v + t).toString()}',
style: TextStyle(
@@ -499,6 +556,7 @@ class MessageWidget extends StatelessWidget {
Offset(0, messageTheme.avatarTheme.constraints.maxHeight / 2),
child: UserAvatar(
user: message.user,
onTap: onUserAvatarTap,
constraints: messageTheme.avatarTheme.constraints,
),
),
+10 -1
View File
@@ -24,7 +24,16 @@ class StreamChatTheme extends InheritedWidget {
/// Use this method to get the current [StreamChatThemeData] instance
static StreamChatThemeData of(BuildContext context) {
return context.dependOnInheritedWidgetOfExactType<StreamChatTheme>().data;
final streamChatTheme =
context.dependOnInheritedWidgetOfExactType<StreamChatTheme>();
if (streamChatTheme == null) {
throw Exception(
'You must have a StreamChatTheme widget at the top of your widget tree',
);
}
return streamChatTheme.data;
}
}
+3 -3
View File
@@ -43,7 +43,7 @@ class _VideoAttachmentState extends State<VideoAttachment> {
}
_chewieController = ChewieController(
videoPlayerController: _videoPlayerController,
autoInitialize: false,
autoInitialize: true,
showControls: false,
aspectRatio: _videoPlayerController.value.aspectRatio,
errorBuilder: (_, e) {
@@ -137,8 +137,8 @@ class _VideoAttachmentState extends State<VideoAttachment> {
@override
void initState() {
super.initState();
_videoPlayerController = VideoPlayerController.network(
widget.attachment.localUri ?? widget.attachment.assetUrl);
_videoPlayerController =
VideoPlayerController.network(widget.attachment.assetUrl);
_videoPlayerController.initialize().whenComplete(() {
setState(() {
initialized = true;
+1
View File
@@ -9,6 +9,7 @@ export 'src/channels_bloc.dart';
export 'src/date_divider.dart';
export 'src/deleted_message.dart';
export 'src/file_attachment.dart';
export 'src/full_screen_video.dart';
export 'src/giphy_attachment.dart';
export 'src/image_attachment.dart';
export 'src/message_input.dart';
+2 -2
View File
@@ -15,10 +15,10 @@ dependencies:
flutter_portal: ^0.1.0
cached_network_image: ^2.2.0+1
flutter_markdown: ^0.3.5
url_launcher: ^5.4.5
url_launcher: ^5.4.7
video_player: ^0.10.10
chewie: ^0.9.10
file_picker: ^1.8.0+2
file_picker: ^1.9.0+1
image_picker: ^0.6.6+1
flutter_keyboard_visibility: ^2.0.0
stream_chat: