From b5a22b9599f4e05fd44295a74a95bd7ee5d54afc Mon Sep 17 00:00:00 2001 From: gianlucaparadise Date: Thu, 13 Jan 2022 19:35:25 +0100 Subject: [PATCH] MiniController thumbnail and play button --- example/lib/main.dart | 4 +- .../mini_controller/MiniController.dart | 97 +++++++++++-------- .../MiniControllerPlayPauseButton.dart | 62 ++++++++++++ .../MiniControllerThumbnail.dart | 35 +++++++ 4 files changed, 158 insertions(+), 40 deletions(-) create mode 100644 lib/src/cast/widgets/mini_controller/MiniControllerPlayPauseButton.dart create mode 100644 lib/src/cast/widgets/mini_controller/MiniControllerThumbnail.dart diff --git a/example/lib/main.dart b/example/lib/main.dart index 90491ef..6bde48f 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -175,7 +175,9 @@ class _MyAppState extends State { _buildTitle("Mini Controller"), Padding( padding: const EdgeInsets.symmetric(vertical: 8.0), - child: MiniController(), + child: MiniController( + castFramework: castFramework, + ), ), ], ), diff --git a/lib/src/cast/widgets/mini_controller/MiniController.dart b/lib/src/cast/widgets/mini_controller/MiniController.dart index 7bf6119..c9fc2d5 100644 --- a/lib/src/cast/widgets/mini_controller/MiniController.dart +++ b/lib/src/cast/widgets/mini_controller/MiniController.dart @@ -1,63 +1,82 @@ import 'package:flutter/material.dart'; -import 'package:flutter_cast_framework/src/cast/widgets/mini_controller/TransparentImage.dart'; + +import '../../../../cast.dart'; +import 'MiniControllerThumbnail.dart'; +import 'MiniControllerPlayPauseButton.dart'; class MiniController extends StatelessWidget { - const MiniController({Key? key}) : super(key: key); + final FlutterCastFramework castFramework; - void _onPausePressed() {} + const MiniController({ + Key? key, + required this.castFramework, + }) : super(key: key); - @override - Widget build(BuildContext context) { - final thumbnail = AspectRatio( - aspectRatio: 1, - child: FadeInImage.memoryNetwork( - fit: BoxFit.cover, - placeholder: kTransparentImage, - image: - "https://commondatastorage.googleapis.com/gtv-videos-bucket/CastVideos/images/480x270/BigBuckBunny.jpg", - ), - ); + Widget _getControls(MediaStatus? status) { + final thumbnail = MiniControllerThumbnail(mediaInfo: status?.mediaInfo); + // final titleText = mediaInfo?.mediaMetadata?.strings[MediaMetadataKey.title] + // final subtitleText = mediaInfo?.mediaMetadata?.strings[MediaMetadataKey.subtitle] + final titleText = ""; + final subtitleText = ""; final title = Text( - "this.title", + titleText, maxLines: 1, overflow: TextOverflow.ellipsis, style: TextStyle(fontWeight: FontWeight.w500), ); final subtitle = Text( - "this.subtitle", + subtitleText, maxLines: 1, overflow: TextOverflow.ellipsis, style: TextStyle(color: Colors.grey), ); - final playPauseButton = IconButton( - padding: EdgeInsets.zero, - onPressed: _onPausePressed, - icon: Icon(Icons.pause, color: Colors.black, size: 38), + final playPauseButton = MiniControllerPlayPauseButton( + castFramework: castFramework, + status: status, ); + return SizedBox( + height: 60, + child: Row( + children: [ + thumbnail, + Container(width: 12), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + title, + subtitle, + ], + ), + ), + playPauseButton, + ], + ), + ); + } + + @override + Widget build(BuildContext context) { + var remoteMediaClient = + this.castFramework.castContext.sessionManager.remoteMediaClient; + return Stack( children: [ - SizedBox( - height: 60, - child: Row( - children: [ - thumbnail, - Container(width: 12), - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.center, - children: [ - title, - subtitle, - ], - ), - ), - playPauseButton, - ], - ), + StreamBuilder( + stream: remoteMediaClient.mediaStatusStream, + builder: (BuildContext context, AsyncSnapshot snapshot) { + if (snapshot.hasData && snapshot.data != null) { + return _getControls(snapshot.data); + } else if (snapshot.hasError) { + return _getControls(null); + } else { + return _getControls(null); + } + }, ), LinearProgressIndicator( color: Colors.red, diff --git a/lib/src/cast/widgets/mini_controller/MiniControllerPlayPauseButton.dart b/lib/src/cast/widgets/mini_controller/MiniControllerPlayPauseButton.dart new file mode 100644 index 0000000..4885c9d --- /dev/null +++ b/lib/src/cast/widgets/mini_controller/MiniControllerPlayPauseButton.dart @@ -0,0 +1,62 @@ +import 'package:flutter/material.dart'; + +import '../../../../cast.dart'; + +class MiniControllerPlayPauseButton extends StatelessWidget { + final FlutterCastFramework castFramework; + final MediaStatus? status; + + const MiniControllerPlayPauseButton({ + Key? key, + required this.castFramework, + this.status, + }) : super(key: key); + + void _onPausePressed() { + var remoteMediaClient = + this.castFramework.castContext.sessionManager.remoteMediaClient; + + remoteMediaClient.pause(); + } + + void _onPlayPressed() { + var remoteMediaClient = + this.castFramework.castContext.sessionManager.remoteMediaClient; + + remoteMediaClient.play(); + } + + @override + Widget build(BuildContext context) { + switch (status?.playerState) { + case PlayerState.playing: + case PlayerState.buffering: + return IconButton( + padding: EdgeInsets.zero, + onPressed: _onPausePressed, + icon: Icon(Icons.pause, color: Colors.black, size: 38), + ); + + case PlayerState.paused: + return IconButton( + padding: EdgeInsets.zero, + onPressed: _onPlayPressed, + icon: Icon(Icons.play_arrow, color: Colors.black, size: 38), + ); + + case PlayerState.loading: + return Padding( + padding: const EdgeInsets.all(8.0), + child: CircularProgressIndicator(), + ); + + default: + // return disabled button + return IconButton( + padding: EdgeInsets.zero, + onPressed: null, + icon: Icon(Icons.play_arrow, color: Colors.grey, size: 38), + ); + } + } +} diff --git a/lib/src/cast/widgets/mini_controller/MiniControllerThumbnail.dart b/lib/src/cast/widgets/mini_controller/MiniControllerThumbnail.dart new file mode 100644 index 0000000..6b0ea00 --- /dev/null +++ b/lib/src/cast/widgets/mini_controller/MiniControllerThumbnail.dart @@ -0,0 +1,35 @@ +import 'package:flutter/material.dart'; + +import '../../../../cast.dart'; +import 'TransparentImage.dart'; + +class MiniControllerThumbnail extends StatelessWidget { + final MediaInfo? mediaInfo; + + const MiniControllerThumbnail({ + Key? key, + this.mediaInfo, + }) : super(key: key); + + @override + Widget build(BuildContext context) { + final webImages = mediaInfo?.mediaMetadata?.webImages; + if (webImages?.isEmpty == true) { + return SizedBox.shrink(); + } + + final imgUrl = webImages?.first?.url; + if (imgUrl == null || imgUrl.isEmpty) { + return SizedBox.shrink(); + } + + return AspectRatio( + aspectRatio: 1, + child: FadeInImage.memoryNetwork( + fit: BoxFit.cover, + placeholder: kTransparentImage, + image: imgUrl, + ), + ); + } +}