refactor: improve fullscreen_media, minor changes.
Signed-off-by: xsahil03x <[email protected]>
This commit is contained in:
@@ -2,14 +2,11 @@ import 'dart:async';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:chewie/chewie.dart';
|
||||
import 'package:contextmenu/contextmenu.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:photo_view/photo_view.dart';
|
||||
import 'package:stream_chat_flutter/platform_widget_builder/platform_widget_builder.dart';
|
||||
import 'package:stream_chat_flutter/src/attachment/thumbnail/media_attachment_thumbnail.dart';
|
||||
import 'package:stream_chat_flutter/src/context_menu_items/download_menu_item.dart';
|
||||
import 'package:stream_chat_flutter/src/fullscreen_media/full_screen_media_widget.dart';
|
||||
import 'package:stream_chat_flutter/src/fullscreen_media/gallery_navigation_item.dart';
|
||||
import 'package:stream_chat_flutter/stream_chat_flutter.dart';
|
||||
import 'package:video_player/video_player.dart';
|
||||
|
||||
@@ -291,22 +288,16 @@ class _FullScreenMediaState extends State<StreamFullScreenMedia> {
|
||||
? StreamChannelHeaderTheme.of(context).color
|
||||
: Colors.black,
|
||||
duration: kThemeAnimationDuration,
|
||||
child: ContextMenuArea(
|
||||
verticalPadding: 0,
|
||||
builder: (_) => [
|
||||
DownloadMenuItem(attachment: attachment),
|
||||
],
|
||||
child: PhotoView.customChild(
|
||||
maxScale: PhotoViewComputedScale.covered,
|
||||
minScale: PhotoViewComputedScale.contained,
|
||||
backgroundDecoration: const BoxDecoration(
|
||||
color: Colors.transparent,
|
||||
),
|
||||
child: StreamMediaAttachmentThumbnail(
|
||||
media: attachment,
|
||||
width: double.infinity,
|
||||
height: double.infinity,
|
||||
),
|
||||
child: PhotoView.customChild(
|
||||
maxScale: PhotoViewComputedScale.covered,
|
||||
minScale: PhotoViewComputedScale.contained,
|
||||
backgroundDecoration: const BoxDecoration(
|
||||
color: Colors.transparent,
|
||||
),
|
||||
child: StreamMediaAttachmentThumbnail(
|
||||
media: attachment,
|
||||
width: double.infinity,
|
||||
height: double.infinity,
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -318,19 +309,11 @@ class _FullScreenMediaState extends State<StreamFullScreenMedia> {
|
||||
child: CircularProgressIndicator.adaptive(),
|
||||
);
|
||||
}
|
||||
|
||||
return InkWell(
|
||||
onTap: switchDisplayingDetail,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 50),
|
||||
child: ContextMenuArea(
|
||||
verticalPadding: 0,
|
||||
builder: (_) => [
|
||||
DownloadMenuItem(attachment: attachment),
|
||||
],
|
||||
child: Chewie(
|
||||
controller: controller.chewieController!,
|
||||
),
|
||||
),
|
||||
child: Chewie(
|
||||
controller: controller.chewieController!,
|
||||
),
|
||||
);
|
||||
}
|
||||
@@ -344,74 +327,6 @@ class _FullScreenMediaState extends State<StreamFullScreenMedia> {
|
||||
}
|
||||
}
|
||||
|
||||
/// A widget for desktop and web users to be able to navigate left and right
|
||||
/// through a gallery of images.
|
||||
class GalleryNavigationItem extends StatelessWidget {
|
||||
/// Builds a [GalleryNavigationItem].
|
||||
const GalleryNavigationItem({
|
||||
super.key,
|
||||
required this.icon,
|
||||
this.iconSize = 48,
|
||||
required this.onPressed,
|
||||
required this.opacityAnimation,
|
||||
this.left,
|
||||
this.right,
|
||||
});
|
||||
|
||||
/// The icon to display.
|
||||
final Widget icon;
|
||||
|
||||
/// The size of the icon.
|
||||
///
|
||||
/// Defaults to 48.
|
||||
final double iconSize;
|
||||
|
||||
/// The callback to perform when the button is clicked.
|
||||
final VoidCallback onPressed;
|
||||
|
||||
/// The animation for showing & hiding this widget.
|
||||
final ValueListenable<bool> opacityAnimation;
|
||||
|
||||
/// The left-hand placement of the button.
|
||||
final double? left;
|
||||
|
||||
/// The right-hand placement of the button.
|
||||
final double? right;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return PlatformWidgetBuilder(
|
||||
desktop: (_, child) => child,
|
||||
web: (_, child) => child,
|
||||
child: Positioned(
|
||||
left: left,
|
||||
right: right,
|
||||
top: MediaQuery.of(context).size.height / 2,
|
||||
child: ValueListenableBuilder<bool>(
|
||||
valueListenable: opacityAnimation,
|
||||
builder: (context, shouldShow, child) {
|
||||
return AnimatedOpacity(
|
||||
opacity: shouldShow ? 1 : 0,
|
||||
duration: kThemeAnimationDuration,
|
||||
child: child,
|
||||
);
|
||||
},
|
||||
child: Material(
|
||||
color: Colors.transparent,
|
||||
type: MaterialType.circle,
|
||||
clipBehavior: Clip.antiAlias,
|
||||
child: IconButton(
|
||||
icon: icon,
|
||||
iconSize: iconSize,
|
||||
onPressed: onPressed,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// Class for packaging up things required for videos
|
||||
class VideoPackage {
|
||||
/// Constructor for creating [VideoPackage]
|
||||
|
||||
+16
-118
@@ -1,13 +1,13 @@
|
||||
import 'package:cached_network_image/cached_network_image.dart';
|
||||
import 'package:contextmenu/contextmenu.dart';
|
||||
import 'package:dart_vlc/dart_vlc.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:photo_view/photo_view.dart';
|
||||
import 'package:shimmer/shimmer.dart';
|
||||
import 'package:stream_chat_flutter/platform_widget_builder/platform_widget_builder.dart';
|
||||
import 'package:stream_chat_flutter/src/attachment/thumbnail/media_attachment_thumbnail.dart';
|
||||
import 'package:stream_chat_flutter/src/context_menu_items/download_menu_item.dart';
|
||||
import 'package:stream_chat_flutter/src/fullscreen_media/full_screen_media_widget.dart';
|
||||
import 'package:stream_chat_flutter/src/fullscreen_media/gallery_navigation_item.dart';
|
||||
import 'package:stream_chat_flutter/stream_chat_flutter.dart';
|
||||
|
||||
/// Returns an instance of [FullScreenMediaDesktop].
|
||||
@@ -310,9 +310,6 @@ class _FullScreenMediaDesktopState extends State<FullScreenMediaDesktop> {
|
||||
final attachment = currentAttachmentPackage.attachment;
|
||||
if (attachment.type == AttachmentType.image ||
|
||||
attachment.type == AttachmentType.giphy) {
|
||||
final imageUrl = attachment.imageUrl ??
|
||||
attachment.assetUrl ??
|
||||
attachment.thumbUrl;
|
||||
return ValueListenableBuilder<bool>(
|
||||
valueListenable: _isDisplayingDetail,
|
||||
builder: (context, isDisplayingDetail, _) =>
|
||||
@@ -324,39 +321,19 @@ class _FullScreenMediaDesktopState extends State<FullScreenMediaDesktop> {
|
||||
child: ContextMenuArea(
|
||||
verticalPadding: 0,
|
||||
builder: (_) => [
|
||||
DownloadMenuItem(
|
||||
attachment: attachment,
|
||||
),
|
||||
DownloadMenuItem(attachment: attachment),
|
||||
],
|
||||
child: PhotoView(
|
||||
imageProvider: (imageUrl == null &&
|
||||
attachment.localUri != null &&
|
||||
attachment.file?.bytes != null)
|
||||
? Image.memory(attachment.file!.bytes!).image
|
||||
: CachedNetworkImageProvider(imageUrl!),
|
||||
errorBuilder: (_, __, ___) => const AttachmentError(),
|
||||
loadingBuilder: (context, _) {
|
||||
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.disabled,
|
||||
highlightColor: colorTheme.inputBg,
|
||||
child: image,
|
||||
);
|
||||
},
|
||||
child: PhotoView.customChild(
|
||||
maxScale: PhotoViewComputedScale.covered,
|
||||
minScale: PhotoViewComputedScale.contained,
|
||||
heroAttributes: PhotoViewHeroAttributes(
|
||||
tag: widget.mediaAttachmentPackages,
|
||||
),
|
||||
backgroundDecoration: const BoxDecoration(
|
||||
color: Colors.transparent,
|
||||
),
|
||||
child: StreamMediaAttachmentThumbnail(
|
||||
media: attachment,
|
||||
width: double.infinity,
|
||||
height: double.infinity,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -364,29 +341,18 @@ class _FullScreenMediaDesktopState extends State<FullScreenMediaDesktop> {
|
||||
} else if (attachment.type == AttachmentType.video) {
|
||||
final package = videoPackages[attachment.id]!;
|
||||
package.player.open(
|
||||
Playlist(
|
||||
medias: [
|
||||
Media.network(package.attachment.assetUrl),
|
||||
],
|
||||
),
|
||||
Media.network(package.attachment.assetUrl),
|
||||
autoStart: widget.autoplayVideos,
|
||||
);
|
||||
|
||||
return InkWell(
|
||||
onTap: switchDisplayingDetail,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 50),
|
||||
child: ContextMenuArea(
|
||||
verticalPadding: 0,
|
||||
builder: (_) => [
|
||||
DownloadMenuItem(
|
||||
attachment: attachment,
|
||||
),
|
||||
],
|
||||
child: Video(
|
||||
player: package.player,
|
||||
),
|
||||
),
|
||||
child: ContextMenuArea(
|
||||
verticalPadding: 0,
|
||||
builder: (_) => [
|
||||
DownloadMenuItem(attachment: attachment),
|
||||
],
|
||||
child: Video(player: package.player),
|
||||
),
|
||||
);
|
||||
}
|
||||
@@ -399,74 +365,6 @@ class _FullScreenMediaDesktopState extends State<FullScreenMediaDesktop> {
|
||||
}
|
||||
}
|
||||
|
||||
/// A widget for desktop and web users to be able to navigate left and right
|
||||
/// through a gallery of images.
|
||||
class GalleryNavigationItem extends StatelessWidget {
|
||||
/// Builds a [GalleryNavigationItem].
|
||||
const GalleryNavigationItem({
|
||||
super.key,
|
||||
required this.icon,
|
||||
this.iconSize = 48,
|
||||
required this.onPressed,
|
||||
required this.opacityAnimation,
|
||||
this.left,
|
||||
this.right,
|
||||
});
|
||||
|
||||
/// The icon to display.
|
||||
final Widget icon;
|
||||
|
||||
/// The size of the icon.
|
||||
///
|
||||
/// Defaults to 48.
|
||||
final double iconSize;
|
||||
|
||||
/// The callback to perform when the button is clicked.
|
||||
final VoidCallback onPressed;
|
||||
|
||||
/// The animation for showing & hiding this widget.
|
||||
final ValueListenable<bool> opacityAnimation;
|
||||
|
||||
/// The left-hand placement of the button.
|
||||
final double? left;
|
||||
|
||||
/// The right-hand placement of the button.
|
||||
final double? right;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return PlatformWidgetBuilder(
|
||||
desktop: (_, child) => child,
|
||||
web: (_, child) => child,
|
||||
child: Positioned(
|
||||
left: left,
|
||||
right: right,
|
||||
top: MediaQuery.of(context).size.height / 2,
|
||||
child: ValueListenableBuilder<bool>(
|
||||
valueListenable: opacityAnimation,
|
||||
builder: (context, shouldShow, child) {
|
||||
return AnimatedOpacity(
|
||||
opacity: shouldShow ? 1 : 0,
|
||||
duration: kThemeAnimationDuration,
|
||||
child: child,
|
||||
);
|
||||
},
|
||||
child: Material(
|
||||
color: Colors.transparent,
|
||||
type: MaterialType.circle,
|
||||
clipBehavior: Clip.antiAlias,
|
||||
child: IconButton(
|
||||
icon: icon,
|
||||
iconSize: iconSize,
|
||||
onPressed: onPressed,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// Class for packaging up things required for videos
|
||||
class DesktopVideoPackage {
|
||||
/// Constructor for creating [VideoPackage]
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:stream_chat_flutter/platform_widget_builder/src/platform_widget_builder.dart';
|
||||
|
||||
/// A widget for desktop and web users to be able to navigate left and right
|
||||
/// through a gallery of images.
|
||||
class GalleryNavigationItem extends StatelessWidget {
|
||||
/// Builds a [GalleryNavigationItem].
|
||||
const GalleryNavigationItem({
|
||||
super.key,
|
||||
required this.icon,
|
||||
this.iconSize = 48,
|
||||
required this.onPressed,
|
||||
required this.opacityAnimation,
|
||||
this.left,
|
||||
this.right,
|
||||
});
|
||||
|
||||
/// The icon to display.
|
||||
final Widget icon;
|
||||
|
||||
/// The size of the icon.
|
||||
///
|
||||
/// Defaults to 48.
|
||||
final double iconSize;
|
||||
|
||||
/// The callback to perform when the button is clicked.
|
||||
final VoidCallback onPressed;
|
||||
|
||||
/// The animation for showing & hiding this widget.
|
||||
final ValueListenable<bool> opacityAnimation;
|
||||
|
||||
/// The left-hand placement of the button.
|
||||
final double? left;
|
||||
|
||||
/// The right-hand placement of the button.
|
||||
final double? right;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return PlatformWidgetBuilder(
|
||||
desktop: (_, child) => child,
|
||||
web: (_, child) => child,
|
||||
child: Positioned(
|
||||
left: left,
|
||||
right: right,
|
||||
top: MediaQuery.of(context).size.height / 2,
|
||||
child: ValueListenableBuilder<bool>(
|
||||
valueListenable: opacityAnimation,
|
||||
builder: (context, shouldShow, child) {
|
||||
return AnimatedOpacity(
|
||||
opacity: shouldShow ? 1 : 0,
|
||||
duration: kThemeAnimationDuration,
|
||||
child: child,
|
||||
);
|
||||
},
|
||||
child: Material(
|
||||
color: Colors.transparent,
|
||||
type: MaterialType.circle,
|
||||
clipBehavior: Clip.antiAlias,
|
||||
child: IconButton(
|
||||
icon: icon,
|
||||
iconSize: iconSize,
|
||||
onPressed: onPressed,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user