Add Arabic lyrics review
This commit is contained in:
@@ -0,0 +1,108 @@
|
||||
import MusicAssistantCore
|
||||
import SwiftUI
|
||||
|
||||
struct ArabicLyricsReviewView: View {
|
||||
@Binding var project: SongProject
|
||||
|
||||
private let processor = ArabicPronunciationProcessor()
|
||||
|
||||
@State private var processedLyrics = ""
|
||||
@State private var processingNotes: [ArabicPronunciationProcessingNote] = []
|
||||
|
||||
var body: some View {
|
||||
VStack(alignment: .leading, spacing: 10) {
|
||||
HStack {
|
||||
Text("Arabic lyrics review")
|
||||
.font(.headline)
|
||||
|
||||
Spacer()
|
||||
|
||||
Button(action: refreshProcessedLyrics) {
|
||||
Label("Refresh processed lyrics", systemImage: "arrow.clockwise")
|
||||
.labelStyle(.iconOnly)
|
||||
}
|
||||
.buttonStyle(.borderless)
|
||||
.help("Refresh processed lyrics")
|
||||
}
|
||||
|
||||
Text("Original lyrics")
|
||||
.font(.subheadline)
|
||||
.foregroundStyle(.secondary)
|
||||
|
||||
TextEditor(text: .constant(project.lyrics.text))
|
||||
.font(.body)
|
||||
.frame(minHeight: 96)
|
||||
.disabled(true)
|
||||
|
||||
Text("Processed lyrics")
|
||||
.font(.subheadline)
|
||||
.foregroundStyle(.secondary)
|
||||
|
||||
TextEditor(text: $processedLyrics)
|
||||
.font(.body)
|
||||
.frame(minHeight: 96)
|
||||
|
||||
ForEach(Array(processingNotes.enumerated()), id: \.offset) { entry in
|
||||
Label(entry.element.title, systemImage: entry.element.systemImage)
|
||||
.font(.caption)
|
||||
.foregroundStyle(.secondary)
|
||||
}
|
||||
|
||||
Button(action: applyProcessedLyrics) {
|
||||
Label("Use processed lyrics", systemImage: "checkmark.circle")
|
||||
}
|
||||
.disabled(!canApplyProcessedLyrics)
|
||||
}
|
||||
.onAppear(perform: refreshProcessedLyrics)
|
||||
}
|
||||
|
||||
private var canApplyProcessedLyrics: Bool {
|
||||
let trimmedLyrics = processedLyrics.trimmingCharacters(in: .whitespacesAndNewlines)
|
||||
return !trimmedLyrics.isEmpty && processedLyrics != project.lyrics.text
|
||||
}
|
||||
|
||||
private func refreshProcessedLyrics() {
|
||||
let result = processor.process(
|
||||
lyrics: project.lyrics.text,
|
||||
settings: project.arabicPronunciationSettings
|
||||
)
|
||||
processedLyrics = result.text
|
||||
processingNotes = result.notes
|
||||
}
|
||||
|
||||
private func applyProcessedLyrics() {
|
||||
project.applyReviewedArabicLyrics(processedLyrics)
|
||||
}
|
||||
}
|
||||
|
||||
private extension ArabicPronunciationProcessingNote {
|
||||
var title: String {
|
||||
switch self {
|
||||
case .processingDisabled:
|
||||
return "Arabic processing is disabled"
|
||||
case .diacritizationPolicyUnspecified:
|
||||
return "Select a diacritics policy to continue"
|
||||
case .pronunciationTargetedDiacriticsNeedReview:
|
||||
return "Targeted diacritics need review"
|
||||
case .fullTashkeelNeedsReview:
|
||||
return "Full tashkeel needs review"
|
||||
case .tanweenAdditionNeedsReview:
|
||||
return "Tanween addition needs review"
|
||||
case let .preservedSpellingsProtected(count):
|
||||
return "Protected \(count) preserved spelling\(count == 1 ? "" : "s")"
|
||||
}
|
||||
}
|
||||
|
||||
var systemImage: String {
|
||||
switch self {
|
||||
case .processingDisabled, .diacritizationPolicyUnspecified:
|
||||
return "info.circle"
|
||||
case .pronunciationTargetedDiacriticsNeedReview,
|
||||
.fullTashkeelNeedsReview,
|
||||
.tanweenAdditionNeedsReview:
|
||||
return "exclamationmark.triangle"
|
||||
case .preservedSpellingsProtected:
|
||||
return "checkmark.shield"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,6 +9,10 @@ struct FinalReviewView: View {
|
||||
|
||||
var body: some View {
|
||||
VStack(alignment: .leading, spacing: 12) {
|
||||
ArabicLyricsReviewView(project: $project)
|
||||
|
||||
Divider()
|
||||
|
||||
TextField("Approved lyrics", text: $project.lyrics.text, axis: .vertical)
|
||||
.lineLimit(4...10)
|
||||
|
||||
|
||||
@@ -199,6 +199,15 @@ public extension SongProject {
|
||||
dialects.removeAll { $0.id == dialectID }
|
||||
}
|
||||
|
||||
mutating func applyReviewedArabicLyrics(_ reviewedLyrics: String) {
|
||||
let originalLyrics = lyrics.text
|
||||
lyrics.text = reviewedLyrics
|
||||
|
||||
if sunoOutput?.lyricsText == originalLyrics {
|
||||
sunoOutput?.lyricsText = reviewedLyrics
|
||||
}
|
||||
}
|
||||
|
||||
mutating func setBPMManually(_ value: Int) {
|
||||
bpm = ManualAutoValue(mode: .manual, value: value)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user