import DesignSystem import MusubiCore import SwiftUI struct ContentView: View { let sourceList: SourceListModel var body: some View { NavigationSplitView { SourceListView(sourceList: sourceList) .navigationSplitViewColumnWidth(min: 220, ideal: 260) } detail: { EmptyStateView(text: "Noch keine Szene. Zieh eine Quelle auf einen Bildschirm.") } .navigationTitle("Musubi") .navigationSubtitle("NDI rein. Bild, Ton und Stimme raus.") } } private struct SourceListView: View { let sourceList: SourceListModel var body: some View { Group { switch sourceList.state { case .unavailable: EmptyStateView(text: "NDI lässt sich nicht starten. Prüfe die Installation des NDI SDK.") case .idle, .searching: if sourceList.sources.isEmpty { EmptyStateView(text: "Keine NDI-Quellen gefunden. Prüfe, ob das Technik-Netz an en7 hängt.") } else { List(sourceList.sources, id: \.ndiName) { source in SourceRow(source: source) } .scrollContentBackground(.hidden) } } } .background(Theme.Color.kasumi) .safeAreaInset(edge: .top, spacing: 0) { Text("Quellen") .font(Theme.Font.title) .foregroundStyle(Theme.Color.washi) .frame(maxWidth: .infinity, alignment: .leading) .padding(Theme.Space.card) } } } private struct SourceRow: View { let source: Source var body: some View { VStack(alignment: .leading, spacing: Theme.Space.unit / 2) { Text(verbatim: source.label) .font(Theme.Font.body) .foregroundStyle(Theme.Color.washi) Text(verbatim: source.ndiName) .font(Theme.Font.caption.monospaced()) .foregroundStyle(Theme.Color.nezumi) } .padding(.vertical, Theme.Space.unit / 2) } } private struct EmptyStateView: View { let text: LocalizedStringKey var body: some View { Text(text) .font(Theme.Font.body) .foregroundStyle(Theme.Color.nezumi) .multilineTextAlignment(.center) .padding(Theme.Space.card * 2) .frame(maxWidth: .infinity, maxHeight: .infinity) .background(Theme.Color.sumi) } }