diff --git a/lib/components/player/player_controls.dart b/lib/components/player/player_controls.dart index 7ae4fa82f..07a6b7ba3 100644 --- a/lib/components/player/player_controls.dart +++ b/lib/components/player/player_controls.dart @@ -7,12 +7,12 @@ import 'package:palette_generator/palette_generator.dart'; import 'package:spotube/collections/spotube_icons.dart'; import 'package:spotube/collections/intents.dart'; import 'package:spotube/extensions/context.dart'; +import 'package:spotube/extensions/duration.dart'; import 'package:spotube/hooks/use_progress.dart'; import 'package:spotube/models/logger.dart'; import 'package:spotube/provider/proxy_playlist/proxy_playlist_provider.dart'; import 'package:spotube/services/audio_player/audio_player.dart'; import 'package:spotube/services/audio_player/loop_mode.dart'; -import 'package:spotube/utils/primitive_utils.dart'; class PlayerControls extends HookConsumerWidget { final PaletteGenerator? palette; @@ -113,19 +113,6 @@ class PlayerControls extends HookConsumerWidget { :progressStatic ) = useProgress(ref); - final totalMinutes = PrimitiveUtils.zeroPadNumStr( - duration.inMinutes.remainder(60), - ); - final totalSeconds = PrimitiveUtils.zeroPadNumStr( - duration.inSeconds.remainder(60), - ); - final currentMinutes = PrimitiveUtils.zeroPadNumStr( - position.inMinutes.remainder(60), - ); - final currentSeconds = PrimitiveUtils.zeroPadNumStr( - position.inSeconds.remainder(60), - ); - final progress = useState( useMemoized(() => progressStatic, []), ); @@ -173,8 +160,8 @@ class PlayerControls extends HookConsumerWidget { child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - Text("$currentMinutes:$currentSeconds"), - Text("$totalMinutes:$totalSeconds"), + Text(position.toHumanReadableString()), + Text(duration.toHumanReadableString()), ], ), ), diff --git a/lib/components/player/sibling_tracks_sheet.dart b/lib/components/player/sibling_tracks_sheet.dart index b7d802f94..d4857853c 100644 --- a/lib/components/player/sibling_tracks_sheet.dart +++ b/lib/components/player/sibling_tracks_sheet.dart @@ -9,6 +9,7 @@ import 'package:spotube/collections/spotube_icons.dart'; import 'package:spotube/components/shared/image/universal_image.dart'; import 'package:spotube/extensions/constrains.dart'; import 'package:spotube/extensions/context.dart'; +import 'package:spotube/extensions/duration.dart'; import 'package:spotube/hooks/use_debounce.dart'; import 'package:spotube/models/matched_track.dart'; import 'package:spotube/models/spotube_track.dart'; @@ -99,9 +100,7 @@ class SiblingTracksSheet extends HookConsumerWidget { shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(5), ), - trailing: Text( - PrimitiveUtils.toReadableDuration(video.duration), - ), + trailing: Text(video.duration.toHumanReadableString()), subtitle: Text(video.channelName), enabled: playlist.isFetching != true, selected: playlist.isFetching != true && diff --git a/lib/components/shared/track_table/track_tile.dart b/lib/components/shared/track_table/track_tile.dart index 757432fe8..0666b7f9f 100644 --- a/lib/components/shared/track_table/track_tile.dart +++ b/lib/components/shared/track_table/track_tile.dart @@ -242,7 +242,7 @@ class TrackTile extends HookConsumerWidget { const SizedBox(width: 8), Text( Duration(milliseconds: track.durationMs ?? 0) - .toHumanReadableString(), + .toHumanReadableString(padZero: false), maxLines: 1, overflow: TextOverflow.ellipsis, ), diff --git a/lib/extensions/duration.dart b/lib/extensions/duration.dart index 183fce5f0..c8612425d 100644 --- a/lib/extensions/duration.dart +++ b/lib/extensions/duration.dart @@ -1,10 +1,21 @@ import 'package:duration/locale.dart'; -import 'package:spotube/utils/primitive_utils.dart'; import 'package:duration/duration.dart'; extension DurationToHumanReadableString on Duration { - String toHumanReadableString() => - "${inMinutes.remainder(60)}:${PrimitiveUtils.zeroPadNumStr(inSeconds.remainder(60))}"; + String toHumanReadableString({padZero = true}) { + final mm = inMinutes + .remainder(60) + .toString() + .padLeft(2, !padZero && inHours == 0 ? '' : "0"); + final ss = inSeconds.remainder(60).toString().padLeft(2, "0"); + + if (inHours > 0) { + final hh = inHours.toString().padLeft(2, !padZero ? '' : "0"); + return "$hh:$mm:$ss"; + } + + return "$mm:$ss"; + } String format({ DurationTersity tersity = DurationTersity.second, diff --git a/lib/utils/primitive_utils.dart b/lib/utils/primitive_utils.dart index a0e54430c..3843601e4 100644 --- a/lib/utils/primitive_utils.dart +++ b/lib/utils/primitive_utils.dart @@ -31,17 +31,6 @@ abstract class PrimitiveUtils { } } - static String zeroPadNumStr(int input) { - return input < 10 ? "0$input" : input.toString(); - } - - static String toReadableDuration(Duration duration) { - final hours = duration.inHours; - final minutes = duration.inMinutes % 60; - final seconds = duration.inSeconds % 60; - return "${hours > 0 ? "${zeroPadNumStr(hours)}:" : ""}${zeroPadNumStr(minutes)}:${zeroPadNumStr(seconds)}"; - } - static Future raceMultiple( Future Function() inner, { Duration timeout = const Duration(milliseconds: 2500),