Skip to content

Commit

Permalink
<Merge> improve-lyrics-ui -> dev
Browse files Browse the repository at this point in the history
  • Loading branch information
chr56 committed May 2, 2023
2 parents c21cae8 + 067f1b5 commit 9765d6f
Show file tree
Hide file tree
Showing 13 changed files with 440 additions and 368 deletions.
24 changes: 19 additions & 5 deletions app/src/main/java/player/phonograph/mediastore/LyricsLoader.kt
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,16 @@ import player.phonograph.App
import player.phonograph.model.Song
import player.phonograph.model.lyrics.AbsLyrics
import player.phonograph.model.lyrics.LrcLyrics
import player.phonograph.model.lyrics.LyricsList
import player.phonograph.model.lyrics.LyricsInfo
import player.phonograph.model.lyrics.LyricsSource
import player.phonograph.model.lyrics.TextLyrics
import player.phonograph.settings.Setting
import player.phonograph.util.FileUtil
import player.phonograph.util.debug
import player.phonograph.util.permissions.hasStorageReadPermission
import player.phonograph.util.reportError
import android.content.Context
import android.net.Uri
import android.util.Log
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
Expand All @@ -31,19 +33,19 @@ object LyricsLoader {

private val backgroundCoroutine: CoroutineScope by lazy { CoroutineScope(Dispatchers.IO) }

suspend fun loadLyrics(songFile: File, song: Song): LyricsList {
suspend fun loadLyrics(songFile: File, song: Song): LyricsInfo {
if (!Setting.instance.enableLyrics) {
debug {
Log.v(TAG, "Lyrics is off for ${song.title}")
}
return LyricsList()
return LyricsInfo.EMPTY
}

if (!hasStorageReadPermission(App.instance)) {
debug {
Log.v(TAG, "No storage read permission to fetch lyrics for ${song.title}")
}
return LyricsList()
return LyricsInfo.EMPTY
}

// embedded
Expand Down Expand Up @@ -73,8 +75,10 @@ object LyricsLoader {
addAll(vagueLyrics)
}

val activated: Int = resultList.indexOfFirst { it is LrcLyrics }

// end of fetching
return LyricsList(resultList)
return LyricsInfo(song, resultList, activated)
}

private fun parseEmbedded(
Expand Down Expand Up @@ -185,5 +189,15 @@ object LyricsLoader {
}
}


fun parseFromUri(context: Context, uri: Uri): AbsLyrics? {
return context.contentResolver.openInputStream(uri)?.use { inputStream ->
inputStream.reader().use {
parse(it.readText(), LyricsSource.ManuallyLoaded())
}
}
}


private const val TAG = "LyricsLoader"
}
2 changes: 1 addition & 1 deletion app/src/main/java/player/phonograph/misc/LyricsUpdater.kt
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ class LyricsUpdater(song: Song?) {
if (!file.exists()) return@also
runBlocking(exceptionHandler) {
LyricsLoader.loadLyrics(file, song).let {
fetcher = LyricsFetcher(it.getLrcLyrics())
fetcher = LyricsFetcher(it.firstLrcLyrics())
}
}
}
Expand Down
43 changes: 0 additions & 43 deletions app/src/main/java/player/phonograph/model/lyrics/LyricsCursor.kt

This file was deleted.

68 changes: 68 additions & 0 deletions app/src/main/java/player/phonograph/model/lyrics/LyricsInfo.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/*
* Copyright (c) 2022~2023 chr_56
*/

package player.phonograph.model.lyrics

import player.phonograph.model.Song
import android.os.Parcelable
import kotlinx.parcelize.Parcelize


@Parcelize
data class LyricsInfo(
val linkedSong: Song,
private val lyricsList: ArrayList<AbsLyrics>,
private val activatedLyricsNumber: Int,
) : Parcelable, List<AbsLyrics> by lyricsList {


fun firstLrcLyrics(): LrcLyrics? = findFirst<LrcLyrics>()
fun firstTextLyrics(): TextLyrics? = findFirst<TextLyrics>()
fun allLyricsFrom(source: LyricsSource): List<AbsLyrics> = lyricsList.filter { it.source == source }
fun firstLyricsFrom(source: LyricsSource): AbsLyrics? = allLyricsFrom(source).firstOrNull()
fun availableSources(): Set<LyricsSource> = lyricsList.map { it.source }.toSet()
val activatedLyrics: AbsLyrics? get() = lyricsList.getOrNull(activatedLyricsNumber)

fun isActive(index: Int) = index == activatedLyricsNumber

private inline fun <reified L> findFirst(): L? {
for (lyric in lyricsList) {
if (lyric is L) return lyric
}
return null
}

fun createAmended(absLyrics: AbsLyrics): LyricsInfo = insect(this, absLyrics)

fun replaceActivated(index: Int): LyricsInfo = setActive(this, index)
fun replaceActivated(lyrics: AbsLyrics): LyricsInfo? = setActive(this, lyrics)

companion object {
val EMPTY = LyricsInfo(Song.EMPTY_SONG, ArrayList(), -1)

private fun insect(old: LyricsInfo, newLyrics: AbsLyrics): LyricsInfo =
LyricsInfo(
old.linkedSong,
ArrayList(old.lyricsList).also { it.add(newLyrics) },
old.activatedLyricsNumber
)

private fun setActive(old: LyricsInfo, index: Int): LyricsInfo =
LyricsInfo(
old.linkedSong,
old.lyricsList,
index
)

private fun setActive(old: LyricsInfo, lyrics: AbsLyrics): LyricsInfo? {
var index = -1
for ((i, l) in old.lyricsList.withIndex()) {
if (l === lyrics) {
index = i
}
}
return if (index > -1) setActive(old, index) else null
}
}
}
79 changes: 0 additions & 79 deletions app/src/main/java/player/phonograph/model/lyrics/LyricsList.kt

This file was deleted.

12 changes: 12 additions & 0 deletions app/src/main/java/player/phonograph/model/lyrics/LyricsSource.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,31 @@

package player.phonograph.model.lyrics

import player.phonograph.R
import android.content.Context

@JvmInline
value class LyricsSource(val type: Int = UNKNOWN_SOURCE) {
@Suppress("FunctionName")
companion object {
fun Embedded() = LyricsSource(EMBEDDED)
fun ExternalPrecise() = LyricsSource(EXTERNAL_PRECISE)
fun ExternalDecorated() = LyricsSource(EXTERNAL_DECORATED)
fun ManuallyLoaded() = LyricsSource(MANUALLY_LOADED)

const val EMBEDDED = 0
const val EXTERNAL_PRECISE = 1
const val EXTERNAL_DECORATED = 2
const val MANUALLY_LOADED = 4

fun Unknown() = LyricsSource(UNKNOWN_SOURCE)
const val UNKNOWN_SOURCE = -1
}

fun name(context: Context): String = when (type) {
EMBEDDED -> context.getString(R.string.embedded_lyrics)
EXTERNAL_DECORATED, EXTERNAL_PRECISE -> context.getString(R.string.external_lyrics)
MANUALLY_LOADED -> context.getString(R.string.loaded)
else -> "unknown"
}
}
Loading

0 comments on commit 9765d6f

Please sign in to comment.