Fix lyrics navigation, translation line alignment, and store reset
Navigation: present search as a sheet from library (avoids nested NavigationStack), use view-based NavigationLink for song rows (fixes double-push from duplicate navigationDestination). Translation: Apple Translation inserts a blank line after every translated line. Strip all blanks from the EN output, then re-insert them at the same positions where the original ES has blanks. Result is 1:1 line pairing between Spanish and English. Store reset: revert localStoreResetVersion bump — adding SavedSong is a lightweight SwiftData migration, no store nuke needed. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -134,16 +134,70 @@ struct LyricsConfirmationView: View {
|
||||
private func translateLyrics(session: sending TranslationSession) async {
|
||||
await MainActor.run { isTranslating = true }
|
||||
let text = result.lyricsES
|
||||
let esLines = text.components(separatedBy: "\n")
|
||||
print("[LyricsTranslation] Spanish line count: \(esLines.count)")
|
||||
print("[LyricsTranslation] Spanish blank lines: \(esLines.filter { $0.trimmingCharacters(in: .whitespaces).isEmpty }.count)")
|
||||
print("[LyricsTranslation] First 10 ES lines:")
|
||||
for (i, line) in esLines.prefix(10).enumerated() {
|
||||
print(" ES[\(i)]: \(line.isEmpty ? "(blank)" : line)")
|
||||
}
|
||||
|
||||
do {
|
||||
let response = try await session.translate(text)
|
||||
await MainActor.run { translatedEN = response.targetText }
|
||||
let enLines = response.targetText.components(separatedBy: "\n")
|
||||
print("[LyricsTranslation] English line count: \(enLines.count)")
|
||||
print("[LyricsTranslation] English blank lines: \(enLines.filter { $0.trimmingCharacters(in: .whitespaces).isEmpty }.count)")
|
||||
print("[LyricsTranslation] First 10 EN lines:")
|
||||
for (i, line) in enLines.prefix(10).enumerated() {
|
||||
print(" EN[\(i)]: \(line.isEmpty ? "(blank)" : line)")
|
||||
}
|
||||
// The Translation framework often inserts a blank line after every
|
||||
// translated line. Collapse consecutive blank lines into single blanks,
|
||||
// then trim leading/trailing blanks so the EN structure matches the ES.
|
||||
let normalized = Self.normalizeTranslationLineBreaks(
|
||||
translated: response.targetText,
|
||||
originalES: text
|
||||
)
|
||||
let normalizedLines = normalized.components(separatedBy: "\n")
|
||||
print("[LyricsTranslation] After normalization: EN lines \(enLines.count) → \(normalizedLines.count) (target: \(esLines.count))")
|
||||
|
||||
await MainActor.run { translatedEN = normalized }
|
||||
} catch {
|
||||
print("Translation error: \(error)")
|
||||
print("[LyricsTranslation] Translation error: \(error)")
|
||||
await MainActor.run { translationError = true }
|
||||
}
|
||||
await MainActor.run { isTranslating = false }
|
||||
}
|
||||
|
||||
/// Re-align translated line breaks to match the original Spanish structure.
|
||||
/// The Translation framework often inserts a blank line after every translated
|
||||
/// line. We strip all blanks from the EN output, then re-insert them at the
|
||||
/// same positions where the original ES text has blank lines.
|
||||
/// Re-align translated line breaks to match the original Spanish structure.
|
||||
private static func normalizeTranslationLineBreaks(translated: String, originalES: String) -> String {
|
||||
let esLines = originalES.components(separatedBy: "\n")
|
||||
let enContentLines = translated.components(separatedBy: "\n")
|
||||
.filter { !$0.trimmingCharacters(in: .whitespaces).isEmpty }
|
||||
|
||||
// Walk ES lines. For each blank ES line, insert a blank in the result.
|
||||
// For each content ES line, consume the next EN content line.
|
||||
var result: [String] = []
|
||||
var enIndex = 0
|
||||
for esLine in esLines {
|
||||
if esLine.trimmingCharacters(in: .whitespaces).isEmpty {
|
||||
result.append("")
|
||||
} else if enIndex < enContentLines.count {
|
||||
result.append(enContentLines[enIndex])
|
||||
enIndex += 1
|
||||
} else {
|
||||
result.append("")
|
||||
}
|
||||
}
|
||||
|
||||
print("[LyricsNormalize] ES lines: \(esLines.count), EN content: \(enContentLines.count), result: \(result.count), EN consumed: \(enIndex)")
|
||||
return result.joined(separator: "\n")
|
||||
}
|
||||
|
||||
private func saveSong() {
|
||||
let song = SavedSong(
|
||||
title: result.title,
|
||||
|
||||
Reference in New Issue
Block a user