Files
2026-09-13 22:42:50 +02:00

109 lines
3.6 KiB
Swift

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"
}
}
}