mirror of
https://github.com/whoeevee/EeveeSpotifyReborn.git
synced 2026-01-09 00:23:20 +01:00
romanized lyrics for all sources
This commit is contained in:
@@ -213,7 +213,8 @@ func getCurrentTrackLyricsData(originalLyrics: Lyrics? = nil) throws -> Data {
|
||||
lyricsDto = try repository.getLyrics(searchQuery, options: options)
|
||||
}
|
||||
|
||||
lastLyricsWasRomanized = lyricsDto.romanized
|
||||
lastLyricsWasRomanized = lyricsDto.romanization == .romanized
|
||||
|| (lyricsDto.romanization == .canBeRomanized && UserDefaults.lyricsOptions.romanization)
|
||||
lastLyricsAreEmpty = lyricsDto.lines.isEmpty
|
||||
|
||||
let lyrics = Lyrics.with {
|
||||
|
||||
@@ -3,7 +3,7 @@ import Foundation
|
||||
struct LyricsDto {
|
||||
var lines: [LyricsLineDto]
|
||||
var timeSynced: Bool
|
||||
var romanized: Bool = false
|
||||
var romanization: LyricsRomanizationStatus
|
||||
var translation: LyricsTranslationDto?
|
||||
|
||||
func toLyricsData(source: String) -> LyricsData {
|
||||
@@ -13,8 +13,10 @@ struct LyricsDto {
|
||||
$0.providedBy = "\(source) (EeveeSpotify)"
|
||||
}
|
||||
|
||||
lyricsData.lines = lines.isEmpty
|
||||
? [
|
||||
let shouldRomanize = UserDefaults.lyricsOptions.romanization
|
||||
|
||||
if lines.isEmpty {
|
||||
lyricsData.lines = [
|
||||
LyricsLine.with {
|
||||
$0.content = "This song is instrumental."
|
||||
},
|
||||
@@ -25,12 +27,17 @@ struct LyricsDto {
|
||||
$0.content = ""
|
||||
}
|
||||
]
|
||||
: lines.map { line in
|
||||
}
|
||||
else {
|
||||
lyricsData.lines = lines.map { line in
|
||||
LyricsLine.with {
|
||||
$0.content = line.content
|
||||
$0.content = (shouldRomanize && romanization == .canBeRomanized)
|
||||
? line.content.applyingTransform(.toLatin, reverse: false)!
|
||||
: line.content
|
||||
$0.offsetMs = Int32(line.offsetMs ?? 0)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if let translation = translation {
|
||||
lyricsData.translation = LyricsTranslation.with {
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
import Foundation
|
||||
|
||||
enum LyricsRomanizationStatus {
|
||||
case romanized
|
||||
case canBeRomanized
|
||||
case original
|
||||
}
|
||||
@@ -145,12 +145,22 @@ struct GeniusLyricsRepository: LyricsRepository {
|
||||
)
|
||||
|
||||
let songInfo = try getSongInfo(song.id)
|
||||
let plainLines = songInfo.lyrics.plain.components(separatedBy: "\n")
|
||||
let plainLyrics = songInfo.lyrics.plain
|
||||
let plainLines = plainLyrics.components(separatedBy: "\n")
|
||||
|
||||
var romanization = LyricsRomanizationStatus.original
|
||||
|
||||
if hasFoundRomanizedLyrics {
|
||||
romanization = .romanized
|
||||
}
|
||||
else if plainLyrics.canBeRomanized {
|
||||
romanization = .canBeRomanized
|
||||
}
|
||||
|
||||
return LyricsDto(
|
||||
lines: mapLyricsLines(plainLines).map { line in LyricsLineDto(content: line) },
|
||||
timeSynced: false,
|
||||
romanized: hasFoundRomanizedLyrics
|
||||
romanization: romanization
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -105,7 +105,8 @@ struct LrcLibLyricsRepository: LyricsRepository {
|
||||
lines: mapSyncedLyricsLines(
|
||||
syncedLyrics.components(separatedBy: "\n").dropLast()
|
||||
),
|
||||
timeSynced: true
|
||||
timeSynced: true,
|
||||
romanization: syncedLyrics.canBeRomanized ? .canBeRomanized : .original
|
||||
)
|
||||
}
|
||||
|
||||
@@ -118,7 +119,8 @@ struct LrcLibLyricsRepository: LyricsRepository {
|
||||
.components(separatedBy: "\n")
|
||||
.dropLast()
|
||||
.map { content in LyricsLineDto(content: content) },
|
||||
timeSynced: false
|
||||
timeSynced: false,
|
||||
romanization: plainLyrics.canBeRomanized ? .canBeRomanized : .original
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -228,10 +228,19 @@ class MusixmatchLyricsRepository: LyricsRepository {
|
||||
}
|
||||
}
|
||||
|
||||
var romanization = LyricsRomanizationStatus.original
|
||||
|
||||
if romanized {
|
||||
romanization = .romanized
|
||||
}
|
||||
else if lyricsLines.map({ $0.content }).joined().canBeRomanized {
|
||||
romanization = .canBeRomanized
|
||||
}
|
||||
|
||||
return LyricsDto(
|
||||
lines: lyricsLines,
|
||||
timeSynced: true,
|
||||
romanized: romanized,
|
||||
romanization: romanization,
|
||||
translation: translation
|
||||
)
|
||||
}
|
||||
@@ -258,7 +267,8 @@ class MusixmatchLyricsRepository: LyricsRepository {
|
||||
.components(separatedBy: "\n")
|
||||
.dropLast()
|
||||
.map { LyricsLineDto(content: $0.lyricsNoteIfEmpty) },
|
||||
timeSynced: false
|
||||
timeSynced: false,
|
||||
romanization: plainLyrics.canBeRomanized ? .canBeRomanized : .original
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -115,7 +115,10 @@ struct PetitLyricsRepository: LyricsRepository {
|
||||
offsetMs: $0.words.first!.starttime
|
||||
)
|
||||
},
|
||||
timeSynced: true
|
||||
timeSynced: true,
|
||||
romanization: lyrics.lines.map { $0.linestring }.joined().canBeRomanized
|
||||
? .canBeRomanized
|
||||
: .original
|
||||
)
|
||||
|
||||
case .plain:
|
||||
@@ -125,7 +128,8 @@ struct PetitLyricsRepository: LyricsRepository {
|
||||
lines: stringLyrics
|
||||
.components(separatedBy: "\n")
|
||||
.map { LyricsLineDto(content: $0) },
|
||||
timeSynced: false
|
||||
timeSynced: false,
|
||||
romanization: stringLyrics.canBeRomanized ? .canBeRomanized : .original
|
||||
)
|
||||
|
||||
default:
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import Foundation
|
||||
import NaturalLanguage
|
||||
|
||||
extension String {
|
||||
|
||||
@@ -45,6 +46,17 @@ extension String {
|
||||
)
|
||||
}
|
||||
|
||||
var canBeRomanized: Bool {
|
||||
let languageRecognizer = NLLanguageRecognizer()
|
||||
languageRecognizer.processString(self)
|
||||
|
||||
if let code = languageRecognizer.dominantLanguage?.rawValue {
|
||||
return ["ja", "ko"].contains(code) || code.contains("zh")
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
var hexadecimal: Data? {
|
||||
var data = Data(capacity: count / 2)
|
||||
|
||||
|
||||
@@ -37,13 +37,11 @@ struct EeveeLyricsSettingsView: View {
|
||||
|
||||
//
|
||||
|
||||
if [.genius, .musixmatch].contains(lyricsSource) || geniusFallback {
|
||||
Section(footer: Text("Load romanized lyrics from Musixmatch or Genius.")) {
|
||||
Toggle(
|
||||
"Romanized Lyrics",
|
||||
isOn: $lyricsOptions.romanization
|
||||
)
|
||||
}
|
||||
Section(footer: Text("Display romanized lyrics for Japanese, Korean, and Chinese.")) {
|
||||
Toggle(
|
||||
"Romanized Lyrics",
|
||||
isOn: $lyricsOptions.romanization
|
||||
)
|
||||
}
|
||||
|
||||
if lyricsSource == .musixmatch {
|
||||
@@ -64,7 +62,7 @@ struct EeveeLyricsSettingsView: View {
|
||||
.foregroundColor(.gray)
|
||||
}
|
||||
} footer: {
|
||||
Text("You can enter a 2-letter Musixmatch language code and see translated lyrics on Musixmatch if they are available. It overrides Romanized Lyrics.")
|
||||
Text("You can enter a 2-letter Musixmatch language code and see translated lyrics on Musixmatch if they are available.")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user