From 70a0ce95e38529b08e223290d4d0ad099e8c1cd4 Mon Sep 17 00:00:00 2001 From: gianlucaparadise Date: Thu, 25 Nov 2021 06:28:15 +0100 Subject: [PATCH] RemoteMediaClient Stub ExpandedControls page --- .../expanded_controls/ExpandedControls.dart | 115 ++++++++++++++++++ .../ExpandedControlsPlayer.dart | 50 ++++++++ .../ExpandedControlsProgress.dart | 34 ++++++ .../ExpandedControlsToolbar.dart | 67 ++++++++++ lib/widgets.dart | 3 +- pubspec.yaml | 5 + 6 files changed, 273 insertions(+), 1 deletion(-) create mode 100644 lib/src/cast/widgets/expanded_controls/ExpandedControls.dart create mode 100644 lib/src/cast/widgets/expanded_controls/ExpandedControlsPlayer.dart create mode 100644 lib/src/cast/widgets/expanded_controls/ExpandedControlsProgress.dart create mode 100644 lib/src/cast/widgets/expanded_controls/ExpandedControlsToolbar.dart diff --git a/lib/src/cast/widgets/expanded_controls/ExpandedControls.dart b/lib/src/cast/widgets/expanded_controls/ExpandedControls.dart new file mode 100644 index 0000000..2874d38 --- /dev/null +++ b/lib/src/cast/widgets/expanded_controls/ExpandedControls.dart @@ -0,0 +1,115 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_cast_framework/src/cast/widgets/expanded_controls/ExpandedControlsToolbar.dart'; + +import '../../../../cast.dart'; +import 'ExpandedControlsPlayer.dart'; +import 'ExpandedControlsProgress.dart'; + +// TODO call framework to get cast device +const String castDevice = "cast device"; + +const _topDownBlackGradient = BoxDecoration( + gradient: LinearGradient( + begin: Alignment.topCenter, + end: Alignment.bottomCenter, + colors: [ + Colors.black, + Colors.transparent, + ], + ), +); + +const _bottomUpBlackGradient = BoxDecoration( + gradient: LinearGradient( + begin: Alignment.topCenter, + end: Alignment.bottomCenter, + colors: [ + Colors.transparent, + Colors.black, + ], + ), +); + +class ExpandedControls extends StatelessWidget { + final FlutterCastFramework castFramework; + final String castingToText; + final VoidCallback? onBackTapped; + + ExpandedControls({ + required this.castFramework, + this.castingToText = "Casting to", + this.onBackTapped, + }); + + Widget _getDecoratedToolbar(MediaInfo? mediaInfo) { + return Container( + decoration: _topDownBlackGradient, + child: ExpandedControlsToolbar( + castFramework: castFramework, + title: "Title", + subtitle: "Subtitle", + onBackTapped: onBackTapped, + ), + ); + } + + Widget _getDecorateControls(BuildContext context) { + final textStyle = + Theme.of(context).textTheme.bodyText2?.copyWith(color: Colors.white); + + return Container( + decoration: _bottomUpBlackGradient, + child: Column( + children: [ + Padding( + padding: const EdgeInsets.all(8.0), + child: Text("$castingToText $castDevice", style: textStyle), + ), + Padding( + padding: const EdgeInsets.all(8.0), + child: ExpandedControlsProgress(), + ), + Padding( + padding: const EdgeInsets.all(8.0), + child: ExpandedControlsPlayer(), + ), + ], + ), + ); + } + + DecorationImage? _getBackgroundImage(MediaInfo? mediaInfo) { + final imgUrl = mediaInfo?.mediaMetadata?.webImages?.first?.url; + if (imgUrl == null || imgUrl.isEmpty) { + return null; + } + + return DecorationImage( + image: NetworkImage(imgUrl), + fit: BoxFit.cover, + ); + } + + Widget _getFullControls(BuildContext context, MediaInfo? mediaInfo) { + return Container( + decoration: BoxDecoration( + color: Colors.black, + image: _getBackgroundImage(mediaInfo), + ), + child: Column( + children: [ + _getDecoratedToolbar(mediaInfo), + Spacer(), + _getDecorateControls(context), + ], + ), + ); + } + + @override + Widget build(BuildContext context) { + return SafeArea( + child: _getFullControls(context, null), + ); + } +} diff --git a/lib/src/cast/widgets/expanded_controls/ExpandedControlsPlayer.dart b/lib/src/cast/widgets/expanded_controls/ExpandedControlsPlayer.dart new file mode 100644 index 0000000..b243d64 --- /dev/null +++ b/lib/src/cast/widgets/expanded_controls/ExpandedControlsPlayer.dart @@ -0,0 +1,50 @@ +import 'package:flutter/material.dart'; + +class ExpandedControlsPlayer extends StatelessWidget { + final VoidCallback? onClosedCaptionPressed; + final VoidCallback? onPrevPressed; + final VoidCallback? onPlayPausePressed; + final VoidCallback? onNextPressed; + final VoidCallback? onVolumePressed; + + ExpandedControlsPlayer({ + this.onClosedCaptionPressed, + this.onPrevPressed, + this.onPlayPausePressed, + this.onNextPressed, + this.onVolumePressed, + }); + + Widget _getIconButton(IconData icon, VoidCallback? onPressed) { + return IconButton( + padding: EdgeInsets.zero, + onPressed: onPressed, + icon: Icon(icon, color: Colors.white, size: 36), + ); + } + + Widget _getBigIconButton(IconData icon, VoidCallback? onPressed) { + return IconButton( + padding: EdgeInsets.zero, + onPressed: onPressed, + icon: Icon(icon, color: Colors.white, size: 48), + ); + } + + @override + Widget build(BuildContext context) { + return Padding( + padding: const EdgeInsets.symmetric(horizontal: 36, vertical: 0), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + _getIconButton(Icons.closed_caption, onClosedCaptionPressed), + _getIconButton(Icons.skip_previous, onPrevPressed), + _getBigIconButton(Icons.pause_circle, onPlayPausePressed), + _getIconButton(Icons.skip_next, onNextPressed), + _getIconButton(Icons.volume_up, onVolumePressed), + ], + ), + ); + } +} diff --git a/lib/src/cast/widgets/expanded_controls/ExpandedControlsProgress.dart b/lib/src/cast/widgets/expanded_controls/ExpandedControlsProgress.dart new file mode 100644 index 0000000..d759b5f --- /dev/null +++ b/lib/src/cast/widgets/expanded_controls/ExpandedControlsProgress.dart @@ -0,0 +1,34 @@ +import 'package:flutter/material.dart'; +import 'package:flutter/widgets.dart'; + +class ExpandedControlsProgress extends StatelessWidget { + @override + Widget build(BuildContext context) { + final textStyle = + Theme.of(context).textTheme.bodyText2?.copyWith(color: Colors.white); + + return Column( + children: [ + LinearProgressIndicator( + color: Colors.red, + backgroundColor: Colors.grey, + value: 0.5, + ), + Container(height: 8), // Spacer + Row( + children: [ + Text( + "start", + style: textStyle, + ), + Spacer(), + Text( + "end", + style: textStyle, + ), + ], + ), + ], + ); + } +} diff --git a/lib/src/cast/widgets/expanded_controls/ExpandedControlsToolbar.dart b/lib/src/cast/widgets/expanded_controls/ExpandedControlsToolbar.dart new file mode 100644 index 0000000..6dfb4f7 --- /dev/null +++ b/lib/src/cast/widgets/expanded_controls/ExpandedControlsToolbar.dart @@ -0,0 +1,67 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_cast_framework/cast.dart'; +import 'package:flutter_cast_framework/widgets.dart'; + +class ExpandedControlsToolbar extends StatelessWidget { + final FlutterCastFramework castFramework; + final String title; + final String subtitle; + final VoidCallback? onBackTapped; + + const ExpandedControlsToolbar({ + required this.castFramework, + this.title = "", + this.subtitle = "", + this.onBackTapped, + Key? key, + }) : super(key: key); + + @override + Widget build(BuildContext context) { + final titleStyle = Theme.of(context) + .textTheme + .headline5 + ?.copyWith(fontWeight: FontWeight.bold, color: Colors.white); + + final subtitleStyle = + Theme.of(context).textTheme.subtitle1?.copyWith(color: Colors.grey); + + return Row( + children: [ + GestureDetector( + child: Padding( + padding: const EdgeInsets.fromLTRB(8, 8, 16, 8), + child: Icon( + Icons.keyboard_arrow_down, + color: Colors.white, + ), + ), + onTap: onBackTapped, + ), + Expanded( + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceAround, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + this.title, + maxLines: 1, + overflow: TextOverflow.ellipsis, + style: titleStyle, + ), + Text( + this.subtitle, + maxLines: 1, + overflow: TextOverflow.ellipsis, + style: subtitleStyle, + ), + ], + ), + ), + CastButton( + castFramework: castFramework, + ) + ], + ); + } +} diff --git a/lib/widgets.dart b/lib/widgets.dart index 8b0ea75..4497735 100644 --- a/lib/widgets.dart +++ b/lib/widgets.dart @@ -1,4 +1,5 @@ library widgets; export 'src/cast/widgets/CastButton.dart'; -export 'src/cast/widgets/CastIcon.dart'; \ No newline at end of file +export 'src/cast/widgets/CastIcon.dart'; +export 'src/cast/widgets/expanded_controls/ExpandedControls.dart'; diff --git a/pubspec.yaml b/pubspec.yaml index 61420c9..8b5ffb0 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -33,6 +33,11 @@ flutter: ios: pluginClass: FlutterCastFrameworkPlugin + # The following line ensures that the Material Icons font is + # included with your application, so that you can use the icons in + # the material Icons class. + uses-material-design: true + # To add assets to your plugin package, add an assets section, like this: # assets: # - images/a_dot_burr.jpeg