Remove external music generation handoff

This commit is contained in:
diyaa
2026-09-15 12:16:08 +02:00
parent cd066d0a82
commit 1ebb5aadc3
11 changed files with 22 additions and 409 deletions
@@ -1,4 +1,3 @@
import AppKit
import MusicAssistantCore
import SwiftUI
@@ -7,8 +6,6 @@ struct FinalReviewView: View {
@State private var newFieldKey = ""
@State private var newFieldValue = ""
@State private var handoffStatus: HandoffStatus?
@State private var sunoPayload: SunoHandoffPayload?
var body: some View {
VStack(alignment: .leading, spacing: 12) {
@@ -34,7 +31,7 @@ struct FinalReviewView: View {
Divider()
HStack {
Text("Suno fields")
Text("Final song output")
.font(.headline)
Spacer()
@@ -46,31 +43,11 @@ struct FinalReviewView: View {
}
.disabled(project.sunoOutput != nil)
Button(action: sendToSuno) {
Label("Send to Suno", systemImage: "arrow.up.forward.app")
}
}
if let handoffStatus {
Label(handoffStatus.title, systemImage: handoffStatus.systemImage)
.font(.caption)
.foregroundStyle(handoffStatus.foregroundStyle)
}
if let fieldsToCopy, let output = project.sunoOutput {
HStack(spacing: 8) {
ForEach(fieldsToCopy) { field in
Button("Copy \(field.displayName)") {
copy(field, from: output)
}
.buttonStyle(.bordered)
}
}
}
TextField("Suno lyrics", text: sunoLyricsBinding, axis: .vertical)
TextField("Lyrics", text: sunoLyricsBinding, axis: .vertical)
.lineLimit(4...10)
TextField("Suno style prompt", text: sunoStylePromptBinding, axis: .vertical)
TextField("Style prompt", text: sunoStylePromptBinding, axis: .vertical)
.lineLimit(3...8)
if !additionalFieldKeys.isEmpty {
@@ -110,16 +87,6 @@ struct FinalReviewView: View {
.help("Add field")
}
}
.sheet(isPresented: Binding(
get: { sunoPayload != nil },
set: { if !$0 { sunoPayload = nil } }
)) {
if let sunoPayload {
SunoHandoffSheet(payload: sunoPayload) { report in
handoffStatus = .fieldFill(report)
}
}
}
}
private var additionalFieldKeys: [String] {
@@ -200,95 +167,6 @@ struct FinalReviewView: View {
)
}
private func sendToSuno() {
ensureSunoOutput()
guard let output = project.sunoOutput else { return }
do {
try CompiledSunoOutputValidator().validate(
CompiledSunoOutput(lyricsText: output.lyricsText, stylePrompt: output.stylePrompt)
)
} catch let validationError as LocalizedError {
handoffStatus = .failed(validationError.errorDescription ?? "Unable to prepare the Suno handoff.")
return
} catch {
handoffStatus = .failed("Unable to prepare the Suno handoff.")
return
}
sunoPayload = SunoHandoffPayload(
title: project.title,
lyrics: output.lyricsText,
stylePrompt: output.stylePrompt
)
}
private var fieldsToCopy: [SunoHandoffField]? {
guard case let .fieldFill(report) = handoffStatus else { return nil }
let fields = SunoHandoffField.allCases.filter {
if case .copyRequired = report.results[$0] { return true }
return false
}
return fields.isEmpty ? nil : fields
}
private func copy(_ field: SunoHandoffField, from output: SunoOutput) {
let value: String
switch field {
case .title:
value = project.title
case .lyrics:
value = output.lyricsText
case .stylePrompt:
value = output.stylePrompt
}
NSPasteboard.general.clearContents()
NSPasteboard.general.setString(value, forType: .string)
}
}
private enum HandoffStatus: Equatable {
case fieldFill(SunoFieldFillReport)
case failed(String)
var title: String {
switch self {
case let .fieldFill(report):
let fieldsToCopy = report.results.compactMap { field, result in
if case .copyRequired = result { return field.displayName }
return nil
}
return fieldsToCopy.isEmpty
? "Suno fields filled in your browser."
: "Copy these fields into Suno: \(fieldsToCopy.joined(separator: ", "))."
case let .failed(message):
return message
}
}
var systemImage: String {
switch self {
case let .fieldFill(report):
return report.results.values.contains { if case .copyRequired = $0 { return true }; return false }
? "exclamationmark.triangle.fill"
: "checkmark.circle.fill"
case .failed:
return "exclamationmark.triangle.fill"
}
}
var foregroundStyle: Color {
switch self {
case let .fieldFill(report):
return report.results.values.contains { if case .copyRequired = $0 { return true }; return false }
? .orange
: .green
case .failed:
return .red
}
}
}
#Preview {