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