[iOS] Update Playlist timestamp formatting when content over 1 hour long (#28497)

This replaces the hardcoded minute second formatting used on the scrubber to dynamically include the hour if the duration is 60 minutes or longer
This commit is contained in:
Kyle Hickinson
2025-04-09 09:53:59 -04:00
committed by GitHub
parent f1d9eb8010
commit d613b5a90f
4 changed files with 40 additions and 9 deletions
@@ -39,7 +39,7 @@ struct MediaScrubber<Label: View>: View {
@Environment(\.layoutDirection) private var layoutDirection
private var currentValueLabel: Text {
return Text(.seconds(currentTime), format: .time(pattern: .minuteSecond))
return Text(.seconds(currentTime), format: .timestamp)
}
@ViewBuilder private var remainingTimeLabel: some View {
@@ -47,7 +47,7 @@ struct MediaScrubber<Label: View>: View {
case .unknown:
EmptyView()
case .seconds(let duration):
Text(.seconds(currentTime - duration), format: .time(pattern: .minuteSecond))
Text(.seconds(currentTime - duration), format: .timestamp)
case .indefinite:
Text(Strings.Playlist.liveIndicator)
}
@@ -55,7 +55,7 @@ struct MediaScrubber<Label: View>: View {
private var durationLabel: Text {
if case .seconds(let duration) = duration {
return Text(.seconds(duration), format: .time(pattern: .minuteSecond))
return Text(.seconds(duration), format: .timestamp)
}
return Text("")
}
@@ -202,7 +202,7 @@ struct DefaultMediaScrubberLabel: View {
var body: some View {
HStack {
Text(.seconds(currentTime), format: .time(pattern: .minuteSecond))
Text(.seconds(currentTime), format: .timestamp)
Spacer()
switch duration {
case .unknown:
@@ -214,9 +214,9 @@ struct DefaultMediaScrubberLabel: View {
} label: {
Group {
if isShowingTotalTime {
Text(.seconds(duration), format: .time(pattern: .minuteSecond))
Text(.seconds(duration), format: .timestamp)
} else {
Text(.seconds(currentTime - duration), format: .time(pattern: .minuteSecond))
Text(.seconds(currentTime - duration), format: .timestamp)
}
}
.transition(.move(edge: .trailing).combined(with: .opacity))
@@ -248,6 +248,12 @@ private struct MediaScrubberPreview: View {
isScrubbing: $isScrubbing
)
.padding()
MediaScrubber(
currentTime: $currentTime,
duration: .seconds(3600),
isScrubbing: $isScrubbing
)
.padding()
MediaScrubber(
currentTime: $currentTime,
duration: .seconds(1000),
@@ -353,7 +353,7 @@ struct CompactMediaScrubberLabel: View {
var duration: PlayerModel.ItemDuration
private var currentValueLabel: Text {
return Text(.seconds(currentTime), format: .time(pattern: .minuteSecond))
return Text(.seconds(currentTime), format: .timestamp)
}
var body: some View {
@@ -361,7 +361,7 @@ struct CompactMediaScrubberLabel: View {
currentValueLabel
if case .seconds(let duration) = duration {
Text(verbatim: "/") // FIXME: Does this need some sort of localization?
Text(.seconds(currentTime - duration), format: .time(pattern: .minuteSecond))
Text(.seconds(currentTime - duration), format: .timestamp)
}
}
.font(.caption2)
@@ -57,7 +57,7 @@ struct PlaylistItemView: View {
switch duration {
case .seconds(let duration):
if duration > 0 {
Text(.seconds(duration), format: .time(pattern: .minuteSecond))
Text(.seconds(duration), format: .timestamp)
} else {
EmptyView()
}
@@ -0,0 +1,25 @@
// Copyright (c) 2025 The Brave Authors. All rights reserved.
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this file,
// You can obtain one at https://mozilla.org/MPL/2.0/.
import Foundation
/// Formats a Duration dynamically based on if the value is over an hour.
struct TimestampFormatStyle: FormatStyle {
func format(_ value: Duration) -> String {
let pattern: Duration.TimeFormatStyle.Pattern
if abs(value.components.seconds) >= (60 * 60) {
pattern = .hourMinuteSecond
} else {
pattern = .minuteSecond
}
return value.formatted(.time(pattern: pattern))
}
}
extension FormatStyle where Self == TimestampFormatStyle {
static var timestamp: TimestampFormatStyle {
.init()
}
}