Skip to content

Commit

Permalink
added timeLabelType for showing remaining time
Browse files Browse the repository at this point in the history
  • Loading branch information
suragch committed Apr 30, 2021
1 parent fd9a1ee commit 7e0fdb3
Show file tree
Hide file tree
Showing 7 changed files with 179 additions and 78 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## [0.4.0] - April 30, 2021

* Added `timeLabelType` as a `TimeLabelType` enum with values of `totalTime` and `remainingTime`, which shows the time left as a negative number.

## [0.3.2] - April 26, 2021

* Fixed bug with failure to update label color on theme change.
Expand Down
194 changes: 125 additions & 69 deletions example/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,7 @@ class MyApp extends StatelessWidget {
builder: (context, value, child) {
return MaterialApp(
theme: ThemeData(
primarySwatch: value.color,
brightness: value.brightness
),
primarySwatch: value.color, brightness: value.brightness),
home: HomeWidget(),
);
});
Expand All @@ -44,6 +42,8 @@ class _HomeWidgetState extends State<HomeWidget> {
late AudioPlayer _player;
final url = 'https://www.soundhelix.com/examples/mp3/SoundHelix-Song-2.mp3';
late Stream<DurationState> _durationState;
var _labelLocation = TimeLabelLocation.below;
var _labelType = TimeLabelType.totalTime;

@override
void initState() {
Expand Down Expand Up @@ -82,78 +82,134 @@ class _HomeWidgetState extends State<HomeWidget> {
padding: const EdgeInsets.all(20.0),
child: Column(
children: [
Wrap(children: [
OutlinedButton(
child: Text('Light'),
onPressed: () {
themeNotifier.value = ThemeVariation(Colors.blue, Brightness.light);
},
),
OutlinedButton(
child: Text('Dark'),
onPressed: () {
themeNotifier.value = ThemeVariation(Colors.blue, Brightness.dark);
},
),
]),
_themeButtons(),
_labelLocationButtons(),
_labelTypeButtons(),
Spacer(),
StreamBuilder<DurationState>(
stream: _durationState,
builder: (context, snapshot) {
final durationState = snapshot.data;
final progress = durationState?.progress ?? Duration.zero;
final buffered = durationState?.buffered ?? Duration.zero;
final total = durationState?.total ?? Duration.zero;
return ProgressBar(
progress: progress,
buffered: buffered,
total: total,
onSeek: (duration) {
_player.seek(duration);
},
);
},
),
StreamBuilder<PlayerState>(
stream: _player.playerStateStream,
builder: (context, snapshot) {
final playerState = snapshot.data;
final processingState = playerState?.processingState;
final playing = playerState?.playing;
if (processingState == ProcessingState.loading ||
processingState == ProcessingState.buffering) {
return Container(
margin: EdgeInsets.all(8.0),
width: 32.0,
height: 32.0,
child: CircularProgressIndicator(),
);
} else if (playing != true) {
return IconButton(
icon: Icon(Icons.play_arrow),
iconSize: 32.0,
onPressed: _player.play,
);
} else if (processingState != ProcessingState.completed) {
return IconButton(
icon: Icon(Icons.pause),
iconSize: 32.0,
onPressed: _player.pause,
);
} else {
return IconButton(
icon: Icon(Icons.replay),
iconSize: 32.0,
onPressed: () => _player.seek(Duration.zero),
);
}
},
),
_progressBar(),
_playButton(),
],
),
),
);
}

Wrap _themeButtons() {
return Wrap(children: [
OutlinedButton(
child: Text('light'),
onPressed: () {
themeNotifier.value = ThemeVariation(Colors.blue, Brightness.light);
},
),
OutlinedButton(
child: Text('dark'),
onPressed: () {
themeNotifier.value = ThemeVariation(Colors.blue, Brightness.dark);
},
),
]);
}

Wrap _labelLocationButtons() {
return Wrap(children: [
OutlinedButton(
child: Text('below'),
onPressed: () {
setState(() => _labelLocation = TimeLabelLocation.below);
},
),
OutlinedButton(
child: Text('sides'),
onPressed: () {
setState(() => _labelLocation = TimeLabelLocation.sides);
},
),
OutlinedButton(
child: Text('none'),
onPressed: () {
setState(() => _labelLocation = TimeLabelLocation.none);
},
),
]);
}

Wrap _labelTypeButtons() {
return Wrap(children: [
OutlinedButton(
child: Text('total time'),
onPressed: () {
setState(() => _labelType = TimeLabelType.totalTime);
},
),
OutlinedButton(
child: Text('remaining time'),
onPressed: () {
setState(() => _labelType = TimeLabelType.remainingTime);
},
),
]);
}

StreamBuilder<DurationState> _progressBar() {
return StreamBuilder<DurationState>(
stream: _durationState,
builder: (context, snapshot) {
final durationState = snapshot.data;
final progress = durationState?.progress ?? Duration.zero;
final buffered = durationState?.buffered ?? Duration.zero;
final total = durationState?.total ?? Duration.zero;
return ProgressBar(
progress: progress,
buffered: buffered,
total: total,
onSeek: (duration) {
_player.seek(duration);
},
timeLabelLocation: _labelLocation,
timeLabelType: _labelType,
);
},
);
}

StreamBuilder<PlayerState> _playButton() {
return StreamBuilder<PlayerState>(
stream: _player.playerStateStream,
builder: (context, snapshot) {
final playerState = snapshot.data;
final processingState = playerState?.processingState;
final playing = playerState?.playing;
if (processingState == ProcessingState.loading ||
processingState == ProcessingState.buffering) {
return Container(
margin: EdgeInsets.all(8.0),
width: 32.0,
height: 32.0,
child: CircularProgressIndicator(),
);
} else if (playing != true) {
return IconButton(
icon: Icon(Icons.play_arrow),
iconSize: 32.0,
onPressed: _player.play,
);
} else if (processingState != ProcessingState.completed) {
return IconButton(
icon: Icon(Icons.pause),
iconSize: 32.0,
onPressed: _player.pause,
);
} else {
return IconButton(
icon: Icon(Icons.replay),
iconSize: 32.0,
onPressed: () => _player.seek(Duration.zero),
);
}
},
);
}
}

class DurationState {
Expand Down
6 changes: 3 additions & 3 deletions example/pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ packages:
path: ".."
relative: true
source: path
version: "0.3.2"
version: "0.4.0"
boolean_selector:
dependency: transitive
description:
Expand Down Expand Up @@ -113,7 +113,7 @@ packages:
name: just_audio
url: "https://pub.dartlang.org"
source: hosted
version: "0.7.0"
version: "0.7.4"
just_audio_platform_interface:
dependency: transitive
description:
Expand All @@ -127,7 +127,7 @@ packages:
name: just_audio_web
url: "https://pub.dartlang.org"
source: hosted
version: "0.3.0"
version: "0.3.1"
matcher:
dependency: transitive
description:
Expand Down
2 changes: 1 addition & 1 deletion example/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ dependencies:
sdk: flutter
audio_video_progress_bar:
path: ../
just_audio: ^0.7.0
just_audio: ^0.7.4
rxdart: ^0.26.0

dev_dependencies:
Expand Down
47 changes: 43 additions & 4 deletions lib/audio_video_progress_bar.dart
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,14 @@ enum TimeLabelLocation {
none,
}

/// The right time label can be shown as the [totalTime] or as the
/// [remainingTime]. If the choice is [remainingTime] then this will be shown
/// as a negative number.
enum TimeLabelType {
totalTime,
remainingTime,
}

/// A progress bar widget to show or set the location of the currently
/// playing audio or video content.
///
Expand Down Expand Up @@ -41,6 +49,7 @@ class ProgressBar extends LeafRenderObjectWidget {
this.thumbGlowColor,
this.thumbGlowRadius = 30.0,
this.timeLabelLocation,
this.timeLabelType,
this.timeLabelTextStyle,
}) : super(key: key);

Expand Down Expand Up @@ -113,6 +122,12 @@ class ProgressBar extends LeafRenderObjectWidget {
/// put them on the sides or remove them altogether.
final TimeLabelLocation? timeLabelLocation;

/// What to display for the time label on the right
///
/// The right time label can show the total time or the remaining time as a
/// negative number. The default is [TimeLabelType.totalTime].
final TimeLabelType? timeLabelType;

/// The [TextStyle] used by the time labels.
///
/// By default it is [TextTheme.bodyText1].
Expand All @@ -138,6 +153,7 @@ class ProgressBar extends LeafRenderObjectWidget {
thumbGlowColor ?? (thumbColor ?? primaryColor).withAlpha(80),
thumbGlowRadius: thumbGlowRadius,
timeLabelLocation: timeLabelLocation ?? TimeLabelLocation.below,
timeLabelType: timeLabelType ?? TimeLabelType.totalTime,
timeLabelTextStyle: textStyle,
);
}
Expand All @@ -163,6 +179,7 @@ class ProgressBar extends LeafRenderObjectWidget {
thumbGlowColor ?? (thumbColor ?? primaryColor).withAlpha(80)
..thumbGlowRadius = thumbGlowRadius
..timeLabelLocation = timeLabelLocation ?? TimeLabelLocation.below
..timeLabelType = timeLabelType ?? TimeLabelType.totalTime
..timeLabelTextStyle = textStyle;
}

Expand All @@ -184,6 +201,7 @@ class ProgressBar extends LeafRenderObjectWidget {
properties.add(DoubleProperty('thumbGlowRadius', thumbGlowRadius));
properties
.add(StringProperty('timeLabelLocation', timeLabelLocation.toString()));
properties.add(StringProperty('timeLabelType', timeLabelType.toString()));
properties
.add(DiagnosticsProperty('timeLabelTextStyle', timeLabelTextStyle));
}
Expand All @@ -204,6 +222,7 @@ class _RenderProgressBar extends RenderBox {
required Color thumbGlowColor,
double thumbGlowRadius = 30.0,
required TimeLabelLocation timeLabelLocation,
required TimeLabelType timeLabelType,
TextStyle? timeLabelTextStyle,
}) : _progress = progress,
_total = total,
Expand All @@ -218,6 +237,7 @@ class _RenderProgressBar extends RenderBox {
_thumbGlowColor = thumbGlowColor,
_thumbGlowRadius = thumbGlowRadius,
_timeLabelLocation = timeLabelLocation,
_timeLabelType = timeLabelType,
_timeLabelTextStyle = timeLabelTextStyle {
_drag = HorizontalDragGestureRecognizer()
..onStart = _onDragStart
Expand Down Expand Up @@ -302,8 +322,15 @@ class _RenderProgressBar extends RenderBox {
}

TextPainter _rightTimeLabel() {
final text = _getTimeString(total);
return _layoutText(text);
switch (timeLabelType) {
case TimeLabelType.totalTime:
final text = _getTimeString(total);
return _layoutText(text);
case TimeLabelType.remainingTime:
final remaining = total - progress;
final text = '-${_getTimeString(remaining)}';
return _layoutText(text);
}
}

TextPainter _layoutText(String text) {
Expand Down Expand Up @@ -428,6 +455,18 @@ class _RenderProgressBar extends RenderBox {
markNeedsLayout();
}

/// What to display for the time label on the right
///
/// The right time label can show the total time or the remaining time as a
/// negative number. The default is [TimeLabelType.totalTime].
TimeLabelType get timeLabelType => _timeLabelType;
TimeLabelType _timeLabelType;
set timeLabelType(TimeLabelType value) {
if (_timeLabelType == value) return;
_timeLabelType = value;
markNeedsLayout();
}

/// The text style for the duration text labels. By default this style is
/// taken from the theme's [textStyle.bodyText1].
TextStyle? get timeLabelTextStyle => _timeLabelTextStyle;
Expand Down Expand Up @@ -545,7 +584,7 @@ class _RenderProgressBar extends RenderBox {
final leftTimeLabel = _leftTimeLabel();
leftTimeLabel.paint(canvas, labelOffset);

// total time label
// total or remaining time label
final rightTimeLabel = _rightTimeLabel();
final rightLabelDx = size.width - padding - rightTimeLabel.width;
final rightLabelOffset = Offset(rightLabelDx, barHeight);
Expand Down Expand Up @@ -573,7 +612,7 @@ class _RenderProgressBar extends RenderBox {
final currentLabelOffset = Offset(0, verticalOffset);
leftTimeLabel.paint(canvas, currentLabelOffset);

// total time label
// total or remaining time label
final totalLabelDx = size.width - rightTimeLabel.width;
final totalLabelOffset = Offset(totalLabelDx, verticalOffset);
rightTimeLabel.paint(canvas, totalLabelOffset);
Expand Down
Loading

0 comments on commit 7e0fdb3

Please sign in to comment.