broken changes

This commit is contained in:
Mark Gregory
2026-11-05 16:26:24 +00:00
parent eb98f97ded
commit 7bf251c5e6
215 changed files with 822178 additions and 26 deletions
+28 -15
View File
@@ -673,7 +673,7 @@ private struct TransportButton: View {
}
struct LibraryView: View {
@ObservedObject var model: AppModel
@State var showDJ = true
@State var workspaceTab = "Karaoke"
@State private var djSongSettings = false
@State private var studioSettingsModal = false
@State private var selected: Int64?
@@ -730,7 +730,7 @@ struct LibraryView: View {
Divider()
TransportView(player:model.player,model:model,search:$search,hasSelection:selectedSong != nil,
play:playSelected,next:playNext,display:{ openWindow(id:"lyrics") })
.padding(showDJ ? 12 : 20)
.padding(20)
Divider()
HStack {
VStack(alignment:.leading,spacing:4) {
@@ -738,7 +738,8 @@ struct LibraryView: View {
Text(source == "Library" ? "\(model.songs.count) songs in your collection" : model.currentVenueName).font(.callout).foregroundStyle(.secondary)
}
Spacer()
if showDJ,["Library","Singer Songs","Playlists"].contains(source) {
TextField("Search karaoke music",text:$search).textFieldStyle(.roundedBorder).frame(maxWidth:260)
if ["Library","Singer Songs","Playlists"].contains(source) {
Button("Song Settings") { djSongSettings = true }
.sheet(isPresented:$djSongSettings) {
VStack(spacing:0) {
@@ -753,7 +754,7 @@ struct LibraryView: View {
if source == "Library" {
Button { importing = true } label: { Label("Import Music",systemImage:"plus") }.buttonStyle(.bordered)
}
}.padding(.horizontal,22).padding(.vertical,showDJ ? 8 : 18)
}.padding(.horizontal,22).padding(.vertical,18)
sourceContent.frame(maxWidth:.infinity,maxHeight:.infinity)
if let progress = model.waveformJob {
HStack(spacing:10) {
@@ -765,19 +766,31 @@ struct LibraryView: View {
}.padding(.horizontal,18).padding(.vertical,8)
}
Divider()
if !showDJ,["Library","Singer Songs","Playlists"].contains(source) { detailPanel.frame(height:135) }
if ["Library","Singer Songs","Playlists"].contains(source) { detailPanel.frame(height:135) }
Divider()
footer.padding(.horizontal,18).padding(.vertical,8)
}.frame(minWidth:780)
}
}
@ViewBuilder private var workspaceLayout: some View {
if showDJ {
VSplitView {
libraryWorkspace.frame(minHeight:400)
DJConsole(model:model,system:model.dj).frame(minHeight:440,idealHeight:510)
}
} else { libraryWorkspace }
private var workspaceLayout: some View {
VStack(spacing:0) {
HStack {
Spacer()
Picker("Workspace",selection:$workspaceTab) {
Label("Karaoke",systemImage:"music.mic").tag("Karaoke")
Label("DJ Studio",systemImage:"opticaldisc").tag("DJ Studio")
}.pickerStyle(.segmented).frame(width:340).accessibilityIdentifier("workspace.tabs")
Spacer()
}.frame(height:43).background(.bar)
Divider()
// Keep both workspaces mounted: playback, selection and MIDI stay alive between tabs.
ZStack {
libraryWorkspace.opacity(workspaceTab == "Karaoke" ? 1 : 0)
.allowsHitTesting(workspaceTab == "Karaoke").accessibilityHidden(workspaceTab != "Karaoke")
DJConsole(model:model,system:model.dj,expanded:true).opacity(workspaceTab == "DJ Studio" ? 1 : 0)
.allowsHitTesting(workspaceTab == "DJ Studio").accessibilityHidden(workspaceTab != "DJ Studio")
}.frame(maxWidth:.infinity,maxHeight:.infinity)
}
}
private var workspace: some View {
workspaceLayout
@@ -786,13 +799,12 @@ struct LibraryView: View {
.focusedSceneValue(\.nameReinterpretation,NameReinterpretationCommands(perform:{beginReinterpretation()},enabled:["Library","Singer Songs"].contains(source) && (selectedSong != nil || !tableSelection.isEmpty)))
.focusedSceneValue(\.libraryCommands,LibraryCommands(importMusic:{importing = true},songInfo:{editingSong = selectedSong},canEdit:selectedSong != nil,play:playSelected,next:playNext,video:{openWindow(id:"lyrics")},settings:{studioSettingsModal = true}))
.sheet(isPresented:$studioSettingsModal) { StudioSettingsDialog(model:model) }
.navigationTitle(source == "Singer Songs" ? (model.singers.first { $0.id == model.selectedSinger }?.name ?? "Singer") : source)
.navigationTitle(workspaceTab == "DJ Studio" ? "DJ Studio" : source == "Singer Songs" ? (model.singers.first { $0.id == model.selectedSinger }?.name ?? "Singer") : source)
.navigationSubtitle(model.currentVenueName)
.searchable(text:$search,placement:.toolbar,prompt:"Search Music")
.toolbar {
ToolbarItemGroup {
Button { studioSettingsModal = true } label: { Label("Settings",systemImage:"gearshape") }
Button { showDJ.toggle() } label: { Label(showDJ ? "Hide DJ" : "Show DJ",systemImage:"waveform.path") }.help("Show or hide the DJ workspace; playback continues")
if workspaceTab == "Karaoke" {
Menu {
Button("Import Files or Folder…") { importing = true }
Button("Import from SMB/NAS…") { importingServer = true }
@@ -805,6 +817,7 @@ struct LibraryView: View {
} label: { Label("Add",systemImage:"plus") }
Button { editingSong = selectedSong } label: { Label("Song Info",systemImage:"info.circle") }.disabled(selectedSong == nil)
Button { openWindow(id:"lyrics") } label: { Label("Video Output",systemImage:"rectangle.on.rectangle") }
}
}
}