RemoteMediaClient Stub ExpandedControls page
This commit is contained in:
parent
73e30bb8c8
commit
70a0ce95e3
6 changed files with 273 additions and 1 deletions
115
lib/src/cast/widgets/expanded_controls/ExpandedControls.dart
Normal file
115
lib/src/cast/widgets/expanded_controls/ExpandedControls.dart
Normal file
|
|
@ -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),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -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),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -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,
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -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,
|
||||
)
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -2,3 +2,4 @@ library widgets;
|
|||
|
||||
export 'src/cast/widgets/CastButton.dart';
|
||||
export 'src/cast/widgets/CastIcon.dart';
|
||||
export 'src/cast/widgets/expanded_controls/ExpandedControls.dart';
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in a new issue