Stemify iOS 1.1 and WebUI updates, repo restructure into desktop/ios/server/web
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
894dd5a695
commit
df5d847169
157 files changed
+3935
-742
No files matched your search
@@ -0,0 +1,89 @@
|
||||
import SwiftUI
|
||||
|
||||
/// The buttons under the transport on Now Playing that the user can hide.
|
||||
enum NowPlayingButton: String, CaseIterable, Identifiable {
|
||||
case Mixer, Speed, Route, AirPlay, Karaoke
|
||||
var id: String { rawValue }
|
||||
var label: String {
|
||||
switch self {
|
||||
case .Mixer: "Stem Mixer"
|
||||
case .Speed: "Speed"
|
||||
case .Route: "Output & EQ"
|
||||
case .AirPlay: "AirPlay"
|
||||
case .Karaoke: "Karaoke"
|
||||
}
|
||||
}
|
||||
var icon: String {
|
||||
switch self {
|
||||
case .Mixer: "slider.vertical.3"
|
||||
case .Speed: "speedometer"
|
||||
case .Route: "hifispeaker"
|
||||
case .AirPlay: "airplayaudio"
|
||||
case .Karaoke: "music.mic"
|
||||
}
|
||||
}
|
||||
static func hidden(_ s: String) -> Set<NowPlayingButton> { Set(s.split(separator: ",").compactMap { Self(rawValue: String($0)) }) }
|
||||
}
|
||||
|
||||
struct NowPlayingOptionsScreen: View {
|
||||
private var g: AppGraph { .shared }
|
||||
@Environment(\.palette) private var p
|
||||
|
||||
var body: some View {
|
||||
@Bindable var s = g.settings
|
||||
List {
|
||||
Section {
|
||||
ForEach(NowPlayingButton.allCases) { b in
|
||||
Toggle(isOn: Binding(
|
||||
get: { !NowPlayingButton.hidden(s.hiddenNowPlaying).contains(b) },
|
||||
set: { on in
|
||||
var h = NowPlayingButton.hidden(s.hiddenNowPlaying)
|
||||
if on { h.remove(b) } else { h.insert(b) }
|
||||
s.hiddenNowPlaying = h.map(\.rawValue).sorted().joined(separator: ",")
|
||||
})) {
|
||||
HStack(spacing: 14) {
|
||||
SettingsIcon(symbol: b.icon, bg: 0x5AC8FA)
|
||||
Text(b.label).foregroundStyle(p.label)
|
||||
}
|
||||
}
|
||||
.tint(Color(hex: 0x34C759))
|
||||
.themedRow()
|
||||
}
|
||||
} footer: { Text("Choose which buttons show under the playback controls.").foregroundStyle(p.label2) }
|
||||
Section {
|
||||
Toggle(isOn: $s.lockScreenMix) {
|
||||
HStack(spacing: 14) {
|
||||
SettingsIcon(symbol: "lock.fill", bg: 0xFF9500)
|
||||
Text("Back Button Changes Mix").foregroundStyle(p.label)
|
||||
}
|
||||
}
|
||||
.tint(Color(hex: 0x34C759))
|
||||
.themedRow()
|
||||
} header: { Text("Lock Screen").foregroundStyle(p.label2) } footer: {
|
||||
Text("While stems play, the back button on the lock screen, Control Center and headphones moves to the next mix instead of the previous song, like the Mix button in CarPlay. The mix name shows after the artist.").foregroundStyle(p.label2)
|
||||
}
|
||||
}
|
||||
.listStyle(.insetGrouped)
|
||||
.themedList()
|
||||
.navigationTitle("Now Playing")
|
||||
}
|
||||
}
|
||||
|
||||
struct StepperCell: View {
|
||||
let title: String
|
||||
@Binding var value: Int
|
||||
let icon: String
|
||||
let iconBg: UInt32
|
||||
@Environment(\.palette) private var p
|
||||
var body: some View {
|
||||
Stepper(value: $value, in: 0...50) {
|
||||
HStack(spacing: 14) {
|
||||
SettingsIcon(symbol: icon, bg: iconBg)
|
||||
Text(title).foregroundStyle(p.label)
|
||||
Spacer(minLength: 8)
|
||||
Text(value == 0 ? "Off" : "\(value) songs").foregroundStyle(p.label2)
|
||||
}
|
||||
}
|
||||
.themedRow()
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user