ExpandedControls: integrate stream progress

This commit is contained in:
gianlucaparadise 2021-11-29 20:09:25 +01:00
parent a5530e7441
commit d8d815710f
2 changed files with 106 additions and 9 deletions

View file

@ -30,10 +30,11 @@ const _bottomUpBlackGradient = BoxDecoration(
), ),
); );
class ExpandedControls extends StatelessWidget { class ExpandedControls extends StatefulWidget {
final FlutterCastFramework castFramework; final FlutterCastFramework castFramework;
final String castingToText; final String castingToText;
final VoidCallback? onBackTapped; final VoidCallback? onBackTapped;
final controller = ExpandedControlsProgressController();
ExpandedControls({ ExpandedControls({
required this.castFramework, required this.castFramework,
@ -41,6 +42,33 @@ class ExpandedControls extends StatelessWidget {
this.onBackTapped, this.onBackTapped,
}); });
@override
State<ExpandedControls> createState() => _ExpandedControlsState();
}
class _ExpandedControlsState extends State<ExpandedControls> {
@override
void initState() {
final sessionManager = widget.castFramework.castContext.sessionManager;
sessionManager.remoteMediaClient.onProgressUpdated = _onProgressUpdated;
super.initState();
}
@override
void dispose() {
final sessionManager = widget.castFramework.castContext.sessionManager;
sessionManager.remoteMediaClient.onProgressUpdated = null;
widget.controller.dispose();
super.dispose();
}
void _onProgressUpdated(int progress, int duration) {
widget.controller.updateProgress(progress, duration);
}
Widget _getDecoratedToolbar(MediaInfo? mediaInfo) { Widget _getDecoratedToolbar(MediaInfo? mediaInfo) {
// Title and subtitle can't be retrieved at the moment // Title and subtitle can't be retrieved at the moment
// final title = mediaInfo?.mediaMetadata?.strings[MediaMetadataKey.title] // final title = mediaInfo?.mediaMetadata?.strings[MediaMetadataKey.title]
@ -51,13 +79,15 @@ class ExpandedControls extends StatelessWidget {
return Container( return Container(
decoration: _topDownBlackGradient, decoration: _topDownBlackGradient,
child: ExpandedControlsToolbar( child: ExpandedControlsToolbar(
castFramework: widget.castFramework,
title: title, title: title,
subtitle: subtitle, subtitle: subtitle,
onBackTapped: widget.onBackTapped,
), ),
); );
} }
Widget _getDecorateControls(BuildContext context) { Widget _getDecoratedControls(BuildContext context, MediaInfo? mediaInfo) {
final textStyle = final textStyle =
Theme.of(context).textTheme.bodyText2?.copyWith(color: Colors.white); Theme.of(context).textTheme.bodyText2?.copyWith(color: Colors.white);
@ -67,11 +97,14 @@ class ExpandedControls extends StatelessWidget {
children: [ children: [
Padding( Padding(
padding: const EdgeInsets.all(8.0), padding: const EdgeInsets.all(8.0),
child: Text("$castingToText $castDevice", style: textStyle), child:
Text("${widget.castingToText} $castDevice", style: textStyle),
), ),
Padding( Padding(
padding: const EdgeInsets.all(8.0), padding: const EdgeInsets.all(8.0),
child: ExpandedControlsProgress(), child: ExpandedControlsProgress(
controller: widget.controller,
),
), ),
Padding( Padding(
padding: const EdgeInsets.all(8.0), padding: const EdgeInsets.all(8.0),
@ -104,7 +137,7 @@ class ExpandedControls extends StatelessWidget {
children: [ children: [
_getDecoratedToolbar(mediaInfo), _getDecoratedToolbar(mediaInfo),
Spacer(), Spacer(),
_getDecorateControls(context), _getDecoratedControls(context, mediaInfo),
], ],
), ),
); );

View file

@ -1,29 +1,83 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
class ExpandedControlsProgress extends StatelessWidget { class ExpandedControlsProgressController extends ChangeNotifier {
int progress = 0;
int duration = 0;
void updateProgress(int progress, int duration) {
this.progress = progress;
this.duration = duration;
notifyListeners();
}
}
class ExpandedControlsProgress extends StatefulWidget {
final ExpandedControlsProgressController controller;
const ExpandedControlsProgress({
Key? key,
required this.controller,
}) : super(key: key);
@override
State<ExpandedControlsProgress> createState() =>
_ExpandedControlsProgressState();
}
class _ExpandedControlsProgressState extends State<ExpandedControlsProgress> {
int progress = 0;
int duration = 0;
@override
void initState() {
widget.controller.addListener(_onProgressUpdated);
super.initState();
}
@override
void dispose() {
widget.controller.removeListener(_onProgressUpdated);
super.dispose();
}
void _onProgressUpdated() {
setState(() {
if (!mounted) return;
this.progress = widget.controller.progress;
this.duration = widget.controller.duration;
});
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final textStyle = final textStyle =
Theme.of(context).textTheme.bodyText2?.copyWith(color: Colors.white); Theme.of(context).textTheme.bodyText2?.copyWith(color: Colors.white);
// this is the denominator, can't be 0
final durationFix = this.duration == 0 ? 1 : this.duration;
final progressPercent = this.progress / durationFix;
final progressD = Duration(milliseconds: this.progress);
final durationD = Duration(milliseconds: this.duration);
return Column( return Column(
children: [ children: [
LinearProgressIndicator( LinearProgressIndicator(
color: Colors.red, color: Colors.red,
backgroundColor: Colors.grey, backgroundColor: Colors.grey,
value: 0.5, value: progressPercent,
), ),
Container(height: 8), // Spacer Container(height: 8), // Spacer
Row( Row(
children: [ children: [
Text( Text(
"start", _positionToString(progressD, durationD),
style: textStyle, style: textStyle,
), ),
Spacer(), Spacer(),
Text( Text(
"end", _positionToString(durationD, durationD),
style: textStyle, style: textStyle,
), ),
], ],
@ -32,3 +86,13 @@ class ExpandedControlsProgress extends StatelessWidget {
); );
} }
} }
String _positionToString(Duration d, Duration total) {
String twoDigits(int n) => n.toString().padLeft(2, "0");
if (total.inMinutes <= 60) {
// This is less than a hour, I display only minutes and seconds
return "${twoDigits(d.inMinutes)}:${twoDigits(d.inSeconds.remainder(60))}";
}
return "${twoDigits(d.inHours)}:${twoDigits(d.inMinutes.remainder(60))}:${twoDigits(d.inSeconds.remainder(60))}";
}