ios 1.0.10: shuffle/repeat on Now Playing, playback speed

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
cdnutterandClaude Opus 5.5 committed 2026-10-20 11:21:32 -07:00
1 parent 5b767cacc2
commit b0dba777f9
6 files changed
+96 -8

No files matched your search

@@ -153,6 +153,7 @@ struct NowPlayingScreen: View {
ProgressVolumeBar(played: c.label, unplayed: c.label3, centerLabel: badge(track))
.padding(.top, panel == .Art ? 34 : 18)
HStack {
SideToggle(symbol: "shuffle", on: pm.shuffle, action: pm.toggleShuffle)
Spacer()
TransportButton(symbol: "backward.fill", size: 34, action: pm.previous)
Spacer()
@@ -169,10 +170,12 @@ struct NowPlayingScreen: View {
Spacer()
TransportButton(symbol: "forward.fill", size: 34, action: pm.next)
Spacer()
SideToggle(symbol: pm.repeatMode == .One ? "repeat.1" : "repeat", on: pm.repeatMode != .Off, action: pm.cycleRepeat)
}
.frame(height: 84)
HStack {
PanelToggle(symbol: "slider.vertical.3", on: panel == .Mixer) { show(.Mixer) }
SpeedMenu()
Button { ui.showInSettings(.Eq) } label: { routeLabel(c) }.buttonStyle(PressFade()).frame(maxWidth: .infinity)
PanelToggle(symbol: "music.mic", on: pm.karaoke) { karaoke() }
PanelToggle(symbol: "list.bullet", on: panel == .Queue) { show(.Queue) }
@@ -246,6 +249,51 @@ private struct TransportButton: View {
}
}
/// Shuffle and repeat, either side of the transport. A dot underneath when on.
private struct SideToggle: View {
let symbol: String
let on: Bool
let action: () -> Void
@Environment(\.palette) private var p
var body: some View {
Button(action: action) {
VStack(spacing: 4) {
Image(systemName: symbol).font(.system(size: 19, weight: .semibold)).contentTransition(.symbolEffect(.replace))
Circle().frame(width: 4, height: 4).opacity(on ? 1 : 0)
}
.foregroundStyle(on ? p.label : p.label3)
.frame(width: 40, height: 56)
.contentShape(Rectangle())
}
.buttonStyle(PressFade())
.sensoryFeedback(.selection, trigger: symbol + "\(on)")
}
}
/// Playback speed picker; shows the current speed.
private struct SpeedMenu: View {
private var g: AppGraph { .shared }
@Environment(\.palette) private var p
var body: some View {
let pm = g.playback
Menu {
Picker("Speed", selection: Binding(get: { pm.speed }, set: { pm.setSpeed($0) })) {
ForEach(PlaybackManager.speeds, id: \.self) { Text(Self.label($0)).tag($0) }
}
} label: {
Text(Self.label(pm.speed)).font(.system(size: 14, weight: .semibold).monospacedDigit())
.foregroundStyle(pm.speed == 1 ? p.label2 : p.bg)
.frame(minWidth: 40, minHeight: 40)
.padding(.horizontal, 2)
.background(pm.speed == 1 ? .clear : p.label, in: RoundedRectangle(cornerRadius: 10, style: .continuous))
}
.menuOrder(.fixed)
}
static func label(_ v: Double) -> String {
(v == v.rounded() ? String(Int(v)) : String(format: "%g", v)) + "×"
}
}
private struct PanelToggle: View {
let symbol: String
let on: Bool