yattee/Shared/Player/StreamControl.swift

93 lines
3.5 KiB
Swift
Raw Normal View History

2022-02-16 20:23:11 +00:00
import SwiftUI
struct StreamControl: View {
2022-08-14 22:17:00 +00:00
@Binding var presentingButtonHintAlert: Bool
2022-02-16 20:23:11 +00:00
@EnvironmentObject<PlayerModel> private var player
2022-08-14 22:17:00 +00:00
init(presentingButtonHintAlert: Binding<Bool> = .constant(false)) {
_presentingButtonHintAlert = presentingButtonHintAlert
}
2022-02-16 20:23:11 +00:00
var body: some View {
Group {
#if os(macOS)
Picker("", selection: $player.streamSelection) {
ForEach(InstancesModel.all) { instance in
let instanceStreams = availableStreamsForInstance(instance)
if !instanceStreams.values.isEmpty {
let kinds = Array(instanceStreams.keys).sorted { $0 < $1 }
Section(header: Text(instance.longDescription)) {
ForEach(kinds, id: \.self) { key in
ForEach(instanceStreams[key] ?? []) { stream in
2022-05-21 19:30:39 +00:00
Text(stream.description).tag(Stream?.some(stream))
2022-02-16 20:23:11 +00:00
}
if kinds.count > 1 {
Divider()
}
}
}
}
}
}
.disabled(player.isLoadingAvailableStreams)
2022-08-14 17:06:22 +00:00
#elseif os(iOS)
2022-06-14 22:41:49 +00:00
Picker("", selection: $player.streamSelection) {
2022-02-16 20:23:11 +00:00
ForEach(InstancesModel.all) { instance in
let instanceStreams = availableStreamsForInstance(instance)
if !instanceStreams.values.isEmpty {
let kinds = Array(instanceStreams.keys).sorted { $0 < $1 }
2022-06-14 22:41:49 +00:00
ForEach(kinds, id: \.self) { key in
ForEach(instanceStreams[key] ?? []) { stream in
Text(stream.description).tag(Stream?.some(stream))
2022-02-16 20:23:11 +00:00
}
}
}
}
}
2022-06-14 22:41:49 +00:00
.frame(minWidth: 110)
.fixedSize(horizontal: true, vertical: true)
2022-02-16 20:23:11 +00:00
.disabled(player.isLoadingAvailableStreams)
2022-08-14 17:06:22 +00:00
#else
2022-08-14 22:17:00 +00:00
Button {
presentingButtonHintAlert = true
} label: {
2022-08-14 17:06:22 +00:00
Text(player.streamSelection?.shortQuality ?? "loading")
.frame(maxWidth: 320)
}
.contextMenu {
ForEach(player.availableStreamsSorted) { stream in
Button(stream.description) { player.streamSelection = stream }
}
Button("Close", role: .cancel) {}
}
2022-02-16 20:23:11 +00:00
#endif
}
.transaction { t in t.animation = .none }
.onChange(of: player.streamSelection) { selection in
2022-08-14 17:06:22 +00:00
guard let selection = selection else { return }
player.upgradeToStream(selection)
player.controls.hideOverlays()
2022-02-16 20:23:11 +00:00
}
.frame(alignment: .trailing)
}
private func availableStreamsForInstance(_ instance: Instance) -> [Stream.Kind: [Stream]] {
let streams = player.availableStreamsSorted.filter { $0.instance == instance }.filter { player.backend.canPlay($0) }
return Dictionary(grouping: streams, by: \.kind!)
}
}
struct StreamControl_Previews: PreviewProvider {
static var previews: some View {
StreamControl()
}
}