Common screen for Normal and Synced the later is preferred

This commit is contained in:
Prathamesh More 2022-06-20 14:43:06 +05:30
parent dd59459786
commit 62372ec205
11 changed files with 177 additions and 261 deletions

View file

@ -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')}\"")

View file

@ -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)

View file

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

View file

@ -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 {

View file

@ -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())

View file

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

View file

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

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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>