Add explicit Suno handoff action

This commit is contained in:
diyaa
2026-09-14 22:22:38 +02:00
parent 61267e201e
commit 448d390671
4 changed files with 88 additions and 2 deletions
@@ -3,9 +3,11 @@ import SwiftUI
struct FinalReviewView: View {
@Binding var project: SongProject
@Environment(\.openURL) private var openURL
@State private var newFieldKey = ""
@State private var newFieldValue = ""
@State private var handoffStatus: HandoffStatus?
var body: some View {
VStack(alignment: .leading, spacing: 12) {
@@ -42,6 +44,16 @@ struct FinalReviewView: View {
Label("Prepare fields", systemImage: "wand.and.stars")
}
.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)
}
TextField("Suno lyrics", text: sunoLyricsBinding, axis: .vertical)
@@ -165,6 +177,62 @@ struct FinalReviewView: View {
generatedAt: Date()
)
}
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
}
openURL(SunoHandoffDestination.createPageURL) { accepted in
handoffStatus = accepted
? .opened
: .failed("Unable to open the Suno Create page.")
}
}
}
private enum HandoffStatus: Equatable {
case opened
case failed(String)
var title: String {
switch self {
case .opened:
return "Suno Create opened in your browser."
case let .failed(message):
return message
}
}
var systemImage: String {
switch self {
case .opened:
return "checkmark.circle.fill"
case .failed:
return "exclamationmark.triangle.fill"
}
}
var foregroundStyle: Color {
switch self {
case .opened:
return .green
case .failed:
return .red
}
}
}
#Preview {