Common screen for Normal and Synced the later is preferred
This commit is contained in:
parent
dd59459786
commit
62372ec205
11 changed files with 177 additions and 261 deletions
|
@ -14,7 +14,7 @@ android {
|
||||||
vectorDrawables.useSupportLibrary = true
|
vectorDrawables.useSupportLibrary = true
|
||||||
|
|
||||||
applicationId "code.name.monkey.retromusic"
|
applicationId "code.name.monkey.retromusic"
|
||||||
versionCode 10595
|
versionCode 10596
|
||||||
versionName '6.0.2-beta'
|
versionName '6.0.2-beta'
|
||||||
|
|
||||||
buildConfigField("String", "GOOGLE_PLAY_LICENSING_KEY", "\"${getProperty(getProperties('../public.properties'), 'GOOGLE_PLAY_LICENSE_KEY')}\"")
|
buildConfigField("String", "GOOGLE_PLAY_LICENSING_KEY", "\"${getProperty(getProperties('../public.properties'), 'GOOGLE_PLAY_LICENSE_KEY')}\"")
|
||||||
|
|
|
@ -234,8 +234,7 @@ abstract class AbsSlidingMusicPanelActivity : AbsMusicServiceActivity(),
|
||||||
navigationView.labelVisibilityMode = PreferenceUtil.tabTitleMode
|
navigationView.labelVisibilityMode = PreferenceUtil.tabTitleMode
|
||||||
}
|
}
|
||||||
TOGGLE_FULL_SCREEN -> {
|
TOGGLE_FULL_SCREEN -> {
|
||||||
if (!PreferenceUtil.isFullScreenMode) exitFullscreen()
|
recreate()
|
||||||
setEdgeToEdgeOrImmersive()
|
|
||||||
}
|
}
|
||||||
SCREEN_ON_LYRICS -> {
|
SCREEN_ON_LYRICS -> {
|
||||||
keepScreenOn(bottomSheetBehavior.state == STATE_EXPANDED && PreferenceUtil.lyricsScreenOn && PreferenceUtil.showLyrics || PreferenceUtil.isScreenOnEnabled)
|
keepScreenOn(bottomSheetBehavior.state == STATE_EXPANDED && PreferenceUtil.lyricsScreenOn && PreferenceUtil.showLyrics || PreferenceUtil.isScreenOnEnabled)
|
||||||
|
|
|
@ -12,11 +12,10 @@
|
||||||
* See the GNU General Public License for more details.
|
* See the GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
package code.name.monkey.retromusic.fragments.other
|
package code.name.monkey.retromusic.fragments.lyrics
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
import android.app.Activity
|
import android.app.Activity
|
||||||
import android.content.Intent
|
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.provider.MediaStore
|
import android.provider.MediaStore
|
||||||
|
@ -26,22 +25,19 @@ import androidx.activity.result.ActivityResultLauncher
|
||||||
import androidx.activity.result.IntentSenderRequest
|
import androidx.activity.result.IntentSenderRequest
|
||||||
import androidx.activity.result.contract.ActivityResultContracts
|
import androidx.activity.result.contract.ActivityResultContracts
|
||||||
import androidx.core.view.isVisible
|
import androidx.core.view.isVisible
|
||||||
import androidx.fragment.app.Fragment
|
|
||||||
import androidx.fragment.app.FragmentActivity
|
|
||||||
import androidx.navigation.fragment.findNavController
|
import androidx.navigation.fragment.findNavController
|
||||||
import androidx.transition.Fade
|
import androidx.transition.Fade
|
||||||
import androidx.viewpager2.adapter.FragmentStateAdapter
|
|
||||||
import code.name.monkey.appthemehelper.common.ATHToolbarActivity
|
import code.name.monkey.appthemehelper.common.ATHToolbarActivity
|
||||||
import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper
|
import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper
|
||||||
import code.name.monkey.appthemehelper.util.VersionUtils
|
import code.name.monkey.appthemehelper.util.VersionUtils
|
||||||
import code.name.monkey.retromusic.R
|
import code.name.monkey.retromusic.R
|
||||||
import code.name.monkey.retromusic.activities.tageditor.TagWriter
|
import code.name.monkey.retromusic.activities.tageditor.TagWriter
|
||||||
import code.name.monkey.retromusic.databinding.FragmentLyricsBinding
|
import code.name.monkey.retromusic.databinding.FragmentLyricsBinding
|
||||||
import code.name.monkey.retromusic.databinding.FragmentNormalLyricsBinding
|
import code.name.monkey.retromusic.extensions.accentColor
|
||||||
import code.name.monkey.retromusic.databinding.FragmentSyncedLyricsBinding
|
import code.name.monkey.retromusic.extensions.materialDialog
|
||||||
import code.name.monkey.retromusic.extensions.*
|
import code.name.monkey.retromusic.extensions.openUrl
|
||||||
|
import code.name.monkey.retromusic.extensions.uri
|
||||||
import code.name.monkey.retromusic.fragments.base.AbsMainActivityFragment
|
import code.name.monkey.retromusic.fragments.base.AbsMainActivityFragment
|
||||||
import code.name.monkey.retromusic.fragments.base.AbsMusicServiceFragment
|
|
||||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote
|
import code.name.monkey.retromusic.helper.MusicPlayerRemote
|
||||||
import code.name.monkey.retromusic.helper.MusicProgressViewUpdateHelper
|
import code.name.monkey.retromusic.helper.MusicProgressViewUpdateHelper
|
||||||
import code.name.monkey.retromusic.lyrics.LrcView
|
import code.name.monkey.retromusic.lyrics.LrcView
|
||||||
|
@ -51,7 +47,6 @@ import code.name.monkey.retromusic.util.FileUtils
|
||||||
import code.name.monkey.retromusic.util.LyricUtil
|
import code.name.monkey.retromusic.util.LyricUtil
|
||||||
import code.name.monkey.retromusic.util.UriUtil
|
import code.name.monkey.retromusic.util.UriUtil
|
||||||
import com.afollestad.materialdialogs.input.input
|
import com.afollestad.materialdialogs.input.input
|
||||||
import com.google.android.material.tabs.TabLayoutMediator
|
|
||||||
import kotlinx.coroutines.GlobalScope
|
import kotlinx.coroutines.GlobalScope
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import org.jaudiotagger.audio.AudioFileIO
|
import org.jaudiotagger.audio.AudioFileIO
|
||||||
|
@ -59,14 +54,23 @@ import org.jaudiotagger.tag.FieldKey
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.io.FileOutputStream
|
import java.io.FileOutputStream
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
import kotlin.collections.set
|
||||||
|
|
||||||
class LyricsFragment : AbsMainActivityFragment(R.layout.fragment_lyrics) {
|
class LyricsFragment : AbsMainActivityFragment(R.layout.fragment_lyrics),
|
||||||
|
MusicProgressViewUpdateHelper.Callback {
|
||||||
|
|
||||||
private var _binding: FragmentLyricsBinding? = null
|
private var _binding: FragmentLyricsBinding? = null
|
||||||
private val binding get() = _binding!!
|
private val binding get() = _binding!!
|
||||||
private lateinit var song: Song
|
private lateinit var song: Song
|
||||||
|
|
||||||
private lateinit var lyricsSectionsAdapter: LyricsSectionsAdapter
|
private lateinit var normalLyricsLauncher: ActivityResultLauncher<IntentSenderRequest>
|
||||||
|
private lateinit var editSyncedLyricsLauncher: ActivityResultLauncher<IntentSenderRequest>
|
||||||
|
|
||||||
|
private lateinit var cacheFile: File
|
||||||
|
private var syncedLyrics: String = ""
|
||||||
|
private lateinit var syncedFileUri: Uri
|
||||||
|
|
||||||
|
private var lyricsType: LyricsType = LyricsType.NORMAL_LYRICS
|
||||||
|
|
||||||
private val googleSearchLrcUrl: String
|
private val googleSearchLrcUrl: String
|
||||||
get() {
|
get() {
|
||||||
|
@ -77,13 +81,7 @@ class LyricsFragment : AbsMainActivityFragment(R.layout.fragment_lyrics) {
|
||||||
return baseUrl
|
return baseUrl
|
||||||
}
|
}
|
||||||
|
|
||||||
private lateinit var normalLyricsLauncher: ActivityResultLauncher<IntentSenderRequest>
|
private lateinit var updateHelper: MusicProgressViewUpdateHelper
|
||||||
private lateinit var newSyncedLyricsLauncher: ActivityResultLauncher<Intent>
|
|
||||||
private lateinit var editSyncedLyricsLauncher: ActivityResultLauncher<IntentSenderRequest>
|
|
||||||
|
|
||||||
private lateinit var cacheFile: File
|
|
||||||
private var syncedLyrics: String = ""
|
|
||||||
private lateinit var syncedFileUri: Uri
|
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
|
@ -94,14 +92,6 @@ class LyricsFragment : AbsMainActivityFragment(R.layout.fragment_lyrics) {
|
||||||
FileUtils.copyFileToUri(requireContext(), cacheFile, song.uri)
|
FileUtils.copyFileToUri(requireContext(), cacheFile, song.uri)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
newSyncedLyricsLauncher =
|
|
||||||
registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
|
|
||||||
if (result.resultCode == Activity.RESULT_OK) {
|
|
||||||
context?.contentResolver?.openOutputStream(result.data?.data!!)?.use {
|
|
||||||
it.write(syncedLyrics.toByteArray())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
editSyncedLyricsLauncher =
|
editSyncedLyricsLauncher =
|
||||||
registerForActivityResult(ActivityResultContracts.StartIntentSenderForResult()) {
|
registerForActivityResult(ActivityResultContracts.StartIntentSenderForResult()) {
|
||||||
if (it.resultCode == Activity.RESULT_OK) {
|
if (it.resultCode == Activity.RESULT_OK) {
|
||||||
|
@ -118,36 +108,42 @@ class LyricsFragment : AbsMainActivityFragment(R.layout.fragment_lyrics) {
|
||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
enterTransition = Fade()
|
enterTransition = Fade()
|
||||||
exitTransition = Fade()
|
exitTransition = Fade()
|
||||||
updateTitleSong()
|
|
||||||
lyricsSectionsAdapter = LyricsSectionsAdapter(requireActivity())
|
|
||||||
_binding = FragmentLyricsBinding.bind(view)
|
_binding = FragmentLyricsBinding.bind(view)
|
||||||
binding.container.transitionName = "lyrics"
|
updateHelper = MusicProgressViewUpdateHelper(this, 500, 1000)
|
||||||
|
updateTitleSong()
|
||||||
|
setupLyricsView()
|
||||||
|
loadLyrics()
|
||||||
|
|
||||||
setupWakelock()
|
setupWakelock()
|
||||||
setupViews()
|
setupViews()
|
||||||
setupToolbar()
|
setupToolbar()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setupViews() {
|
private fun setupLyricsView() {
|
||||||
binding.lyricsPager.adapter = lyricsSectionsAdapter
|
binding.lyricsView.apply {
|
||||||
TabLayoutMediator(binding.tabLyrics, binding.lyricsPager) { tab, position ->
|
setCurrentColor(accentColor())
|
||||||
tab.text = when (position) {
|
setTimeTextColor(accentColor())
|
||||||
0 -> getString(R.string.synced_lyrics)
|
setTimelineColor(accentColor())
|
||||||
1 -> getString(R.string.normal_lyrics)
|
setTimelineTextColor(accentColor())
|
||||||
else -> ""
|
setDraggable(true, LrcView.OnPlayClickListener {
|
||||||
}
|
MusicPlayerRemote.seekTo(it.toInt())
|
||||||
}.attach()
|
return@OnPlayClickListener true
|
||||||
// lyricsPager.isUserInputEnabled = false
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
binding.tabLyrics.setSelectedTabIndicatorColor(accentColor())
|
override fun onUpdateProgressViews(progress: Int, total: Int) {
|
||||||
binding.tabLyrics.setTabTextColors(textColorSecondary(), accentColor())
|
binding.lyricsView.updateTime(progress.toLong())
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun setupViews() {
|
||||||
binding.editButton.accentColor()
|
binding.editButton.accentColor()
|
||||||
binding.editButton.setOnClickListener {
|
binding.editButton.setOnClickListener {
|
||||||
when (binding.lyricsPager.currentItem) {
|
when (lyricsType) {
|
||||||
0 -> {
|
LyricsType.SYNCED_LYRICS -> {
|
||||||
editSyncedLyrics()
|
editSyncedLyrics()
|
||||||
}
|
}
|
||||||
1 -> {
|
LyricsType.NORMAL_LYRICS -> {
|
||||||
editNormalLyrics()
|
editNormalLyrics()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -157,11 +153,13 @@ class LyricsFragment : AbsMainActivityFragment(R.layout.fragment_lyrics) {
|
||||||
override fun onPlayingMetaChanged() {
|
override fun onPlayingMetaChanged() {
|
||||||
super.onPlayingMetaChanged()
|
super.onPlayingMetaChanged()
|
||||||
updateTitleSong()
|
updateTitleSong()
|
||||||
|
loadLyrics()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onServiceConnected() {
|
override fun onServiceConnected() {
|
||||||
super.onServiceConnected()
|
super.onServiceConnected()
|
||||||
updateTitleSong()
|
updateTitleSong()
|
||||||
|
loadLyrics()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun updateTitleSong() {
|
private fun updateTitleSong() {
|
||||||
|
@ -181,7 +179,7 @@ class LyricsFragment : AbsMainActivityFragment(R.layout.fragment_lyrics) {
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCreateMenu(menu: Menu, inflater: MenuInflater) {
|
override fun onCreateMenu(menu: Menu, inflater: MenuInflater) {
|
||||||
inflater.inflate(R.menu.menu_search, menu)
|
inflater.inflate(R.menu.menu_lyrics, menu)
|
||||||
ToolbarContentTintHelper.handleOnCreateOptionsMenu(
|
ToolbarContentTintHelper.handleOnCreateOptionsMenu(
|
||||||
requireContext(),
|
requireContext(),
|
||||||
binding.toolbar,
|
binding.toolbar,
|
||||||
|
@ -197,17 +195,18 @@ class LyricsFragment : AbsMainActivityFragment(R.layout.fragment_lyrics) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@SuppressLint("CheckResult")
|
@SuppressLint("CheckResult")
|
||||||
private fun editNormalLyrics() {
|
private fun editNormalLyrics(lyrics: String? = null) {
|
||||||
var content = ""
|
val file = File(song.data)
|
||||||
val file = File(MusicPlayerRemote.currentSong.data)
|
val content = lyrics ?: try {
|
||||||
try {
|
AudioFileIO.read(file).tagOrCreateDefault.getFirst(FieldKey.LYRICS)
|
||||||
content = AudioFileIO.read(file).tagOrCreateDefault.getFirst(FieldKey.LYRICS)
|
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
e.printStackTrace()
|
e.printStackTrace()
|
||||||
|
""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val song = song
|
||||||
|
|
||||||
materialDialog().show {
|
materialDialog().show {
|
||||||
title(res = R.string.edit_normal_lyrics)
|
title(res = R.string.edit_normal_lyrics)
|
||||||
input(
|
input(
|
||||||
|
@ -217,7 +216,6 @@ class LyricsFragment : AbsMainActivityFragment(R.layout.fragment_lyrics) {
|
||||||
) { _, input ->
|
) { _, input ->
|
||||||
val fieldKeyValueMap = EnumMap<FieldKey, String>(FieldKey::class.java)
|
val fieldKeyValueMap = EnumMap<FieldKey, String>(FieldKey::class.java)
|
||||||
fieldKeyValueMap[FieldKey.LYRICS] = input.toString()
|
fieldKeyValueMap[FieldKey.LYRICS] = input.toString()
|
||||||
syncedLyrics = input.toString()
|
|
||||||
GlobalScope.launch {
|
GlobalScope.launch {
|
||||||
if (VersionUtils.hasR()) {
|
if (VersionUtils.hasR()) {
|
||||||
cacheFile = TagWriter.writeTagsToFilesR(
|
cacheFile = TagWriter.writeTagsToFilesR(
|
||||||
|
@ -244,7 +242,7 @@ class LyricsFragment : AbsMainActivityFragment(R.layout.fragment_lyrics) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
positiveButton(res = R.string.save) {
|
positiveButton(res = R.string.save) {
|
||||||
(lyricsSectionsAdapter.fragments[1].first as NormalLyrics).loadNormalLyrics()
|
loadNormalLyrics()
|
||||||
}
|
}
|
||||||
negativeButton(res = android.R.string.cancel)
|
negativeButton(res = android.R.string.cancel)
|
||||||
}
|
}
|
||||||
|
@ -252,9 +250,10 @@ class LyricsFragment : AbsMainActivityFragment(R.layout.fragment_lyrics) {
|
||||||
|
|
||||||
|
|
||||||
@SuppressLint("CheckResult")
|
@SuppressLint("CheckResult")
|
||||||
private fun editSyncedLyrics() {
|
private fun editSyncedLyrics(lyrics: String? = null) {
|
||||||
val content: String = LyricUtil.getStringFromLrc(LyricUtil.getSyncedLyricsFile(song))
|
val content = lyrics ?: LyricUtil.getStringFromLrc(LyricUtil.getSyncedLyricsFile(song))
|
||||||
|
|
||||||
|
val song = song
|
||||||
materialDialog().show {
|
materialDialog().show {
|
||||||
title(res = R.string.edit_synced_lyrics)
|
title(res = R.string.edit_synced_lyrics)
|
||||||
input(
|
input(
|
||||||
|
@ -277,145 +276,86 @@ class LyricsFragment : AbsMainActivityFragment(R.layout.fragment_lyrics) {
|
||||||
IntentSenderRequest.Builder(pendingIntent).build()
|
IntentSenderRequest.Builder(pendingIntent).build()
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
val intent = Intent(Intent.ACTION_CREATE_DOCUMENT)
|
val fieldKeyValueMap = EnumMap<FieldKey, String>(FieldKey::class.java)
|
||||||
intent.addCategory(Intent.CATEGORY_OPENABLE)
|
fieldKeyValueMap[FieldKey.LYRICS] = input.toString()
|
||||||
intent.type = "*/*"
|
GlobalScope.launch {
|
||||||
intent.putExtra(
|
cacheFile = TagWriter.writeTagsToFilesR(
|
||||||
Intent.EXTRA_TITLE,
|
requireContext(),
|
||||||
LyricUtil.getLrcOriginalPath(File(song.data).name)
|
AudioTagInfo(listOf(song.data), fieldKeyValueMap, null)
|
||||||
)
|
)[0]
|
||||||
newSyncedLyricsLauncher.launch(intent)
|
val pendingIntent = MediaStore.createWriteRequest(
|
||||||
|
requireContext().contentResolver,
|
||||||
|
listOf(song.uri)
|
||||||
|
)
|
||||||
|
|
||||||
|
normalLyricsLauncher.launch(
|
||||||
|
IntentSenderRequest.Builder(pendingIntent).build()
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
LyricUtil.writeLrc(song, input.toString())
|
LyricUtil.writeLrc(song, input.toString())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
positiveButton(res = R.string.save) {
|
positiveButton(res = R.string.save) {
|
||||||
(lyricsSectionsAdapter.fragments[0].first as SyncedLyrics).loadLRCLyrics()
|
loadLRCLyrics()
|
||||||
}
|
}
|
||||||
negativeButton(res = android.R.string.cancel)
|
negativeButton(res = android.R.string.cancel)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class LyricsSectionsAdapter(fragmentActivity: FragmentActivity) :
|
private fun loadNormalLyrics() {
|
||||||
FragmentStateAdapter(fragmentActivity) {
|
var lyrics: String? = null
|
||||||
val fragments = listOf(
|
val file = File(song.data)
|
||||||
Pair(SyncedLyrics(), R.string.synced_lyrics),
|
try {
|
||||||
Pair(NormalLyrics(), R.string.normal_lyrics)
|
lyrics = AudioFileIO.read(file).tagOrCreateDefault.getFirst(FieldKey.LYRICS)
|
||||||
)
|
} catch (e: Exception) {
|
||||||
|
e.printStackTrace()
|
||||||
|
|
||||||
override fun getItemCount(): Int {
|
|
||||||
return fragments.size
|
|
||||||
}
|
}
|
||||||
|
binding.noLyricsFound.isVisible = lyrics.isNullOrEmpty()
|
||||||
|
binding.normalLyrics.text = lyrics
|
||||||
|
}
|
||||||
|
|
||||||
override fun createFragment(position: Int): Fragment {
|
/**
|
||||||
return fragments[position].first
|
* @return success
|
||||||
|
*/
|
||||||
|
private fun loadLRCLyrics(): Boolean {
|
||||||
|
binding.lyricsView.setLabel(getString(R.string.empty))
|
||||||
|
val lrcFile = LyricUtil.getSyncedLyricsFile(song)
|
||||||
|
if (lrcFile != null) {
|
||||||
|
binding.lyricsView.loadLrc(lrcFile)
|
||||||
|
println("File: ${lrcFile.absolutePath}")
|
||||||
|
} else {
|
||||||
|
val embeddedLyrics = LyricUtil.getEmbeddedSyncedLyrics(song.data)
|
||||||
|
if (embeddedLyrics != null) {
|
||||||
|
binding.lyricsView.loadLrc(embeddedLyrics)
|
||||||
|
println("Lyrics: ${embeddedLyrics.substring(0..50)}")
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun loadLyrics() {
|
||||||
|
lyricsType = if (!loadLRCLyrics()) {
|
||||||
|
loadNormalLyrics()
|
||||||
|
LyricsType.SYNCED_LYRICS
|
||||||
|
} else {
|
||||||
|
binding.noLyricsFound.isVisible = false
|
||||||
|
binding.normalLyrics.text = ""
|
||||||
|
LyricsType.NORMAL_LYRICS
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class NormalLyrics : AbsMusicServiceFragment(R.layout.fragment_normal_lyrics) {
|
override fun onResume() {
|
||||||
|
super.onResume()
|
||||||
private var _binding: FragmentNormalLyricsBinding? = null
|
updateHelper.start()
|
||||||
private val binding get() = _binding!!
|
|
||||||
|
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
|
||||||
_binding = FragmentNormalLyricsBinding.bind(view)
|
|
||||||
loadNormalLyrics()
|
|
||||||
super.onViewCreated(view, savedInstanceState)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun loadNormalLyrics() {
|
|
||||||
var lyrics: String? = null
|
|
||||||
val file = File(MusicPlayerRemote.currentSong.data)
|
|
||||||
try {
|
|
||||||
lyrics = AudioFileIO.read(file).tagOrCreateDefault.getFirst(FieldKey.LYRICS)
|
|
||||||
} catch (e: Exception) {
|
|
||||||
e.printStackTrace()
|
|
||||||
}
|
|
||||||
binding.noLyricsFound.isVisible = lyrics.isNullOrEmpty()
|
|
||||||
binding.normalLyrics.text = lyrics
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onPlayingMetaChanged() {
|
|
||||||
super.onPlayingMetaChanged()
|
|
||||||
loadNormalLyrics()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onServiceConnected() {
|
|
||||||
super.onServiceConnected()
|
|
||||||
loadNormalLyrics()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onDestroyView() {
|
|
||||||
super.onDestroyView()
|
|
||||||
_binding = null
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class SyncedLyrics : AbsMusicServiceFragment(R.layout.fragment_synced_lyrics),
|
override fun onPause() {
|
||||||
MusicProgressViewUpdateHelper.Callback {
|
super.onPause()
|
||||||
|
updateHelper.stop()
|
||||||
private var _binding: FragmentSyncedLyricsBinding? = null
|
|
||||||
private val binding get() = _binding!!
|
|
||||||
private lateinit var updateHelper: MusicProgressViewUpdateHelper
|
|
||||||
|
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
|
||||||
updateHelper = MusicProgressViewUpdateHelper(this, 500, 1000)
|
|
||||||
_binding = FragmentSyncedLyricsBinding.bind(view)
|
|
||||||
setupLyricsView()
|
|
||||||
loadLRCLyrics()
|
|
||||||
super.onViewCreated(view, savedInstanceState)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun loadLRCLyrics() {
|
|
||||||
binding.lyricsView.setLabel(getString(R.string.empty))
|
|
||||||
LyricUtil.getSyncedLyricsFile(MusicPlayerRemote.currentSong)?.let {
|
|
||||||
binding.lyricsView.loadLrc(it)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun setupLyricsView() {
|
|
||||||
binding.lyricsView.apply {
|
|
||||||
setCurrentColor(accentColor())
|
|
||||||
setTimeTextColor(accentColor())
|
|
||||||
setTimelineColor(accentColor())
|
|
||||||
setTimelineTextColor(accentColor())
|
|
||||||
setDraggable(true, LrcView.OnPlayClickListener {
|
|
||||||
MusicPlayerRemote.seekTo(it.toInt())
|
|
||||||
return@OnPlayClickListener true
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onUpdateProgressViews(progress: Int, total: Int) {
|
|
||||||
binding.lyricsView.updateTime(progress.toLong())
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onPlayingMetaChanged() {
|
|
||||||
super.onPlayingMetaChanged()
|
|
||||||
loadLRCLyrics()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onServiceConnected() {
|
|
||||||
super.onServiceConnected()
|
|
||||||
loadLRCLyrics()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onResume() {
|
|
||||||
super.onResume()
|
|
||||||
updateHelper.start()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onPause() {
|
|
||||||
super.onPause()
|
|
||||||
updateHelper.stop()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onDestroyView() {
|
|
||||||
super.onDestroyView()
|
|
||||||
_binding = null
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDestroyView() {
|
override fun onDestroyView() {
|
||||||
|
@ -424,4 +364,9 @@ class LyricsFragment : AbsMainActivityFragment(R.layout.fragment_lyrics) {
|
||||||
mainActivity.expandPanel()
|
mainActivity.expandPanel()
|
||||||
_binding = null
|
_binding = null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum class LyricsType {
|
||||||
|
NORMAL_LYRICS,
|
||||||
|
SYNCED_LYRICS
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -46,7 +46,7 @@ import code.name.monkey.retromusic.model.lyrics.Lyrics
|
||||||
import code.name.monkey.retromusic.transform.CarousalPagerTransformer
|
import code.name.monkey.retromusic.transform.CarousalPagerTransformer
|
||||||
import code.name.monkey.retromusic.transform.ParallaxPagerTransformer
|
import code.name.monkey.retromusic.transform.ParallaxPagerTransformer
|
||||||
import code.name.monkey.retromusic.util.LyricUtil
|
import code.name.monkey.retromusic.util.LyricUtil
|
||||||
import code.name.monkey.retromusic.util.LyricsType
|
import code.name.monkey.retromusic.util.CoverLyricsType
|
||||||
import code.name.monkey.retromusic.util.PreferenceUtil
|
import code.name.monkey.retromusic.util.PreferenceUtil
|
||||||
import code.name.monkey.retromusic.util.color.MediaNotificationProcessor
|
import code.name.monkey.retromusic.util.color.MediaNotificationProcessor
|
||||||
import code.name.monkey.retromusic.util.logD
|
import code.name.monkey.retromusic.util.logD
|
||||||
|
@ -174,13 +174,11 @@ class PlayerAlbumCoverFragment : AbsMusicServiceFragment(R.layout.fragment_playe
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onServiceConnected() {
|
override fun onServiceConnected() {
|
||||||
logD("Service Connected")
|
|
||||||
updatePlayingQueue()
|
updatePlayingQueue()
|
||||||
updateLyrics()
|
updateLyrics()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onPlayingMetaChanged() {
|
override fun onPlayingMetaChanged() {
|
||||||
logD("Playing Meta Changed")
|
|
||||||
if (viewPager.currentItem != MusicPlayerRemote.position) {
|
if (viewPager.currentItem != MusicPlayerRemote.position) {
|
||||||
viewPager.setCurrentItem(MusicPlayerRemote.position, true)
|
viewPager.setCurrentItem(MusicPlayerRemote.position, true)
|
||||||
}
|
}
|
||||||
|
@ -188,7 +186,6 @@ class PlayerAlbumCoverFragment : AbsMusicServiceFragment(R.layout.fragment_playe
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onQueueChanged() {
|
override fun onQueueChanged() {
|
||||||
logD("Queue Changed")
|
|
||||||
updatePlayingQueue()
|
updatePlayingQueue()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -222,7 +219,7 @@ class PlayerAlbumCoverFragment : AbsMusicServiceFragment(R.layout.fragment_playe
|
||||||
binding.coverLyrics.isVisible = false
|
binding.coverLyrics.isVisible = false
|
||||||
binding.lyricsView.isVisible = false
|
binding.lyricsView.isVisible = false
|
||||||
binding.viewPager.isVisible = true
|
binding.viewPager.isVisible = true
|
||||||
val lyrics: View = if (PreferenceUtil.lyricsType == LyricsType.REPLACE_COVER) {
|
val lyrics: View = if (PreferenceUtil.lyricsType == CoverLyricsType.REPLACE_COVER) {
|
||||||
ObjectAnimator.ofFloat(viewPager, View.ALPHA, if (visible) 0F else 1F).start()
|
ObjectAnimator.ofFloat(viewPager, View.ALPHA, if (visible) 0F else 1F).start()
|
||||||
lrcView
|
lrcView
|
||||||
} else {
|
} else {
|
||||||
|
@ -242,7 +239,7 @@ class PlayerAlbumCoverFragment : AbsMusicServiceFragment(R.layout.fragment_playe
|
||||||
// Don't show lyrics container for below conditions
|
// Don't show lyrics container for below conditions
|
||||||
if (lyricViewNpsList.contains(nps) && PreferenceUtil.showLyrics) {
|
if (lyricViewNpsList.contains(nps) && PreferenceUtil.showLyrics) {
|
||||||
showLyrics(true)
|
showLyrics(true)
|
||||||
if (PreferenceUtil.lyricsType == LyricsType.REPLACE_COVER) {
|
if (PreferenceUtil.lyricsType == CoverLyricsType.REPLACE_COVER) {
|
||||||
progressViewUpdateHelper?.start()
|
progressViewUpdateHelper?.start()
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -23,6 +23,7 @@ import code.name.monkey.retromusic.helper.menu.PlaylistMenuHelper
|
||||||
import code.name.monkey.retromusic.interfaces.ICabCallback
|
import code.name.monkey.retromusic.interfaces.ICabCallback
|
||||||
import code.name.monkey.retromusic.interfaces.ICabHolder
|
import code.name.monkey.retromusic.interfaces.ICabHolder
|
||||||
import code.name.monkey.retromusic.model.Song
|
import code.name.monkey.retromusic.model.Song
|
||||||
|
import code.name.monkey.retromusic.util.MusicUtil
|
||||||
import code.name.monkey.retromusic.util.RetroColorUtil
|
import code.name.monkey.retromusic.util.RetroColorUtil
|
||||||
import code.name.monkey.retromusic.util.ThemedFastScroller
|
import code.name.monkey.retromusic.util.ThemedFastScroller
|
||||||
import com.afollestad.materialcab.attached.AttachedCab
|
import com.afollestad.materialcab.attached.AttachedCab
|
||||||
|
@ -72,6 +73,8 @@ class PlaylistDetailsFragment : AbsMainActivityFragment(R.layout.fragment_playli
|
||||||
binding.container.transitionName = "playlist"
|
binding.container.transitionName = "playlist"
|
||||||
playlist = arguments.extraPlaylist
|
playlist = arguments.extraPlaylist
|
||||||
binding.toolbar.title = playlist.playlistEntity.playlistName
|
binding.toolbar.title = playlist.playlistEntity.playlistName
|
||||||
|
binding.toolbar.subtitle =
|
||||||
|
MusicUtil.getPlaylistInfoString(requireContext(), playlist.songs.toSongs())
|
||||||
setUpRecyclerView()
|
setUpRecyclerView()
|
||||||
viewModel.getSongs().observe(viewLifecycleOwner) {
|
viewModel.getSongs().observe(viewLifecycleOwner) {
|
||||||
songs(it.toSongs())
|
songs(it.toSongs())
|
||||||
|
|
|
@ -695,11 +695,11 @@ object PreferenceUtil {
|
||||||
val isSnowFalling
|
val isSnowFalling
|
||||||
get() = sharedPreferences.getBoolean(SNOWFALL, false)
|
get() = sharedPreferences.getBoolean(SNOWFALL, false)
|
||||||
|
|
||||||
val lyricsType: LyricsType
|
val lyricsType: CoverLyricsType
|
||||||
get() = if (sharedPreferences.getString(LYRICS_TYPE, "0") == "0") {
|
get() = if (sharedPreferences.getString(LYRICS_TYPE, "0") == "0") {
|
||||||
LyricsType.REPLACE_COVER
|
CoverLyricsType.REPLACE_COVER
|
||||||
} else {
|
} else {
|
||||||
LyricsType.OVER_COVER
|
CoverLyricsType.OVER_COVER
|
||||||
}
|
}
|
||||||
|
|
||||||
var playbackSpeed
|
var playbackSpeed
|
||||||
|
@ -738,6 +738,6 @@ object PreferenceUtil {
|
||||||
get() = sharedPreferences.getBoolean(SWIPE_DOWN_DISMISS, true)
|
get() = sharedPreferences.getBoolean(SWIPE_DOWN_DISMISS, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
enum class LyricsType {
|
enum class CoverLyricsType {
|
||||||
REPLACE_COVER, OVER_COVER
|
REPLACE_COVER, OVER_COVER
|
||||||
}
|
}
|
|
@ -28,37 +28,56 @@
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:background="?attr/colorSurface"
|
android:background="?attr/colorSurface"
|
||||||
android:gravity="start"
|
android:gravity="start"
|
||||||
app:contentInsetLeft="0dp"
|
app:contentInsetLeft="0dp"
|
||||||
app:contentInsetStart="0dp"
|
app:contentInsetStart="0dp"
|
||||||
app:contentInsetStartWithNavigation="0dp"
|
app:contentInsetStartWithNavigation="0dp"
|
||||||
app:navigationIcon="@drawable/ic_keyboard_backspace_black"
|
app:navigationIcon="@drawable/ic_keyboard_backspace_black"
|
||||||
app:subtitleTextAppearance="@style/TextViewCaption"
|
app:title="@string/lyrics"
|
||||||
app:titleMargin="0dp"
|
app:titleMargin="0dp"
|
||||||
app:titleMarginStart="0dp"
|
app:titleMarginStart="0dp"
|
||||||
app:titleTextAppearance="@style/TextViewSubtitle1">
|
app:titleTextAppearance="@style/ToolbarTextAppearanceNormal" />
|
||||||
|
|
||||||
<com.google.android.material.tabs.TabLayout
|
|
||||||
android:id="@+id/tabLyrics"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
|
||||||
app:tabIndicator="@drawable/tab_lyrics_indicator"
|
|
||||||
app:tabIndicatorAnimationMode="elastic"
|
|
||||||
app:tabIndicatorFullWidth="false"
|
|
||||||
app:tabIndicatorHeight="5dp" />
|
|
||||||
</com.google.android.material.appbar.MaterialToolbar>
|
|
||||||
</com.google.android.material.appbar.AppBarLayout>
|
</com.google.android.material.appbar.AppBarLayout>
|
||||||
|
|
||||||
<androidx.viewpager2.widget.ViewPager2
|
<FrameLayout
|
||||||
android:id="@+id/lyricsPager"
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:layout_marginTop="?attr/actionBarSize"
|
android:layout_marginTop="?attr/actionBarSize">
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
<ScrollView
|
||||||
app:layout_constraintStart_toStartOf="parent" />
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:scrollbars="vertical">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/normalLyrics"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:padding="@dimen/normal_lyrics_padding"
|
||||||
|
android:textIsSelectable="true"
|
||||||
|
android:textSize="@dimen/lyrics_text_size"
|
||||||
|
tools:text="@tools:sample/lorem[100]" />
|
||||||
|
</ScrollView>
|
||||||
|
|
||||||
|
<code.name.monkey.retromusic.lyrics.LrcView
|
||||||
|
android:id="@+id/lyricsView"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior"
|
||||||
|
app:lrcLabel="@string/no_lyrics_found"
|
||||||
|
app:lrcNormalTextSize="24sp"
|
||||||
|
app:lrcPadding="24dp"
|
||||||
|
app:lrcTextGravity="left"
|
||||||
|
app:lrcTextSize="28sp" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/noLyricsFound"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:gravity="center"
|
||||||
|
android:text="@string/no_lyrics_found"
|
||||||
|
android:textSize="24sp"
|
||||||
|
android:visibility="gone" />
|
||||||
|
</FrameLayout>
|
||||||
|
|
||||||
<com.google.android.material.floatingactionbutton.FloatingActionButton
|
<com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||||
android:id="@+id/edit_button"
|
android:id="@+id/edit_button"
|
||||||
|
|
|
@ -1,29 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent">
|
|
||||||
|
|
||||||
<ScrollView
|
|
||||||
android:id="@+id/nomal_lyrics_container"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:scrollbars="vertical">
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/normalLyrics"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:padding="@dimen/normal_lyrics_padding"
|
|
||||||
android:textIsSelectable="true"
|
|
||||||
android:textSize="@dimen/lyrics_text_size" />
|
|
||||||
</ScrollView>
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/noLyricsFound"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:gravity="center"
|
|
||||||
android:text="@string/no_lyrics_found"
|
|
||||||
android:textSize="24sp"
|
|
||||||
android:visibility="gone" />
|
|
||||||
</FrameLayout>
|
|
|
@ -1,18 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
|
||||||
android:id="@+id/synced_lyrics_container"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent">
|
|
||||||
|
|
||||||
<code.name.monkey.retromusic.lyrics.LrcView
|
|
||||||
android:id="@+id/lyricsView"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior"
|
|
||||||
app:lrcLabel="@string/no_lyrics_found"
|
|
||||||
app:lrcNormalTextSize="24sp"
|
|
||||||
app:lrcPadding="24dp"
|
|
||||||
app:lrcTextGravity="left"
|
|
||||||
app:lrcTextSize="28sp" />
|
|
||||||
</FrameLayout>
|
|
|
@ -125,5 +125,5 @@
|
||||||
|
|
||||||
<fragment
|
<fragment
|
||||||
android:id="@+id/lyrics_fragment"
|
android:id="@+id/lyrics_fragment"
|
||||||
android:name="code.name.monkey.retromusic.fragments.other.LyricsFragment" />
|
android:name="code.name.monkey.retromusic.fragments.lyrics.LyricsFragment" />
|
||||||
</navigation>
|
</navigation>
|
|
@ -94,6 +94,7 @@
|
||||||
<string name="black_theme_name">Just Black</string>
|
<string name="black_theme_name">Just Black</string>
|
||||||
<string name="blacklist">Blacklist</string>
|
<string name="blacklist">Blacklist</string>
|
||||||
<string name="bluetooth_summary">The app needs nearby devices permission to check for bluetooth devices</string>
|
<string name="bluetooth_summary">The app needs nearby devices permission to check for bluetooth devices</string>
|
||||||
|
<string name="bluetooth_title">Nearby devices</string>
|
||||||
<string name="blur">Blur</string>
|
<string name="blur">Blur</string>
|
||||||
<string name="blur_card">Blur Card</string>
|
<string name="blur_card">Blur Card</string>
|
||||||
<string name="bug_report_failed">Unable to send report</string>
|
<string name="bug_report_failed">Unable to send report</string>
|
||||||
|
@ -561,5 +562,4 @@
|
||||||
<string name="you_have_to_select_at_least_one_category">You have to select at least one category.</string>
|
<string name="you_have_to_select_at_least_one_category">You have to select at least one category.</string>
|
||||||
<string name="you_will_be_forwarded_to_the_issue_tracker_website">You will be forwarded to the issue tracker website.</string>
|
<string name="you_will_be_forwarded_to_the_issue_tracker_website">You will be forwarded to the issue tracker website.</string>
|
||||||
<string name="your_account_data_is_only_used_for_authentication">Your account data is only used for authentication.</string>
|
<string name="your_account_data_is_only_used_for_authentication">Your account data is only used for authentication.</string>
|
||||||
<string name="bluetooth_title">Nearby devices</string>
|
|
||||||
</resources>
|
</resources>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue