2020-10-06 08:46:04 +00:00
|
|
|
/*
|
|
|
|
* Copyright (c) 2020 Hemanth Savarla.
|
|
|
|
*
|
|
|
|
* Licensed under the GNU General Public License v3
|
|
|
|
*
|
|
|
|
* This is free software: you can redistribute it and/or modify it
|
|
|
|
* under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
|
|
|
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
|
|
* See the GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
*/
|
2019-04-20 05:29:45 +00:00
|
|
|
package code.name.monkey.retromusic.activities
|
2018-12-06 08:52:57 +00:00
|
|
|
|
2019-12-01 15:27:01 +00:00
|
|
|
import android.os.Bundle
|
2021-09-08 18:30:20 +00:00
|
|
|
import android.text.InputType
|
|
|
|
import android.view.*
|
2020-10-09 17:44:02 +00:00
|
|
|
import androidx.core.view.ViewCompat
|
2021-09-08 18:30:20 +00:00
|
|
|
import androidx.fragment.app.Fragment
|
|
|
|
import androidx.fragment.app.FragmentActivity
|
|
|
|
import androidx.viewpager2.adapter.FragmentStateAdapter
|
2018-12-06 08:52:57 +00:00
|
|
|
import code.name.monkey.appthemehelper.ThemeStore
|
2020-05-24 18:04:50 +00:00
|
|
|
import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper
|
2018-12-06 08:52:57 +00:00
|
|
|
import code.name.monkey.retromusic.R
|
2019-05-16 18:52:48 +00:00
|
|
|
import code.name.monkey.retromusic.activities.base.AbsMusicServiceActivity
|
2021-09-08 18:30:20 +00:00
|
|
|
import code.name.monkey.retromusic.activities.tageditor.WriteTagsAsyncTask
|
|
|
|
import code.name.monkey.retromusic.databinding.ActivityLyricsBinding
|
|
|
|
import code.name.monkey.retromusic.databinding.FragmentNormalLyricsBinding
|
|
|
|
import code.name.monkey.retromusic.databinding.FragmentSyncedLyricsBinding
|
|
|
|
import code.name.monkey.retromusic.extensions.accentColor
|
2020-05-20 20:28:38 +00:00
|
|
|
import code.name.monkey.retromusic.extensions.surfaceColor
|
2021-09-08 18:30:20 +00:00
|
|
|
import code.name.monkey.retromusic.extensions.textColorSecondary
|
|
|
|
import code.name.monkey.retromusic.fragments.base.AbsMusicServiceFragment
|
2019-12-01 15:27:01 +00:00
|
|
|
import code.name.monkey.retromusic.helper.MusicPlayerRemote
|
|
|
|
import code.name.monkey.retromusic.helper.MusicProgressViewUpdateHelper
|
2020-06-30 17:45:47 +00:00
|
|
|
import code.name.monkey.retromusic.lyrics.LrcView
|
2021-09-08 18:30:20 +00:00
|
|
|
import code.name.monkey.retromusic.model.LoadingInfo
|
2018-12-06 08:52:57 +00:00
|
|
|
import code.name.monkey.retromusic.model.Song
|
2020-05-23 13:53:10 +00:00
|
|
|
import code.name.monkey.retromusic.util.LyricUtil
|
2020-06-30 17:45:47 +00:00
|
|
|
import code.name.monkey.retromusic.util.RetroUtil
|
2021-09-08 18:30:20 +00:00
|
|
|
import com.afollestad.materialdialogs.LayoutMode
|
|
|
|
import com.afollestad.materialdialogs.MaterialDialog
|
|
|
|
import com.afollestad.materialdialogs.bottomsheets.BottomSheet
|
|
|
|
import com.afollestad.materialdialogs.input.input
|
2020-09-27 18:59:09 +00:00
|
|
|
import com.google.android.material.color.MaterialColors
|
2021-09-08 18:30:20 +00:00
|
|
|
import com.google.android.material.tabs.TabLayoutMediator
|
2020-09-27 18:59:09 +00:00
|
|
|
import com.google.android.material.transition.platform.MaterialContainerTransform
|
2021-09-08 18:30:20 +00:00
|
|
|
import kotlinx.coroutines.*
|
|
|
|
import org.jaudiotagger.audio.AudioFileIO
|
|
|
|
import org.jaudiotagger.tag.FieldKey
|
|
|
|
import java.io.File
|
|
|
|
import java.util.*
|
2018-12-06 08:52:57 +00:00
|
|
|
|
2021-09-08 18:30:20 +00:00
|
|
|
class LyricsActivity : AbsMusicServiceActivity() {
|
2019-12-01 15:27:01 +00:00
|
|
|
|
2021-09-08 18:30:20 +00:00
|
|
|
private lateinit var binding: ActivityLyricsBinding
|
2019-12-01 15:27:01 +00:00
|
|
|
private lateinit var song: Song
|
|
|
|
|
2021-09-08 18:30:20 +00:00
|
|
|
private val lyricsSectionsAdapter = LyricsSectionsAdapter(this)
|
|
|
|
|
2019-12-01 15:27:01 +00:00
|
|
|
private val googleSearchLrcUrl: String
|
|
|
|
get() {
|
|
|
|
var baseUrl = "http://www.google.com/search?"
|
|
|
|
var query = song.title + "+" + song.artistName
|
2021-09-08 18:30:20 +00:00
|
|
|
query = "q=" + query.replace(" ", "+") + " lyrics"
|
|
|
|
baseUrl += query
|
|
|
|
return baseUrl
|
|
|
|
}
|
|
|
|
private val syairSearchLrcUrl: String
|
|
|
|
get() {
|
|
|
|
var baseUrl = "https://www.syair.info/search?"
|
|
|
|
var query = song.title + "+" + song.artistName
|
|
|
|
query = "q=" + query.replace(" ", "+")
|
2019-12-01 15:27:01 +00:00
|
|
|
baseUrl += query
|
|
|
|
return baseUrl
|
|
|
|
}
|
|
|
|
|
2020-10-06 08:46:04 +00:00
|
|
|
private fun buildContainerTransform(): MaterialContainerTransform {
|
2020-09-27 18:59:09 +00:00
|
|
|
val transform = MaterialContainerTransform()
|
|
|
|
transform.setAllContainerColors(
|
2020-10-09 17:44:02 +00:00
|
|
|
MaterialColors.getColor(findViewById(R.id.container), R.attr.colorSurface)
|
2020-09-27 18:59:09 +00:00
|
|
|
)
|
2020-10-09 17:44:02 +00:00
|
|
|
transform.addTarget(R.id.container)
|
2020-09-27 18:59:09 +00:00
|
|
|
transform.duration = 300
|
|
|
|
return transform
|
|
|
|
}
|
|
|
|
|
2019-12-01 15:27:01 +00:00
|
|
|
override fun onCreate(savedInstanceState: Bundle?) {
|
|
|
|
super.onCreate(savedInstanceState)
|
2021-09-08 18:30:20 +00:00
|
|
|
binding = ActivityLyricsBinding.inflate(layoutInflater)
|
|
|
|
setContentView(binding.root)
|
|
|
|
ViewCompat.setTransitionName(binding.container, "lyrics")
|
2019-12-01 15:27:01 +00:00
|
|
|
setStatusbarColorAuto()
|
|
|
|
setTaskDescriptionColorAuto()
|
2019-12-05 18:18:54 +00:00
|
|
|
setNavigationbarColorAuto()
|
2019-12-01 15:27:01 +00:00
|
|
|
|
|
|
|
setupWakelock()
|
|
|
|
|
2021-09-08 18:30:20 +00:00
|
|
|
binding.toolbar.setBackgroundColor(surfaceColor())
|
|
|
|
binding.tabLyrics.setBackgroundColor(surfaceColor())
|
|
|
|
binding.container.setBackgroundColor(surfaceColor())
|
|
|
|
ToolbarContentTintHelper.colorBackButton(binding.toolbar)
|
|
|
|
setSupportActionBar(binding.toolbar)
|
|
|
|
setupViews()
|
2020-06-30 17:45:47 +00:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-09-08 18:30:20 +00:00
|
|
|
private fun setupViews() {
|
|
|
|
binding.lyricsPager.adapter = lyricsSectionsAdapter
|
|
|
|
TabLayoutMediator(binding.tabLyrics, binding.lyricsPager) { tab, position ->
|
|
|
|
tab.text = when (position) {
|
|
|
|
0 -> "Synced Lyrics"
|
|
|
|
1 -> "Normal Lyrics"
|
|
|
|
else -> ""
|
|
|
|
}
|
|
|
|
}.attach()
|
|
|
|
// lyricsPager.isUserInputEnabled = false
|
2020-06-30 17:45:47 +00:00
|
|
|
|
2021-09-08 18:30:20 +00:00
|
|
|
binding.tabLyrics.setSelectedTabIndicatorColor(ThemeStore.accentColor(this))
|
|
|
|
binding.tabLyrics.setTabTextColors(textColorSecondary(), accentColor())
|
2020-06-30 17:45:47 +00:00
|
|
|
}
|
|
|
|
|
2019-12-01 15:27:01 +00:00
|
|
|
|
|
|
|
override fun onPlayingMetaChanged() {
|
|
|
|
super.onPlayingMetaChanged()
|
2019-12-16 05:06:08 +00:00
|
|
|
updateTitleSong()
|
2019-12-01 15:27:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
override fun onServiceConnected() {
|
|
|
|
super.onServiceConnected()
|
2019-12-16 05:06:08 +00:00
|
|
|
updateTitleSong()
|
|
|
|
}
|
|
|
|
|
|
|
|
private fun updateTitleSong() {
|
2019-12-01 15:27:01 +00:00
|
|
|
song = MusicPlayerRemote.currentSong
|
2021-09-08 18:30:20 +00:00
|
|
|
binding.toolbar.title = song.title
|
|
|
|
binding.toolbar.subtitle = song.artistName
|
2019-12-01 15:27:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
private fun setupWakelock() {
|
|
|
|
window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
|
|
|
|
}
|
|
|
|
|
2020-06-30 17:45:47 +00:00
|
|
|
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
|
|
|
|
menuInflater.inflate(R.menu.menu_search, menu)
|
|
|
|
return super.onCreateOptionsMenu(menu)
|
|
|
|
}
|
|
|
|
|
2019-12-01 15:27:01 +00:00
|
|
|
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
|
|
|
if (item.itemId == android.R.id.home) {
|
2019-12-22 16:36:11 +00:00
|
|
|
finish()
|
|
|
|
return true
|
2019-12-01 15:27:01 +00:00
|
|
|
}
|
2020-06-30 17:45:47 +00:00
|
|
|
if (item.itemId == R.id.action_search) {
|
2021-09-08 18:30:20 +00:00
|
|
|
RetroUtil.openUrl(
|
|
|
|
this, when (binding.lyricsPager.currentItem) {
|
|
|
|
0 -> syairSearchLrcUrl
|
|
|
|
1 -> googleSearchLrcUrl
|
|
|
|
else -> googleSearchLrcUrl
|
|
|
|
}
|
|
|
|
)
|
|
|
|
} else if (item.itemId == R.id.action_edit) {
|
|
|
|
when (binding.lyricsPager.currentItem) {
|
|
|
|
0 -> {
|
|
|
|
editSyncedLyrics()
|
|
|
|
}
|
|
|
|
1 -> {
|
|
|
|
editNormalLyrics()
|
|
|
|
}
|
|
|
|
}
|
2019-12-01 15:27:01 +00:00
|
|
|
}
|
2020-06-30 17:45:47 +00:00
|
|
|
return super.onOptionsItemSelected(item)
|
2019-12-01 15:27:01 +00:00
|
|
|
}
|
2021-09-08 18:30:20 +00:00
|
|
|
|
|
|
|
|
|
|
|
private fun editNormalLyrics() {
|
|
|
|
var content = ""
|
|
|
|
val file = File(MusicPlayerRemote.currentSong.data)
|
|
|
|
try {
|
|
|
|
content = AudioFileIO.read(file).tagOrCreateDefault.getFirst(FieldKey.LYRICS)
|
|
|
|
} catch (e: Exception) {
|
|
|
|
e.printStackTrace()
|
|
|
|
}
|
|
|
|
|
|
|
|
MaterialDialog(this, BottomSheet(LayoutMode.WRAP_CONTENT)).show {
|
|
|
|
title(res = R.string.edit_normal_lyrics)
|
|
|
|
input(
|
|
|
|
hintRes = R.string.paste_lyrics_here,
|
|
|
|
prefill = content,
|
|
|
|
inputType = InputType.TYPE_TEXT_FLAG_MULTI_LINE or InputType.TYPE_CLASS_TEXT
|
|
|
|
) { _, input ->
|
|
|
|
val fieldKeyValueMap = EnumMap<FieldKey, String>(FieldKey::class.java)
|
|
|
|
fieldKeyValueMap[FieldKey.LYRICS] = input.toString()
|
|
|
|
WriteTagsAsyncTask(this@LyricsActivity).execute(
|
|
|
|
LoadingInfo(
|
|
|
|
listOf(song.data), fieldKeyValueMap, null
|
|
|
|
)
|
|
|
|
)
|
|
|
|
}
|
|
|
|
positiveButton(res = R.string.save) {
|
|
|
|
(lyricsSectionsAdapter.fragments[1].first as NormalLyrics).loadNormalLyrics()
|
|
|
|
}
|
|
|
|
negativeButton(res = android.R.string.cancel)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private fun editSyncedLyrics() {
|
|
|
|
var lrcFile: File? = null
|
|
|
|
if (LyricUtil.isLrcOriginalFileExist(song.data)) {
|
|
|
|
lrcFile = LyricUtil.getLocalLyricOriginalFile(song.data)
|
|
|
|
} else if (LyricUtil.isLrcFileExist(song.title, song.artistName)) {
|
|
|
|
lrcFile = LyricUtil.getLocalLyricFile(song.title, song.artistName)
|
|
|
|
}
|
|
|
|
val content: String = LyricUtil.getStringFromLrc(lrcFile)
|
|
|
|
|
|
|
|
MaterialDialog(this, BottomSheet(LayoutMode.WRAP_CONTENT)).show {
|
|
|
|
title(res = R.string.edit_synced_lyrics)
|
|
|
|
input(
|
|
|
|
hintRes = R.string.paste_timeframe_lyrics_here,
|
|
|
|
prefill = content,
|
|
|
|
inputType = InputType.TYPE_TEXT_FLAG_MULTI_LINE or InputType.TYPE_CLASS_TEXT
|
|
|
|
) { _, input ->
|
|
|
|
LyricUtil.writeLrc(song, input.toString())
|
|
|
|
}
|
|
|
|
positiveButton(res = R.string.save) {
|
|
|
|
(lyricsSectionsAdapter.fragments[0].first as SyncedLyrics).loadLRCLyrics()
|
|
|
|
}
|
|
|
|
negativeButton(res = android.R.string.cancel)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
class LyricsSectionsAdapter(fragmentActivity: FragmentActivity) :
|
|
|
|
FragmentStateAdapter(fragmentActivity) {
|
|
|
|
val fragments = listOf(
|
|
|
|
Pair(SyncedLyrics(), R.string.synced_lyrics),
|
|
|
|
Pair(NormalLyrics(), R.string.normal_lyrics)
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
override fun getItemCount(): Int {
|
|
|
|
return fragments.size
|
|
|
|
}
|
|
|
|
|
|
|
|
override fun createFragment(position: Int): Fragment {
|
|
|
|
return fragments[position].first
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
class NormalLyrics : AbsMusicServiceFragment(R.layout.fragment_normal_lyrics) {
|
|
|
|
|
|
|
|
private var _binding: FragmentNormalLyricsBinding? = null
|
|
|
|
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()
|
|
|
|
}
|
|
|
|
if (lyrics.isNullOrEmpty()) {
|
|
|
|
binding.noLyricsFound.visibility = View.VISIBLE
|
|
|
|
} else {
|
|
|
|
binding.noLyricsFound.visibility = View.GONE
|
|
|
|
}
|
|
|
|
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),
|
|
|
|
MusicProgressViewUpdateHelper.Callback {
|
|
|
|
|
|
|
|
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("Empty")
|
|
|
|
val song = MusicPlayerRemote.currentSong
|
|
|
|
if (LyricUtil.isLrcOriginalFileExist(song.data)) {
|
|
|
|
binding.lyricsView.loadLrc(LyricUtil.getLocalLyricOriginalFile(song.data))
|
|
|
|
} else if (LyricUtil.isLrcFileExist(song.title, song.artistName)) {
|
|
|
|
binding.lyricsView.loadLrc(LyricUtil.getLocalLyricFile(song.title, song.artistName))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private fun setupLyricsView() {
|
|
|
|
binding.lyricsView.apply {
|
|
|
|
setCurrentColor(ThemeStore.accentColor(context))
|
|
|
|
setTimeTextColor(ThemeStore.accentColor(context))
|
|
|
|
setTimelineColor(ThemeStore.accentColor(context))
|
|
|
|
setTimelineTextColor(ThemeStore.accentColor(context))
|
|
|
|
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()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2020-10-06 08:46:04 +00:00
|
|
|
}
|