V5 Push
Here's a list of changes/features: https://github.com/RetroMusicPlayer/RetroMusicPlayer/releases/tag/v5.0 Internal Changes: 1) Migrated to ViewBinding 2) Migrated to Glide V4 3) Migrated to kotlin version of Material Dialogs
This commit is contained in:
parent
fc42767031
commit
bce6dbfa27
421 changed files with 13285 additions and 5757 deletions
|
@ -17,6 +17,7 @@ package code.name.monkey.retromusic.fragments
|
|||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import androidx.core.os.bundleOf
|
||||
import androidx.core.view.doOnPreDraw
|
||||
import androidx.navigation.fragment.FragmentNavigatorExtras
|
||||
import androidx.navigation.fragment.findNavController
|
||||
import androidx.navigation.fragment.navArgs
|
||||
|
@ -28,26 +29,48 @@ import code.name.monkey.retromusic.adapter.album.AlbumAdapter
|
|||
import code.name.monkey.retromusic.adapter.artist.ArtistAdapter
|
||||
import code.name.monkey.retromusic.adapter.song.ShuffleButtonSongAdapter
|
||||
import code.name.monkey.retromusic.adapter.song.SongAdapter
|
||||
import code.name.monkey.retromusic.databinding.FragmentPlaylistDetailBinding
|
||||
import code.name.monkey.retromusic.db.toSong
|
||||
import code.name.monkey.retromusic.extensions.dipToPix
|
||||
import code.name.monkey.retromusic.extensions.hide
|
||||
import code.name.monkey.retromusic.fragments.base.AbsMainActivityFragment
|
||||
import code.name.monkey.retromusic.interfaces.IAlbumClickListener
|
||||
import code.name.monkey.retromusic.interfaces.IArtistClickListener
|
||||
import code.name.monkey.retromusic.model.Album
|
||||
import code.name.monkey.retromusic.model.Artist
|
||||
import code.name.monkey.retromusic.util.RetroUtil
|
||||
import kotlinx.android.synthetic.main.fragment_playlist_detail.*
|
||||
import com.google.android.material.transition.MaterialSharedAxis
|
||||
|
||||
class DetailListFragment : AbsMainActivityFragment(R.layout.fragment_playlist_detail),
|
||||
IArtistClickListener, IAlbumClickListener {
|
||||
private val args by navArgs<DetailListFragmentArgs>()
|
||||
private var _binding: FragmentPlaylistDetailBinding? = null
|
||||
private val binding get() = _binding!!
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
_binding = FragmentPlaylistDetailBinding.bind(view)
|
||||
when (args.type) {
|
||||
TOP_ARTISTS,
|
||||
RECENT_ARTISTS,
|
||||
TOP_ALBUMS,
|
||||
RECENT_ALBUMS,
|
||||
FAVOURITES -> {
|
||||
enterTransition = MaterialSharedAxis(MaterialSharedAxis.X, true)
|
||||
returnTransition = MaterialSharedAxis(MaterialSharedAxis.X, false)
|
||||
}
|
||||
else -> {
|
||||
enterTransition = MaterialSharedAxis(MaterialSharedAxis.Y, true)
|
||||
returnTransition = MaterialSharedAxis(MaterialSharedAxis.Y, false)
|
||||
}
|
||||
}
|
||||
postponeEnterTransition()
|
||||
view.doOnPreDraw { startPostponedEnterTransition() }
|
||||
}
|
||||
|
||||
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||
super.onActivityCreated(savedInstanceState)
|
||||
mainActivity.setBottomBarVisibility(false)
|
||||
mainActivity.setSupportActionBar(toolbar)
|
||||
progressIndicator.hide()
|
||||
mainActivity.setSupportActionBar(binding.toolbar)
|
||||
binding.progressIndicator.hide()
|
||||
when (args.type) {
|
||||
TOP_ARTISTS -> loadArtists(R.string.top_artists, TOP_ARTISTS)
|
||||
RECENT_ARTISTS -> loadArtists(R.string.recent_artists, RECENT_ARTISTS)
|
||||
|
@ -59,23 +82,23 @@ class DetailListFragment : AbsMainActivityFragment(R.layout.fragment_playlist_de
|
|||
TOP_PLAYED_PLAYLIST -> topPlayed()
|
||||
}
|
||||
|
||||
recyclerView.adapter?.registerAdapterDataObserver(object : AdapterDataObserver() {
|
||||
binding.recyclerView.adapter?.registerAdapterDataObserver(object : AdapterDataObserver() {
|
||||
override fun onChanged() {
|
||||
super.onChanged()
|
||||
val height = dipToPix(52f)
|
||||
recyclerView.setPadding(0, 0, 0, height.toInt())
|
||||
binding.recyclerView.setPadding(0, 0, 0, height.toInt())
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
private fun lastAddedSongs() {
|
||||
toolbar.setTitle(R.string.last_added)
|
||||
binding.toolbar.setTitle(R.string.last_added)
|
||||
val songAdapter = ShuffleButtonSongAdapter(
|
||||
requireActivity(),
|
||||
mutableListOf(),
|
||||
R.layout.item_list, null
|
||||
)
|
||||
recyclerView.apply {
|
||||
binding.recyclerView.apply {
|
||||
adapter = songAdapter
|
||||
layoutManager = linearLayoutManager()
|
||||
}
|
||||
|
@ -85,13 +108,13 @@ class DetailListFragment : AbsMainActivityFragment(R.layout.fragment_playlist_de
|
|||
}
|
||||
|
||||
private fun topPlayed() {
|
||||
toolbar.setTitle(R.string.my_top_tracks)
|
||||
binding.toolbar.setTitle(R.string.my_top_tracks)
|
||||
val songAdapter = ShuffleButtonSongAdapter(
|
||||
requireActivity(),
|
||||
mutableListOf(),
|
||||
R.layout.item_list, null
|
||||
)
|
||||
recyclerView.apply {
|
||||
binding.recyclerView.apply {
|
||||
adapter = songAdapter
|
||||
layoutManager = linearLayoutManager()
|
||||
}
|
||||
|
@ -101,14 +124,14 @@ class DetailListFragment : AbsMainActivityFragment(R.layout.fragment_playlist_de
|
|||
}
|
||||
|
||||
private fun loadHistory() {
|
||||
toolbar.setTitle(R.string.history)
|
||||
binding.toolbar.setTitle(R.string.history)
|
||||
|
||||
val songAdapter = ShuffleButtonSongAdapter(
|
||||
requireActivity(),
|
||||
mutableListOf(),
|
||||
R.layout.item_list, null
|
||||
)
|
||||
recyclerView.apply {
|
||||
binding.recyclerView.apply {
|
||||
adapter = songAdapter
|
||||
layoutManager = linearLayoutManager()
|
||||
}
|
||||
|
@ -118,13 +141,13 @@ class DetailListFragment : AbsMainActivityFragment(R.layout.fragment_playlist_de
|
|||
}
|
||||
|
||||
private fun loadFavorite() {
|
||||
toolbar.setTitle(R.string.favorites)
|
||||
binding.toolbar.setTitle(R.string.favorites)
|
||||
val songAdapter = SongAdapter(
|
||||
requireActivity(),
|
||||
mutableListOf(),
|
||||
R.layout.item_list, null
|
||||
)
|
||||
recyclerView.apply {
|
||||
binding.recyclerView.apply {
|
||||
adapter = songAdapter
|
||||
layoutManager = linearLayoutManager()
|
||||
}
|
||||
|
@ -135,9 +158,9 @@ class DetailListFragment : AbsMainActivityFragment(R.layout.fragment_playlist_de
|
|||
}
|
||||
|
||||
private fun loadArtists(title: Int, type: Int) {
|
||||
toolbar.setTitle(title)
|
||||
binding.toolbar.setTitle(title)
|
||||
libraryViewModel.artists(type).observe(viewLifecycleOwner, { artists ->
|
||||
recyclerView.apply {
|
||||
binding.recyclerView.apply {
|
||||
adapter = artistAdapter(artists)
|
||||
layoutManager = gridLayoutManager()
|
||||
}
|
||||
|
@ -145,9 +168,9 @@ class DetailListFragment : AbsMainActivityFragment(R.layout.fragment_playlist_de
|
|||
}
|
||||
|
||||
private fun loadAlbums(title: Int, type: Int) {
|
||||
toolbar.setTitle(title)
|
||||
binding.toolbar.setTitle(title)
|
||||
libraryViewModel.albums(type).observe(viewLifecycleOwner, { albums ->
|
||||
recyclerView.apply {
|
||||
binding.recyclerView.apply {
|
||||
adapter = albumAdapter(albums)
|
||||
layoutManager = gridLayoutManager()
|
||||
}
|
||||
|
@ -186,7 +209,7 @@ class DetailListFragment : AbsMainActivityFragment(R.layout.fragment_playlist_de
|
|||
R.id.artistDetailsFragment,
|
||||
bundleOf(EXTRA_ARTIST_ID to artistId),
|
||||
null,
|
||||
FragmentNavigatorExtras(view to "artist")
|
||||
FragmentNavigatorExtras(view to artistId.toString())
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -196,8 +219,13 @@ class DetailListFragment : AbsMainActivityFragment(R.layout.fragment_playlist_de
|
|||
bundleOf(EXTRA_ALBUM_ID to albumId),
|
||||
null,
|
||||
FragmentNavigatorExtras(
|
||||
view to "album"
|
||||
view to albumId.toString()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
_binding = null
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,9 +25,7 @@ import code.name.monkey.retromusic.model.*
|
|||
import code.name.monkey.retromusic.repository.RealRepository
|
||||
import code.name.monkey.retromusic.util.PreferenceUtil
|
||||
import kotlinx.coroutines.Dispatchers.IO
|
||||
import kotlinx.coroutines.Dispatchers.Main
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
|
||||
class LibraryViewModel(
|
||||
private val repository: RealRepository
|
||||
|
@ -129,16 +127,16 @@ class LibraryViewModel(
|
|||
}
|
||||
}
|
||||
|
||||
private fun fetchHomeSections() {
|
||||
fun fetchHomeSections() {
|
||||
viewModelScope.launch(IO) {
|
||||
home.postValue(repository.homeSections())
|
||||
}
|
||||
}
|
||||
|
||||
fun search(query: String?) {
|
||||
fun search(query: String?, filters: List<Boolean>) {
|
||||
viewModelScope.launch(IO) {
|
||||
val result = repository.search(query)
|
||||
withContext(Main) { searchResults.postValue(result) }
|
||||
val result = repository.search(query, filters)
|
||||
searchResults.postValue(result)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -190,6 +188,10 @@ class LibraryViewModel(
|
|||
println("onShuffleModeChanged")
|
||||
}
|
||||
|
||||
override fun onFavoriteStateChanged() {
|
||||
println("onFavoriteStateChanged")
|
||||
}
|
||||
|
||||
fun shuffleSongs() = viewModelScope.launch(IO) {
|
||||
val songs = repository.allSongs()
|
||||
MusicPlayerRemote.openAndShuffleQueue(
|
||||
|
|
|
@ -26,23 +26,26 @@ import android.view.MotionEvent
|
|||
import android.view.View
|
||||
import android.view.animation.DecelerateInterpolator
|
||||
import code.name.monkey.retromusic.R
|
||||
import code.name.monkey.retromusic.databinding.FragmentMiniPlayerBinding
|
||||
import code.name.monkey.retromusic.extensions.accentColor
|
||||
import code.name.monkey.retromusic.extensions.applyColor
|
||||
import code.name.monkey.retromusic.extensions.show
|
||||
import code.name.monkey.retromusic.extensions.textColorPrimary
|
||||
import code.name.monkey.retromusic.extensions.textColorSecondary
|
||||
import code.name.monkey.retromusic.fragments.base.AbsMusicServiceFragment
|
||||
import code.name.monkey.retromusic.glide.GlideApp
|
||||
import code.name.monkey.retromusic.glide.RetroGlideExtension
|
||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote
|
||||
import code.name.monkey.retromusic.helper.MusicProgressViewUpdateHelper
|
||||
import code.name.monkey.retromusic.helper.PlayPauseButtonOnClickHandler
|
||||
import code.name.monkey.retromusic.util.PreferenceUtil
|
||||
import code.name.monkey.retromusic.util.RetroUtil
|
||||
import kotlin.math.abs
|
||||
import kotlinx.android.synthetic.main.fragment_mini_player.*
|
||||
|
||||
open class MiniPlayerFragment : AbsMusicServiceFragment(R.layout.fragment_mini_player),
|
||||
MusicProgressViewUpdateHelper.Callback, View.OnClickListener {
|
||||
|
||||
private var _binding: FragmentMiniPlayerBinding? = null
|
||||
private val binding get() = _binding!!
|
||||
private lateinit var progressViewUpdateHelper: MusicProgressViewUpdateHelper
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
|
@ -59,38 +62,38 @@ open class MiniPlayerFragment : AbsMusicServiceFragment(R.layout.fragment_mini_p
|
|||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
_binding = FragmentMiniPlayerBinding.bind(view)
|
||||
view.setOnTouchListener(FlingPlayBackController(requireContext()))
|
||||
setUpMiniPlayer()
|
||||
|
||||
if (RetroUtil.isTablet()) {
|
||||
actionNext.show()
|
||||
actionPrevious.show()
|
||||
actionNext?.show()
|
||||
actionPrevious?.show()
|
||||
binding.actionNext.show()
|
||||
binding.actionPrevious.show()
|
||||
} else {
|
||||
actionNext.visibility = if (PreferenceUtil.isExtraControls) View.VISIBLE else View.GONE
|
||||
actionPrevious.visibility =
|
||||
binding.actionNext.visibility =
|
||||
if (PreferenceUtil.isExtraControls) View.VISIBLE else View.GONE
|
||||
binding.actionPrevious.visibility =
|
||||
if (PreferenceUtil.isExtraControls) View.VISIBLE else View.GONE
|
||||
}
|
||||
actionNext.setOnClickListener(this)
|
||||
actionPrevious.setOnClickListener(this)
|
||||
actionNext?.setOnClickListener(this)
|
||||
actionPrevious?.setOnClickListener(this)
|
||||
binding.actionNext.setOnClickListener(this)
|
||||
binding.actionPrevious.setOnClickListener(this)
|
||||
}
|
||||
|
||||
private fun setUpMiniPlayer() {
|
||||
setUpPlayPauseButton()
|
||||
progressBar.accentColor()
|
||||
binding.progressBar.accentColor()
|
||||
}
|
||||
|
||||
private fun setUpPlayPauseButton() {
|
||||
miniPlayerPlayPauseButton.setOnClickListener(PlayPauseButtonOnClickHandler())
|
||||
binding.miniPlayerPlayPauseButton.setOnClickListener(PlayPauseButtonOnClickHandler())
|
||||
}
|
||||
|
||||
private fun updateSongTitle() {
|
||||
val builder = SpannableStringBuilder()
|
||||
|
||||
val song = MusicPlayerRemote.currentSong
|
||||
|
||||
val builder = SpannableStringBuilder()
|
||||
|
||||
val title = SpannableString(song.title)
|
||||
title.setSpan(ForegroundColorSpan(textColorPrimary()), 0, title.length, 0)
|
||||
|
||||
|
@ -99,17 +102,34 @@ open class MiniPlayerFragment : AbsMusicServiceFragment(R.layout.fragment_mini_p
|
|||
|
||||
builder.append(title).append(" • ").append(text)
|
||||
|
||||
miniPlayerTitle.isSelected = true
|
||||
miniPlayerTitle.text = builder
|
||||
binding.miniPlayerTitle.isSelected = true
|
||||
binding.miniPlayerTitle.text = builder
|
||||
|
||||
// binding.title.isSelected = true
|
||||
// binding.title.text = song.title
|
||||
// binding.text.isSelected = true
|
||||
// binding.text.text = song.artistName
|
||||
}
|
||||
|
||||
private fun updateSongCover() {
|
||||
// val song = MusicPlayerRemote.currentSong
|
||||
// GlideApp.with(requireContext())
|
||||
// .asBitmap()
|
||||
// .songCoverOptions(song)
|
||||
// .transition(RetroGlideExtension.getDefaultTransition())
|
||||
// .load(RetroGlideExtension.getSongModel(song))
|
||||
// .into(binding.image)
|
||||
}
|
||||
|
||||
override fun onServiceConnected() {
|
||||
updateSongTitle()
|
||||
updateSongCover()
|
||||
updatePlayPauseDrawableState()
|
||||
}
|
||||
|
||||
override fun onPlayingMetaChanged() {
|
||||
updateSongTitle()
|
||||
updateSongCover()
|
||||
}
|
||||
|
||||
override fun onPlayStateChanged() {
|
||||
|
@ -117,8 +137,8 @@ open class MiniPlayerFragment : AbsMusicServiceFragment(R.layout.fragment_mini_p
|
|||
}
|
||||
|
||||
override fun onUpdateProgressViews(progress: Int, total: Int) {
|
||||
progressBar.max = total
|
||||
val animator = ObjectAnimator.ofInt(progressBar, "progress", progress)
|
||||
binding.progressBar.max = total
|
||||
val animator = ObjectAnimator.ofInt(binding.progressBar, "progress", progress)
|
||||
animator.duration = 1000
|
||||
animator.interpolator = DecelerateInterpolator()
|
||||
animator.start()
|
||||
|
@ -136,16 +156,12 @@ open class MiniPlayerFragment : AbsMusicServiceFragment(R.layout.fragment_mini_p
|
|||
|
||||
protected fun updatePlayPauseDrawableState() {
|
||||
if (MusicPlayerRemote.isPlaying) {
|
||||
miniPlayerPlayPauseButton.setImageResource(R.drawable.ic_pause)
|
||||
binding.miniPlayerPlayPauseButton.setImageResource(R.drawable.ic_pause)
|
||||
} else {
|
||||
miniPlayerPlayPauseButton.setImageResource(R.drawable.ic_play_arrow)
|
||||
binding.miniPlayerPlayPauseButton.setImageResource(R.drawable.ic_play_arrow)
|
||||
}
|
||||
}
|
||||
|
||||
fun updateProgressBar(paletteColor: Int) {
|
||||
progressBar.applyColor(paletteColor)
|
||||
}
|
||||
|
||||
class FlingPlayBackController(context: Context) : View.OnTouchListener {
|
||||
|
||||
private var flingPlayBackController: GestureDetector
|
||||
|
@ -178,4 +194,9 @@ open class MiniPlayerFragment : AbsMusicServiceFragment(R.layout.fragment_mini_p
|
|||
return flingPlayBackController.onTouchEvent(event)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
_binding = null
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,34 +26,38 @@ import android.widget.SeekBar
|
|||
import androidx.fragment.app.Fragment
|
||||
import code.name.monkey.appthemehelper.ThemeStore
|
||||
import code.name.monkey.retromusic.R
|
||||
import code.name.monkey.retromusic.databinding.FragmentVolumeBinding
|
||||
import code.name.monkey.retromusic.extensions.applyColor
|
||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote
|
||||
import code.name.monkey.retromusic.util.PreferenceUtil
|
||||
import code.name.monkey.retromusic.volume.AudioVolumeObserver
|
||||
import code.name.monkey.retromusic.volume.OnAudioVolumeChangedListener
|
||||
import kotlinx.android.synthetic.main.fragment_volume.*
|
||||
|
||||
class VolumeFragment : Fragment(), SeekBar.OnSeekBarChangeListener, OnAudioVolumeChangedListener,
|
||||
View.OnClickListener {
|
||||
|
||||
private var _binding: FragmentVolumeBinding? = null
|
||||
private val binding get() = _binding!!
|
||||
|
||||
private var audioVolumeObserver: AudioVolumeObserver? = null
|
||||
|
||||
private val audioManager: AudioManager?
|
||||
private val audioManager: AudioManager
|
||||
get() = requireContext().getSystemService(Context.AUDIO_SERVICE) as AudioManager
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View? {
|
||||
return inflater.inflate(R.layout.fragment_volume, container, false)
|
||||
): View {
|
||||
_binding = FragmentVolumeBinding.inflate(inflater, container, false)
|
||||
return binding.root
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
setTintable(ThemeStore.accentColor(requireContext()))
|
||||
volumeDown.setOnClickListener(this)
|
||||
volumeUp.setOnClickListener(this)
|
||||
binding.volumeDown.setOnClickListener(this)
|
||||
binding.volumeUp.setOnClickListener(this)
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
|
@ -64,33 +68,30 @@ class VolumeFragment : Fragment(), SeekBar.OnSeekBarChangeListener, OnAudioVolum
|
|||
audioVolumeObserver?.register(AudioManager.STREAM_MUSIC, this)
|
||||
|
||||
val audioManager = audioManager
|
||||
if (audioManager != null) {
|
||||
volumeSeekBar.max = audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC)
|
||||
volumeSeekBar.progress = audioManager.getStreamVolume(AudioManager.STREAM_MUSIC)
|
||||
}
|
||||
volumeSeekBar.setOnSeekBarChangeListener(this)
|
||||
binding.volumeSeekBar.max = audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC)
|
||||
binding.volumeSeekBar.progress = audioManager.getStreamVolume(AudioManager.STREAM_MUSIC)
|
||||
binding.volumeSeekBar.setOnSeekBarChangeListener(this)
|
||||
}
|
||||
|
||||
override fun onAudioVolumeChanged(currentVolume: Int, maxVolume: Int) {
|
||||
if (volumeSeekBar == null) {
|
||||
return
|
||||
if (_binding != null) {
|
||||
binding.volumeSeekBar.max = maxVolume
|
||||
binding.volumeSeekBar.progress = currentVolume
|
||||
binding.volumeDown.setImageResource(if (currentVolume == 0) R.drawable.ic_volume_off else R.drawable.ic_volume_down)
|
||||
}
|
||||
|
||||
volumeSeekBar.max = maxVolume
|
||||
volumeSeekBar.progress = currentVolume
|
||||
volumeDown.setImageResource(if (currentVolume == 0) R.drawable.ic_volume_off else R.drawable.ic_volume_down)
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
audioVolumeObserver?.unregister()
|
||||
_binding = null
|
||||
}
|
||||
|
||||
override fun onProgressChanged(seekBar: SeekBar, i: Int, b: Boolean) {
|
||||
val audioManager = audioManager
|
||||
audioManager?.setStreamVolume(AudioManager.STREAM_MUSIC, i, 0)
|
||||
audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, i, 0)
|
||||
setPauseWhenZeroVolume(i < 1)
|
||||
volumeDown?.setImageResource(if (i == 0) R.drawable.ic_volume_off else R.drawable.ic_volume_down)
|
||||
binding.volumeDown.setImageResource(if (i == 0) R.drawable.ic_volume_off else R.drawable.ic_volume_down)
|
||||
}
|
||||
|
||||
override fun onStartTrackingTouch(seekBar: SeekBar) {
|
||||
|
@ -102,10 +103,10 @@ class VolumeFragment : Fragment(), SeekBar.OnSeekBarChangeListener, OnAudioVolum
|
|||
override fun onClick(view: View) {
|
||||
val audioManager = audioManager
|
||||
when (view.id) {
|
||||
R.id.volumeDown -> audioManager?.adjustStreamVolume(
|
||||
R.id.volumeDown -> audioManager.adjustStreamVolume(
|
||||
AudioManager.STREAM_MUSIC, AudioManager.ADJUST_LOWER, 0
|
||||
)
|
||||
R.id.volumeUp -> audioManager?.adjustStreamVolume(
|
||||
R.id.volumeUp -> audioManager.adjustStreamVolume(
|
||||
AudioManager.STREAM_MUSIC, AudioManager.ADJUST_RAISE, 0
|
||||
)
|
||||
}
|
||||
|
@ -113,13 +114,13 @@ class VolumeFragment : Fragment(), SeekBar.OnSeekBarChangeListener, OnAudioVolum
|
|||
|
||||
fun tintWhiteColor() {
|
||||
val color = Color.WHITE
|
||||
volumeDown.setColorFilter(color, PorterDuff.Mode.SRC_IN)
|
||||
volumeUp.setColorFilter(color, PorterDuff.Mode.SRC_IN)
|
||||
volumeSeekBar.applyColor(color)
|
||||
binding.volumeDown.setColorFilter(color, PorterDuff.Mode.SRC_IN)
|
||||
binding.volumeUp.setColorFilter(color, PorterDuff.Mode.SRC_IN)
|
||||
binding.volumeSeekBar.applyColor(color)
|
||||
}
|
||||
|
||||
fun setTintable(color: Int) {
|
||||
volumeSeekBar.applyColor(color)
|
||||
binding.volumeSeekBar.applyColor(color)
|
||||
}
|
||||
|
||||
private fun setPauseWhenZeroVolume(pauseWhenZeroVolume: Boolean) {
|
||||
|
@ -129,10 +130,10 @@ class VolumeFragment : Fragment(), SeekBar.OnSeekBarChangeListener, OnAudioVolum
|
|||
}
|
||||
|
||||
fun setTintableColor(color: Int) {
|
||||
volumeDown.setColorFilter(color, PorterDuff.Mode.SRC_IN)
|
||||
volumeUp.setColorFilter(color, PorterDuff.Mode.SRC_IN)
|
||||
binding.volumeDown.setColorFilter(color, PorterDuff.Mode.SRC_IN)
|
||||
binding.volumeUp.setColorFilter(color, PorterDuff.Mode.SRC_IN)
|
||||
// TintHelper.setTint(volumeSeekBar, color, false)
|
||||
volumeSeekBar.applyColor(color)
|
||||
binding.volumeSeekBar.applyColor(color)
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
|
|
@ -27,20 +27,20 @@ import code.name.monkey.retromusic.App
|
|||
import code.name.monkey.retromusic.Constants
|
||||
import code.name.monkey.retromusic.R
|
||||
import code.name.monkey.retromusic.adapter.ContributorAdapter
|
||||
import code.name.monkey.retromusic.databinding.FragmentAboutBinding
|
||||
import code.name.monkey.retromusic.fragments.LibraryViewModel
|
||||
import code.name.monkey.retromusic.util.NavigationUtil
|
||||
import kotlinx.android.synthetic.main.card_credit.*
|
||||
import kotlinx.android.synthetic.main.card_other.*
|
||||
import kotlinx.android.synthetic.main.card_retro_info.*
|
||||
import kotlinx.android.synthetic.main.card_social.*
|
||||
import org.koin.androidx.viewmodel.ext.android.sharedViewModel
|
||||
|
||||
class AboutFragment : Fragment(R.layout.fragment_about), View.OnClickListener {
|
||||
private var _binding: FragmentAboutBinding? = null
|
||||
private val binding get() = _binding!!
|
||||
private val libraryViewModel by sharedViewModel<LibraryViewModel>()
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
version.setSummary(getAppVersion())
|
||||
_binding = FragmentAboutBinding.bind(view)
|
||||
binding.aboutContent.cardOther.version.setSummary(getAppVersion())
|
||||
setUpView()
|
||||
loadContributors()
|
||||
}
|
||||
|
@ -53,19 +53,20 @@ class AboutFragment : Fragment(R.layout.fragment_about), View.OnClickListener {
|
|||
}
|
||||
|
||||
private fun setUpView() {
|
||||
appGithub.setOnClickListener(this)
|
||||
faqLink.setOnClickListener(this)
|
||||
telegramLink.setOnClickListener(this)
|
||||
appRate.setOnClickListener(this)
|
||||
appTranslation.setOnClickListener(this)
|
||||
appShare.setOnClickListener(this)
|
||||
donateLink.setOnClickListener(this)
|
||||
instagramLink.setOnClickListener(this)
|
||||
twitterLink.setOnClickListener(this)
|
||||
changelog.setOnClickListener(this)
|
||||
openSource.setOnClickListener(this)
|
||||
pinterestLink.setOnClickListener(this)
|
||||
bugReportLink.setOnClickListener(this)
|
||||
binding.aboutContent.cardRetroInfo.appGithub.setOnClickListener(this)
|
||||
binding.aboutContent.cardRetroInfo.faqLink.setOnClickListener(this)
|
||||
binding.aboutContent.cardSocial.telegramLink.setOnClickListener(this)
|
||||
binding.aboutContent.cardRetroInfo.appRate.setOnClickListener(this)
|
||||
binding.aboutContent.cardRetroInfo.appTranslation.setOnClickListener(this)
|
||||
binding.aboutContent.cardRetroInfo.appShare.setOnClickListener(this)
|
||||
binding.aboutContent.cardRetroInfo.donateLink.setOnClickListener(this)
|
||||
binding.aboutContent.cardSocial.instagramLink.setOnClickListener(this)
|
||||
binding.aboutContent.cardSocial.twitterLink.setOnClickListener(this)
|
||||
binding.aboutContent.cardOther.changelog.setOnClickListener(this)
|
||||
binding.aboutContent.cardOther.openSource.setOnClickListener(this)
|
||||
binding.aboutContent.cardSocial.pinterestLink.setOnClickListener(this)
|
||||
binding.aboutContent.cardRetroInfo.bugReportLink.setOnClickListener(this)
|
||||
binding.aboutContent.cardSocial.websiteLink.setOnClickListener(this)
|
||||
}
|
||||
|
||||
override fun onClick(view: View) {
|
||||
|
@ -80,9 +81,10 @@ class AboutFragment : Fragment(R.layout.fragment_about), View.OnClickListener {
|
|||
R.id.donateLink -> NavigationUtil.goToSupportDevelopment(requireActivity())
|
||||
R.id.instagramLink -> openUrl(Constants.APP_INSTAGRAM_LINK)
|
||||
R.id.twitterLink -> openUrl(Constants.APP_TWITTER_LINK)
|
||||
R.id.changelog -> openUrl(Constants.TELEGRAM_CHANGE_LOG)
|
||||
R.id.changelog -> NavigationUtil.gotoWhatNews(requireActivity())
|
||||
R.id.openSource -> NavigationUtil.goToOpenSource(requireActivity())
|
||||
R.id.bugReportLink -> NavigationUtil.bugReport(requireActivity())
|
||||
R.id.websiteLink -> openUrl(Constants.WEBSITE)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -99,7 +101,7 @@ class AboutFragment : Fragment(R.layout.fragment_about), View.OnClickListener {
|
|||
}
|
||||
|
||||
private fun shareApp() {
|
||||
ShareCompat.IntentBuilder.from(requireActivity()).setType("text/plain")
|
||||
ShareCompat.IntentBuilder(requireActivity()).setType("text/plain")
|
||||
.setChooserTitle(R.string.share_app)
|
||||
.setText(String.format(getString(R.string.app_share), requireActivity().packageName))
|
||||
.startChooser()
|
||||
|
@ -107,7 +109,7 @@ class AboutFragment : Fragment(R.layout.fragment_about), View.OnClickListener {
|
|||
|
||||
private fun loadContributors() {
|
||||
val contributorAdapter = ContributorAdapter(emptyList())
|
||||
recyclerView.apply {
|
||||
binding.aboutContent.cardCredit.recyclerView.apply {
|
||||
layoutManager = LinearLayoutManager(requireContext())
|
||||
itemAnimator = DefaultItemAnimator()
|
||||
adapter = contributorAdapter
|
||||
|
@ -116,4 +118,9 @@ class AboutFragment : Fragment(R.layout.fragment_about), View.OnClickListener {
|
|||
contributorAdapter.swapData(contributors)
|
||||
})
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
_binding = null
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,11 +19,12 @@ import android.content.Intent
|
|||
import android.graphics.Color
|
||||
import android.os.Bundle
|
||||
import android.view.*
|
||||
import androidx.activity.addCallback
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.os.bundleOf
|
||||
import androidx.core.text.HtmlCompat
|
||||
import androidx.core.view.ViewCompat
|
||||
import androidx.lifecycle.Observer
|
||||
import androidx.core.view.doOnPreDraw
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.navigation.fragment.FragmentNavigatorExtras
|
||||
import androidx.navigation.fragment.findNavController
|
||||
|
@ -35,17 +36,19 @@ import code.name.monkey.appthemehelper.common.ATHToolbarActivity.getToolbarBackg
|
|||
import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper
|
||||
import code.name.monkey.retromusic.EXTRA_ALBUM_ID
|
||||
import code.name.monkey.retromusic.EXTRA_ARTIST_ID
|
||||
import code.name.monkey.retromusic.EXTRA_ARTIST_NAME
|
||||
import code.name.monkey.retromusic.R
|
||||
import code.name.monkey.retromusic.activities.tageditor.AbsTagEditorActivity
|
||||
import code.name.monkey.retromusic.activities.tageditor.AlbumTagEditorActivity
|
||||
import code.name.monkey.retromusic.adapter.album.HorizontalAlbumAdapter
|
||||
import code.name.monkey.retromusic.adapter.song.SimpleSongAdapter
|
||||
import code.name.monkey.retromusic.databinding.FragmentAlbumDetailsBinding
|
||||
import code.name.monkey.retromusic.dialogs.AddToPlaylistDialog
|
||||
import code.name.monkey.retromusic.dialogs.DeleteSongsDialog
|
||||
import code.name.monkey.retromusic.extensions.*
|
||||
import code.name.monkey.retromusic.fragments.base.AbsMainActivityFragment
|
||||
import code.name.monkey.retromusic.glide.AlbumGlideRequest
|
||||
import code.name.monkey.retromusic.glide.ArtistGlideRequest
|
||||
import code.name.monkey.retromusic.glide.GlideApp
|
||||
import code.name.monkey.retromusic.glide.RetroGlideExtension
|
||||
import code.name.monkey.retromusic.glide.RetroMusicColoredTarget
|
||||
import code.name.monkey.retromusic.glide.SingleColorTarget
|
||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote
|
||||
|
@ -54,6 +57,7 @@ import code.name.monkey.retromusic.helper.SortOrder.AlbumSongSortOrder.Companion
|
|||
import code.name.monkey.retromusic.helper.SortOrder.AlbumSongSortOrder.Companion.SONG_TRACK_LIST
|
||||
import code.name.monkey.retromusic.helper.SortOrder.AlbumSongSortOrder.Companion.SONG_Z_A
|
||||
import code.name.monkey.retromusic.interfaces.IAlbumClickListener
|
||||
import code.name.monkey.retromusic.interfaces.ICabHolder
|
||||
import code.name.monkey.retromusic.model.Album
|
||||
import code.name.monkey.retromusic.model.Artist
|
||||
import code.name.monkey.retromusic.network.Result
|
||||
|
@ -61,14 +65,12 @@ import code.name.monkey.retromusic.network.model.LastFmAlbum
|
|||
import code.name.monkey.retromusic.repository.RealRepository
|
||||
import code.name.monkey.retromusic.util.MusicUtil
|
||||
import code.name.monkey.retromusic.util.PreferenceUtil
|
||||
import code.name.monkey.retromusic.util.RetroColorUtil
|
||||
import code.name.monkey.retromusic.util.RetroUtil
|
||||
import code.name.monkey.retromusic.util.color.MediaNotificationProcessor
|
||||
import com.bumptech.glide.Glide
|
||||
import com.afollestad.materialcab.MaterialCab
|
||||
import com.google.android.material.transition.MaterialArcMotion
|
||||
import com.google.android.material.transition.MaterialContainerTransform
|
||||
import com.google.android.material.transition.MaterialElevationScale
|
||||
import kotlinx.android.synthetic.main.fragment_album_content.*
|
||||
import kotlinx.android.synthetic.main.fragment_album_details.*
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
|
@ -78,7 +80,10 @@ import org.koin.core.parameter.parametersOf
|
|||
import java.util.*
|
||||
|
||||
class AlbumDetailsFragment : AbsMainActivityFragment(R.layout.fragment_album_details),
|
||||
IAlbumClickListener {
|
||||
IAlbumClickListener, ICabHolder {
|
||||
|
||||
private var _binding: FragmentAlbumDetailsBinding? = null
|
||||
private val binding get() = _binding!!
|
||||
|
||||
private val arguments by navArgs<AlbumDetailsFragmentArgs>()
|
||||
private val detailsViewModel by viewModel<AlbumDetailsViewModel> {
|
||||
|
@ -87,6 +92,7 @@ class AlbumDetailsFragment : AbsMainActivityFragment(R.layout.fragment_album_det
|
|||
|
||||
private lateinit var simpleSongAdapter: SimpleSongAdapter
|
||||
private lateinit var album: Album
|
||||
private var albumArtistExists = false
|
||||
|
||||
private val savedSortOrder: String
|
||||
get() = PreferenceUtil.albumDetailSongSortOrder
|
||||
|
@ -104,51 +110,70 @@ class AlbumDetailsFragment : AbsMainActivityFragment(R.layout.fragment_album_det
|
|||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
_binding = FragmentAlbumDetailsBinding.bind(view)
|
||||
setHasOptionsMenu(true)
|
||||
mainActivity.setBottomBarVisibility(false)
|
||||
mainActivity.addMusicServiceEventListener(detailsViewModel)
|
||||
mainActivity.setSupportActionBar(toolbar)
|
||||
mainActivity.setSupportActionBar(binding.toolbar)
|
||||
|
||||
toolbar.title = " "
|
||||
ViewCompat.setTransitionName(albumCoverContainer, "album")
|
||||
binding.toolbar.title = " "
|
||||
ViewCompat.setTransitionName(binding.albumCoverContainer, arguments.extraAlbumId.toString())
|
||||
postponeEnterTransition()
|
||||
detailsViewModel.getAlbum().observe(viewLifecycleOwner, Observer {
|
||||
startPostponedEnterTransition()
|
||||
detailsViewModel.getAlbum().observe(viewLifecycleOwner, {
|
||||
requireView().doOnPreDraw {
|
||||
startPostponedEnterTransition()
|
||||
}
|
||||
albumArtistExists = !it.albumArtist.isNullOrEmpty()
|
||||
showAlbum(it)
|
||||
if (albumArtistExists) {
|
||||
ViewCompat.setTransitionName(binding.artistImage, album.albumArtist)
|
||||
} else {
|
||||
ViewCompat.setTransitionName(binding.artistImage, album.artistId.toString())
|
||||
}
|
||||
})
|
||||
|
||||
setupRecyclerView()
|
||||
artistImage.setOnClickListener { artistView ->
|
||||
ViewCompat.setTransitionName(artistView, "artist")
|
||||
exitTransition = MaterialElevationScale(false).apply {
|
||||
duration = 300L
|
||||
binding.artistImage.setOnClickListener { artistView ->
|
||||
if (albumArtistExists) {
|
||||
findActivityNavController(R.id.fragment_container)
|
||||
.navigate(
|
||||
R.id.albumArtistDetailsFragment,
|
||||
bundleOf(EXTRA_ARTIST_NAME to album.albumArtist),
|
||||
null,
|
||||
FragmentNavigatorExtras(artistView to album.albumArtist.toString())
|
||||
)
|
||||
} else {
|
||||
findActivityNavController(R.id.fragment_container)
|
||||
.navigate(
|
||||
R.id.artistDetailsFragment,
|
||||
bundleOf(EXTRA_ARTIST_ID to album.artistId),
|
||||
null,
|
||||
FragmentNavigatorExtras(artistView to album.artistId.toString())
|
||||
)
|
||||
}
|
||||
reenterTransition = MaterialElevationScale(true).apply {
|
||||
duration = 300L
|
||||
}
|
||||
findActivityNavController(R.id.fragment_container)
|
||||
.navigate(
|
||||
R.id.artistDetailsFragment,
|
||||
bundleOf(EXTRA_ARTIST_ID to album.artistId),
|
||||
null,
|
||||
FragmentNavigatorExtras(artistView to "artist")
|
||||
)
|
||||
|
||||
}
|
||||
playAction.setOnClickListener {
|
||||
binding.fragmentAlbumContent.playAction.setOnClickListener {
|
||||
MusicPlayerRemote.openQueue(album.songs, 0, true)
|
||||
}
|
||||
shuffleAction.setOnClickListener {
|
||||
binding.fragmentAlbumContent.shuffleAction.setOnClickListener {
|
||||
MusicPlayerRemote.openAndShuffleQueue(
|
||||
album.songs,
|
||||
true
|
||||
)
|
||||
}
|
||||
|
||||
aboutAlbumText.setOnClickListener {
|
||||
if (aboutAlbumText.maxLines == 4) {
|
||||
aboutAlbumText.maxLines = Integer.MAX_VALUE
|
||||
binding.fragmentAlbumContent.aboutAlbumText.setOnClickListener {
|
||||
if (binding.fragmentAlbumContent.aboutAlbumText.maxLines == 4) {
|
||||
binding.fragmentAlbumContent.aboutAlbumText.maxLines = Integer.MAX_VALUE
|
||||
} else {
|
||||
aboutAlbumText.maxLines = 4
|
||||
binding.fragmentAlbumContent.aboutAlbumText.maxLines = 4
|
||||
}
|
||||
}
|
||||
|
||||
requireActivity().onBackPressedDispatcher.addCallback(viewLifecycleOwner) {
|
||||
if (!handleBackPress()) {
|
||||
remove()
|
||||
requireActivity().onBackPressed()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -163,9 +188,9 @@ class AlbumDetailsFragment : AbsMainActivityFragment(R.layout.fragment_album_det
|
|||
requireActivity() as AppCompatActivity,
|
||||
ArrayList(),
|
||||
R.layout.item_song,
|
||||
null
|
||||
this
|
||||
)
|
||||
recyclerView.apply {
|
||||
binding.fragmentAlbumContent.recyclerView.apply {
|
||||
layoutManager = LinearLayoutManager(requireContext())
|
||||
itemAnimator = DefaultItemAnimator()
|
||||
isNestedScrollingEnabled = false
|
||||
|
@ -179,21 +204,21 @@ class AlbumDetailsFragment : AbsMainActivityFragment(R.layout.fragment_album_det
|
|||
}
|
||||
this.album = album
|
||||
|
||||
albumTitle.text = album.title
|
||||
binding.albumTitle.text = album.title
|
||||
val songText = resources.getQuantityString(
|
||||
R.plurals.albumSongs,
|
||||
album.songCount,
|
||||
album.songCount
|
||||
)
|
||||
songTitle.text = songText
|
||||
binding.fragmentAlbumContent.songTitle.text = songText
|
||||
if (MusicUtil.getYearString(album.year) == "-") {
|
||||
albumText.text = String.format(
|
||||
binding.albumText.text = String.format(
|
||||
"%s • %s",
|
||||
album.artistName,
|
||||
if (albumArtistExists) album.albumArtist else album.artistName,
|
||||
MusicUtil.getReadableDurationString(MusicUtil.getTotalDuration(album.songs))
|
||||
)
|
||||
} else {
|
||||
albumText.text = String.format(
|
||||
binding.albumText.text = String.format(
|
||||
"%s • %s • %s",
|
||||
album.artistName,
|
||||
MusicUtil.getYearString(album.year),
|
||||
|
@ -202,11 +227,18 @@ class AlbumDetailsFragment : AbsMainActivityFragment(R.layout.fragment_album_det
|
|||
}
|
||||
loadAlbumCover(album)
|
||||
simpleSongAdapter.swapDataSet(album.songs)
|
||||
detailsViewModel.getArtist(album.artistId).observe(viewLifecycleOwner, Observer {
|
||||
loadArtistImage(it)
|
||||
})
|
||||
if (albumArtistExists) {
|
||||
detailsViewModel.getAlbumArtist(album.albumArtist.toString()).observe(viewLifecycleOwner, {
|
||||
loadArtistImage(it)
|
||||
})
|
||||
} else {
|
||||
detailsViewModel.getArtist(album.artistId).observe(viewLifecycleOwner, {
|
||||
loadArtistImage(it)
|
||||
})
|
||||
}
|
||||
|
||||
detailsViewModel.getAlbumInfo(album).observe(viewLifecycleOwner, Observer { result ->
|
||||
|
||||
detailsViewModel.getAlbumInfo(album).observe(viewLifecycleOwner, { result ->
|
||||
when (result) {
|
||||
is Result.Loading -> {
|
||||
println("Loading")
|
||||
|
@ -222,41 +254,44 @@ class AlbumDetailsFragment : AbsMainActivityFragment(R.layout.fragment_album_det
|
|||
}
|
||||
|
||||
private fun moreAlbums(albums: List<Album>) {
|
||||
moreTitle.show()
|
||||
moreRecyclerView.show()
|
||||
moreTitle.text = String.format(getString(R.string.label_more_from), album.artistName)
|
||||
binding.fragmentAlbumContent.moreTitle.show()
|
||||
binding.fragmentAlbumContent.moreRecyclerView.show()
|
||||
binding.fragmentAlbumContent.moreTitle.text =
|
||||
String.format(getString(R.string.label_more_from), album.artistName)
|
||||
|
||||
val albumAdapter =
|
||||
HorizontalAlbumAdapter(requireActivity() as AppCompatActivity, albums, null, this)
|
||||
moreRecyclerView.layoutManager = GridLayoutManager(
|
||||
HorizontalAlbumAdapter(requireActivity() as AppCompatActivity, albums, this, this)
|
||||
binding.fragmentAlbumContent.moreRecyclerView.layoutManager = GridLayoutManager(
|
||||
requireContext(),
|
||||
1,
|
||||
GridLayoutManager.HORIZONTAL,
|
||||
false
|
||||
)
|
||||
moreRecyclerView.adapter = albumAdapter
|
||||
binding.fragmentAlbumContent.moreRecyclerView.adapter = albumAdapter
|
||||
}
|
||||
|
||||
private fun aboutAlbum(lastFmAlbum: LastFmAlbum) {
|
||||
if (lastFmAlbum.album != null) {
|
||||
if (lastFmAlbum.album.wiki != null) {
|
||||
aboutAlbumText.show()
|
||||
aboutAlbumTitle.show()
|
||||
aboutAlbumTitle.text =
|
||||
binding.fragmentAlbumContent.aboutAlbumText.show()
|
||||
binding.fragmentAlbumContent.aboutAlbumTitle.show()
|
||||
binding.fragmentAlbumContent.aboutAlbumTitle.text =
|
||||
String.format(getString(R.string.about_album_label), lastFmAlbum.album.name)
|
||||
aboutAlbumText.text = HtmlCompat.fromHtml(
|
||||
binding.fragmentAlbumContent.aboutAlbumText.text = HtmlCompat.fromHtml(
|
||||
lastFmAlbum.album.wiki.content,
|
||||
HtmlCompat.FROM_HTML_MODE_LEGACY
|
||||
)
|
||||
}
|
||||
if (lastFmAlbum.album.listeners.isNotEmpty()) {
|
||||
listeners.show()
|
||||
listenersLabel.show()
|
||||
scrobbles.show()
|
||||
scrobblesLabel.show()
|
||||
binding.fragmentAlbumContent.listeners.show()
|
||||
binding.fragmentAlbumContent.listenersLabel.show()
|
||||
binding.fragmentAlbumContent.scrobbles.show()
|
||||
binding.fragmentAlbumContent.scrobblesLabel.show()
|
||||
|
||||
listeners.text = RetroUtil.formatValue(lastFmAlbum.album.listeners.toFloat())
|
||||
scrobbles.text = RetroUtil.formatValue(lastFmAlbum.album.playcount.toFloat())
|
||||
binding.fragmentAlbumContent.listeners.text =
|
||||
RetroUtil.formatValue(lastFmAlbum.album.listeners.toFloat())
|
||||
binding.fragmentAlbumContent.scrobbles.text =
|
||||
RetroUtil.formatValue(lastFmAlbum.album.playcount.toFloat())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -265,24 +300,22 @@ class AlbumDetailsFragment : AbsMainActivityFragment(R.layout.fragment_album_det
|
|||
detailsViewModel.getMoreAlbums(artist).observe(viewLifecycleOwner, {
|
||||
moreAlbums(it)
|
||||
})
|
||||
ArtistGlideRequest.Builder.from(Glide.with(requireContext()), artist)
|
||||
.forceDownload(PreferenceUtil.isAllowedToDownloadMetadata())
|
||||
.generatePalette(requireContext())
|
||||
.build()
|
||||
GlideApp.with(requireContext()).asBitmapPalette().artistImageOptions(artist)
|
||||
//.forceDownload(PreferenceUtil.isAllowedToDownloadMetadata())
|
||||
.load(RetroGlideExtension.getArtistModel(artist, PreferenceUtil.isAllowedToDownloadMetadata()))
|
||||
.dontAnimate()
|
||||
.dontTransform()
|
||||
.into(object : RetroMusicColoredTarget(artistImage) {
|
||||
.into(object : RetroMusicColoredTarget(binding.artistImage) {
|
||||
override fun onColorReady(colors: MediaNotificationProcessor) {
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
private fun loadAlbumCover(album: Album) {
|
||||
AlbumGlideRequest.Builder.from(Glide.with(requireContext()), album.safeGetFirstSong())
|
||||
.checkIgnoreMediaStore()
|
||||
.generatePalette(requireContext())
|
||||
.build()
|
||||
.into(object : SingleColorTarget(image) {
|
||||
GlideApp.with(requireContext()).asBitmapPalette().albumCoverOptions(album.safeGetFirstSong())
|
||||
//.checkIgnoreMediaStore()
|
||||
.load(RetroGlideExtension.getSongModel(album.safeGetFirstSong()))
|
||||
.into(object : SingleColorTarget(binding.image) {
|
||||
override fun onColorReady(color: Int) {
|
||||
setColors(color)
|
||||
}
|
||||
|
@ -290,23 +323,17 @@ class AlbumDetailsFragment : AbsMainActivityFragment(R.layout.fragment_album_det
|
|||
}
|
||||
|
||||
private fun setColors(color: Int) {
|
||||
shuffleAction?.applyColor(color)
|
||||
playAction?.applyOutlineColor(color)
|
||||
binding.fragmentAlbumContent.shuffleAction.applyColor(color)
|
||||
binding.fragmentAlbumContent.playAction.applyOutlineColor(color)
|
||||
}
|
||||
|
||||
override fun onAlbumClick(albumId: Long, view: View) {
|
||||
exitTransition = MaterialElevationScale(false).apply {
|
||||
duration = 300L
|
||||
}
|
||||
reenterTransition = MaterialElevationScale(false).apply {
|
||||
duration = 300L
|
||||
}
|
||||
findNavController().navigate(
|
||||
R.id.albumDetailsFragment,
|
||||
bundleOf(EXTRA_ALBUM_ID to albumId),
|
||||
null,
|
||||
FragmentNavigatorExtras(
|
||||
view to "album"
|
||||
view to albumId.toString()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
@ -318,9 +345,9 @@ class AlbumDetailsFragment : AbsMainActivityFragment(R.layout.fragment_album_det
|
|||
setUpSortOrderMenu(sortOrder.subMenu)
|
||||
ToolbarContentTintHelper.handleOnCreateOptionsMenu(
|
||||
requireContext(),
|
||||
toolbar,
|
||||
binding.toolbar,
|
||||
menu,
|
||||
getToolbarBackgroundColor(toolbar)
|
||||
getToolbarBackgroundColor(binding.toolbar)
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -360,7 +387,7 @@ class AlbumDetailsFragment : AbsMainActivityFragment(R.layout.fragment_album_det
|
|||
intent.putExtra(AbsTagEditorActivity.EXTRA_ID, album.id)
|
||||
val options = ActivityOptions.makeSceneTransitionAnimation(
|
||||
requireActivity(),
|
||||
albumCoverContainer,
|
||||
binding.albumCoverContainer,
|
||||
"${getString(R.string.transition_album_art)}_${album.id}"
|
||||
)
|
||||
startActivityForResult(
|
||||
|
@ -421,6 +448,37 @@ class AlbumDetailsFragment : AbsMainActivityFragment(R.layout.fragment_album_det
|
|||
simpleSongAdapter.swapDataSet(album.songs)
|
||||
}
|
||||
|
||||
private fun handleBackPress(): Boolean {
|
||||
cab?.let {
|
||||
if (it.isActive) {
|
||||
it.finish()
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
private var cab: MaterialCab? = null
|
||||
|
||||
override fun openCab(menuRes: Int, callback: MaterialCab.Callback): MaterialCab {
|
||||
cab?.let {
|
||||
if (it.isActive) {
|
||||
it.finish()
|
||||
}
|
||||
}
|
||||
cab = MaterialCab(mainActivity, R.id.cab_stub)
|
||||
.setMenu(menuRes)
|
||||
.setCloseDrawableRes(R.drawable.ic_close)
|
||||
.setBackgroundColor(RetroColorUtil.shiftBackgroundColorForLightText(surfaceColor()))
|
||||
.start(callback)
|
||||
return cab as MaterialCab
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
_binding = null
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val TAG_EDITOR_REQUEST = 9002
|
||||
}
|
||||
|
|
|
@ -14,11 +14,7 @@
|
|||
*/
|
||||
package code.name.monkey.retromusic.fragments.albums
|
||||
|
||||
import androidx.lifecycle.LiveData
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.liveData
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import androidx.lifecycle.*
|
||||
import code.name.monkey.retromusic.interfaces.IMusicServiceEventListener
|
||||
import code.name.monkey.retromusic.model.Album
|
||||
import code.name.monkey.retromusic.model.Artist
|
||||
|
@ -51,6 +47,11 @@ class AlbumDetailsViewModel(
|
|||
emit(artist)
|
||||
}
|
||||
|
||||
fun getAlbumArtist(artistName: String): LiveData<Artist> = liveData(IO) {
|
||||
val artist = repository.albumArtistByName(artistName)
|
||||
emit(artist)
|
||||
}
|
||||
|
||||
fun getAlbumInfo(album: Album): LiveData<Result<LastFmAlbum>> = liveData {
|
||||
emit(Result.Loading)
|
||||
emit(repository.albumInfo(album.artistName ?: "-", album.title ?: "-"))
|
||||
|
@ -73,4 +74,5 @@ class AlbumDetailsViewModel(
|
|||
override fun onPlayStateChanged() {}
|
||||
override fun onRepeatModeChanged() {}
|
||||
override fun onShuffleModeChanged() {}
|
||||
override fun onFavoriteStateChanged() {}
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@ package code.name.monkey.retromusic.fragments.albums
|
|||
|
||||
import android.os.Bundle
|
||||
import android.view.*
|
||||
import androidx.activity.addCallback
|
||||
import androidx.core.os.bundleOf
|
||||
import androidx.navigation.fragment.FragmentNavigatorExtras
|
||||
import androidx.navigation.fragment.findNavController
|
||||
|
@ -33,7 +34,7 @@ import code.name.monkey.retromusic.util.PreferenceUtil
|
|||
import code.name.monkey.retromusic.util.RetroColorUtil
|
||||
import code.name.monkey.retromusic.util.RetroUtil
|
||||
import com.afollestad.materialcab.MaterialCab
|
||||
import com.google.android.material.transition.MaterialElevationScale
|
||||
import com.google.android.gms.cast.framework.CastButtonFactory
|
||||
|
||||
class AlbumsFragment : AbsRecyclerViewCustomGridSizeFragment<AlbumAdapter, GridLayoutManager>(),
|
||||
IAlbumClickListener, ICabHolder {
|
||||
|
@ -46,8 +47,17 @@ class AlbumsFragment : AbsRecyclerViewCustomGridSizeFragment<AlbumAdapter, GridL
|
|||
else
|
||||
adapter?.swapDataSet(listOf())
|
||||
})
|
||||
requireActivity().onBackPressedDispatcher.addCallback(viewLifecycleOwner) {
|
||||
if (!handleBackPress()) {
|
||||
remove()
|
||||
requireActivity().onBackPressed()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override val titleRes: Int
|
||||
get() = R.string.albums
|
||||
|
||||
override val emptyMessage: Int
|
||||
get() = R.string.no_albums
|
||||
|
||||
|
@ -114,20 +124,15 @@ class AlbumsFragment : AbsRecyclerViewCustomGridSizeFragment<AlbumAdapter, GridL
|
|||
}
|
||||
|
||||
override fun onAlbumClick(albumId: Long, view: View) {
|
||||
exitTransition = MaterialElevationScale(false).apply {
|
||||
duration = 300L
|
||||
}
|
||||
reenterTransition = MaterialElevationScale(true).apply {
|
||||
duration = 300L
|
||||
}
|
||||
findNavController().navigate(
|
||||
R.id.albumDetailsFragment,
|
||||
bundleOf(EXTRA_ALBUM_ID to albumId),
|
||||
null,
|
||||
FragmentNavigatorExtras(
|
||||
view to "album"
|
||||
view to albumId.toString()
|
||||
)
|
||||
)
|
||||
reenterTransition = null
|
||||
}
|
||||
|
||||
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
|
||||
|
@ -140,6 +145,8 @@ class AlbumsFragment : AbsRecyclerViewCustomGridSizeFragment<AlbumAdapter, GridL
|
|||
val layoutItem = menu.findItem(R.id.action_layout_type)
|
||||
setupLayoutMenu(layoutItem.subMenu)
|
||||
setUpSortOrderMenu(menu.findItem(R.id.action_sort_order).subMenu)
|
||||
//Setting up cast button
|
||||
CastButtonFactory.setUpMediaRouteButton(requireContext(), menu, R.id.action_cast)
|
||||
}
|
||||
|
||||
private fun setUpSortOrderMenu(
|
||||
|
@ -175,6 +182,13 @@ class AlbumsFragment : AbsRecyclerViewCustomGridSizeFragment<AlbumAdapter, GridL
|
|||
R.string.sort_order_year
|
||||
).isChecked =
|
||||
currentSortOrder.equals(AlbumSortOrder.ALBUM_YEAR)
|
||||
sortOrderMenu.add(
|
||||
0,
|
||||
R.id.action_album_sort_order_num_songs,
|
||||
4,
|
||||
R.string.sort_order_num_songs
|
||||
).isChecked =
|
||||
currentSortOrder.equals(AlbumSortOrder.ALBUM_NUMBER_OF_SONGS)
|
||||
|
||||
sortOrderMenu.setGroupCheckable(0, true, true)
|
||||
}
|
||||
|
@ -251,6 +265,7 @@ class AlbumsFragment : AbsRecyclerViewCustomGridSizeFragment<AlbumAdapter, GridL
|
|||
R.id.action_album_sort_order_desc -> AlbumSortOrder.ALBUM_Z_A
|
||||
R.id.action_album_sort_order_artist -> AlbumSortOrder.ALBUM_ARTIST
|
||||
R.id.action_album_sort_order_year -> AlbumSortOrder.ALBUM_YEAR
|
||||
R.id.action_album_sort_order_num_songs -> AlbumSortOrder.ALBUM_NUMBER_OF_SONGS
|
||||
else -> PreferenceUtil.albumSortOrder
|
||||
}
|
||||
if (sortOrder != PreferenceUtil.albumSortOrder) {
|
||||
|
@ -303,6 +318,21 @@ class AlbumsFragment : AbsRecyclerViewCustomGridSizeFragment<AlbumAdapter, GridL
|
|||
return false
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
libraryViewModel.forceReload(ReloadType.Albums)
|
||||
}
|
||||
|
||||
private fun handleBackPress(): Boolean {
|
||||
cab?.let {
|
||||
if (it.isActive) {
|
||||
it.finish()
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
private var cab: MaterialCab? = null
|
||||
|
||||
override fun openCab(menuRes: Int, callback: MaterialCab.Callback): MaterialCab {
|
||||
|
|
|
@ -0,0 +1,342 @@
|
|||
package code.name.monkey.retromusic.fragments.artists
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.Intent
|
||||
import android.graphics.Color
|
||||
import android.os.Bundle
|
||||
import android.text.Spanned
|
||||
import android.view.Menu
|
||||
import android.view.MenuInflater
|
||||
import android.view.MenuItem
|
||||
import android.view.View
|
||||
import androidx.activity.addCallback
|
||||
import androidx.core.os.bundleOf
|
||||
import androidx.core.text.HtmlCompat
|
||||
import androidx.core.view.ViewCompat
|
||||
import androidx.core.view.doOnPreDraw
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.navigation.fragment.FragmentNavigatorExtras
|
||||
import androidx.navigation.fragment.findNavController
|
||||
import androidx.recyclerview.widget.DefaultItemAnimator
|
||||
import androidx.recyclerview.widget.GridLayoutManager
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import code.name.monkey.retromusic.EXTRA_ALBUM_ID
|
||||
import code.name.monkey.retromusic.R
|
||||
import code.name.monkey.retromusic.adapter.album.HorizontalAlbumAdapter
|
||||
import code.name.monkey.retromusic.adapter.song.SimpleSongAdapter
|
||||
import code.name.monkey.retromusic.databinding.FragmentArtistDetailsBinding
|
||||
import code.name.monkey.retromusic.dialogs.AddToPlaylistDialog
|
||||
import code.name.monkey.retromusic.extensions.*
|
||||
import code.name.monkey.retromusic.fragments.base.AbsMainActivityFragment
|
||||
import code.name.monkey.retromusic.glide.GlideApp
|
||||
import code.name.monkey.retromusic.glide.RetroGlideExtension
|
||||
import code.name.monkey.retromusic.glide.SingleColorTarget
|
||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote
|
||||
import code.name.monkey.retromusic.interfaces.IAlbumClickListener
|
||||
import code.name.monkey.retromusic.interfaces.ICabHolder
|
||||
import code.name.monkey.retromusic.model.Artist
|
||||
import code.name.monkey.retromusic.network.Result
|
||||
import code.name.monkey.retromusic.network.model.LastFmArtist
|
||||
import code.name.monkey.retromusic.repository.RealRepository
|
||||
import code.name.monkey.retromusic.util.CustomArtistImageUtil
|
||||
import code.name.monkey.retromusic.util.MusicUtil
|
||||
import code.name.monkey.retromusic.util.RetroColorUtil
|
||||
import code.name.monkey.retromusic.util.RetroUtil
|
||||
import com.afollestad.materialcab.MaterialCab
|
||||
import com.google.android.material.transition.MaterialContainerTransform
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.koin.android.ext.android.get
|
||||
import java.util.*
|
||||
import kotlin.collections.ArrayList
|
||||
|
||||
abstract class AbsArtistDetailsFragment : AbsMainActivityFragment(R.layout.fragment_artist_details),
|
||||
IAlbumClickListener, ICabHolder {
|
||||
private var _binding: FragmentArtistDetailsBinding? = null
|
||||
private val binding get() = _binding!!
|
||||
|
||||
abstract val detailsViewModel: ArtistDetailsViewModel
|
||||
abstract val artistId: Long?
|
||||
abstract val artistName: String?
|
||||
private lateinit var artist: Artist
|
||||
private lateinit var songAdapter: SimpleSongAdapter
|
||||
private lateinit var albumAdapter: HorizontalAlbumAdapter
|
||||
private var forceDownload: Boolean = false
|
||||
private var lang: String? = null
|
||||
private var biography: Spanned? = null
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
sharedElementEnterTransition = MaterialContainerTransform().apply {
|
||||
drawingViewId = R.id.fragment_container
|
||||
duration = 300L
|
||||
scrimColor = Color.TRANSPARENT
|
||||
setAllContainerColors(requireContext().resolveColor(R.attr.colorSurface))
|
||||
}
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
_binding = FragmentArtistDetailsBinding.bind(view)
|
||||
}
|
||||
|
||||
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||
super.onActivityCreated(savedInstanceState)
|
||||
setHasOptionsMenu(true)
|
||||
mainActivity.addMusicServiceEventListener(detailsViewModel)
|
||||
mainActivity.setSupportActionBar(binding.toolbar)
|
||||
binding.toolbar.title = null
|
||||
ViewCompat.setTransitionName(
|
||||
binding.artistCoverContainer,
|
||||
(artistId ?: artistName).toString()
|
||||
)
|
||||
postponeEnterTransition()
|
||||
detailsViewModel.getArtist().observe(viewLifecycleOwner, {
|
||||
requireView().doOnPreDraw {
|
||||
startPostponedEnterTransition()
|
||||
}
|
||||
showArtist(it)
|
||||
})
|
||||
setupRecyclerView()
|
||||
|
||||
binding.fragmentArtistContent.playAction.apply {
|
||||
setOnClickListener { MusicPlayerRemote.openQueue(artist.songs, 0, true) }
|
||||
}
|
||||
binding.fragmentArtistContent.shuffleAction.apply {
|
||||
setOnClickListener { MusicPlayerRemote.openAndShuffleQueue(artist.songs, true) }
|
||||
}
|
||||
|
||||
binding.fragmentArtistContent.biographyText.setOnClickListener {
|
||||
if (binding.fragmentArtistContent.biographyText.maxLines == 4) {
|
||||
binding.fragmentArtistContent.biographyText.maxLines = Integer.MAX_VALUE
|
||||
} else {
|
||||
binding.fragmentArtistContent.biographyText.maxLines = 4
|
||||
}
|
||||
}
|
||||
|
||||
requireActivity().onBackPressedDispatcher.addCallback(viewLifecycleOwner) {
|
||||
if (!handleBackPress()) {
|
||||
remove()
|
||||
requireActivity().onBackPressed()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun setupRecyclerView() {
|
||||
albumAdapter = HorizontalAlbumAdapter(requireActivity(), ArrayList(), this, this)
|
||||
binding.fragmentArtistContent.albumRecyclerView.apply {
|
||||
itemAnimator = DefaultItemAnimator()
|
||||
layoutManager = GridLayoutManager(this.context, 1, GridLayoutManager.HORIZONTAL, false)
|
||||
adapter = albumAdapter
|
||||
}
|
||||
songAdapter = SimpleSongAdapter(requireActivity(), ArrayList(), R.layout.item_song, this)
|
||||
binding.fragmentArtistContent.recyclerView.apply {
|
||||
itemAnimator = DefaultItemAnimator()
|
||||
layoutManager = LinearLayoutManager(this.context)
|
||||
adapter = songAdapter
|
||||
}
|
||||
}
|
||||
|
||||
private fun showArtist(artist: Artist) {
|
||||
this.artist = artist
|
||||
loadArtistImage(artist)
|
||||
if (RetroUtil.isAllowedToDownloadMetadata(requireContext())) {
|
||||
loadBiography(artist.name)
|
||||
}
|
||||
binding.artistTitle.text = artist.name
|
||||
binding.text.text = String.format(
|
||||
"%s • %s",
|
||||
MusicUtil.getArtistInfoString(requireContext(), artist),
|
||||
MusicUtil.getReadableDurationString(MusicUtil.getTotalDuration(artist.songs))
|
||||
)
|
||||
val songText = resources.getQuantityString(
|
||||
R.plurals.albumSongs,
|
||||
artist.songCount,
|
||||
artist.songCount
|
||||
)
|
||||
val albumText = resources.getQuantityString(
|
||||
R.plurals.albums,
|
||||
artist.songCount,
|
||||
artist.songCount
|
||||
)
|
||||
binding.fragmentArtistContent.songTitle.text = songText
|
||||
binding.fragmentArtistContent.albumTitle.text = albumText
|
||||
songAdapter.swapDataSet(artist.songs.sortedBy { it.trackNumber })
|
||||
albumAdapter.swapDataSet(artist.albums)
|
||||
}
|
||||
|
||||
private fun loadBiography(
|
||||
name: String,
|
||||
lang: String? = Locale.getDefault().language
|
||||
) {
|
||||
biography = null
|
||||
this.lang = lang
|
||||
detailsViewModel.getArtistInfo(name, lang, null)
|
||||
.observe(viewLifecycleOwner, { result ->
|
||||
when (result) {
|
||||
is Result.Loading -> println("Loading")
|
||||
is Result.Error -> println("Error")
|
||||
is Result.Success -> artistInfo(result.data)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
private fun artistInfo(lastFmArtist: LastFmArtist?) {
|
||||
if (lastFmArtist != null && lastFmArtist.artist != null && lastFmArtist.artist.bio != null) {
|
||||
val bioContent = lastFmArtist.artist.bio.content
|
||||
if (bioContent != null && bioContent.trim { it <= ' ' }.isNotEmpty()) {
|
||||
binding.fragmentArtistContent.biographyText.visibility = View.VISIBLE
|
||||
binding.fragmentArtistContent.biographyTitle.visibility = View.VISIBLE
|
||||
biography = HtmlCompat.fromHtml(bioContent, HtmlCompat.FROM_HTML_MODE_LEGACY)
|
||||
binding.fragmentArtistContent.biographyText.text = biography
|
||||
if (lastFmArtist.artist.stats.listeners.isNotEmpty()) {
|
||||
binding.fragmentArtistContent.listeners.show()
|
||||
binding.fragmentArtistContent.listenersLabel.show()
|
||||
binding.fragmentArtistContent.scrobbles.show()
|
||||
binding.fragmentArtistContent.scrobblesLabel.show()
|
||||
binding.fragmentArtistContent.listeners.text =
|
||||
RetroUtil.formatValue(lastFmArtist.artist.stats.listeners.toFloat())
|
||||
binding.fragmentArtistContent.scrobbles.text =
|
||||
RetroUtil.formatValue(lastFmArtist.artist.stats.playcount.toFloat())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If the "lang" parameter is set and no biography is given, retry with default language
|
||||
if (biography == null && lang != null) {
|
||||
loadBiography(artist.name, null)
|
||||
}
|
||||
}
|
||||
|
||||
private fun loadArtistImage(artist: Artist) {
|
||||
GlideApp.with(requireContext()).asBitmapPalette().artistImageOptions(artist)
|
||||
.load(RetroGlideExtension.getArtistModel(artist))
|
||||
.dontAnimate()
|
||||
.into(object : SingleColorTarget(binding.image) {
|
||||
override fun onColorReady(color: Int) {
|
||||
setColors(color)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
private fun setColors(color: Int) {
|
||||
if (_binding != null) {
|
||||
binding.fragmentArtistContent.shuffleAction.applyColor(color)
|
||||
binding.fragmentArtistContent.playAction.applyOutlineColor(color)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onAlbumClick(albumId: Long, view: View) {
|
||||
findNavController().navigate(
|
||||
R.id.albumDetailsFragment,
|
||||
bundleOf(EXTRA_ALBUM_ID to albumId),
|
||||
null,
|
||||
FragmentNavigatorExtras(
|
||||
view to albumId.toString()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||
return handleSortOrderMenuItem(item)
|
||||
}
|
||||
|
||||
private fun handleSortOrderMenuItem(item: MenuItem): Boolean {
|
||||
val songs = artist.songs
|
||||
when (item.itemId) {
|
||||
android.R.id.home -> findNavController().navigateUp()
|
||||
R.id.action_play_next -> {
|
||||
MusicPlayerRemote.playNext(songs)
|
||||
return true
|
||||
}
|
||||
R.id.action_add_to_current_playing -> {
|
||||
MusicPlayerRemote.enqueue(songs)
|
||||
return true
|
||||
}
|
||||
R.id.action_add_to_playlist -> {
|
||||
lifecycleScope.launch(Dispatchers.IO) {
|
||||
val playlists = get<RealRepository>().fetchPlaylists()
|
||||
withContext(Dispatchers.Main) {
|
||||
AddToPlaylistDialog.create(playlists, songs)
|
||||
.show(childFragmentManager, "ADD_PLAYLIST")
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
R.id.action_set_artist_image -> {
|
||||
val intent = Intent(Intent.ACTION_GET_CONTENT)
|
||||
intent.type = "image/*"
|
||||
startActivityForResult(
|
||||
Intent.createChooser(intent, getString(R.string.pick_from_local_storage)),
|
||||
REQUEST_CODE_SELECT_IMAGE
|
||||
)
|
||||
return true
|
||||
}
|
||||
R.id.action_reset_artist_image -> {
|
||||
showToast(resources.getString(R.string.updating))
|
||||
CustomArtistImageUtil.getInstance(requireContext()).resetCustomArtistImage(artist)
|
||||
forceDownload = true
|
||||
return true
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||
super.onActivityResult(requestCode, resultCode, data)
|
||||
when (requestCode) {
|
||||
REQUEST_CODE_SELECT_IMAGE -> if (resultCode == Activity.RESULT_OK) {
|
||||
data?.data?.let {
|
||||
CustomArtistImageUtil.getInstance(requireContext())
|
||||
.setCustomArtistImage(artist, it)
|
||||
}
|
||||
}
|
||||
else -> if (resultCode == Activity.RESULT_OK) {
|
||||
println("OK")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
|
||||
super.onCreateOptionsMenu(menu, inflater)
|
||||
inflater.inflate(R.menu.menu_artist_detail, menu)
|
||||
}
|
||||
|
||||
|
||||
private fun handleBackPress(): Boolean {
|
||||
cab?.let {
|
||||
if (it.isActive) {
|
||||
it.finish()
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
private var cab: MaterialCab? = null
|
||||
|
||||
override fun openCab(menuRes: Int, callback: MaterialCab.Callback): MaterialCab {
|
||||
cab?.let {
|
||||
if (it.isActive) {
|
||||
it.finish()
|
||||
}
|
||||
}
|
||||
cab = MaterialCab(mainActivity, R.id.cab_stub)
|
||||
.setMenu(menuRes)
|
||||
.setCloseDrawableRes(R.drawable.ic_close)
|
||||
.setBackgroundColor(RetroColorUtil.shiftBackgroundColorForLightText(surfaceColor()))
|
||||
.start(callback)
|
||||
return cab as MaterialCab
|
||||
}
|
||||
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
_binding = null
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val REQUEST_CODE_SELECT_IMAGE = 9002
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
package code.name.monkey.retromusic.fragments.artists
|
||||
|
||||
import androidx.navigation.fragment.navArgs
|
||||
import org.koin.androidx.viewmodel.ext.android.viewModel
|
||||
import org.koin.core.parameter.parametersOf
|
||||
|
||||
class AlbumArtistDetailsFragment : AbsArtistDetailsFragment() {
|
||||
|
||||
private val arguments by navArgs<AlbumArtistDetailsFragmentArgs>()
|
||||
|
||||
override val detailsViewModel: ArtistDetailsViewModel by viewModel {
|
||||
parametersOf(null, arguments.extraArtistName)
|
||||
}
|
||||
override val artistId: Long?
|
||||
get() = null
|
||||
override val artistName: String
|
||||
get() = arguments.extraArtistName
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
package code.name.monkey.retromusic.fragments.artists
|
||||
|
||||
import androidx.lifecycle.*
|
||||
import code.name.monkey.retromusic.interfaces.IMusicServiceEventListener
|
||||
import code.name.monkey.retromusic.model.Artist
|
||||
import code.name.monkey.retromusic.network.Result
|
||||
import code.name.monkey.retromusic.network.model.LastFmArtist
|
||||
import code.name.monkey.retromusic.repository.RealRepository
|
||||
import kotlinx.coroutines.Dispatchers.IO
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
class AlbumArtistDetailsViewModel(
|
||||
private val realRepository: RealRepository,
|
||||
private val artistName: String
|
||||
) : ViewModel(), IMusicServiceEventListener {
|
||||
private val artistDetails = MutableLiveData<Artist>()
|
||||
|
||||
init {
|
||||
fetchAlbumArtist()
|
||||
}
|
||||
|
||||
private fun fetchAlbumArtist() {
|
||||
viewModelScope.launch(IO) {
|
||||
artistDetails.postValue(realRepository.albumArtistByName(artistName))
|
||||
}
|
||||
}
|
||||
|
||||
fun getArtist(): LiveData<Artist> = artistDetails
|
||||
|
||||
fun getArtistInfo(
|
||||
name: String,
|
||||
lang: String?,
|
||||
cache: String?
|
||||
): LiveData<Result<LastFmArtist>> = liveData(IO) {
|
||||
emit(Result.Loading)
|
||||
val info = realRepository.artistInfo(name, lang, cache)
|
||||
emit(info)
|
||||
}
|
||||
|
||||
override fun onMediaStoreChanged() {
|
||||
fetchAlbumArtist()
|
||||
}
|
||||
|
||||
override fun onServiceConnected() {}
|
||||
override fun onServiceDisconnected() {}
|
||||
override fun onQueueChanged() {}
|
||||
override fun onFavoriteStateChanged() {}
|
||||
override fun onPlayingMetaChanged() {}
|
||||
override fun onPlayStateChanged() {}
|
||||
override fun onRepeatModeChanged() {}
|
||||
override fun onShuffleModeChanged() {}
|
||||
}
|
|
@ -14,298 +14,18 @@
|
|||
*/
|
||||
package code.name.monkey.retromusic.fragments.artists
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.Intent
|
||||
import android.graphics.Color
|
||||
import android.os.Bundle
|
||||
import android.text.Spanned
|
||||
import android.view.Menu
|
||||
import android.view.MenuInflater
|
||||
import android.view.MenuItem
|
||||
import android.view.View
|
||||
import androidx.core.os.bundleOf
|
||||
import androidx.core.text.HtmlCompat
|
||||
import androidx.core.view.ViewCompat
|
||||
import androidx.lifecycle.Observer
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.navigation.fragment.FragmentNavigatorExtras
|
||||
import androidx.navigation.fragment.findNavController
|
||||
import androidx.navigation.fragment.navArgs
|
||||
import androidx.recyclerview.widget.DefaultItemAnimator
|
||||
import androidx.recyclerview.widget.GridLayoutManager
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import code.name.monkey.appthemehelper.util.ATHUtil
|
||||
import code.name.monkey.retromusic.EXTRA_ALBUM_ID
|
||||
import code.name.monkey.retromusic.R
|
||||
import code.name.monkey.retromusic.adapter.album.HorizontalAlbumAdapter
|
||||
import code.name.monkey.retromusic.adapter.song.SimpleSongAdapter
|
||||
import code.name.monkey.retromusic.dialogs.AddToPlaylistDialog
|
||||
import code.name.monkey.retromusic.extensions.*
|
||||
import code.name.monkey.retromusic.fragments.base.AbsMainActivityFragment
|
||||
import code.name.monkey.retromusic.glide.ArtistGlideRequest
|
||||
import code.name.monkey.retromusic.glide.SingleColorTarget
|
||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote
|
||||
import code.name.monkey.retromusic.interfaces.IAlbumClickListener
|
||||
import code.name.monkey.retromusic.model.Artist
|
||||
import code.name.monkey.retromusic.network.Result
|
||||
import code.name.monkey.retromusic.network.model.LastFmArtist
|
||||
import code.name.monkey.retromusic.repository.RealRepository
|
||||
import code.name.monkey.retromusic.util.CustomArtistImageUtil
|
||||
import code.name.monkey.retromusic.util.MusicUtil
|
||||
import code.name.monkey.retromusic.util.RetroUtil
|
||||
import com.bumptech.glide.Glide
|
||||
import com.google.android.material.transition.MaterialContainerTransform
|
||||
import com.google.android.material.transition.MaterialElevationScale
|
||||
import kotlinx.android.synthetic.main.fragment_artist_content.*
|
||||
import kotlinx.android.synthetic.main.fragment_artist_details.*
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.koin.android.ext.android.get
|
||||
import org.koin.androidx.viewmodel.ext.android.viewModel
|
||||
import org.koin.core.parameter.parametersOf
|
||||
import java.util.*
|
||||
import kotlin.collections.ArrayList
|
||||
|
||||
class ArtistDetailsFragment : AbsMainActivityFragment(R.layout.fragment_artist_details),
|
||||
IAlbumClickListener {
|
||||
class ArtistDetailsFragment : AbsArtistDetailsFragment() {
|
||||
private val arguments by navArgs<ArtistDetailsFragmentArgs>()
|
||||
private val detailsViewModel: ArtistDetailsViewModel by viewModel {
|
||||
parametersOf(arguments.extraArtistId)
|
||||
override val detailsViewModel: ArtistDetailsViewModel by viewModel {
|
||||
parametersOf(arguments.extraArtistId, null)
|
||||
}
|
||||
private lateinit var artist: Artist
|
||||
private lateinit var songAdapter: SimpleSongAdapter
|
||||
private lateinit var albumAdapter: HorizontalAlbumAdapter
|
||||
private var forceDownload: Boolean = false
|
||||
private var lang: String? = null
|
||||
private var biography: Spanned? = null
|
||||
override val artistId: Long
|
||||
get() = arguments.extraArtistId
|
||||
override val artistName: String?
|
||||
get() = null
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
sharedElementEnterTransition = MaterialContainerTransform().apply {
|
||||
drawingViewId = R.id.fragment_container
|
||||
duration = 300L
|
||||
scrimColor = Color.TRANSPARENT
|
||||
setAllContainerColors(requireContext().resolveColor(R.attr.colorSurface))
|
||||
}
|
||||
}
|
||||
|
||||
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||
super.onActivityCreated(savedInstanceState)
|
||||
setHasOptionsMenu(true)
|
||||
mainActivity.setBottomBarVisibility(false)
|
||||
mainActivity.addMusicServiceEventListener(detailsViewModel)
|
||||
mainActivity.setSupportActionBar(toolbar)
|
||||
toolbar.title = null
|
||||
ViewCompat.setTransitionName(artistCoverContainer, "artist")
|
||||
postponeEnterTransition()
|
||||
detailsViewModel.getArtist().observe(viewLifecycleOwner, {
|
||||
startPostponedEnterTransition()
|
||||
showArtist(it)
|
||||
})
|
||||
setupRecyclerView()
|
||||
|
||||
playAction.apply {
|
||||
setOnClickListener { MusicPlayerRemote.openQueue(artist.songs, 0, true) }
|
||||
}
|
||||
shuffleAction.apply {
|
||||
setOnClickListener { MusicPlayerRemote.openAndShuffleQueue(artist.songs, true) }
|
||||
}
|
||||
|
||||
biographyText.setOnClickListener {
|
||||
if (biographyText.maxLines == 4) {
|
||||
biographyText.maxLines = Integer.MAX_VALUE
|
||||
} else {
|
||||
biographyText.maxLines = 4
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun setupRecyclerView() {
|
||||
albumAdapter = HorizontalAlbumAdapter(requireActivity(), ArrayList(), null, this)
|
||||
albumRecyclerView.apply {
|
||||
itemAnimator = DefaultItemAnimator()
|
||||
layoutManager = GridLayoutManager(this.context, 1, GridLayoutManager.HORIZONTAL, false)
|
||||
adapter = albumAdapter
|
||||
}
|
||||
songAdapter = SimpleSongAdapter(requireActivity(), ArrayList(), R.layout.item_song, null)
|
||||
recyclerView.apply {
|
||||
itemAnimator = DefaultItemAnimator()
|
||||
layoutManager = LinearLayoutManager(this.context)
|
||||
adapter = songAdapter
|
||||
}
|
||||
}
|
||||
|
||||
private fun showArtist(artist: Artist) {
|
||||
this.artist = artist
|
||||
loadArtistImage(artist)
|
||||
if (RetroUtil.isAllowedToDownloadMetadata(requireContext())) {
|
||||
loadBiography(artist.name)
|
||||
}
|
||||
artistTitle.text = artist.name
|
||||
text.text = String.format(
|
||||
"%s • %s",
|
||||
MusicUtil.getArtistInfoString(requireContext(), artist),
|
||||
MusicUtil.getReadableDurationString(MusicUtil.getTotalDuration(artist.songs))
|
||||
)
|
||||
val songText = resources.getQuantityString(
|
||||
R.plurals.albumSongs,
|
||||
artist.songCount,
|
||||
artist.songCount
|
||||
)
|
||||
val albumText = resources.getQuantityString(
|
||||
R.plurals.albums,
|
||||
artist.songCount,
|
||||
artist.songCount
|
||||
)
|
||||
songTitle.text = songText
|
||||
albumTitle.text = albumText
|
||||
songAdapter.swapDataSet(artist.songs.sortedBy { it.trackNumber })
|
||||
albumAdapter.swapDataSet(artist.albums)
|
||||
}
|
||||
|
||||
private fun loadBiography(
|
||||
name: String,
|
||||
lang: String? = Locale.getDefault().language
|
||||
) {
|
||||
biography = null
|
||||
this.lang = lang
|
||||
detailsViewModel.getArtistInfo(name, lang, null)
|
||||
.observe(viewLifecycleOwner, { result ->
|
||||
when (result) {
|
||||
is Result.Loading -> println("Loading")
|
||||
is Result.Error -> println("Error")
|
||||
is Result.Success -> artistInfo(result.data)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
private fun artistInfo(lastFmArtist: LastFmArtist?) {
|
||||
if (lastFmArtist != null && lastFmArtist.artist != null) {
|
||||
val bioContent = lastFmArtist.artist.bio.content
|
||||
if (bioContent != null && bioContent.trim { it <= ' ' }.isNotEmpty()) {
|
||||
biographyText.visibility = View.VISIBLE
|
||||
biographyTitle.visibility = View.VISIBLE
|
||||
biography = HtmlCompat.fromHtml(bioContent, HtmlCompat.FROM_HTML_MODE_LEGACY)
|
||||
biographyText.text = biography
|
||||
if (lastFmArtist.artist.stats.listeners.isNotEmpty()) {
|
||||
listeners.show()
|
||||
listenersLabel.show()
|
||||
scrobbles.show()
|
||||
scrobblesLabel.show()
|
||||
listeners.text =
|
||||
RetroUtil.formatValue(lastFmArtist.artist.stats.listeners.toFloat())
|
||||
scrobbles.text =
|
||||
RetroUtil.formatValue(lastFmArtist.artist.stats.playcount.toFloat())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If the "lang" parameter is set and no biography is given, retry with default language
|
||||
if (biography == null && lang != null) {
|
||||
loadBiography(artist.name, null)
|
||||
}
|
||||
}
|
||||
|
||||
private fun loadArtistImage(artist: Artist) {
|
||||
ArtistGlideRequest.Builder.from(Glide.with(requireContext()), artist)
|
||||
.generatePalette(requireContext()).build()
|
||||
.dontAnimate()
|
||||
.into(object : SingleColorTarget(image) {
|
||||
override fun onColorReady(color: Int) {
|
||||
setColors(color)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
private fun setColors(color: Int) {
|
||||
shuffleAction?.applyColor(color)
|
||||
playAction?.applyOutlineColor(color)
|
||||
}
|
||||
|
||||
override fun onAlbumClick(albumId: Long, view: View) {
|
||||
exitTransition = MaterialElevationScale(false).apply {
|
||||
duration = 300L
|
||||
}
|
||||
reenterTransition = MaterialElevationScale(false).apply {
|
||||
duration = 300L
|
||||
}
|
||||
findNavController().navigate(
|
||||
R.id.albumDetailsFragment,
|
||||
bundleOf(EXTRA_ALBUM_ID to albumId),
|
||||
null,
|
||||
FragmentNavigatorExtras(
|
||||
view to "album"
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||
return handleSortOrderMenuItem(item)
|
||||
}
|
||||
|
||||
private fun handleSortOrderMenuItem(item: MenuItem): Boolean {
|
||||
val songs = artist.songs
|
||||
when (item.itemId) {
|
||||
android.R.id.home -> findNavController().navigateUp()
|
||||
R.id.action_play_next -> {
|
||||
MusicPlayerRemote.playNext(songs)
|
||||
return true
|
||||
}
|
||||
R.id.action_add_to_current_playing -> {
|
||||
MusicPlayerRemote.enqueue(songs)
|
||||
return true
|
||||
}
|
||||
R.id.action_add_to_playlist -> {
|
||||
lifecycleScope.launch(Dispatchers.IO) {
|
||||
val playlists = get<RealRepository>().fetchPlaylists()
|
||||
withContext(Dispatchers.Main) {
|
||||
AddToPlaylistDialog.create(playlists, songs)
|
||||
.show(childFragmentManager, "ADD_PLAYLIST")
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
R.id.action_set_artist_image -> {
|
||||
val intent = Intent(Intent.ACTION_GET_CONTENT)
|
||||
intent.type = "image/*"
|
||||
startActivityForResult(
|
||||
Intent.createChooser(intent, getString(R.string.pick_from_local_storage)),
|
||||
REQUEST_CODE_SELECT_IMAGE
|
||||
)
|
||||
return true
|
||||
}
|
||||
R.id.action_reset_artist_image -> {
|
||||
showToast(resources.getString(R.string.updating))
|
||||
CustomArtistImageUtil.getInstance(requireContext()).resetCustomArtistImage(artist)
|
||||
forceDownload = true
|
||||
return true
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||
super.onActivityResult(requestCode, resultCode, data)
|
||||
when (requestCode) {
|
||||
REQUEST_CODE_SELECT_IMAGE -> if (resultCode == Activity.RESULT_OK) {
|
||||
data?.data?.let {
|
||||
CustomArtistImageUtil.getInstance(requireContext())
|
||||
.setCustomArtistImage(artist, it)
|
||||
}
|
||||
}
|
||||
else -> if (resultCode == Activity.RESULT_OK) {
|
||||
println("OK")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
|
||||
super.onCreateOptionsMenu(menu, inflater)
|
||||
inflater.inflate(R.menu.menu_artist_detail, menu)
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val REQUEST_CODE_SELECT_IMAGE = 9002
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,11 +14,7 @@
|
|||
*/
|
||||
package code.name.monkey.retromusic.fragments.artists
|
||||
|
||||
import androidx.lifecycle.LiveData
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.liveData
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import androidx.lifecycle.*
|
||||
import code.name.monkey.retromusic.interfaces.IMusicServiceEventListener
|
||||
import code.name.monkey.retromusic.model.Artist
|
||||
import code.name.monkey.retromusic.network.Result
|
||||
|
@ -29,7 +25,8 @@ import kotlinx.coroutines.launch
|
|||
|
||||
class ArtistDetailsViewModel(
|
||||
private val realRepository: RealRepository,
|
||||
private val artistId: Long
|
||||
private val artistId: Long?,
|
||||
private val artistName: String?
|
||||
) : ViewModel(), IMusicServiceEventListener {
|
||||
private val artistDetails = MutableLiveData<Artist>()
|
||||
|
||||
|
@ -39,7 +36,9 @@ class ArtistDetailsViewModel(
|
|||
|
||||
private fun fetchArtist() {
|
||||
viewModelScope.launch(IO) {
|
||||
artistDetails.postValue(realRepository.artistById(artistId))
|
||||
artistId?.let { artistDetails.postValue(realRepository.artistById(it)) }
|
||||
|
||||
artistName?.let { artistDetails.postValue(realRepository.albumArtistByName(it)) }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -56,7 +55,7 @@ class ArtistDetailsViewModel(
|
|||
}
|
||||
|
||||
override fun onMediaStoreChanged() {
|
||||
fetchArtist()
|
||||
fetchArtist()
|
||||
}
|
||||
|
||||
override fun onServiceConnected() {}
|
||||
|
@ -66,4 +65,5 @@ class ArtistDetailsViewModel(
|
|||
override fun onPlayStateChanged() {}
|
||||
override fun onRepeatModeChanged() {}
|
||||
override fun onShuffleModeChanged() {}
|
||||
override fun onFavoriteStateChanged() {}
|
||||
}
|
||||
|
|
|
@ -16,38 +16,48 @@ package code.name.monkey.retromusic.fragments.artists
|
|||
|
||||
import android.os.Bundle
|
||||
import android.view.*
|
||||
import androidx.activity.addCallback
|
||||
import androidx.core.os.bundleOf
|
||||
import androidx.lifecycle.Observer
|
||||
import androidx.navigation.fragment.FragmentNavigatorExtras
|
||||
import androidx.navigation.fragment.findNavController
|
||||
import androidx.recyclerview.widget.GridLayoutManager
|
||||
import code.name.monkey.retromusic.EXTRA_ARTIST_ID
|
||||
import code.name.monkey.retromusic.EXTRA_ARTIST_NAME
|
||||
import code.name.monkey.retromusic.R
|
||||
import code.name.monkey.retromusic.adapter.artist.ArtistAdapter
|
||||
import code.name.monkey.retromusic.extensions.surfaceColor
|
||||
import code.name.monkey.retromusic.fragments.ReloadType
|
||||
import code.name.monkey.retromusic.fragments.base.AbsRecyclerViewCustomGridSizeFragment
|
||||
import code.name.monkey.retromusic.helper.SortOrder.ArtistSortOrder
|
||||
import code.name.monkey.retromusic.interfaces.IAlbumArtistClickListener
|
||||
import code.name.monkey.retromusic.interfaces.IArtistClickListener
|
||||
import code.name.monkey.retromusic.interfaces.ICabHolder
|
||||
import code.name.monkey.retromusic.util.PreferenceUtil
|
||||
import code.name.monkey.retromusic.util.RetroColorUtil
|
||||
import code.name.monkey.retromusic.util.RetroUtil
|
||||
import com.afollestad.materialcab.MaterialCab
|
||||
import com.google.android.material.transition.MaterialElevationScale
|
||||
import com.google.android.gms.cast.framework.CastButtonFactory
|
||||
|
||||
class ArtistsFragment : AbsRecyclerViewCustomGridSizeFragment<ArtistAdapter, GridLayoutManager>(),
|
||||
IArtistClickListener, ICabHolder {
|
||||
IArtistClickListener, IAlbumArtistClickListener, ICabHolder {
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
libraryViewModel.getArtists().observe(viewLifecycleOwner, Observer {
|
||||
libraryViewModel.getArtists().observe(viewLifecycleOwner, {
|
||||
if (it.isNotEmpty())
|
||||
adapter?.swapDataSet(it)
|
||||
else
|
||||
adapter?.swapDataSet(listOf())
|
||||
})
|
||||
requireActivity().onBackPressedDispatcher.addCallback(viewLifecycleOwner) {
|
||||
if (!handleBackPress()) {
|
||||
remove()
|
||||
requireActivity().onBackPressed()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override val titleRes: Int
|
||||
get() = R.string.artists
|
||||
override val emptyMessage: Int
|
||||
get() = R.string.no_artists
|
||||
|
||||
|
@ -66,7 +76,7 @@ class ArtistsFragment : AbsRecyclerViewCustomGridSizeFragment<ArtistAdapter, Gri
|
|||
dataSet,
|
||||
itemLayoutRes(),
|
||||
this,
|
||||
this
|
||||
this, this
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -115,18 +125,23 @@ class ArtistsFragment : AbsRecyclerViewCustomGridSizeFragment<ArtistAdapter, Gri
|
|||
}
|
||||
|
||||
override fun onArtist(artistId: Long, view: View) {
|
||||
exitTransition = MaterialElevationScale(true).apply {
|
||||
duration = 300L
|
||||
}
|
||||
reenterTransition = MaterialElevationScale(false).apply {
|
||||
duration = 300L
|
||||
}
|
||||
findNavController().navigate(
|
||||
R.id.artistDetailsFragment,
|
||||
bundleOf(EXTRA_ARTIST_ID to artistId),
|
||||
null,
|
||||
FragmentNavigatorExtras(view to "artist")
|
||||
FragmentNavigatorExtras(view to artistId.toString())
|
||||
)
|
||||
reenterTransition = null
|
||||
}
|
||||
|
||||
override fun onAlbumArtist(artistName: String, view: View) {
|
||||
findNavController().navigate(
|
||||
R.id.albumArtistDetailsFragment,
|
||||
bundleOf(EXTRA_ARTIST_NAME to artistName),
|
||||
null,
|
||||
FragmentNavigatorExtras(view to artistName)
|
||||
)
|
||||
reenterTransition = null
|
||||
}
|
||||
|
||||
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
|
||||
|
@ -139,6 +154,16 @@ class ArtistsFragment : AbsRecyclerViewCustomGridSizeFragment<ArtistAdapter, Gri
|
|||
val layoutItem = menu.findItem(R.id.action_layout_type)
|
||||
setupLayoutMenu(layoutItem.subMenu)
|
||||
setUpSortOrderMenu(menu.findItem(R.id.action_sort_order).subMenu)
|
||||
setupAlbumArtistMenu(menu)
|
||||
//Setting up cast button
|
||||
CastButtonFactory.setUpMediaRouteButton(requireContext(), menu, R.id.action_cast)
|
||||
}
|
||||
|
||||
private fun setupAlbumArtistMenu(menu: Menu) {
|
||||
menu.add(0, R.id.action_album_artist, 0, R.string.show_album_artists).apply {
|
||||
isCheckable = true
|
||||
isChecked = PreferenceUtil.albumArtistsOnly
|
||||
}
|
||||
}
|
||||
|
||||
private fun setUpSortOrderMenu(
|
||||
|
@ -222,9 +247,23 @@ class ArtistsFragment : AbsRecyclerViewCustomGridSizeFragment<ArtistAdapter, Gri
|
|||
if (handleSortOrderMenuItem(item)) {
|
||||
return true
|
||||
}
|
||||
if (handleAlbumArtistMenu(item)) {
|
||||
return true
|
||||
}
|
||||
return super.onOptionsItemSelected(item)
|
||||
}
|
||||
|
||||
private fun handleAlbumArtistMenu(item: MenuItem): Boolean {
|
||||
return if (item.itemId == R.id.action_album_artist) {
|
||||
PreferenceUtil.albumArtistsOnly = !item.isChecked
|
||||
item.isChecked = !item.isChecked
|
||||
libraryViewModel.forceReload(ReloadType.Artists)
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleSortOrderMenuItem(
|
||||
item: MenuItem
|
||||
): Boolean {
|
||||
|
@ -283,6 +322,16 @@ class ArtistsFragment : AbsRecyclerViewCustomGridSizeFragment<ArtistAdapter, Gri
|
|||
return false
|
||||
}
|
||||
|
||||
private fun handleBackPress(): Boolean {
|
||||
cab?.let {
|
||||
if (it.isActive) {
|
||||
it.finish()
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
private var cab: MaterialCab? = null
|
||||
|
||||
override fun openCab(menuRes: Int, callback: MaterialCab.Callback): MaterialCab {
|
||||
|
@ -298,4 +347,9 @@ class ArtistsFragment : AbsRecyclerViewCustomGridSizeFragment<ArtistAdapter, Gri
|
|||
.start(callback)
|
||||
return cab as MaterialCab
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
libraryViewModel.forceReload(ReloadType.Artists)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,10 +27,9 @@ import code.name.monkey.retromusic.activities.base.AbsMusicServiceActivity
|
|||
import code.name.monkey.retromusic.interfaces.IMusicServiceEventListener
|
||||
import code.name.monkey.retromusic.model.Song
|
||||
import code.name.monkey.retromusic.util.RetroUtil
|
||||
import org.jaudiotagger.audio.AudioFileIO
|
||||
import java.io.File
|
||||
import java.net.URLEncoder
|
||||
import java.util.*
|
||||
import org.jaudiotagger.audio.AudioFileIO
|
||||
|
||||
/**
|
||||
* Created by hemanths on 18/08/17.
|
||||
|
@ -78,6 +77,9 @@ open class AbsMusicServiceFragment(@LayoutRes layout: Int) : Fragment(layout),
|
|||
serviceActivity?.removeMusicServiceEventListener(this)
|
||||
}
|
||||
|
||||
override fun onFavoriteStateChanged() {
|
||||
}
|
||||
|
||||
override fun onPlayingMetaChanged() {
|
||||
}
|
||||
|
||||
|
@ -121,10 +123,10 @@ open class AbsMusicServiceFragment(@LayoutRes layout: Int) : Fragment(layout),
|
|||
return "-"
|
||||
}
|
||||
|
||||
private fun getMimeType(url: String): String? {
|
||||
private fun getMimeType(url: String): String {
|
||||
var type: String? = MimeTypeMap.getFileExtensionFromUrl(
|
||||
URLEncoder.encode(url, "utf-8")
|
||||
).toUpperCase(Locale.getDefault())
|
||||
).uppercase()
|
||||
if (type == null) {
|
||||
type = url.substring(url.lastIndexOf(".") + 1)
|
||||
}
|
||||
|
|
|
@ -44,7 +44,7 @@ abstract class AbsPlayerControlsFragment(@LayoutRes layout: Int) : AbsMusicServi
|
|||
|
||||
abstract fun setColor(color: MediaNotificationProcessor)
|
||||
|
||||
fun showBonceAnimation(view: View) {
|
||||
fun showBounceAnimation(view: View) {
|
||||
view.apply {
|
||||
clearAnimation()
|
||||
scaleX = 0.9f
|
||||
|
|
|
@ -14,31 +14,41 @@
|
|||
*/
|
||||
package code.name.monkey.retromusic.fragments.base
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.app.Activity
|
||||
import android.content.ContentUris
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.graphics.drawable.AnimatedVectorDrawable
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.media.MediaMetadataRetriever
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.provider.MediaStore
|
||||
import android.text.TextUtils
|
||||
import android.view.GestureDetector
|
||||
import android.view.MenuItem
|
||||
import android.view.MotionEvent
|
||||
import android.view.View
|
||||
import android.widget.RelativeLayout
|
||||
import android.widget.Toast
|
||||
import androidx.annotation.LayoutRes
|
||||
import androidx.appcompat.widget.Toolbar
|
||||
import androidx.core.os.bundleOf
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.navigation.findNavController
|
||||
import androidx.viewpager.widget.ViewPager
|
||||
import code.name.monkey.retromusic.EXTRA_ALBUM_ID
|
||||
import code.name.monkey.retromusic.EXTRA_ARTIST_ID
|
||||
import code.name.monkey.retromusic.R
|
||||
import code.name.monkey.retromusic.activities.MainActivity
|
||||
import code.name.monkey.retromusic.activities.tageditor.AbsTagEditorActivity
|
||||
import code.name.monkey.retromusic.activities.tageditor.SongTagEditorActivity
|
||||
import code.name.monkey.retromusic.db.PlaylistEntity
|
||||
import code.name.monkey.retromusic.db.SongEntity
|
||||
import code.name.monkey.retromusic.db.toSongEntity
|
||||
import code.name.monkey.retromusic.dialogs.*
|
||||
import code.name.monkey.retromusic.extensions.currentFragment
|
||||
import code.name.monkey.retromusic.extensions.hide
|
||||
import code.name.monkey.retromusic.extensions.whichFragment
|
||||
import code.name.monkey.retromusic.fragments.ReloadType
|
||||
|
@ -50,13 +60,14 @@ import code.name.monkey.retromusic.model.lyrics.Lyrics
|
|||
import code.name.monkey.retromusic.repository.RealRepository
|
||||
import code.name.monkey.retromusic.service.MusicService
|
||||
import code.name.monkey.retromusic.util.*
|
||||
import kotlinx.android.synthetic.main.shadow_statusbar_toolbar.*
|
||||
import com.google.android.material.bottomsheet.BottomSheetBehavior
|
||||
import kotlinx.coroutines.Dispatchers.IO
|
||||
import kotlinx.coroutines.Dispatchers.Main
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.koin.android.ext.android.get
|
||||
import java.io.FileNotFoundException
|
||||
import kotlin.math.abs
|
||||
|
||||
abstract class AbsPlayerFragment(@LayoutRes layout: Int) : AbsMainActivityFragment(layout),
|
||||
Toolbar.OnMenuItemClickListener, IPaletteColorHolder, PlayerAlbumCoverFragment.Callbacks {
|
||||
|
@ -68,6 +79,11 @@ abstract class AbsPlayerFragment(@LayoutRes layout: Int) : AbsMainActivityFragme
|
|||
): Boolean {
|
||||
val song = MusicPlayerRemote.currentSong
|
||||
when (item.itemId) {
|
||||
R.id.action_toggle_lyrics -> {
|
||||
PreferenceUtil.showLyrics = !PreferenceUtil.showLyrics
|
||||
showLyricsIcon(item)
|
||||
return true
|
||||
}
|
||||
R.id.action_toggle_favorite -> {
|
||||
toggleFavorite(song)
|
||||
return true
|
||||
|
@ -114,6 +130,8 @@ abstract class AbsPlayerFragment(@LayoutRes layout: Int) : AbsMainActivityFragme
|
|||
return true
|
||||
}
|
||||
R.id.action_go_to_album -> {
|
||||
//Hide Bottom Bar First, else Bottom Sheet doesn't collapse fully
|
||||
mainActivity.setBottomBarVisibility(false)
|
||||
mainActivity.collapsePanel()
|
||||
requireActivity().findNavController(R.id.fragment_container).navigate(
|
||||
R.id.albumDetailsFragment,
|
||||
|
@ -122,11 +140,7 @@ abstract class AbsPlayerFragment(@LayoutRes layout: Int) : AbsMainActivityFragme
|
|||
return true
|
||||
}
|
||||
R.id.action_go_to_artist -> {
|
||||
mainActivity.collapsePanel()
|
||||
requireActivity().findNavController(R.id.fragment_container).navigate(
|
||||
R.id.artistDetailsFragment,
|
||||
bundleOf(EXTRA_ARTIST_ID to song.artistId)
|
||||
)
|
||||
goToArtist(requireActivity())
|
||||
return true
|
||||
}
|
||||
R.id.now_playing -> {
|
||||
|
@ -158,7 +172,7 @@ abstract class AbsPlayerFragment(@LayoutRes layout: Int) : AbsMainActivityFragme
|
|||
val trackUri =
|
||||
ContentUris.withAppendedId(
|
||||
MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
|
||||
song.id.toLong()
|
||||
song.id
|
||||
)
|
||||
retriever.setDataSource(activity, trackUri)
|
||||
var genre: String? =
|
||||
|
@ -173,6 +187,18 @@ abstract class AbsPlayerFragment(@LayoutRes layout: Int) : AbsMainActivityFragme
|
|||
return false
|
||||
}
|
||||
|
||||
private fun showLyricsIcon(item: MenuItem) {
|
||||
val icon =
|
||||
if (PreferenceUtil.showLyrics) R.drawable.ic_lyrics else R.drawable.ic_lyrics_outline
|
||||
val drawable: Drawable? = RetroUtil.getTintedVectorDrawable(
|
||||
requireContext(),
|
||||
icon,
|
||||
toolbarIconColor()
|
||||
)
|
||||
item.isChecked = PreferenceUtil.showLyrics
|
||||
item.icon = drawable
|
||||
}
|
||||
|
||||
abstract fun playerToolbar(): Toolbar?
|
||||
|
||||
abstract fun onShow()
|
||||
|
@ -185,7 +211,6 @@ abstract class AbsPlayerFragment(@LayoutRes layout: Int) : AbsMainActivityFragme
|
|||
|
||||
override fun onServiceConnected() {
|
||||
updateIsFavorite()
|
||||
updateLyrics()
|
||||
}
|
||||
|
||||
override fun onPlayingMetaChanged() {
|
||||
|
@ -193,9 +218,13 @@ abstract class AbsPlayerFragment(@LayoutRes layout: Int) : AbsMainActivityFragme
|
|||
updateLyrics()
|
||||
}
|
||||
|
||||
override fun onFavoriteStateChanged() {
|
||||
updateIsFavorite(animate = true)
|
||||
}
|
||||
|
||||
protected open fun toggleFavorite(song: Song) {
|
||||
lifecycleScope.launch(IO) {
|
||||
val playlist: PlaylistEntity? = libraryViewModel.favoritePlaylist()
|
||||
val playlist: PlaylistEntity = libraryViewModel.favoritePlaylist()
|
||||
if (playlist != null) {
|
||||
val songEntity = song.toSongEntity(playlist.playListId)
|
||||
val isFavorite = libraryViewModel.isFavoriteSong(songEntity).isNotEmpty()
|
||||
|
@ -210,26 +239,36 @@ abstract class AbsPlayerFragment(@LayoutRes layout: Int) : AbsMainActivityFragme
|
|||
}
|
||||
}
|
||||
|
||||
fun updateIsFavorite() {
|
||||
fun updateIsFavorite(animate: Boolean = false) {
|
||||
lifecycleScope.launch(IO) {
|
||||
val playlist: PlaylistEntity? = libraryViewModel.favoritePlaylist()
|
||||
val playlist: PlaylistEntity = libraryViewModel.favoritePlaylist()
|
||||
if (playlist != null) {
|
||||
val song: SongEntity =
|
||||
MusicPlayerRemote.currentSong.toSongEntity(playlist.playListId)
|
||||
val isFavorite: Boolean = libraryViewModel.isFavoriteSong(song).isNotEmpty()
|
||||
withContext(Main) {
|
||||
val icon =
|
||||
val icon = if (animate) {
|
||||
if (isFavorite) R.drawable.avd_favorite else R.drawable.avd_unfavorite
|
||||
} else {
|
||||
if (isFavorite) R.drawable.ic_favorite else R.drawable.ic_favorite_border
|
||||
}
|
||||
val drawable: Drawable? = RetroUtil.getTintedVectorDrawable(
|
||||
requireContext(),
|
||||
icon,
|
||||
toolbarIconColor()
|
||||
)
|
||||
if (playerToolbar() != null) {
|
||||
playerToolbar()?.menu?.findItem(R.id.action_toggle_favorite)
|
||||
?.setIcon(drawable)?.title =
|
||||
if (isFavorite) getString(R.string.action_remove_from_favorites)
|
||||
else getString(R.string.action_add_to_favorites)
|
||||
playerToolbar()?.menu?.findItem(R.id.action_toggle_favorite)?.apply {
|
||||
setIcon(drawable)
|
||||
title =
|
||||
if (isFavorite) getString(R.string.action_remove_from_favorites)
|
||||
else getString(R.string.action_add_to_favorites)
|
||||
getIcon().also {
|
||||
if (it is AnimatedVectorDrawable) {
|
||||
it.start()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -273,7 +312,50 @@ abstract class AbsPlayerFragment(@LayoutRes layout: Int) : AbsMainActivityFragme
|
|||
playerAlbumCoverFragment?.setCallbacks(this)
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
|
||||
statusBarShadow?.hide()
|
||||
view.findViewById<RelativeLayout>(R.id.statusBarShadow)?.hide()
|
||||
}
|
||||
|
||||
@SuppressLint("ClickableViewAccessibility")
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
requireView().setOnTouchListener(
|
||||
SwipeDetector(
|
||||
requireContext(),
|
||||
playerAlbumCoverFragment?.viewPager,
|
||||
requireView()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
class SwipeDetector(val context: Context, val viewPager: ViewPager?, val view: View) :
|
||||
View.OnTouchListener {
|
||||
private var flingPlayBackController: GestureDetector = GestureDetector(
|
||||
context,
|
||||
object : GestureDetector.SimpleOnGestureListener() {
|
||||
override fun onScroll(
|
||||
e1: MotionEvent?,
|
||||
e2: MotionEvent?,
|
||||
distanceX: Float,
|
||||
distanceY: Float
|
||||
): Boolean {
|
||||
return when {
|
||||
abs(distanceX) > abs(distanceY) -> {
|
||||
// Disallow Intercept Touch Event so that parent(BottomSheet) doesn't consume the events
|
||||
view.parent.requestDisallowInterceptTouchEvent(true)
|
||||
true
|
||||
}
|
||||
else -> {
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
@SuppressLint("ClickableViewAccessibility")
|
||||
override fun onTouch(v: View, event: MotionEvent?): Boolean {
|
||||
viewPager?.dispatchTouchEvent(event)
|
||||
return flingPlayBackController.onTouchEvent(event)
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
@ -290,3 +372,44 @@ abstract class AbsPlayerFragment(@LayoutRes layout: Int) : AbsMainActivityFragme
|
|||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun goToArtist(activity: Activity) {
|
||||
if (activity !is MainActivity) return
|
||||
val song = MusicPlayerRemote.currentSong
|
||||
activity.apply {
|
||||
|
||||
// Remove exit transition of current fragment so
|
||||
// it doesn't exit with a weird transition
|
||||
currentFragment(R.id.fragment_container)?.exitTransition = null
|
||||
|
||||
//Hide Bottom Bar First, else Bottom Sheet doesn't collapse fully
|
||||
setBottomBarVisibility(false)
|
||||
if (getBottomSheetBehavior().state == BottomSheetBehavior.STATE_EXPANDED) {
|
||||
collapsePanel()
|
||||
}
|
||||
|
||||
findNavController(R.id.fragment_container).navigate(
|
||||
R.id.artistDetailsFragment,
|
||||
bundleOf(EXTRA_ARTIST_ID to song.artistId)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun goToAlbum(activity: Activity) {
|
||||
if (activity !is MainActivity) return
|
||||
val song = MusicPlayerRemote.currentSong
|
||||
activity.apply {
|
||||
currentFragment(R.id.fragment_container)?.exitTransition = null
|
||||
|
||||
//Hide Bottom Bar First, else Bottom Sheet doesn't collapse fully
|
||||
setBottomBarVisibility(false)
|
||||
if (getBottomSheetBehavior().state == BottomSheetBehavior.STATE_EXPANDED) {
|
||||
collapsePanel()
|
||||
}
|
||||
|
||||
findNavController(R.id.fragment_container).navigate(
|
||||
R.id.albumDetailsFragment,
|
||||
bundleOf(EXTRA_ALBUM_ID to song.albumId)
|
||||
)
|
||||
}
|
||||
}
|
|
@ -14,12 +14,12 @@
|
|||
*/
|
||||
package code.name.monkey.retromusic.fragments.base
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import androidx.annotation.LayoutRes
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import androidx.transition.TransitionManager
|
||||
import code.name.monkey.retromusic.R
|
||||
import code.name.monkey.retromusic.util.RetroUtil
|
||||
import com.google.android.material.transition.MaterialFade
|
||||
|
||||
abstract class AbsRecyclerViewCustomGridSizeFragment<A : RecyclerView.Adapter<*>, LM : RecyclerView.LayoutManager> :
|
||||
AbsRecyclerViewFragment<A, LM>() {
|
||||
|
@ -86,6 +86,7 @@ abstract class AbsRecyclerViewCustomGridSizeFragment<A : RecyclerView.Adapter<*>
|
|||
} else {
|
||||
saveGridSize(gridSize)
|
||||
}
|
||||
recyclerView().isVisible = false
|
||||
invalidateLayoutManager()
|
||||
// only recreate the adapter and layout manager if the layout currentLayoutRes has changed
|
||||
if (oldLayoutRes != itemLayoutRes()) {
|
||||
|
@ -93,26 +94,11 @@ abstract class AbsRecyclerViewCustomGridSizeFragment<A : RecyclerView.Adapter<*>
|
|||
} else {
|
||||
setGridSize(gridSize)
|
||||
}
|
||||
}
|
||||
|
||||
protected fun notifyLayoutResChanged(@LayoutRes res: Int) {
|
||||
this.currentLayoutRes = res
|
||||
val recyclerView = recyclerView()
|
||||
applyRecyclerViewPaddingForLayoutRes(recyclerView, currentLayoutRes)
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
applyRecyclerViewPaddingForLayoutRes(recyclerView(), currentLayoutRes)
|
||||
}
|
||||
|
||||
private fun applyRecyclerViewPaddingForLayoutRes(recyclerView: RecyclerView, res: Int) {
|
||||
val padding: Int = if (res == R.layout.item_grid) {
|
||||
(resources.displayMetrics.density * 2).toInt()
|
||||
} else {
|
||||
0
|
||||
val transition = MaterialFade().apply {
|
||||
addTarget(recyclerView())
|
||||
}
|
||||
//recyclerView.setPadding(padding, padding, padding, padding)
|
||||
TransitionManager.beginDelayedTransition(getContainer(), transition)
|
||||
recyclerView().isVisible = true
|
||||
}
|
||||
|
||||
protected abstract fun setGridSize(gridSize: Int)
|
||||
|
|
|
@ -15,80 +15,73 @@
|
|||
package code.name.monkey.retromusic.fragments.base
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.Menu
|
||||
import android.view.MenuInflater
|
||||
import android.view.MenuItem
|
||||
import android.view.View
|
||||
import android.view.*
|
||||
import androidx.annotation.NonNull
|
||||
import androidx.annotation.StringRes
|
||||
import androidx.core.text.HtmlCompat
|
||||
import androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||
import androidx.core.view.doOnPreDraw
|
||||
import androidx.core.view.updatePadding
|
||||
import androidx.navigation.fragment.findNavController
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import code.name.monkey.appthemehelper.ThemeStore
|
||||
import code.name.monkey.appthemehelper.common.ATHToolbarActivity
|
||||
import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper
|
||||
import code.name.monkey.retromusic.R
|
||||
import code.name.monkey.retromusic.databinding.FragmentMainRecyclerBinding
|
||||
import code.name.monkey.retromusic.dialogs.CreatePlaylistDialog
|
||||
import code.name.monkey.retromusic.dialogs.ImportPlaylistDialog
|
||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote
|
||||
import code.name.monkey.retromusic.util.DensityUtil
|
||||
import code.name.monkey.retromusic.util.ThemedFastScroller.create
|
||||
import com.google.android.material.appbar.AppBarLayout
|
||||
import kotlinx.android.synthetic.main.fragment_main_recycler.*
|
||||
import com.google.android.material.transition.MaterialFadeThrough
|
||||
import com.google.android.material.transition.MaterialSharedAxis
|
||||
import me.zhanghai.android.fastscroll.FastScroller
|
||||
import me.zhanghai.android.fastscroll.FastScrollerBuilder
|
||||
|
||||
abstract class AbsRecyclerViewFragment<A : RecyclerView.Adapter<*>, LM : RecyclerView.LayoutManager> :
|
||||
AbsMainActivityFragment(R.layout.fragment_main_recycler),
|
||||
AppBarLayout.OnOffsetChangedListener {
|
||||
|
||||
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||
super.onActivityCreated(savedInstanceState)
|
||||
setHasOptionsMenu(true)
|
||||
}
|
||||
AbsMainActivityFragment(R.layout.fragment_main_recycler) {
|
||||
|
||||
private var _binding: FragmentMainRecyclerBinding? = null
|
||||
private val binding get() = _binding!!
|
||||
protected var adapter: A? = null
|
||||
protected var layoutManager: LM? = null
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
_binding = FragmentMainRecyclerBinding.bind(view)
|
||||
enterTransition = MaterialFadeThrough()
|
||||
exitTransition = MaterialFadeThrough()
|
||||
postponeEnterTransition()
|
||||
view.doOnPreDraw { startPostponedEnterTransition() }
|
||||
|
||||
mainActivity.setBottomBarVisibility(true)
|
||||
mainActivity.setSupportActionBar(toolbar)
|
||||
mainActivity.setSupportActionBar(binding.toolbar)
|
||||
mainActivity.supportActionBar?.title = null
|
||||
initLayoutManager()
|
||||
initAdapter()
|
||||
setUpRecyclerView()
|
||||
setupTitle()
|
||||
setupToolbar()
|
||||
}
|
||||
|
||||
private fun setupTitle() {
|
||||
toolbar.setNavigationOnClickListener {
|
||||
private fun setupToolbar() {
|
||||
binding.toolbar.setNavigationOnClickListener {
|
||||
exitTransition = MaterialSharedAxis(MaterialSharedAxis.Z, true).addTarget(requireView())
|
||||
reenterTransition = MaterialSharedAxis(MaterialSharedAxis.Z, false)
|
||||
findNavController().navigate(
|
||||
R.id.searchFragment,
|
||||
null,
|
||||
navOptions
|
||||
)
|
||||
}
|
||||
val color = ThemeStore.accentColor(requireContext())
|
||||
val hexColor = String.format("#%06X", 0xFFFFFF and color)
|
||||
val appName = HtmlCompat.fromHtml(
|
||||
"Retro <span style='color:$hexColor';>Music</span>",
|
||||
HtmlCompat.FROM_HTML_MODE_COMPACT
|
||||
)
|
||||
appNameText.text = appName
|
||||
val appName = resources.getString(titleRes)
|
||||
binding.appNameText.text = appName
|
||||
}
|
||||
|
||||
abstract val titleRes: Int
|
||||
|
||||
private fun setUpRecyclerView() {
|
||||
recyclerView.apply {
|
||||
binding.recyclerView.apply {
|
||||
layoutManager = this@AbsRecyclerViewFragment.layoutManager
|
||||
adapter = this@AbsRecyclerViewFragment.adapter
|
||||
val fastScroller = create(this)
|
||||
create(this)
|
||||
}
|
||||
checkForPadding()
|
||||
}
|
||||
|
@ -116,8 +109,8 @@ abstract class AbsRecyclerViewFragment<A : RecyclerView.Adapter<*>, LM : Recycle
|
|||
}
|
||||
|
||||
private fun checkIsEmpty() {
|
||||
emptyText.setText(emptyMessage)
|
||||
empty.visibility = if (adapter!!.itemCount == 0) View.VISIBLE else View.GONE
|
||||
binding.emptyText.setText(emptyMessage)
|
||||
binding.empty.visibility = if (adapter!!.itemCount == 0) View.VISIBLE else View.GONE
|
||||
}
|
||||
|
||||
private fun checkForPadding() {
|
||||
|
@ -125,10 +118,10 @@ abstract class AbsRecyclerViewFragment<A : RecyclerView.Adapter<*>, LM : Recycle
|
|||
|
||||
if (itemCount > 0 && MusicPlayerRemote.playingQueue.isNotEmpty()) {
|
||||
val height = DensityUtil.dip2px(requireContext(), 112f)
|
||||
recyclerView.updatePadding(0, 0, 0, height)
|
||||
binding.recyclerView.updatePadding(0, 0, 0, height)
|
||||
} else {
|
||||
val height = DensityUtil.dip2px(requireContext(), 56f)
|
||||
recyclerView.updatePadding(0, 0, 0, height)
|
||||
binding.recyclerView.updatePadding(0, 0, 0, height)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -141,15 +134,6 @@ abstract class AbsRecyclerViewFragment<A : RecyclerView.Adapter<*>, LM : Recycle
|
|||
@NonNull
|
||||
protected abstract fun createAdapter(): A
|
||||
|
||||
override fun onOffsetChanged(p0: AppBarLayout?, i: Int) {
|
||||
/*recyclerView.setPadding(
|
||||
recyclerView.paddingLeft,
|
||||
recyclerView.paddingTop,
|
||||
recyclerView.paddingRight,
|
||||
i
|
||||
)*/
|
||||
}
|
||||
|
||||
override fun onQueueChanged() {
|
||||
super.onQueueChanged()
|
||||
checkForPadding()
|
||||
|
@ -162,22 +146,31 @@ abstract class AbsRecyclerViewFragment<A : RecyclerView.Adapter<*>, LM : Recycle
|
|||
|
||||
protected fun invalidateLayoutManager() {
|
||||
initLayoutManager()
|
||||
recyclerView.layoutManager = layoutManager
|
||||
binding.recyclerView.layoutManager = layoutManager
|
||||
}
|
||||
|
||||
protected fun invalidateAdapter() {
|
||||
initAdapter()
|
||||
checkIsEmpty()
|
||||
recyclerView.adapter = adapter
|
||||
binding.recyclerView.adapter = adapter
|
||||
}
|
||||
|
||||
fun recyclerView(): RecyclerView {
|
||||
return recyclerView
|
||||
return binding.recyclerView
|
||||
}
|
||||
|
||||
fun getContainer(): CoordinatorLayout {
|
||||
return binding.root
|
||||
}
|
||||
|
||||
fun scrollToTop() {
|
||||
recyclerView().scrollToPosition(0)
|
||||
binding.appBarLayout.setExpanded(true, true)
|
||||
}
|
||||
|
||||
override fun onPrepareOptionsMenu(menu: Menu) {
|
||||
super.onPrepareOptionsMenu(menu)
|
||||
ToolbarContentTintHelper.handleOnPrepareOptionsMenu(requireActivity(), toolbar)
|
||||
ToolbarContentTintHelper.handleOnPrepareOptionsMenu(requireActivity(), binding.toolbar)
|
||||
}
|
||||
|
||||
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
|
||||
|
@ -185,9 +178,9 @@ abstract class AbsRecyclerViewFragment<A : RecyclerView.Adapter<*>, LM : Recycle
|
|||
inflater.inflate(R.menu.menu_main, menu)
|
||||
ToolbarContentTintHelper.handleOnCreateOptionsMenu(
|
||||
requireContext(),
|
||||
toolbar,
|
||||
binding.toolbar,
|
||||
menu,
|
||||
ATHToolbarActivity.getToolbarBackgroundColor(toolbar)
|
||||
ATHToolbarActivity.getToolbarBackgroundColor(binding.toolbar)
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -209,4 +202,9 @@ abstract class AbsRecyclerViewFragment<A : RecyclerView.Adapter<*>, LM : Recycle
|
|||
}
|
||||
return super.onOptionsItemSelected(item)
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
_binding = null
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,13 +14,14 @@
|
|||
|
||||
package code.name.monkey.retromusic.fragments.folder;
|
||||
|
||||
import static code.name.monkey.appthemehelper.common.ATHToolbarActivity.getToolbarBackgroundColor;
|
||||
|
||||
import android.app.Dialog;
|
||||
import android.content.Context;
|
||||
import android.media.MediaScannerConnection;
|
||||
import android.os.Bundle;
|
||||
import android.os.Environment;
|
||||
import android.text.Html;
|
||||
import android.text.Spanned;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
|
@ -30,13 +31,11 @@ import android.view.ViewGroup;
|
|||
import android.view.ViewGroup.MarginLayoutParams;
|
||||
import android.webkit.MimeTypeMap;
|
||||
import android.widget.PopupMenu;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.activity.OnBackPressedCallback;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
import androidx.core.text.HtmlCompat;
|
||||
import androidx.loader.app.LoaderManager;
|
||||
import androidx.loader.content.Loader;
|
||||
import androidx.navigation.Navigation;
|
||||
|
@ -46,25 +45,36 @@ import androidx.recyclerview.widget.RecyclerView;
|
|||
import com.afollestad.materialcab.MaterialCab;
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
||||
import com.google.android.material.snackbar.Snackbar;
|
||||
import com.google.android.material.transition.MaterialFadeThrough;
|
||||
import com.google.android.material.transition.MaterialSharedAxis;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileFilter;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
import code.name.monkey.appthemehelper.ThemeStore;
|
||||
import code.name.monkey.appthemehelper.util.ATHUtil;
|
||||
import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper;
|
||||
import code.name.monkey.retromusic.App;
|
||||
import code.name.monkey.retromusic.R;
|
||||
import code.name.monkey.retromusic.adapter.SongFileAdapter;
|
||||
import code.name.monkey.retromusic.adapter.Storage;
|
||||
import code.name.monkey.retromusic.adapter.StorageAdapter;
|
||||
import code.name.monkey.retromusic.adapter.StorageClickListener;
|
||||
import code.name.monkey.retromusic.databinding.FragmentFolderBinding;
|
||||
import code.name.monkey.retromusic.fragments.base.AbsMainActivityFragment;
|
||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote;
|
||||
import code.name.monkey.retromusic.helper.menu.SongMenuHelper;
|
||||
|
@ -76,6 +86,7 @@ import code.name.monkey.retromusic.misc.DialogAsyncTask;
|
|||
import code.name.monkey.retromusic.misc.UpdateToastMediaScannerCompletionListener;
|
||||
import code.name.monkey.retromusic.misc.WrappedAsyncTaskLoader;
|
||||
import code.name.monkey.retromusic.model.Song;
|
||||
import code.name.monkey.retromusic.providers.BlacklistStore;
|
||||
import code.name.monkey.retromusic.util.DensityUtil;
|
||||
import code.name.monkey.retromusic.util.FileUtil;
|
||||
import code.name.monkey.retromusic.util.PreferenceUtil;
|
||||
|
@ -85,15 +96,14 @@ import code.name.monkey.retromusic.views.BreadCrumbLayout;
|
|||
import code.name.monkey.retromusic.views.ScrollingViewOnApplyWindowInsetsListener;
|
||||
import me.zhanghai.android.fastscroll.FastScroller;
|
||||
|
||||
import static code.name.monkey.appthemehelper.common.ATHToolbarActivity.getToolbarBackgroundColor;
|
||||
|
||||
public class FoldersFragment extends AbsMainActivityFragment
|
||||
implements IMainActivityFragmentCallbacks,
|
||||
ICabHolder,
|
||||
BreadCrumbLayout.SelectionCallback,
|
||||
ICallbacks,
|
||||
LoaderManager.LoaderCallbacks<List<File>> {
|
||||
LoaderManager.LoaderCallbacks<List<File>>, StorageClickListener {
|
||||
|
||||
private FragmentFolderBinding binding;
|
||||
public static final String TAG = FoldersFragment.class.getSimpleName();
|
||||
public static final FileFilter AUDIO_FILE_FILTER =
|
||||
file ->
|
||||
|
@ -106,14 +116,9 @@ public class FoldersFragment extends AbsMainActivityFragment
|
|||
private static final String CRUMBS = "crumbs";
|
||||
private static final int LOADER_ID = 5;
|
||||
private SongFileAdapter adapter;
|
||||
private Toolbar toolbar;
|
||||
private TextView appNameText;
|
||||
private BreadCrumbLayout breadCrumbs;
|
||||
private StorageAdapter storageAdapter;
|
||||
private MaterialCab cab;
|
||||
private View coordinatorLayout;
|
||||
private View empty;
|
||||
private TextView emojiText;
|
||||
private Comparator<File> fileComparator =
|
||||
private final Comparator<File> fileComparator =
|
||||
(lhs, rhs) -> {
|
||||
if (lhs.isDirectory() && !rhs.isDirectory()) {
|
||||
return -1;
|
||||
|
@ -123,7 +128,7 @@ public class FoldersFragment extends AbsMainActivityFragment
|
|||
return lhs.getName().compareToIgnoreCase(rhs.getName());
|
||||
}
|
||||
};
|
||||
private RecyclerView recyclerView;
|
||||
private final ArrayList<Storage> storageItems = new ArrayList<>();
|
||||
|
||||
public FoldersFragment() {
|
||||
super(R.layout.fragment_folder);
|
||||
|
@ -158,35 +163,43 @@ public class FoldersFragment extends AbsMainActivityFragment
|
|||
@Override
|
||||
public View onCreateView(
|
||||
@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
View view = inflater.inflate(R.layout.fragment_folder, container, false);
|
||||
initViews(view);
|
||||
return view;
|
||||
binding = FragmentFolderBinding.inflate(inflater, container, false);
|
||||
return binding.getRoot();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
||||
setEnterTransition(new MaterialFadeThrough());
|
||||
setExitTransition(new MaterialFadeThrough());
|
||||
getMainActivity().addMusicServiceEventListener(getLibraryViewModel());
|
||||
getMainActivity().setBottomBarVisibility(true);
|
||||
getMainActivity().setSupportActionBar(toolbar);
|
||||
getMainActivity().setSupportActionBar(binding.toolbar);
|
||||
getMainActivity().getSupportActionBar().setTitle(null);
|
||||
setStatusBarColorAuto(view);
|
||||
setUpAppbarColor();
|
||||
setUpBreadCrumbs();
|
||||
setUpRecyclerView();
|
||||
listRoots();
|
||||
setUpAdapter();
|
||||
setUpTitle();
|
||||
requireActivity().getOnBackPressedDispatcher().addCallback(getViewLifecycleOwner(), new OnBackPressedCallback(true) {
|
||||
@Override
|
||||
public void handleOnBackPressed() {
|
||||
if (!handleBackPress()) {
|
||||
remove();
|
||||
requireActivity().onBackPressed();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void setUpTitle() {
|
||||
toolbar.setNavigationOnClickListener(
|
||||
v -> Navigation.findNavController(v).navigate(R.id.searchFragment, null, getNavOptions()));
|
||||
int color = ThemeStore.Companion.accentColor(requireContext());
|
||||
String hexColor = String.format("#%06X", 0xFFFFFF & color);
|
||||
Spanned appName =
|
||||
HtmlCompat.fromHtml(
|
||||
"Retro <span style='color:" + hexColor + ";'>Music</span>",
|
||||
HtmlCompat.FROM_HTML_MODE_COMPACT);
|
||||
appNameText.setText(appName);
|
||||
binding.toolbar.setNavigationOnClickListener(
|
||||
v -> {
|
||||
setExitTransition(new MaterialSharedAxis(MaterialSharedAxis.Z, true).setDuration(300));
|
||||
setReenterTransition(new MaterialSharedAxis(MaterialSharedAxis.Z, false).setDuration(300));
|
||||
Navigation.findNavController(v).navigate(R.id.searchFragment, null, getNavOptions());
|
||||
});
|
||||
binding.appNameText.setText(getResources().getString(R.string.folders));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -194,12 +207,14 @@ public class FoldersFragment extends AbsMainActivityFragment
|
|||
super.onActivityCreated(savedInstanceState);
|
||||
setHasOptionsMenu(true);
|
||||
if (savedInstanceState == null) {
|
||||
switchToFileAdapter();
|
||||
setCrumb(
|
||||
new BreadCrumbLayout.Crumb(
|
||||
FileUtil.safeGetCanonicalFile(PreferenceUtil.INSTANCE.getStartDirectory())),
|
||||
true);
|
||||
|
||||
} else {
|
||||
breadCrumbs.restoreFromStateWrapper(savedInstanceState.getParcelable(CRUMBS));
|
||||
binding.breadCrumbs.restoreFromStateWrapper(savedInstanceState.getParcelable(CRUMBS));
|
||||
LoaderManager.getInstance(this).initLoader(LOADER_ID, null, this);
|
||||
}
|
||||
}
|
||||
|
@ -213,8 +228,8 @@ public class FoldersFragment extends AbsMainActivityFragment
|
|||
@Override
|
||||
public void onSaveInstanceState(@NonNull Bundle outState) {
|
||||
super.onSaveInstanceState(outState);
|
||||
if (breadCrumbs != null) {
|
||||
outState.putParcelable(CRUMBS, breadCrumbs.getStateWrapper());
|
||||
if (binding != null) {
|
||||
outState.putParcelable(CRUMBS, binding.breadCrumbs.getStateWrapper());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -224,8 +239,8 @@ public class FoldersFragment extends AbsMainActivityFragment
|
|||
cab.finish();
|
||||
return true;
|
||||
}
|
||||
if (breadCrumbs != null && breadCrumbs.popHistory()) {
|
||||
setCrumb(breadCrumbs.lastHistory(), false);
|
||||
if (binding.breadCrumbs.popHistory()) {
|
||||
setCrumb(binding.breadCrumbs.lastHistory(), false);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -268,6 +283,9 @@ public class FoldersFragment extends AbsMainActivityFragment
|
|||
new ListSongsAsyncTask.LoadingInfo(
|
||||
toList(file), AUDIO_FILE_FILTER, getFileComparator()));
|
||||
return true;
|
||||
case R.id.action_add_to_blacklist:
|
||||
BlacklistStore.getInstance(App.Companion.getContext()).addPath(file);
|
||||
return true;
|
||||
case R.id.action_set_as_start_directory:
|
||||
PreferenceUtil.INSTANCE.setStartDirectory(file);
|
||||
Toast.makeText(
|
||||
|
@ -347,7 +365,7 @@ public class FoldersFragment extends AbsMainActivityFragment
|
|||
} else {
|
||||
final File finalFile = file1;
|
||||
Snackbar.make(
|
||||
coordinatorLayout,
|
||||
binding.coordinatorLayout,
|
||||
Html.fromHtml(
|
||||
String.format(
|
||||
getString(R.string.not_listed_in_media_store), file1.getName())),
|
||||
|
@ -376,7 +394,7 @@ public class FoldersFragment extends AbsMainActivityFragment
|
|||
|
||||
@Override
|
||||
public void onLoaderReset(@NonNull Loader<List<File>> loader) {
|
||||
updateAdapter(new LinkedList<File>());
|
||||
updateAdapter(new LinkedList<>());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -393,7 +411,7 @@ public class FoldersFragment extends AbsMainActivityFragment
|
|||
@Override
|
||||
public void onPrepareOptionsMenu(@NonNull Menu menu) {
|
||||
super.onPrepareOptionsMenu(menu);
|
||||
ToolbarContentTintHelper.handleOnPrepareOptionsMenu(requireActivity(), toolbar);
|
||||
ToolbarContentTintHelper.handleOnPrepareOptionsMenu(requireActivity(), binding.toolbar);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -407,7 +425,7 @@ public class FoldersFragment extends AbsMainActivityFragment
|
|||
menu.removeItem(R.id.action_layout_type);
|
||||
menu.removeItem(R.id.action_sort_order);
|
||||
ToolbarContentTintHelper.handleOnCreateOptionsMenu(
|
||||
requireContext(), toolbar, menu, getToolbarBackgroundColor(toolbar));
|
||||
requireContext(), binding.toolbar, menu, getToolbarBackgroundColor(binding.toolbar));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -462,26 +480,32 @@ public class FoldersFragment extends AbsMainActivityFragment
|
|||
|
||||
private void checkForPadding() {
|
||||
final int count = adapter.getItemCount();
|
||||
final MarginLayoutParams params = (MarginLayoutParams) coordinatorLayout.getLayoutParams();
|
||||
params.bottomMargin =
|
||||
count > 0 && !MusicPlayerRemote.getPlayingQueue().isEmpty()
|
||||
? DensityUtil.dip2px(requireContext(), 104f)
|
||||
: DensityUtil.dip2px(requireContext(), 54f);
|
||||
if (binding != null) {
|
||||
final MarginLayoutParams params = (MarginLayoutParams) binding.coordinatorLayout.getLayoutParams();
|
||||
params.bottomMargin =
|
||||
count > 0 && !MusicPlayerRemote.getPlayingQueue().isEmpty()
|
||||
? DensityUtil.dip2px(requireContext(), 104f)
|
||||
: DensityUtil.dip2px(requireContext(), 54f);
|
||||
binding.coordinatorLayout.setLayoutParams(params);
|
||||
}
|
||||
}
|
||||
|
||||
private void checkIsEmpty() {
|
||||
emojiText.setText(getEmojiByUnicode(0x1F631));
|
||||
if (empty != null) {
|
||||
empty.setVisibility(
|
||||
if (binding != null) {
|
||||
binding.emptyEmoji.setText(getEmojiByUnicode(0x1F631));
|
||||
binding.empty.setVisibility(
|
||||
adapter == null || adapter.getItemCount() == 0 ? View.VISIBLE : View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private BreadCrumbLayout.Crumb getActiveCrumb() {
|
||||
return breadCrumbs != null && breadCrumbs.size() > 0
|
||||
? breadCrumbs.getCrumb(breadCrumbs.getActiveIndex())
|
||||
: null;
|
||||
if (binding != null) {
|
||||
return binding.breadCrumbs.size() > 0
|
||||
? binding.breadCrumbs.getCrumb(binding.breadCrumbs.getActiveIndex())
|
||||
: null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private String getEmojiByUnicode(int unicode) {
|
||||
|
@ -492,21 +516,11 @@ public class FoldersFragment extends AbsMainActivityFragment
|
|||
return fileComparator;
|
||||
}
|
||||
|
||||
private void initViews(View view) {
|
||||
coordinatorLayout = view.findViewById(R.id.coordinatorLayout);
|
||||
recyclerView = view.findViewById(R.id.recyclerView);
|
||||
breadCrumbs = view.findViewById(R.id.breadCrumbs);
|
||||
empty = view.findViewById(android.R.id.empty);
|
||||
emojiText = view.findViewById(R.id.emptyEmoji);
|
||||
toolbar = view.findViewById(R.id.toolbar);
|
||||
appNameText = view.findViewById(R.id.appNameText);
|
||||
}
|
||||
|
||||
private void saveScrollPosition() {
|
||||
BreadCrumbLayout.Crumb crumb = getActiveCrumb();
|
||||
if (crumb != null) {
|
||||
crumb.setScrollPosition(
|
||||
((LinearLayoutManager) recyclerView.getLayoutManager()).findFirstVisibleItemPosition());
|
||||
((LinearLayoutManager) binding.recyclerView.getLayoutManager()).findFirstVisibleItemPosition());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -529,46 +543,39 @@ public class FoldersFragment extends AbsMainActivityFragment
|
|||
if (crumb == null) {
|
||||
return;
|
||||
}
|
||||
saveScrollPosition();
|
||||
breadCrumbs.setActiveOrAdd(crumb, false);
|
||||
if (addToHistory) {
|
||||
breadCrumbs.addHistory(crumb);
|
||||
String path = crumb.getFile().getPath();
|
||||
if (path.equals("/") || path.equals("/storage") || path.equals("/storage/emulated")) {
|
||||
switchToStorageAdapter();
|
||||
} else {
|
||||
saveScrollPosition();
|
||||
binding.breadCrumbs.setActiveOrAdd(crumb, false);
|
||||
if (addToHistory) {
|
||||
binding.breadCrumbs.addHistory(crumb);
|
||||
}
|
||||
LoaderManager.getInstance(this).restartLoader(LOADER_ID, null, this);
|
||||
}
|
||||
LoaderManager.getInstance(this).restartLoader(LOADER_ID, null, this);
|
||||
}
|
||||
|
||||
private void setUpAdapter() {
|
||||
adapter =
|
||||
new SongFileAdapter(getMainActivity(), new LinkedList<>(), R.layout.item_list, this, this);
|
||||
adapter.registerAdapterDataObserver(
|
||||
new RecyclerView.AdapterDataObserver() {
|
||||
@Override
|
||||
public void onChanged() {
|
||||
super.onChanged();
|
||||
checkIsEmpty();
|
||||
checkForPadding();
|
||||
}
|
||||
});
|
||||
recyclerView.setAdapter(adapter);
|
||||
checkIsEmpty();
|
||||
switchToFileAdapter();
|
||||
}
|
||||
|
||||
private void setUpAppbarColor() {
|
||||
breadCrumbs.setActivatedContentColor(
|
||||
binding.breadCrumbs.setActivatedContentColor(
|
||||
ATHUtil.INSTANCE.resolveColor(requireContext(), android.R.attr.textColorPrimary));
|
||||
breadCrumbs.setDeactivatedContentColor(
|
||||
binding.breadCrumbs.setDeactivatedContentColor(
|
||||
ATHUtil.INSTANCE.resolveColor(requireContext(), android.R.attr.textColorSecondary));
|
||||
}
|
||||
|
||||
private void setUpBreadCrumbs() {
|
||||
breadCrumbs.setCallback(this);
|
||||
binding.breadCrumbs.setCallback(this);
|
||||
}
|
||||
|
||||
private void setUpRecyclerView() {
|
||||
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
|
||||
FastScroller fastScroller = ThemedFastScroller.INSTANCE.create(recyclerView);
|
||||
recyclerView.setOnApplyWindowInsetsListener(
|
||||
new ScrollingViewOnApplyWindowInsetsListener(recyclerView, fastScroller));
|
||||
binding.recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
|
||||
FastScroller fastScroller = ThemedFastScroller.INSTANCE.create(binding.recyclerView);
|
||||
binding.recyclerView.setOnApplyWindowInsetsListener(
|
||||
new ScrollingViewOnApplyWindowInsetsListener(binding.recyclerView, fastScroller));
|
||||
}
|
||||
|
||||
private ArrayList<File> toList(File file) {
|
||||
|
@ -580,16 +587,22 @@ public class FoldersFragment extends AbsMainActivityFragment
|
|||
private void updateAdapter(@NonNull List<File> files) {
|
||||
adapter.swapDataSet(files);
|
||||
BreadCrumbLayout.Crumb crumb = getActiveCrumb();
|
||||
if (crumb != null && recyclerView != null) {
|
||||
((LinearLayoutManager) recyclerView.getLayoutManager())
|
||||
if (crumb != null) {
|
||||
((LinearLayoutManager) binding.recyclerView.getLayoutManager())
|
||||
.scrollToPositionWithOffset(crumb.getScrollPosition(), 0);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroyView() {
|
||||
super.onDestroyView();
|
||||
binding = null;
|
||||
}
|
||||
|
||||
public static class ListPathsAsyncTask
|
||||
extends ListingFilesDialogAsyncTask<ListPathsAsyncTask.LoadingInfo, String, String[]> {
|
||||
|
||||
private WeakReference<OnPathsListedCallback> onPathsListedCallbackWeakReference;
|
||||
private final WeakReference<OnPathsListedCallback> onPathsListedCallbackWeakReference;
|
||||
|
||||
public ListPathsAsyncTask(Context context, OnPathsListedCallback callback) {
|
||||
super(context);
|
||||
|
@ -679,7 +692,7 @@ public class FoldersFragment extends AbsMainActivityFragment
|
|||
|
||||
private static class AsyncFileLoader extends WrappedAsyncTaskLoader<List<File>> {
|
||||
|
||||
private WeakReference<FoldersFragment> fragmentWeakReference;
|
||||
private final WeakReference<FoldersFragment> fragmentWeakReference;
|
||||
|
||||
AsyncFileLoader(FoldersFragment foldersFragment) {
|
||||
super(foldersFragment.requireActivity());
|
||||
|
@ -710,8 +723,8 @@ public class FoldersFragment extends AbsMainActivityFragment
|
|||
extends ListingFilesDialogAsyncTask<ListSongsAsyncTask.LoadingInfo, Void, List<Song>> {
|
||||
|
||||
private final Object extra;
|
||||
private WeakReference<OnSongsListedCallback> callbackWeakReference;
|
||||
private WeakReference<Context> contextWeakReference;
|
||||
private final WeakReference<OnSongsListedCallback> callbackWeakReference;
|
||||
private final WeakReference<Context> contextWeakReference;
|
||||
|
||||
ListSongsAsyncTask(Context context, Object extra, OnSongsListedCallback callback) {
|
||||
super(context);
|
||||
|
@ -823,4 +836,107 @@ public class FoldersFragment extends AbsMainActivityFragment
|
|||
.create();
|
||||
}
|
||||
}
|
||||
|
||||
// https://github.com/DrKLO/Telegram/blob/ab221dafadbc17459d78d9ea3e643ae18e934b16/TMessagesProj/src/main/java/org/telegram/ui/Components/ChatAttachAlertDocumentLayout.java#L939
|
||||
private void listRoots() {
|
||||
storageItems.clear();
|
||||
HashSet<String> paths = new HashSet<>();
|
||||
String defaultPath = Environment.getExternalStorageDirectory().getPath();
|
||||
String defaultPathState = Environment.getExternalStorageState();
|
||||
if (defaultPathState.equals(Environment.MEDIA_MOUNTED) || defaultPathState.equals(Environment.MEDIA_MOUNTED_READ_ONLY)) {
|
||||
Storage ext = new Storage();
|
||||
if (Environment.isExternalStorageRemovable()) {
|
||||
ext.title = "SD Card";
|
||||
} else {
|
||||
ext.title = "Internal Storage";
|
||||
}
|
||||
ext.file = Environment.getExternalStorageDirectory();
|
||||
storageItems.add(ext);
|
||||
paths.add(defaultPath);
|
||||
}
|
||||
|
||||
BufferedReader bufferedReader = null;
|
||||
try {
|
||||
bufferedReader = new BufferedReader(new FileReader("/proc/mounts"));
|
||||
String line;
|
||||
while ((line = bufferedReader.readLine()) != null) {
|
||||
if (line.contains("vfat") || line.contains("/mnt")) {
|
||||
StringTokenizer tokens = new StringTokenizer(line, " ");
|
||||
tokens.nextToken();
|
||||
String path = tokens.nextToken();
|
||||
if (paths.contains(path)) {
|
||||
continue;
|
||||
}
|
||||
if (line.contains("/dev/block/vold")) {
|
||||
if (!line.contains("/mnt/secure") && !line.contains("/mnt/asec") && !line.contains("/mnt/obb") && !line.contains("/dev/mapper") && !line.contains("tmpfs")) {
|
||||
if (!new File(path).isDirectory()) {
|
||||
int index = path.lastIndexOf('/');
|
||||
if (index != -1) {
|
||||
String newPath = "/storage/" + path.substring(index + 1);
|
||||
if (new File(newPath).isDirectory()) {
|
||||
path = newPath;
|
||||
}
|
||||
}
|
||||
}
|
||||
paths.add(path);
|
||||
try {
|
||||
Storage item = new Storage();
|
||||
if (path.toLowerCase().contains("sd")) {
|
||||
item.title = "SD Card";
|
||||
} else {
|
||||
item.title = "External Storage";
|
||||
}
|
||||
item.file = new File(path);
|
||||
storageItems.add(item);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
if (bufferedReader != null) {
|
||||
try {
|
||||
bufferedReader.close();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStorageClicked(@NonNull Storage storage) {
|
||||
switchToFileAdapter();
|
||||
setCrumb(
|
||||
new BreadCrumbLayout.Crumb(
|
||||
FileUtil.safeGetCanonicalFile(storage.file)),
|
||||
true);
|
||||
}
|
||||
|
||||
public void switchToFileAdapter() {
|
||||
adapter =
|
||||
new SongFileAdapter(getMainActivity(), new LinkedList<>(), R.layout.item_list, this, this);
|
||||
adapter.registerAdapterDataObserver(
|
||||
new RecyclerView.AdapterDataObserver() {
|
||||
@Override
|
||||
public void onChanged() {
|
||||
super.onChanged();
|
||||
checkIsEmpty();
|
||||
checkForPadding();
|
||||
}
|
||||
});
|
||||
binding.recyclerView.setAdapter(adapter);
|
||||
checkIsEmpty();
|
||||
}
|
||||
|
||||
public void switchToStorageAdapter() {
|
||||
listRoots();
|
||||
storageAdapter = new StorageAdapter(storageItems, this);
|
||||
binding.recyclerView.setAdapter(storageAdapter);
|
||||
binding.breadCrumbs.clearCrumbs();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,28 +14,26 @@
|
|||
*/
|
||||
package code.name.monkey.retromusic.fragments.genres
|
||||
|
||||
import android.graphics.Color
|
||||
import android.os.Bundle
|
||||
import android.view.Menu
|
||||
import android.view.MenuInflater
|
||||
import android.view.MenuItem
|
||||
import android.view.View
|
||||
import androidx.core.view.ViewCompat
|
||||
import androidx.core.view.doOnPreDraw
|
||||
import androidx.navigation.fragment.navArgs
|
||||
import androidx.recyclerview.widget.DefaultItemAnimator
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import code.name.monkey.retromusic.R
|
||||
import code.name.monkey.retromusic.adapter.song.SongAdapter
|
||||
import code.name.monkey.retromusic.databinding.FragmentPlaylistDetailBinding
|
||||
import code.name.monkey.retromusic.extensions.dipToPix
|
||||
import code.name.monkey.retromusic.extensions.resolveColor
|
||||
import code.name.monkey.retromusic.fragments.base.AbsMainActivityFragment
|
||||
import code.name.monkey.retromusic.helper.menu.GenreMenuHelper
|
||||
import code.name.monkey.retromusic.model.Genre
|
||||
import code.name.monkey.retromusic.model.Song
|
||||
import com.google.android.material.transition.MaterialArcMotion
|
||||
import com.google.android.material.transition.MaterialContainerTransform
|
||||
import kotlinx.android.synthetic.main.fragment_playlist_detail.*
|
||||
import com.google.android.material.transition.MaterialSharedAxis
|
||||
import org.koin.androidx.viewmodel.ext.android.viewModel
|
||||
import org.koin.core.parameter.parametersOf
|
||||
import java.util.*
|
||||
|
@ -47,37 +45,33 @@ class GenreDetailsFragment : AbsMainActivityFragment(R.layout.fragment_playlist_
|
|||
}
|
||||
private lateinit var genre: Genre
|
||||
private lateinit var songAdapter: SongAdapter
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
sharedElementEnterTransition = MaterialContainerTransform().apply {
|
||||
drawingViewId = R.id.fragment_container
|
||||
duration = 300L
|
||||
scrimColor = Color.TRANSPARENT
|
||||
setAllContainerColors(requireContext().resolveColor(R.attr.colorSurface))
|
||||
setPathMotion(MaterialArcMotion())
|
||||
}
|
||||
}
|
||||
private var _binding: FragmentPlaylistDetailBinding? = null
|
||||
private val binding get() = _binding!!
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
enterTransition = MaterialSharedAxis(MaterialSharedAxis.Z, true).addTarget(view)
|
||||
returnTransition = MaterialSharedAxis(MaterialSharedAxis.Z, false)
|
||||
_binding = FragmentPlaylistDetailBinding.bind(view)
|
||||
setHasOptionsMenu(true)
|
||||
mainActivity.setBottomBarVisibility(false)
|
||||
mainActivity.addMusicServiceEventListener(detailsViewModel)
|
||||
mainActivity.setSupportActionBar(toolbar)
|
||||
ViewCompat.setTransitionName(container, "genre")
|
||||
mainActivity.setSupportActionBar(binding.toolbar)
|
||||
ViewCompat.setTransitionName(binding.container, "genre")
|
||||
genre = arguments.extraGenre
|
||||
toolbar?.title = arguments.extraGenre.name
|
||||
binding.toolbar.title = arguments.extraGenre.name
|
||||
setupRecyclerView()
|
||||
detailsViewModel.getSongs().observe(viewLifecycleOwner, {
|
||||
songs(it)
|
||||
})
|
||||
|
||||
postponeEnterTransition()
|
||||
view.doOnPreDraw {
|
||||
startPostponedEnterTransition()
|
||||
}
|
||||
}
|
||||
|
||||
private fun setupRecyclerView() {
|
||||
songAdapter = SongAdapter(requireActivity(), ArrayList(), R.layout.item_list, null)
|
||||
recyclerView.apply {
|
||||
binding.recyclerView.apply {
|
||||
itemAnimator = DefaultItemAnimator()
|
||||
layoutManager = LinearLayoutManager(requireContext())
|
||||
adapter = songAdapter
|
||||
|
@ -91,7 +85,7 @@ class GenreDetailsFragment : AbsMainActivityFragment(R.layout.fragment_playlist_
|
|||
}
|
||||
|
||||
fun songs(songs: List<Song>) {
|
||||
progressIndicator.hide()
|
||||
binding.progressIndicator.hide()
|
||||
if (songs.isNotEmpty()) songAdapter.swapDataSet(songs)
|
||||
else songAdapter.swapDataSet(emptyList())
|
||||
}
|
||||
|
@ -102,13 +96,13 @@ class GenreDetailsFragment : AbsMainActivityFragment(R.layout.fragment_playlist_
|
|||
|
||||
private fun checkIsEmpty() {
|
||||
checkForPadding()
|
||||
emptyEmoji.text = getEmojiByUnicode(0x1F631)
|
||||
empty?.visibility = if (songAdapter.itemCount == 0) View.VISIBLE else View.GONE
|
||||
binding.emptyEmoji.text = getEmojiByUnicode(0x1F631)
|
||||
binding.empty.visibility = if (songAdapter.itemCount == 0) View.VISIBLE else View.GONE
|
||||
}
|
||||
|
||||
private fun checkForPadding() {
|
||||
val height = dipToPix(52f).toInt()
|
||||
recyclerView.setPadding(0, 0, 0, height)
|
||||
binding.recyclerView.setPadding(0, 0, 0, height)
|
||||
}
|
||||
|
||||
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
|
||||
|
@ -119,4 +113,9 @@ class GenreDetailsFragment : AbsMainActivityFragment(R.layout.fragment_playlist_
|
|||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||
return GenreMenuHelper.handleMenuClick(requireActivity(), genre, item)
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
_binding = null
|
||||
}
|
||||
}
|
||||
|
|
|
@ -60,4 +60,5 @@ class GenreDetailsViewModel(
|
|||
override fun onPlayStateChanged() {}
|
||||
override fun onRepeatModeChanged() {}
|
||||
override fun onShuffleModeChanged() {}
|
||||
override fun onFavoriteStateChanged() {}
|
||||
}
|
||||
|
|
|
@ -15,25 +15,31 @@
|
|||
package code.name.monkey.retromusic.fragments.genres
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.Menu
|
||||
import android.view.MenuInflater
|
||||
import android.view.MenuItem
|
||||
import android.view.View
|
||||
import androidx.core.os.bundleOf
|
||||
import androidx.lifecycle.Observer
|
||||
import androidx.navigation.fragment.FragmentNavigatorExtras
|
||||
import androidx.navigation.fragment.findNavController
|
||||
import androidx.recyclerview.widget.GridLayoutManager
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import code.name.monkey.retromusic.EXTRA_GENRE
|
||||
import code.name.monkey.retromusic.R
|
||||
import code.name.monkey.retromusic.adapter.GenreAdapter
|
||||
import code.name.monkey.retromusic.fragments.ReloadType
|
||||
import code.name.monkey.retromusic.fragments.base.AbsRecyclerViewFragment
|
||||
import code.name.monkey.retromusic.interfaces.IGenreClickListener
|
||||
import code.name.monkey.retromusic.model.Genre
|
||||
import com.google.android.material.transition.MaterialElevationScale
|
||||
import code.name.monkey.retromusic.util.RetroUtil
|
||||
import com.google.android.gms.cast.framework.CastButtonFactory
|
||||
import com.google.android.material.transition.MaterialSharedAxis
|
||||
|
||||
class GenresFragment : AbsRecyclerViewFragment<GenreAdapter, LinearLayoutManager>(),
|
||||
class
|
||||
GenresFragment : AbsRecyclerViewFragment<GenreAdapter, LinearLayoutManager>(),
|
||||
IGenreClickListener {
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
libraryViewModel.getGenre().observe(viewLifecycleOwner, Observer {
|
||||
libraryViewModel.getGenre().observe(viewLifecycleOwner, {
|
||||
if (it.isNotEmpty())
|
||||
adapter?.swapDataSet(it)
|
||||
else
|
||||
|
@ -42,14 +48,37 @@ class GenresFragment : AbsRecyclerViewFragment<GenreAdapter, LinearLayoutManager
|
|||
}
|
||||
|
||||
override fun createLayoutManager(): LinearLayoutManager {
|
||||
return LinearLayoutManager(activity)
|
||||
return if (RetroUtil.isLandscape()) {
|
||||
GridLayoutManager(activity, 4)
|
||||
} else {
|
||||
GridLayoutManager(activity, 2)
|
||||
}
|
||||
}
|
||||
|
||||
override fun createAdapter(): GenreAdapter {
|
||||
val dataSet = if (adapter == null) ArrayList() else adapter!!.dataSet
|
||||
return GenreAdapter(requireActivity(), dataSet, R.layout.item_list_no_image, this)
|
||||
return GenreAdapter(requireActivity(), dataSet, R.layout.item_genre, this)
|
||||
}
|
||||
|
||||
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
|
||||
super.onCreateOptionsMenu(menu, inflater)
|
||||
menu.removeItem(R.id.action_grid_size)
|
||||
menu.removeItem(R.id.action_layout_type)
|
||||
menu.removeItem(R.id.action_sort_order)
|
||||
menu.findItem(R.id.action_settings).setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM)
|
||||
//Setting up cast button
|
||||
CastButtonFactory.setUpMediaRouteButton(requireContext(), menu, R.id.action_cast)
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
libraryViewModel.forceReload(ReloadType.Genres)
|
||||
}
|
||||
|
||||
|
||||
override val titleRes: Int
|
||||
get() = R.string.genres
|
||||
|
||||
override val emptyMessage: Int
|
||||
get() = R.string.no_genres
|
||||
|
||||
|
@ -64,19 +93,13 @@ class GenresFragment : AbsRecyclerViewFragment<GenreAdapter, LinearLayoutManager
|
|||
}
|
||||
|
||||
override fun onClickGenre(genre: Genre, view: View) {
|
||||
exitTransition = MaterialElevationScale(false).apply {
|
||||
duration = 300L
|
||||
}
|
||||
reenterTransition = MaterialElevationScale(true).apply {
|
||||
duration = 300L
|
||||
}
|
||||
exitTransition = MaterialSharedAxis(MaterialSharedAxis.Z, true).addTarget(requireView())
|
||||
reenterTransition = MaterialSharedAxis(MaterialSharedAxis.Z, false)
|
||||
findNavController().navigate(
|
||||
R.id.genreDetailsFragment,
|
||||
bundleOf(EXTRA_GENRE to genre),
|
||||
null,
|
||||
FragmentNavigatorExtras(
|
||||
view to "genre"
|
||||
)
|
||||
null
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
package code.name.monkey.retromusic.fragments.home
|
||||
|
||||
import code.name.monkey.retromusic.databinding.FragmentBannerHomeBinding
|
||||
import code.name.monkey.retromusic.databinding.FragmentHomeBinding
|
||||
|
||||
class HomeBindingAdapter(
|
||||
homeBinding: FragmentHomeBinding?,
|
||||
bannerHomeBinding: FragmentBannerHomeBinding?
|
||||
) {
|
||||
val root = homeBinding?.root ?: bannerHomeBinding?.root!!
|
||||
val container = homeBinding?.container ?: bannerHomeBinding?.container!!
|
||||
val contentContainer = homeBinding?.contentContainer ?: bannerHomeBinding?.contentContainer!!
|
||||
val appBarLayout = homeBinding?.appBarLayout ?: bannerHomeBinding?.appBarLayout!!
|
||||
val toolbar = homeBinding?.toolbar
|
||||
?: bannerHomeBinding?.toolbar!!
|
||||
val bannerImage = bannerHomeBinding?.bannerImage
|
||||
val userImage = homeBinding?.userImage
|
||||
?: bannerHomeBinding?.userImage!!
|
||||
val lastAdded = homeBinding?.homeContent?.absPlaylists?.lastAdded
|
||||
?: bannerHomeBinding?.homeContent?.absPlaylists?.lastAdded!!
|
||||
val topPlayed = homeBinding?.homeContent?.absPlaylists?.topPlayed
|
||||
?: bannerHomeBinding?.homeContent?.absPlaylists?.topPlayed!!
|
||||
val actionShuffle = homeBinding?.homeContent?.absPlaylists?.actionShuffle
|
||||
?: bannerHomeBinding?.homeContent?.absPlaylists?.actionShuffle!!
|
||||
val history = homeBinding?.homeContent?.absPlaylists?.history
|
||||
?: bannerHomeBinding?.homeContent?.absPlaylists?.history!!
|
||||
val recyclerView = homeBinding?.homeContent?.recyclerView
|
||||
?: bannerHomeBinding?.homeContent?.recyclerView!!
|
||||
val titleWelcome = homeBinding?.titleWelcome ?: bannerHomeBinding?.titleWelcome!!
|
||||
val appNameText = homeBinding?.appNameText ?: bannerHomeBinding?.appNameText!!
|
||||
}
|
|
@ -23,7 +23,7 @@ import android.view.MenuItem.SHOW_AS_ACTION_IF_ROOM
|
|||
import android.view.View
|
||||
import androidx.core.os.bundleOf
|
||||
import androidx.core.text.HtmlCompat
|
||||
import androidx.lifecycle.Observer
|
||||
import androidx.core.view.doOnPreDraw
|
||||
import androidx.navigation.fragment.findNavController
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import code.name.monkey.appthemehelper.ThemeStore
|
||||
|
@ -31,105 +31,111 @@ import code.name.monkey.appthemehelper.common.ATHToolbarActivity
|
|||
import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper
|
||||
import code.name.monkey.retromusic.*
|
||||
import code.name.monkey.retromusic.adapter.HomeAdapter
|
||||
import code.name.monkey.retromusic.databinding.FragmentBannerHomeBinding
|
||||
import code.name.monkey.retromusic.databinding.FragmentHomeBinding
|
||||
import code.name.monkey.retromusic.dialogs.CreatePlaylistDialog
|
||||
import code.name.monkey.retromusic.dialogs.ImportPlaylistDialog
|
||||
import code.name.monkey.retromusic.fragments.base.AbsMainActivityFragment
|
||||
import code.name.monkey.retromusic.glide.ProfileBannerGlideRequest
|
||||
import code.name.monkey.retromusic.glide.UserProfileGlideRequest
|
||||
import code.name.monkey.retromusic.glide.GlideApp
|
||||
import code.name.monkey.retromusic.glide.RetroGlideExtension
|
||||
import code.name.monkey.retromusic.util.NavigationUtil
|
||||
import code.name.monkey.retromusic.util.PreferenceUtil
|
||||
import com.bumptech.glide.Glide
|
||||
import kotlinx.android.synthetic.main.abs_playlists.*
|
||||
import kotlinx.android.synthetic.main.fragment_banner_home.*
|
||||
import kotlinx.android.synthetic.main.home_content.*
|
||||
import com.google.android.gms.cast.framework.CastButtonFactory
|
||||
import com.google.android.material.transition.MaterialFadeThrough
|
||||
import com.google.android.material.transition.MaterialSharedAxis
|
||||
|
||||
class HomeFragment :
|
||||
AbsMainActivityFragment(if (PreferenceUtil.typeHomeBanner == 1) R.layout.fragment_banner_home else R.layout.fragment_home) {
|
||||
AbsMainActivityFragment(if (PreferenceUtil.isHomeBanner) R.layout.fragment_banner_home else R.layout.fragment_home) {
|
||||
|
||||
private var _binding: HomeBindingAdapter? = null
|
||||
private val binding get() = _binding!!
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
mainActivity.setBottomBarVisibility(true)
|
||||
mainActivity.setSupportActionBar(toolbar)
|
||||
_binding = getBinding(PreferenceUtil.isHomeBanner, view)
|
||||
enterTransition = MaterialFadeThrough()
|
||||
exitTransition = MaterialFadeThrough()
|
||||
mainActivity.setSupportActionBar(binding.toolbar)
|
||||
mainActivity.supportActionBar?.title = null
|
||||
setStatusBarColorAuto(view)
|
||||
val needShowProfileOrBanner = (PreferenceUtil.typeHomeBanner != 2)
|
||||
|
||||
if (needShowProfileOrBanner) {
|
||||
bannerImage?.setOnClickListener {
|
||||
val options = ActivityOptions.makeSceneTransitionAnimation(
|
||||
mainActivity,
|
||||
userImage,
|
||||
getString(R.string.transition_user_image)
|
||||
)
|
||||
NavigationUtil.goToUserInfo(requireActivity(), options)
|
||||
}
|
||||
} else {
|
||||
userImage?.visibility = View.GONE
|
||||
titleWelcome?.visibility = View.GONE
|
||||
text?.visibility = View.GONE
|
||||
binding.bannerImage?.setOnClickListener {
|
||||
val options = ActivityOptions.makeSceneTransitionAnimation(
|
||||
mainActivity,
|
||||
binding.userImage,
|
||||
getString(R.string.transition_user_image)
|
||||
)
|
||||
NavigationUtil.goToUserInfo(requireActivity(), options)
|
||||
}
|
||||
|
||||
lastAdded.setOnClickListener {
|
||||
binding.lastAdded.setOnClickListener {
|
||||
findNavController().navigate(
|
||||
R.id.detailListFragment,
|
||||
bundleOf(EXTRA_PLAYLIST_TYPE to LAST_ADDED_PLAYLIST)
|
||||
)
|
||||
setSharedAxisYTransitions()
|
||||
}
|
||||
|
||||
topPlayed.setOnClickListener {
|
||||
binding.topPlayed.setOnClickListener {
|
||||
findNavController().navigate(
|
||||
R.id.detailListFragment,
|
||||
bundleOf(EXTRA_PLAYLIST_TYPE to TOP_PLAYED_PLAYLIST)
|
||||
)
|
||||
setSharedAxisYTransitions()
|
||||
}
|
||||
|
||||
actionShuffle.setOnClickListener {
|
||||
binding.actionShuffle.setOnClickListener {
|
||||
libraryViewModel.shuffleSongs()
|
||||
}
|
||||
|
||||
history.setOnClickListener {
|
||||
binding.history.setOnClickListener {
|
||||
findNavController().navigate(
|
||||
R.id.detailListFragment,
|
||||
bundleOf(EXTRA_PLAYLIST_TYPE to HISTORY_PLAYLIST)
|
||||
)
|
||||
setSharedAxisYTransitions()
|
||||
}
|
||||
|
||||
if (needShowProfileOrBanner) {
|
||||
userImage.setOnClickListener {
|
||||
val options = ActivityOptions.makeSceneTransitionAnimation(
|
||||
mainActivity,
|
||||
userImage,
|
||||
getString(R.string.transition_user_image)
|
||||
)
|
||||
NavigationUtil.goToUserInfo(requireActivity(), options)
|
||||
}
|
||||
titleWelcome?.text = String.format("%s", PreferenceUtil.userName)
|
||||
binding.userImage.setOnClickListener {
|
||||
val options = ActivityOptions.makeSceneTransitionAnimation(
|
||||
mainActivity,
|
||||
binding.userImage,
|
||||
getString(R.string.transition_user_image)
|
||||
)
|
||||
NavigationUtil.goToUserInfo(requireActivity(), options)
|
||||
}
|
||||
binding.titleWelcome.text = String.format("%s", PreferenceUtil.userName)
|
||||
|
||||
val homeAdapter = HomeAdapter(mainActivity)
|
||||
recyclerView.apply {
|
||||
binding.recyclerView.apply {
|
||||
layoutManager = LinearLayoutManager(mainActivity)
|
||||
adapter = homeAdapter
|
||||
}
|
||||
|
||||
libraryViewModel.getHome().observe(viewLifecycleOwner, Observer {
|
||||
libraryViewModel.getHome().observe(viewLifecycleOwner, {
|
||||
homeAdapter.swapData(it)
|
||||
})
|
||||
|
||||
if (needShowProfileOrBanner) {
|
||||
loadProfile()
|
||||
}
|
||||
|
||||
loadProfile()
|
||||
setupTitle()
|
||||
postponeEnterTransition()
|
||||
view.doOnPreDraw { startPostponedEnterTransition() }
|
||||
}
|
||||
|
||||
private fun getBinding(homeBanner: Boolean, view: View): HomeBindingAdapter {
|
||||
return if (homeBanner) {
|
||||
val homeBannerBinding = FragmentBannerHomeBinding.bind(view)
|
||||
HomeBindingAdapter(null, homeBannerBinding)
|
||||
} else {
|
||||
val homeBinding = FragmentHomeBinding.bind(view)
|
||||
HomeBindingAdapter(homeBinding, null)
|
||||
}
|
||||
}
|
||||
|
||||
private fun setupTitle() {
|
||||
toolbar.setNavigationOnClickListener {
|
||||
findNavController().navigate(
|
||||
R.id.searchFragment,
|
||||
null,
|
||||
navOptions
|
||||
)
|
||||
binding.toolbar.setNavigationOnClickListener {
|
||||
exitTransition = MaterialSharedAxis(MaterialSharedAxis.Z, true).addTarget(binding.root)
|
||||
reenterTransition =
|
||||
MaterialSharedAxis(MaterialSharedAxis.Z, false)
|
||||
findNavController().navigate(R.id.searchFragment, null, navOptions)
|
||||
}
|
||||
val color = ThemeStore.accentColor(requireContext())
|
||||
val hexColor = String.format("#%06X", 0xFFFFFF and color)
|
||||
|
@ -137,20 +143,21 @@ class HomeFragment :
|
|||
"Retro <span style='color:$hexColor';>Music</span>",
|
||||
HtmlCompat.FROM_HTML_MODE_COMPACT
|
||||
)
|
||||
appNameText.text = appName
|
||||
binding.appNameText.text = appName
|
||||
}
|
||||
|
||||
private fun loadProfile() {
|
||||
bannerImage?.let {
|
||||
ProfileBannerGlideRequest.Builder.from(
|
||||
Glide.with(requireContext()),
|
||||
ProfileBannerGlideRequest.getBannerModel()
|
||||
).build().into(it)
|
||||
binding.bannerImage?.let {
|
||||
GlideApp.with(requireContext())
|
||||
.asBitmap()
|
||||
.profileBannerOptions(RetroGlideExtension.getBannerModel())
|
||||
.load(RetroGlideExtension.getBannerModel())
|
||||
.into(it)
|
||||
}
|
||||
UserProfileGlideRequest.Builder.from(
|
||||
Glide.with(requireActivity()),
|
||||
UserProfileGlideRequest.getUserModel()
|
||||
).build().into(userImage)
|
||||
GlideApp.with(requireActivity()).asBitmap()
|
||||
.userProfileOptions(RetroGlideExtension.getUserModel())
|
||||
.load(RetroGlideExtension.getUserModel())
|
||||
.into(binding.userImage)
|
||||
}
|
||||
|
||||
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
|
||||
|
@ -162,10 +169,31 @@ class HomeFragment :
|
|||
menu.findItem(R.id.action_settings).setShowAsAction(SHOW_AS_ACTION_IF_ROOM)
|
||||
ToolbarContentTintHelper.handleOnCreateOptionsMenu(
|
||||
requireContext(),
|
||||
toolbar,
|
||||
binding.toolbar,
|
||||
menu,
|
||||
ATHToolbarActivity.getToolbarBackgroundColor(toolbar)
|
||||
ATHToolbarActivity.getToolbarBackgroundColor(binding.toolbar)
|
||||
)
|
||||
//Setting up cast button
|
||||
CastButtonFactory.setUpMediaRouteButton(requireContext(), menu, R.id.action_cast)
|
||||
}
|
||||
|
||||
fun scrollToTop() {
|
||||
binding.container.scrollTo(0, 0)
|
||||
binding.appBarLayout.setExpanded(true)
|
||||
}
|
||||
|
||||
fun setSharedAxisXTransitions() {
|
||||
exitTransition = MaterialSharedAxis(MaterialSharedAxis.X, true).apply {
|
||||
addTarget(binding.root)
|
||||
}
|
||||
reenterTransition = MaterialSharedAxis(MaterialSharedAxis.X, false)
|
||||
}
|
||||
|
||||
private fun setSharedAxisYTransitions() {
|
||||
exitTransition = MaterialSharedAxis(MaterialSharedAxis.Y, true).apply {
|
||||
addTarget(binding.root)
|
||||
}
|
||||
reenterTransition = MaterialSharedAxis(MaterialSharedAxis.Y, false)
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
@ -199,6 +227,16 @@ class HomeFragment :
|
|||
|
||||
override fun onPrepareOptionsMenu(menu: Menu) {
|
||||
super.onPrepareOptionsMenu(menu)
|
||||
ToolbarContentTintHelper.handleOnPrepareOptionsMenu(requireActivity(), toolbar)
|
||||
ToolbarContentTintHelper.handleOnPrepareOptionsMenu(requireActivity(), binding.toolbar)
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
libraryViewModel.fetchHomeSections()
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
_binding = null
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,24 +27,32 @@ import code.name.monkey.appthemehelper.ThemeStore
|
|||
import code.name.monkey.appthemehelper.common.ATHToolbarActivity.getToolbarBackgroundColor
|
||||
import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper
|
||||
import code.name.monkey.retromusic.R
|
||||
import code.name.monkey.retromusic.databinding.FragmentLibraryBinding
|
||||
import code.name.monkey.retromusic.dialogs.CreatePlaylistDialog
|
||||
import code.name.monkey.retromusic.dialogs.ImportPlaylistDialog
|
||||
import code.name.monkey.retromusic.extensions.whichFragment
|
||||
import code.name.monkey.retromusic.fragments.base.AbsMainActivityFragment
|
||||
import code.name.monkey.retromusic.model.CategoryInfo
|
||||
import code.name.monkey.retromusic.state.NowPlayingPanelState
|
||||
import code.name.monkey.retromusic.util.PreferenceUtil
|
||||
import kotlinx.android.synthetic.main.fragment_library.*
|
||||
import com.google.android.gms.cast.framework.CastButtonFactory
|
||||
|
||||
class LibraryFragment : AbsMainActivityFragment(R.layout.fragment_library) {
|
||||
|
||||
private var _binding: FragmentLibraryBinding? = null
|
||||
private val binding get() = _binding!!
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
_binding = FragmentLibraryBinding.bind(view)
|
||||
}
|
||||
|
||||
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||
super.onActivityCreated(savedInstanceState)
|
||||
setHasOptionsMenu(true)
|
||||
mainActivity.setBottomBarVisibility(true)
|
||||
mainActivity.setSupportActionBar(toolbar)
|
||||
mainActivity.setSupportActionBar(binding.toolbar)
|
||||
mainActivity.supportActionBar?.title = null
|
||||
toolbar.setNavigationOnClickListener {
|
||||
binding.toolbar.setNavigationOnClickListener {
|
||||
findNavController().navigate(
|
||||
R.id.searchFragment,
|
||||
null,
|
||||
|
@ -62,7 +70,7 @@ class LibraryFragment : AbsMainActivityFragment(R.layout.fragment_library) {
|
|||
"Retro <span style='color:$hexColor';>Music</span>",
|
||||
HtmlCompat.FROM_HTML_MODE_COMPACT
|
||||
)
|
||||
appNameText.text = appName
|
||||
binding.appNameText.text = appName
|
||||
}
|
||||
|
||||
private fun setupNavigationController() {
|
||||
|
@ -73,18 +81,18 @@ class LibraryFragment : AbsMainActivityFragment(R.layout.fragment_library) {
|
|||
|
||||
val categoryInfo: CategoryInfo = PreferenceUtil.libraryCategory.first { it.visible }
|
||||
if (categoryInfo.visible) {
|
||||
navGraph.startDestination = categoryInfo.category.id
|
||||
navGraph.setStartDestination(categoryInfo.category.id)
|
||||
}
|
||||
navController.graph = navGraph
|
||||
NavigationUI.setupWithNavController(mainActivity.getBottomNavigationView(), navController)
|
||||
navController.addOnDestinationChangedListener { _, _, _ ->
|
||||
appBarLayout.setExpanded(true, true)
|
||||
binding.appBarLayout.setExpanded(true, true)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onPrepareOptionsMenu(menu: Menu) {
|
||||
super.onPrepareOptionsMenu(menu)
|
||||
ToolbarContentTintHelper.handleOnPrepareOptionsMenu(requireActivity(), toolbar)
|
||||
ToolbarContentTintHelper.handleOnPrepareOptionsMenu(requireActivity(), binding.toolbar)
|
||||
}
|
||||
|
||||
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
|
||||
|
@ -92,10 +100,12 @@ class LibraryFragment : AbsMainActivityFragment(R.layout.fragment_library) {
|
|||
inflater.inflate(R.menu.menu_main, menu)
|
||||
ToolbarContentTintHelper.handleOnCreateOptionsMenu(
|
||||
requireContext(),
|
||||
toolbar,
|
||||
binding.toolbar,
|
||||
menu,
|
||||
getToolbarBackgroundColor(toolbar)
|
||||
getToolbarBackgroundColor(binding.toolbar)
|
||||
)
|
||||
//Setting up cast button
|
||||
CastButtonFactory.setUpMediaRouteButton(requireContext(), menu, R.id.action_cast)
|
||||
}
|
||||
|
||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||
|
@ -116,4 +126,9 @@ class LibraryFragment : AbsMainActivityFragment(R.layout.fragment_library) {
|
|||
}
|
||||
return super.onOptionsItemSelected(item)
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
_binding = null
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,26 +14,53 @@
|
|||
*/
|
||||
package code.name.monkey.retromusic.fragments.player
|
||||
|
||||
import android.content.SharedPreferences
|
||||
import android.os.Bundle
|
||||
import android.text.TextUtils
|
||||
import android.view.View
|
||||
import android.widget.FrameLayout
|
||||
import android.widget.TextView
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.preference.PreferenceManager
|
||||
import androidx.viewpager.widget.ViewPager
|
||||
import code.name.monkey.retromusic.R
|
||||
import code.name.monkey.retromusic.SHOW_LYRICS
|
||||
import code.name.monkey.retromusic.adapter.album.AlbumCoverPagerAdapter
|
||||
import code.name.monkey.retromusic.adapter.album.AlbumCoverPagerAdapter.AlbumCoverFragment
|
||||
import code.name.monkey.retromusic.databinding.FragmentPlayerAlbumCoverBinding
|
||||
import code.name.monkey.retromusic.fragments.NowPlayingScreen.*
|
||||
import code.name.monkey.retromusic.fragments.base.AbsMusicServiceFragment
|
||||
import code.name.monkey.retromusic.fragments.base.AbsPlayerFragment
|
||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote
|
||||
import code.name.monkey.retromusic.helper.MusicProgressViewUpdateHelper
|
||||
import code.name.monkey.retromusic.model.lyrics.AbsSynchronizedLyrics
|
||||
import code.name.monkey.retromusic.model.lyrics.Lyrics
|
||||
import code.name.monkey.retromusic.transform.CarousalPagerTransformer
|
||||
import code.name.monkey.retromusic.transform.ParallaxPagerTransformer
|
||||
import code.name.monkey.retromusic.util.LyricUtil
|
||||
import code.name.monkey.retromusic.util.NavigationUtil
|
||||
import code.name.monkey.retromusic.util.PreferenceUtil
|
||||
import code.name.monkey.retromusic.util.color.MediaNotificationProcessor
|
||||
import kotlinx.android.synthetic.main.fragment_player_album_cover.*
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.jaudiotagger.audio.AudioFileIO
|
||||
import org.jaudiotagger.audio.exceptions.CannotReadException
|
||||
import org.jaudiotagger.tag.FieldKey
|
||||
import java.io.File
|
||||
import java.io.FileNotFoundException
|
||||
|
||||
class PlayerAlbumCoverFragment : AbsMusicServiceFragment(R.layout.fragment_player_album_cover),
|
||||
ViewPager.OnPageChangeListener {
|
||||
ViewPager.OnPageChangeListener, MusicProgressViewUpdateHelper.Callback,
|
||||
SharedPreferences.OnSharedPreferenceChangeListener {
|
||||
|
||||
private var _binding: FragmentPlayerAlbumCoverBinding? = null
|
||||
private val binding get() = _binding!!
|
||||
private var callbacks: Callbacks? = null
|
||||
private var currentPosition: Int = 0
|
||||
val viewPager get() = binding.viewPager
|
||||
|
||||
private val colorReceiver = object : AlbumCoverFragment.ColorReceiver {
|
||||
override fun onColorReady(color: MediaNotificationProcessor, request: Int) {
|
||||
if (currentPosition == request) {
|
||||
|
@ -41,64 +68,221 @@ class PlayerAlbumCoverFragment : AbsMusicServiceFragment(R.layout.fragment_playe
|
|||
}
|
||||
}
|
||||
}
|
||||
private var progressViewUpdateHelper: MusicProgressViewUpdateHelper? = null
|
||||
|
||||
private val lyricsLayout: FrameLayout get() = binding.playerLyrics
|
||||
private val lyricsLine1: TextView get() = binding.playerLyricsLine1
|
||||
private val lyricsLine2: TextView get() = binding.playerLyricsLine2
|
||||
|
||||
var lyrics: Lyrics? = null
|
||||
|
||||
fun removeSlideEffect() {
|
||||
val transformer = ParallaxPagerTransformer(R.id.player_image)
|
||||
transformer.setSpeed(0.3f)
|
||||
}
|
||||
|
||||
private fun updateLyrics() {
|
||||
lyrics = null
|
||||
lifecycleScope.launch(Dispatchers.IO) {
|
||||
val song = MusicPlayerRemote.currentSong
|
||||
val lyrics = try {
|
||||
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 data: String = LyricUtil.getStringFromLrc(lrcFile)
|
||||
if (!TextUtils.isEmpty(data)) {
|
||||
Lyrics.parse(song, data)
|
||||
} else {
|
||||
// Get Embedded Lyrics and check if they are Synchronized
|
||||
val embeddedLyrics = try{
|
||||
AudioFileIO.read(File(song.data)).tagOrCreateDefault.getFirst(FieldKey.LYRICS)
|
||||
} catch(e: Exception){
|
||||
null
|
||||
}
|
||||
if (AbsSynchronizedLyrics.isSynchronized(embeddedLyrics)) {
|
||||
Lyrics.parse(song, embeddedLyrics)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
}
|
||||
} catch (err: FileNotFoundException) {
|
||||
null
|
||||
} catch (e: CannotReadException){
|
||||
null
|
||||
}
|
||||
withContext(Dispatchers.Main) {
|
||||
this@PlayerAlbumCoverFragment.lyrics = lyrics
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onUpdateProgressViews(progress: Int, total: Int) {
|
||||
if (_binding == null) return
|
||||
|
||||
if (!isLyricsLayoutVisible()) {
|
||||
hideLyricsLayout()
|
||||
return
|
||||
}
|
||||
|
||||
if (lyrics !is AbsSynchronizedLyrics) return
|
||||
val synchronizedLyrics = lyrics as AbsSynchronizedLyrics
|
||||
|
||||
lyricsLayout.visibility = View.VISIBLE
|
||||
lyricsLayout.alpha = 1f
|
||||
|
||||
val oldLine = lyricsLine2.text.toString()
|
||||
val line = synchronizedLyrics.getLine(progress)
|
||||
|
||||
if (oldLine != line || oldLine.isEmpty()) {
|
||||
lyricsLine1.text = oldLine
|
||||
lyricsLine2.text = line
|
||||
|
||||
lyricsLine1.visibility = View.VISIBLE
|
||||
lyricsLine2.visibility = View.VISIBLE
|
||||
|
||||
lyricsLine2.measure(
|
||||
View.MeasureSpec.makeMeasureSpec(
|
||||
lyricsLine2.measuredWidth,
|
||||
View.MeasureSpec.EXACTLY
|
||||
),
|
||||
View.MeasureSpec.UNSPECIFIED
|
||||
)
|
||||
val h: Float = lyricsLine2.measuredHeight.toFloat()
|
||||
|
||||
lyricsLine1.alpha = 1f
|
||||
lyricsLine1.translationY = 0f
|
||||
lyricsLine1.animate().alpha(0f).translationY(-h).duration =
|
||||
AbsPlayerFragment.VISIBILITY_ANIM_DURATION
|
||||
|
||||
lyricsLine2.alpha = 0f
|
||||
lyricsLine2.translationY = h
|
||||
lyricsLine2.animate().alpha(1f).translationY(0f).duration =
|
||||
AbsPlayerFragment.VISIBILITY_ANIM_DURATION
|
||||
}
|
||||
}
|
||||
|
||||
private fun isLyricsLayoutVisible(): Boolean {
|
||||
return lyrics != null && lyrics!!.isSynchronized && lyrics!!.isValid
|
||||
}
|
||||
|
||||
private fun hideLyricsLayout() {
|
||||
lyricsLayout.animate().alpha(0f).setDuration(AbsPlayerFragment.VISIBILITY_ANIM_DURATION)
|
||||
.withEndAction {
|
||||
if (_binding == null) return@withEndAction
|
||||
lyricsLayout.visibility = View.GONE
|
||||
lyricsLine1.text = null
|
||||
lyricsLine2.text = null
|
||||
}
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
viewPager.addOnPageChangeListener(this)
|
||||
_binding = FragmentPlayerAlbumCoverBinding.bind(view)
|
||||
binding.viewPager.addOnPageChangeListener(this)
|
||||
val nps = PreferenceUtil.nowPlayingScreen
|
||||
|
||||
val metrics = resources.displayMetrics
|
||||
val ratio = metrics.heightPixels.toFloat() / metrics.widthPixels.toFloat()
|
||||
|
||||
if (nps == Full || nps == Classic || nps == Fit || nps == Gradient) {
|
||||
viewPager.offscreenPageLimit = 2
|
||||
binding.viewPager.offscreenPageLimit = 2
|
||||
} else if (PreferenceUtil.isCarouselEffect) {
|
||||
viewPager.clipToPadding = false
|
||||
binding.viewPager.clipToPadding = false
|
||||
val padding =
|
||||
if (ratio >= 1.777f) {
|
||||
40
|
||||
} else {
|
||||
100
|
||||
}
|
||||
viewPager.setPadding(padding, 0, padding, 0)
|
||||
viewPager.pageMargin = 0
|
||||
viewPager.setPageTransformer(false, CarousalPagerTransformer(requireContext()))
|
||||
binding.viewPager.setPadding(padding, 0, padding, 0)
|
||||
binding.viewPager.pageMargin = 0
|
||||
binding.viewPager.setPageTransformer(false, CarousalPagerTransformer(requireContext()))
|
||||
} else {
|
||||
viewPager.offscreenPageLimit = 2
|
||||
viewPager.setPageTransformer(
|
||||
binding.viewPager.offscreenPageLimit = 2
|
||||
binding.viewPager.setPageTransformer(
|
||||
true,
|
||||
PreferenceUtil.albumCoverTransform
|
||||
)
|
||||
}
|
||||
progressViewUpdateHelper = MusicProgressViewUpdateHelper(this, 500, 1000)
|
||||
// Don't show lyrics container for below conditions
|
||||
if (!(nps == Circle || nps == Peak || nps == Tiny || !PreferenceUtil.showLyrics)) {
|
||||
progressViewUpdateHelper?.start()
|
||||
}
|
||||
// Go to lyrics activity when clicked lyrics
|
||||
binding.playerLyricsLine2.setOnClickListener {
|
||||
NavigationUtil.goToLyrics(requireActivity())
|
||||
}
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
val nps = PreferenceUtil.nowPlayingScreen
|
||||
// Don't show lyrics container for below conditions
|
||||
if (nps == Circle || nps == Peak || nps == Tiny || !PreferenceUtil.showLyrics) {
|
||||
lyricsLayout.isVisible = false
|
||||
progressViewUpdateHelper?.stop()
|
||||
} else {
|
||||
lyricsLayout.isVisible = true
|
||||
progressViewUpdateHelper?.start()
|
||||
}
|
||||
PreferenceManager.getDefaultSharedPreferences(requireContext())
|
||||
.registerOnSharedPreferenceChangeListener(this)
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
viewPager.removeOnPageChangeListener(this)
|
||||
PreferenceManager.getDefaultSharedPreferences(requireContext())
|
||||
.unregisterOnSharedPreferenceChangeListener(this)
|
||||
binding.viewPager.removeOnPageChangeListener(this)
|
||||
progressViewUpdateHelper?.stop()
|
||||
_binding = null
|
||||
}
|
||||
|
||||
override fun onServiceConnected() {
|
||||
updatePlayingQueue()
|
||||
updateLyrics()
|
||||
}
|
||||
|
||||
override fun onPlayingMetaChanged() {
|
||||
viewPager.currentItem = MusicPlayerRemote.position
|
||||
binding.viewPager.currentItem = MusicPlayerRemote.position
|
||||
updateLyrics()
|
||||
}
|
||||
|
||||
override fun onQueueChanged() {
|
||||
updatePlayingQueue()
|
||||
}
|
||||
|
||||
override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences, key: String?) {
|
||||
if (key == SHOW_LYRICS) {
|
||||
if (sharedPreferences.getBoolean(key, false)) {
|
||||
progressViewUpdateHelper?.start()
|
||||
lyricsLayout.animate().alpha(1f).duration =
|
||||
AbsPlayerFragment.VISIBILITY_ANIM_DURATION
|
||||
binding.playerLyrics.isVisible = true
|
||||
} else {
|
||||
progressViewUpdateHelper?.stop()
|
||||
lyricsLayout.animate().alpha(0f)
|
||||
.setDuration(AbsPlayerFragment.VISIBILITY_ANIM_DURATION)
|
||||
.withEndAction {
|
||||
if (_binding != null) {
|
||||
binding.playerLyrics.isVisible = false
|
||||
lyricsLine1.text = null
|
||||
lyricsLine2.text = null
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun updatePlayingQueue() {
|
||||
viewPager.apply {
|
||||
binding.viewPager.apply {
|
||||
adapter = AlbumCoverPagerAdapter(childFragmentManager, MusicPlayerRemote.playingQueue)
|
||||
viewPager.adapter!!.notifyDataSetChanged()
|
||||
viewPager.currentItem = MusicPlayerRemote.position
|
||||
adapter!!.notifyDataSetChanged()
|
||||
currentItem = MusicPlayerRemote.position
|
||||
onPageSelected(MusicPlayerRemote.position)
|
||||
}
|
||||
}
|
||||
|
@ -108,8 +292,11 @@ class PlayerAlbumCoverFragment : AbsMusicServiceFragment(R.layout.fragment_playe
|
|||
|
||||
override fun onPageSelected(position: Int) {
|
||||
currentPosition = position
|
||||
if (viewPager.adapter != null) {
|
||||
(viewPager.adapter as AlbumCoverPagerAdapter).receiveColor(colorReceiver, position)
|
||||
if (binding.viewPager.adapter != null) {
|
||||
(binding.viewPager.adapter as AlbumCoverPagerAdapter).receiveColor(
|
||||
colorReceiver,
|
||||
position
|
||||
)
|
||||
}
|
||||
if (position != MusicPlayerRemote.position) {
|
||||
MusicPlayerRemote.playSongAt(position)
|
||||
|
@ -119,6 +306,7 @@ class PlayerAlbumCoverFragment : AbsMusicServiceFragment(R.layout.fragment_playe
|
|||
override fun onPageScrollStateChanged(state: Int) {
|
||||
}
|
||||
|
||||
|
||||
private fun notifyColorChange(color: MediaNotificationProcessor) {
|
||||
callbacks?.onColorChanged(color)
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@ import androidx.appcompat.widget.Toolbar
|
|||
import code.name.monkey.appthemehelper.util.ATHUtil
|
||||
import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper
|
||||
import code.name.monkey.retromusic.R
|
||||
import code.name.monkey.retromusic.databinding.FragmentAdaptivePlayerBinding
|
||||
import code.name.monkey.retromusic.extensions.surfaceColor
|
||||
import code.name.monkey.retromusic.extensions.textColorPrimary
|
||||
import code.name.monkey.retromusic.extensions.textColorSecondary
|
||||
|
@ -28,12 +29,13 @@ import code.name.monkey.retromusic.fragments.player.PlayerAlbumCoverFragment
|
|||
import code.name.monkey.retromusic.helper.MusicPlayerRemote
|
||||
import code.name.monkey.retromusic.model.Song
|
||||
import code.name.monkey.retromusic.util.color.MediaNotificationProcessor
|
||||
import kotlinx.android.synthetic.main.fragment_adaptive_player.*
|
||||
|
||||
class AdaptiveFragment : AbsPlayerFragment(R.layout.fragment_adaptive_player) {
|
||||
|
||||
private var _binding: FragmentAdaptivePlayerBinding? = null
|
||||
private val binding get() = _binding!!
|
||||
override fun playerToolbar(): Toolbar {
|
||||
return playerToolbar
|
||||
return binding.playerToolbar
|
||||
}
|
||||
|
||||
private var lastColor: Int = 0
|
||||
|
@ -41,6 +43,7 @@ class AdaptiveFragment : AbsPlayerFragment(R.layout.fragment_adaptive_player) {
|
|||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
_binding = FragmentAdaptivePlayerBinding.bind(view)
|
||||
setUpSubFragments()
|
||||
setUpPlayerToolbar()
|
||||
}
|
||||
|
@ -57,7 +60,7 @@ class AdaptiveFragment : AbsPlayerFragment(R.layout.fragment_adaptive_player) {
|
|||
}
|
||||
|
||||
private fun setUpPlayerToolbar() {
|
||||
playerToolbar.apply {
|
||||
binding.playerToolbar.apply {
|
||||
inflateMenu(R.menu.menu_player)
|
||||
setNavigationOnClickListener { requireActivity().onBackPressed() }
|
||||
ToolbarContentTintHelper.colorizeToolbar(this, surfaceColor(), requireActivity())
|
||||
|
@ -80,7 +83,7 @@ class AdaptiveFragment : AbsPlayerFragment(R.layout.fragment_adaptive_player) {
|
|||
|
||||
private fun updateSong() {
|
||||
val song = MusicPlayerRemote.currentSong
|
||||
playerToolbar.apply {
|
||||
binding.playerToolbar.apply {
|
||||
title = song.title
|
||||
subtitle = song.artistName
|
||||
}
|
||||
|
@ -102,7 +105,7 @@ class AdaptiveFragment : AbsPlayerFragment(R.layout.fragment_adaptive_player) {
|
|||
lastColor = color.primaryTextColor
|
||||
libraryViewModel.updateColor(color.primaryTextColor)
|
||||
ToolbarContentTintHelper.colorizeToolbar(
|
||||
playerToolbar,
|
||||
binding.playerToolbar,
|
||||
ATHUtil.resolveColor(requireContext(), R.attr.colorControlNormal),
|
||||
requireActivity()
|
||||
)
|
||||
|
@ -119,6 +122,11 @@ class AdaptiveFragment : AbsPlayerFragment(R.layout.fragment_adaptive_player) {
|
|||
return false
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
_binding = null
|
||||
}
|
||||
|
||||
override fun toolbarIconColor(): Int {
|
||||
return ATHUtil.resolveColor(requireContext(), R.attr.colorControlNormal)
|
||||
}
|
||||
|
|
|
@ -28,6 +28,7 @@ import code.name.monkey.appthemehelper.util.ColorUtil
|
|||
import code.name.monkey.appthemehelper.util.MaterialValueHelper
|
||||
import code.name.monkey.appthemehelper.util.TintHelper
|
||||
import code.name.monkey.retromusic.R
|
||||
import code.name.monkey.retromusic.databinding.FragmentAdaptivePlayerPlaybackControlsBinding
|
||||
import code.name.monkey.retromusic.extensions.applyColor
|
||||
import code.name.monkey.retromusic.extensions.hide
|
||||
import code.name.monkey.retromusic.extensions.ripAlpha
|
||||
|
@ -41,7 +42,6 @@ import code.name.monkey.retromusic.service.MusicService
|
|||
import code.name.monkey.retromusic.util.MusicUtil
|
||||
import code.name.monkey.retromusic.util.PreferenceUtil
|
||||
import code.name.monkey.retromusic.util.color.MediaNotificationProcessor
|
||||
import kotlinx.android.synthetic.main.fragment_adaptive_player_playback_controls.*
|
||||
|
||||
class AdaptivePlaybackControlsFragment :
|
||||
AbsPlayerControlsFragment(R.layout.fragment_adaptive_player_playback_controls) {
|
||||
|
@ -49,6 +49,8 @@ class AdaptivePlaybackControlsFragment :
|
|||
private var lastPlaybackControlsColor: Int = 0
|
||||
private var lastDisabledPlaybackControlsColor: Int = 0
|
||||
private var progressViewUpdateHelper: MusicProgressViewUpdateHelper? = null
|
||||
private var _binding: FragmentAdaptivePlayerPlaybackControlsBinding? = null
|
||||
private val binding get() = _binding!!
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
@ -59,34 +61,31 @@ class AdaptivePlaybackControlsFragment :
|
|||
inflater: LayoutInflater,
|
||||
container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View? {
|
||||
return inflater.inflate(
|
||||
R.layout.fragment_adaptive_player_playback_controls,
|
||||
container,
|
||||
false
|
||||
)
|
||||
): View {
|
||||
_binding = FragmentAdaptivePlayerPlaybackControlsBinding.inflate(inflater, container, false)
|
||||
return binding.root
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
setUpMusicControllers()
|
||||
|
||||
playPauseButton.setOnClickListener {
|
||||
binding.playPauseButton.setOnClickListener {
|
||||
if (MusicPlayerRemote.isPlaying) {
|
||||
MusicPlayerRemote.pauseSong()
|
||||
} else {
|
||||
MusicPlayerRemote.resumePlaying()
|
||||
}
|
||||
showBonceAnimation(playPauseButton)
|
||||
showBounceAnimation(binding.playPauseButton)
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateSong() {
|
||||
if (PreferenceUtil.isSongInfo) {
|
||||
songInfo?.text = getSongInfo(MusicPlayerRemote.currentSong)
|
||||
songInfo.show()
|
||||
binding.songInfo.text = getSongInfo(MusicPlayerRemote.currentSong)
|
||||
binding.songInfo.show()
|
||||
} else {
|
||||
songInfo?.hide()
|
||||
binding.songInfo.hide()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -153,12 +152,12 @@ class AdaptivePlaybackControlsFragment :
|
|||
}.ripAlpha()
|
||||
|
||||
TintHelper.setTintAuto(
|
||||
playPauseButton,
|
||||
binding.playPauseButton,
|
||||
MaterialValueHelper.getPrimaryTextColor(context, ColorUtil.isColorLight(colorFinal)),
|
||||
false
|
||||
)
|
||||
TintHelper.setTintAuto(playPauseButton, colorFinal, true)
|
||||
progressSlider.applyColor(colorFinal)
|
||||
TintHelper.setTintAuto(binding.playPauseButton, colorFinal, true)
|
||||
binding.progressSlider.applyColor(colorFinal)
|
||||
volumeFragment?.setTintable(colorFinal)
|
||||
}
|
||||
|
||||
|
@ -167,14 +166,14 @@ class AdaptivePlaybackControlsFragment :
|
|||
}
|
||||
|
||||
private fun setUpPlayPauseFab() {
|
||||
playPauseButton.setOnClickListener(PlayPauseButtonOnClickHandler())
|
||||
binding.playPauseButton.setOnClickListener(PlayPauseButtonOnClickHandler())
|
||||
}
|
||||
|
||||
private fun updatePlayPauseDrawableState() {
|
||||
if (MusicPlayerRemote.isPlaying) {
|
||||
playPauseButton.setImageResource(R.drawable.ic_pause)
|
||||
binding.playPauseButton.setImageResource(R.drawable.ic_pause)
|
||||
} else {
|
||||
playPauseButton.setImageResource(R.drawable.ic_play_arrow_white_32dp)
|
||||
binding.playPauseButton.setImageResource(R.drawable.ic_play_arrow_white_32dp)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -188,17 +187,17 @@ class AdaptivePlaybackControlsFragment :
|
|||
|
||||
private fun setUpPrevNext() {
|
||||
updatePrevNextColor()
|
||||
nextButton.setOnClickListener { MusicPlayerRemote.playNextSong() }
|
||||
previousButton.setOnClickListener { MusicPlayerRemote.back() }
|
||||
binding.nextButton.setOnClickListener { MusicPlayerRemote.playNextSong() }
|
||||
binding.previousButton.setOnClickListener { MusicPlayerRemote.back() }
|
||||
}
|
||||
|
||||
private fun updatePrevNextColor() {
|
||||
nextButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
|
||||
previousButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
|
||||
binding.nextButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
|
||||
binding.previousButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
|
||||
}
|
||||
|
||||
private fun setUpShuffleButton() {
|
||||
shuffleButton.setOnClickListener { MusicPlayerRemote.toggleShuffleMode() }
|
||||
binding.shuffleButton.setOnClickListener { MusicPlayerRemote.toggleShuffleMode() }
|
||||
}
|
||||
|
||||
override fun show() {
|
||||
|
@ -209,11 +208,11 @@ class AdaptivePlaybackControlsFragment :
|
|||
|
||||
override fun updateShuffleState() {
|
||||
when (MusicPlayerRemote.shuffleMode) {
|
||||
MusicService.SHUFFLE_MODE_SHUFFLE -> shuffleButton.setColorFilter(
|
||||
MusicService.SHUFFLE_MODE_SHUFFLE -> binding.shuffleButton.setColorFilter(
|
||||
lastPlaybackControlsColor,
|
||||
PorterDuff.Mode.SRC_IN
|
||||
)
|
||||
else -> shuffleButton.setColorFilter(
|
||||
else -> binding.shuffleButton.setColorFilter(
|
||||
lastDisabledPlaybackControlsColor,
|
||||
PorterDuff.Mode.SRC_IN
|
||||
)
|
||||
|
@ -221,31 +220,37 @@ class AdaptivePlaybackControlsFragment :
|
|||
}
|
||||
|
||||
private fun setUpRepeatButton() {
|
||||
repeatButton.setOnClickListener { MusicPlayerRemote.cycleRepeatMode() }
|
||||
binding.repeatButton.setOnClickListener { MusicPlayerRemote.cycleRepeatMode() }
|
||||
}
|
||||
|
||||
override fun updateRepeatState() {
|
||||
when (MusicPlayerRemote.repeatMode) {
|
||||
MusicService.REPEAT_MODE_NONE -> {
|
||||
repeatButton.setImageResource(R.drawable.ic_repeat)
|
||||
repeatButton.setColorFilter(
|
||||
binding.repeatButton.setImageResource(R.drawable.ic_repeat)
|
||||
binding.repeatButton.setColorFilter(
|
||||
lastDisabledPlaybackControlsColor,
|
||||
PorterDuff.Mode.SRC_IN
|
||||
)
|
||||
}
|
||||
MusicService.REPEAT_MODE_ALL -> {
|
||||
repeatButton.setImageResource(R.drawable.ic_repeat)
|
||||
repeatButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
|
||||
binding.repeatButton.setImageResource(R.drawable.ic_repeat)
|
||||
binding.repeatButton.setColorFilter(
|
||||
lastPlaybackControlsColor,
|
||||
PorterDuff.Mode.SRC_IN
|
||||
)
|
||||
}
|
||||
MusicService.REPEAT_MODE_THIS -> {
|
||||
repeatButton.setImageResource(R.drawable.ic_repeat_one)
|
||||
repeatButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
|
||||
binding.repeatButton.setImageResource(R.drawable.ic_repeat_one)
|
||||
binding.repeatButton.setColorFilter(
|
||||
lastPlaybackControlsColor,
|
||||
PorterDuff.Mode.SRC_IN
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun setUpProgressSlider() {
|
||||
progressSlider.setOnSeekBarChangeListener(object : SimpleOnSeekbarChangeListener() {
|
||||
binding.progressSlider.setOnSeekBarChangeListener(object : SimpleOnSeekbarChangeListener() {
|
||||
override fun onProgressChanged(seekBar: SeekBar, progress: Int, fromUser: Boolean) {
|
||||
if (fromUser) {
|
||||
MusicPlayerRemote.seekTo(progress)
|
||||
|
@ -259,14 +264,19 @@ class AdaptivePlaybackControlsFragment :
|
|||
}
|
||||
|
||||
override fun onUpdateProgressViews(progress: Int, total: Int) {
|
||||
progressSlider.max = total
|
||||
binding.progressSlider.max = total
|
||||
|
||||
val animator = ObjectAnimator.ofInt(progressSlider, "progress", progress)
|
||||
val animator = ObjectAnimator.ofInt(binding.progressSlider, "progress", progress)
|
||||
animator.duration = SLIDER_ANIMATION_TIME
|
||||
animator.interpolator = LinearInterpolator()
|
||||
animator.start()
|
||||
|
||||
songTotalTime.text = MusicUtil.getReadableDurationString(total.toLong())
|
||||
songCurrentProgress.text = MusicUtil.getReadableDurationString(progress.toLong())
|
||||
binding.songTotalTime.text = MusicUtil.getReadableDurationString(total.toLong())
|
||||
binding.songCurrentProgress.text = MusicUtil.getReadableDurationString(progress.toLong())
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
_binding = null
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,9 +28,12 @@ import code.name.monkey.appthemehelper.util.ColorUtil
|
|||
import code.name.monkey.appthemehelper.util.MaterialValueHelper
|
||||
import code.name.monkey.appthemehelper.util.TintHelper
|
||||
import code.name.monkey.retromusic.R
|
||||
import code.name.monkey.retromusic.databinding.FragmentBlurPlayerPlaybackControlsBinding
|
||||
import code.name.monkey.retromusic.extensions.hide
|
||||
import code.name.monkey.retromusic.extensions.show
|
||||
import code.name.monkey.retromusic.fragments.base.AbsPlayerControlsFragment
|
||||
import code.name.monkey.retromusic.fragments.base.goToAlbum
|
||||
import code.name.monkey.retromusic.fragments.base.goToArtist
|
||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote
|
||||
import code.name.monkey.retromusic.helper.MusicProgressViewUpdateHelper
|
||||
import code.name.monkey.retromusic.helper.PlayPauseButtonOnClickHandler
|
||||
|
@ -39,11 +42,11 @@ import code.name.monkey.retromusic.service.MusicService
|
|||
import code.name.monkey.retromusic.util.MusicUtil
|
||||
import code.name.monkey.retromusic.util.PreferenceUtil
|
||||
import code.name.monkey.retromusic.util.color.MediaNotificationProcessor
|
||||
import kotlinx.android.synthetic.main.fragment_blur_player_playback_controls.*
|
||||
|
||||
class BlurPlaybackControlsFragment :
|
||||
AbsPlayerControlsFragment(R.layout.fragment_blur_player_playback_controls) {
|
||||
|
||||
private var _binding: FragmentBlurPlayerPlaybackControlsBinding? = null
|
||||
private val binding get() = _binding!!
|
||||
private var lastPlaybackControlsColor: Int = 0
|
||||
private var lastDisabledPlaybackControlsColor: Int = 0
|
||||
private var progressViewUpdateHelper: MusicProgressViewUpdateHelper? = null
|
||||
|
@ -55,30 +58,37 @@ class BlurPlaybackControlsFragment :
|
|||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
_binding = FragmentBlurPlayerPlaybackControlsBinding.bind(view)
|
||||
setUpMusicControllers()
|
||||
|
||||
playPauseButton.setOnClickListener {
|
||||
binding.playPauseButton.setOnClickListener {
|
||||
if (MusicPlayerRemote.isPlaying) {
|
||||
MusicPlayerRemote.pauseSong()
|
||||
} else {
|
||||
MusicPlayerRemote.resumePlaying()
|
||||
}
|
||||
showBonceAnimation()
|
||||
showBounceAnimation()
|
||||
}
|
||||
binding.title.isSelected = true
|
||||
binding.text.isSelected = true
|
||||
binding.title.setOnClickListener {
|
||||
goToAlbum(requireActivity())
|
||||
}
|
||||
binding.text.setOnClickListener {
|
||||
goToArtist(requireActivity())
|
||||
}
|
||||
title.isSelected = true
|
||||
text.isSelected = true
|
||||
}
|
||||
|
||||
private fun updateSong() {
|
||||
val song = MusicPlayerRemote.currentSong
|
||||
title.text = song.title
|
||||
text.text = String.format("%s • %s", song.artistName, song.albumName)
|
||||
binding.title.text = song.title
|
||||
binding.text.text = String.format("%s • %s", song.artistName, song.albumName)
|
||||
|
||||
if (PreferenceUtil.isSongInfo) {
|
||||
songInfo.show()
|
||||
songInfo?.text = getSongInfo(song)
|
||||
binding.songInfo.show()
|
||||
binding.songInfo.text = getSongInfo(song)
|
||||
} else {
|
||||
songInfo?.hide()
|
||||
binding.songInfo.hide()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -121,41 +131,41 @@ class BlurPlaybackControlsFragment :
|
|||
lastDisabledPlaybackControlsColor =
|
||||
ContextCompat.getColor(requireContext(), R.color.md_grey_500)
|
||||
|
||||
title.setTextColor(lastPlaybackControlsColor)
|
||||
binding.title.setTextColor(lastPlaybackControlsColor)
|
||||
|
||||
songCurrentProgress.setTextColor(lastPlaybackControlsColor)
|
||||
songTotalTime.setTextColor(lastPlaybackControlsColor)
|
||||
binding.songCurrentProgress.setTextColor(lastPlaybackControlsColor)
|
||||
binding.songTotalTime.setTextColor(lastPlaybackControlsColor)
|
||||
|
||||
updateRepeatState()
|
||||
updateShuffleState()
|
||||
updatePrevNextColor()
|
||||
|
||||
text.setTextColor(lastDisabledPlaybackControlsColor)
|
||||
songInfo.setTextColor(lastDisabledPlaybackControlsColor)
|
||||
binding.text.setTextColor(lastPlaybackControlsColor)
|
||||
binding.songInfo.setTextColor(lastDisabledPlaybackControlsColor)
|
||||
|
||||
TintHelper.setTintAuto(progressSlider, lastPlaybackControlsColor, false)
|
||||
TintHelper.setTintAuto(binding.progressSlider, lastPlaybackControlsColor, false)
|
||||
volumeFragment?.setTintableColor(lastPlaybackControlsColor)
|
||||
setFabColor(lastPlaybackControlsColor)
|
||||
}
|
||||
|
||||
private fun setFabColor(i: Int) {
|
||||
TintHelper.setTintAuto(
|
||||
playPauseButton,
|
||||
binding.playPauseButton,
|
||||
MaterialValueHelper.getPrimaryTextColor(context, ColorUtil.isColorLight(i)),
|
||||
false
|
||||
)
|
||||
TintHelper.setTintAuto(playPauseButton, i, true)
|
||||
TintHelper.setTintAuto(binding.playPauseButton, i, true)
|
||||
}
|
||||
|
||||
private fun setUpPlayPauseFab() {
|
||||
playPauseButton.setOnClickListener(PlayPauseButtonOnClickHandler())
|
||||
binding.playPauseButton.setOnClickListener(PlayPauseButtonOnClickHandler())
|
||||
}
|
||||
|
||||
private fun updatePlayPauseDrawableState() {
|
||||
if (MusicPlayerRemote.isPlaying) {
|
||||
playPauseButton.setImageResource(R.drawable.ic_pause)
|
||||
binding.playPauseButton.setImageResource(R.drawable.ic_pause)
|
||||
} else {
|
||||
playPauseButton.setImageResource(R.drawable.ic_play_arrow_white_32dp)
|
||||
binding.playPauseButton.setImageResource(R.drawable.ic_play_arrow_white_32dp)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -169,26 +179,26 @@ class BlurPlaybackControlsFragment :
|
|||
|
||||
private fun setUpPrevNext() {
|
||||
updatePrevNextColor()
|
||||
nextButton.setOnClickListener { MusicPlayerRemote.playNextSong() }
|
||||
previousButton.setOnClickListener { MusicPlayerRemote.back() }
|
||||
binding.nextButton.setOnClickListener { MusicPlayerRemote.playNextSong() }
|
||||
binding.previousButton.setOnClickListener { MusicPlayerRemote.back() }
|
||||
}
|
||||
|
||||
private fun updatePrevNextColor() {
|
||||
nextButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
|
||||
previousButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
|
||||
binding.nextButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
|
||||
binding.previousButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
|
||||
}
|
||||
|
||||
private fun setUpShuffleButton() {
|
||||
shuffleButton.setOnClickListener { MusicPlayerRemote.toggleShuffleMode() }
|
||||
binding.shuffleButton.setOnClickListener { MusicPlayerRemote.toggleShuffleMode() }
|
||||
}
|
||||
|
||||
override fun updateShuffleState() {
|
||||
when (MusicPlayerRemote.shuffleMode) {
|
||||
MusicService.SHUFFLE_MODE_SHUFFLE -> shuffleButton.setColorFilter(
|
||||
MusicService.SHUFFLE_MODE_SHUFFLE -> binding.shuffleButton.setColorFilter(
|
||||
lastPlaybackControlsColor,
|
||||
PorterDuff.Mode.SRC_IN
|
||||
)
|
||||
else -> shuffleButton.setColorFilter(
|
||||
else -> binding.shuffleButton.setColorFilter(
|
||||
lastDisabledPlaybackControlsColor,
|
||||
PorterDuff.Mode.SRC_IN
|
||||
)
|
||||
|
@ -196,31 +206,37 @@ class BlurPlaybackControlsFragment :
|
|||
}
|
||||
|
||||
private fun setUpRepeatButton() {
|
||||
repeatButton.setOnClickListener { MusicPlayerRemote.cycleRepeatMode() }
|
||||
binding.repeatButton.setOnClickListener { MusicPlayerRemote.cycleRepeatMode() }
|
||||
}
|
||||
|
||||
override fun updateRepeatState() {
|
||||
when (MusicPlayerRemote.repeatMode) {
|
||||
MusicService.REPEAT_MODE_NONE -> {
|
||||
repeatButton.setImageResource(R.drawable.ic_repeat)
|
||||
repeatButton.setColorFilter(
|
||||
binding.repeatButton.setImageResource(R.drawable.ic_repeat)
|
||||
binding.repeatButton.setColorFilter(
|
||||
lastDisabledPlaybackControlsColor,
|
||||
PorterDuff.Mode.SRC_IN
|
||||
)
|
||||
}
|
||||
MusicService.REPEAT_MODE_ALL -> {
|
||||
repeatButton.setImageResource(R.drawable.ic_repeat)
|
||||
repeatButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
|
||||
binding.repeatButton.setImageResource(R.drawable.ic_repeat)
|
||||
binding.repeatButton.setColorFilter(
|
||||
lastPlaybackControlsColor,
|
||||
PorterDuff.Mode.SRC_IN
|
||||
)
|
||||
}
|
||||
MusicService.REPEAT_MODE_THIS -> {
|
||||
repeatButton.setImageResource(R.drawable.ic_repeat_one)
|
||||
repeatButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
|
||||
binding.repeatButton.setImageResource(R.drawable.ic_repeat_one)
|
||||
binding.repeatButton.setColorFilter(
|
||||
lastPlaybackControlsColor,
|
||||
PorterDuff.Mode.SRC_IN
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override fun show() {
|
||||
playPauseButton!!.animate()
|
||||
binding.playPauseButton.animate()
|
||||
.scaleX(1f)
|
||||
.scaleY(1f)
|
||||
.rotation(360f)
|
||||
|
@ -229,17 +245,15 @@ class BlurPlaybackControlsFragment :
|
|||
}
|
||||
|
||||
public override fun hide() {
|
||||
if (playPauseButton != null) {
|
||||
playPauseButton!!.apply {
|
||||
scaleX = 0f
|
||||
scaleY = 0f
|
||||
rotation = 0f
|
||||
}
|
||||
binding.playPauseButton.apply {
|
||||
scaleX = 0f
|
||||
scaleY = 0f
|
||||
rotation = 0f
|
||||
}
|
||||
}
|
||||
|
||||
private fun showBonceAnimation() {
|
||||
playPauseButton.apply {
|
||||
private fun showBounceAnimation() {
|
||||
binding.playPauseButton.apply {
|
||||
clearAnimation()
|
||||
scaleX = 0.9f
|
||||
scaleY = 0.9f
|
||||
|
@ -262,7 +276,7 @@ class BlurPlaybackControlsFragment :
|
|||
}
|
||||
|
||||
override fun setUpProgressSlider() {
|
||||
progressSlider.setOnSeekBarChangeListener(object : SimpleOnSeekbarChangeListener() {
|
||||
binding.progressSlider.setOnSeekBarChangeListener(object : SimpleOnSeekbarChangeListener() {
|
||||
override fun onProgressChanged(seekBar: SeekBar, progress: Int, fromUser: Boolean) {
|
||||
if (fromUser) {
|
||||
MusicPlayerRemote.seekTo(progress)
|
||||
|
@ -276,14 +290,19 @@ class BlurPlaybackControlsFragment :
|
|||
}
|
||||
|
||||
override fun onUpdateProgressViews(progress: Int, total: Int) {
|
||||
progressSlider.max = total
|
||||
binding.progressSlider.max = total
|
||||
|
||||
val animator = ObjectAnimator.ofInt(progressSlider, "progress", progress)
|
||||
val animator = ObjectAnimator.ofInt(binding.progressSlider, "progress", progress)
|
||||
animator.duration = SLIDER_ANIMATION_TIME
|
||||
animator.interpolator = LinearInterpolator()
|
||||
animator.start()
|
||||
|
||||
songTotalTime.text = MusicUtil.getReadableDurationString(total.toLong())
|
||||
songCurrentProgress.text = MusicUtil.getReadableDurationString(progress.toLong())
|
||||
binding.songTotalTime.text = MusicUtil.getReadableDurationString(total.toLong())
|
||||
binding.songCurrentProgress.text = MusicUtil.getReadableDurationString(progress.toLong())
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
_binding = null
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,30 +23,35 @@ import androidx.preference.PreferenceManager
|
|||
import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper
|
||||
import code.name.monkey.retromusic.NEW_BLUR_AMOUNT
|
||||
import code.name.monkey.retromusic.R
|
||||
import code.name.monkey.retromusic.databinding.FragmentBlurBinding
|
||||
import code.name.monkey.retromusic.fragments.base.AbsPlayerFragment
|
||||
import code.name.monkey.retromusic.fragments.player.PlayerAlbumCoverFragment
|
||||
import code.name.monkey.retromusic.glide.BlurTransformation
|
||||
import code.name.monkey.retromusic.glide.GlideApp
|
||||
import code.name.monkey.retromusic.glide.RetroGlideExtension
|
||||
import code.name.monkey.retromusic.glide.RetroMusicColoredTarget
|
||||
import code.name.monkey.retromusic.glide.SongGlideRequest
|
||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote
|
||||
import code.name.monkey.retromusic.model.Song
|
||||
import code.name.monkey.retromusic.util.color.MediaNotificationProcessor
|
||||
import com.bumptech.glide.Glide
|
||||
import kotlinx.android.synthetic.main.fragment_blur.*
|
||||
|
||||
class BlurPlayerFragment : AbsPlayerFragment(R.layout.fragment_blur),
|
||||
SharedPreferences.OnSharedPreferenceChangeListener {
|
||||
|
||||
override fun playerToolbar(): Toolbar {
|
||||
return playerToolbar
|
||||
return binding.playerToolbar
|
||||
}
|
||||
|
||||
private lateinit var playbackControlsFragment: BlurPlaybackControlsFragment
|
||||
|
||||
private var lastColor: Int = 0
|
||||
|
||||
private var _binding: FragmentBlurBinding? = null
|
||||
private val binding get() = _binding!!
|
||||
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
_binding = FragmentBlurBinding.bind(view)
|
||||
setUpSubFragments()
|
||||
setUpPlayerToolbar()
|
||||
}
|
||||
|
@ -60,7 +65,7 @@ class BlurPlayerFragment : AbsPlayerFragment(R.layout.fragment_blur),
|
|||
}
|
||||
|
||||
private fun setUpPlayerToolbar() {
|
||||
playerToolbar.apply {
|
||||
binding.playerToolbar.apply {
|
||||
inflateMenu(R.menu.menu_player)
|
||||
setNavigationOnClickListener { requireActivity().onBackPressed() }
|
||||
ToolbarContentTintHelper.colorizeToolbar(this, Color.WHITE, activity)
|
||||
|
@ -75,7 +80,7 @@ class BlurPlayerFragment : AbsPlayerFragment(R.layout.fragment_blur),
|
|||
playbackControlsFragment.setColor(color)
|
||||
lastColor = color.backgroundColor
|
||||
libraryViewModel.updateColor(color.backgroundColor)
|
||||
ToolbarContentTintHelper.colorizeToolbar(playerToolbar, Color.WHITE, activity)
|
||||
ToolbarContentTintHelper.colorizeToolbar(binding.playerToolbar, Color.WHITE, activity)
|
||||
}
|
||||
|
||||
override fun toggleFavorite(song: Song) {
|
||||
|
@ -105,20 +110,20 @@ class BlurPlayerFragment : AbsPlayerFragment(R.layout.fragment_blur),
|
|||
private fun updateBlur() {
|
||||
val blurAmount = PreferenceManager.getDefaultSharedPreferences(requireContext())
|
||||
.getInt(NEW_BLUR_AMOUNT, 25)
|
||||
colorBackground.clearColorFilter()
|
||||
SongGlideRequest.Builder.from(Glide.with(requireActivity()), MusicPlayerRemote.currentSong)
|
||||
.checkIgnoreMediaStore(requireContext())
|
||||
.generatePalette(requireContext()).build()
|
||||
binding.colorBackground.clearColorFilter()
|
||||
GlideApp.with(requireActivity()).asBitmapPalette()
|
||||
.songCoverOptions(MusicPlayerRemote.currentSong)
|
||||
.load(RetroGlideExtension.getSongModel(MusicPlayerRemote.currentSong))
|
||||
.dontAnimate()
|
||||
.transform(
|
||||
BlurTransformation.Builder(requireContext())
|
||||
.blurRadius(blurAmount.toFloat())
|
||||
.build()
|
||||
)
|
||||
.into(object : RetroMusicColoredTarget(colorBackground) {
|
||||
.into(object : RetroMusicColoredTarget(binding.colorBackground) {
|
||||
override fun onColorReady(colors: MediaNotificationProcessor) {
|
||||
if (colors.backgroundColor == defaultFooterColor) {
|
||||
colorBackground.setColorFilter(colors.backgroundColor)
|
||||
binding.colorBackground.setColorFilter(colors.backgroundColor)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
@ -144,6 +149,7 @@ class BlurPlayerFragment : AbsPlayerFragment(R.layout.fragment_blur),
|
|||
super.onDestroyView()
|
||||
PreferenceManager.getDefaultSharedPreferences(requireContext())
|
||||
.unregisterOnSharedPreferenceChangeListener(this)
|
||||
_binding = null
|
||||
}
|
||||
|
||||
override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences?, key: String?) {
|
||||
|
|
|
@ -20,17 +20,17 @@ import android.view.View
|
|||
import androidx.appcompat.widget.Toolbar
|
||||
import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper
|
||||
import code.name.monkey.retromusic.R
|
||||
import code.name.monkey.retromusic.databinding.FragmentCardPlayerBinding
|
||||
import code.name.monkey.retromusic.fragments.base.AbsPlayerFragment
|
||||
import code.name.monkey.retromusic.fragments.player.PlayerAlbumCoverFragment
|
||||
import code.name.monkey.retromusic.fragments.player.normal.PlayerFragment
|
||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote
|
||||
import code.name.monkey.retromusic.model.Song
|
||||
import code.name.monkey.retromusic.util.color.MediaNotificationProcessor
|
||||
import kotlinx.android.synthetic.main.fragment_card_player.*
|
||||
|
||||
class CardFragment : AbsPlayerFragment(R.layout.fragment_card_player) {
|
||||
override fun playerToolbar(): Toolbar {
|
||||
return playerToolbar
|
||||
return binding.playerToolbar
|
||||
}
|
||||
|
||||
private var lastColor: Int = 0
|
||||
|
@ -38,6 +38,9 @@ class CardFragment : AbsPlayerFragment(R.layout.fragment_card_player) {
|
|||
get() = lastColor
|
||||
|
||||
private lateinit var playbackControlsFragment: CardPlaybackControlsFragment
|
||||
private var _binding: FragmentCardPlayerBinding? = null
|
||||
private val binding get() = _binding!!
|
||||
|
||||
|
||||
override fun onShow() {
|
||||
playbackControlsFragment.show()
|
||||
|
@ -60,7 +63,7 @@ class CardFragment : AbsPlayerFragment(R.layout.fragment_card_player) {
|
|||
playbackControlsFragment.setColor(color)
|
||||
lastColor = color.primaryTextColor
|
||||
libraryViewModel.updateColor(color.primaryTextColor)
|
||||
ToolbarContentTintHelper.colorizeToolbar(playerToolbar, Color.WHITE, activity)
|
||||
ToolbarContentTintHelper.colorizeToolbar(binding.playerToolbar, Color.WHITE, activity)
|
||||
}
|
||||
|
||||
override fun toggleFavorite(song: Song) {
|
||||
|
@ -76,6 +79,7 @@ class CardFragment : AbsPlayerFragment(R.layout.fragment_card_player) {
|
|||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
_binding = FragmentCardPlayerBinding.bind(view)
|
||||
setUpSubFragments()
|
||||
setUpPlayerToolbar()
|
||||
}
|
||||
|
@ -90,11 +94,11 @@ class CardFragment : AbsPlayerFragment(R.layout.fragment_card_player) {
|
|||
}
|
||||
|
||||
private fun setUpPlayerToolbar() {
|
||||
playerToolbar.inflateMenu(R.menu.menu_player)
|
||||
playerToolbar.setNavigationOnClickListener { requireActivity().onBackPressed() }
|
||||
playerToolbar.setOnMenuItemClickListener(this)
|
||||
binding.playerToolbar.inflateMenu(R.menu.menu_player)
|
||||
binding.playerToolbar.setNavigationOnClickListener { requireActivity().onBackPressed() }
|
||||
binding.playerToolbar.setOnMenuItemClickListener(this)
|
||||
|
||||
ToolbarContentTintHelper.colorizeToolbar(playerToolbar, Color.WHITE, activity)
|
||||
ToolbarContentTintHelper.colorizeToolbar(binding.playerToolbar, Color.WHITE, activity)
|
||||
}
|
||||
|
||||
override fun onServiceConnected() {
|
||||
|
@ -105,6 +109,11 @@ class CardFragment : AbsPlayerFragment(R.layout.fragment_card_player) {
|
|||
updateIsFavorite()
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
_binding = null
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
fun newInstance(): PlayerFragment {
|
||||
|
|
|
@ -26,10 +26,13 @@ import code.name.monkey.appthemehelper.util.ColorUtil
|
|||
import code.name.monkey.appthemehelper.util.MaterialValueHelper
|
||||
import code.name.monkey.appthemehelper.util.TintHelper
|
||||
import code.name.monkey.retromusic.R
|
||||
import code.name.monkey.retromusic.databinding.FragmentCardPlayerPlaybackControlsBinding
|
||||
import code.name.monkey.retromusic.extensions.hide
|
||||
import code.name.monkey.retromusic.extensions.ripAlpha
|
||||
import code.name.monkey.retromusic.extensions.show
|
||||
import code.name.monkey.retromusic.fragments.base.AbsPlayerControlsFragment
|
||||
import code.name.monkey.retromusic.fragments.base.goToAlbum
|
||||
import code.name.monkey.retromusic.fragments.base.goToArtist
|
||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote
|
||||
import code.name.monkey.retromusic.helper.MusicProgressViewUpdateHelper
|
||||
import code.name.monkey.retromusic.helper.PlayPauseButtonOnClickHandler
|
||||
|
@ -38,8 +41,6 @@ import code.name.monkey.retromusic.service.MusicService
|
|||
import code.name.monkey.retromusic.util.MusicUtil
|
||||
import code.name.monkey.retromusic.util.PreferenceUtil
|
||||
import code.name.monkey.retromusic.util.color.MediaNotificationProcessor
|
||||
import kotlinx.android.synthetic.main.fragment_card_player_playback_controls.*
|
||||
import kotlinx.android.synthetic.main.media_button.*
|
||||
|
||||
class CardPlaybackControlsFragment :
|
||||
AbsPlayerControlsFragment(R.layout.fragment_card_player_playback_controls) {
|
||||
|
@ -47,6 +48,9 @@ class CardPlaybackControlsFragment :
|
|||
private var lastPlaybackControlsColor: Int = 0
|
||||
private var lastDisabledPlaybackControlsColor: Int = 0
|
||||
private var progressViewUpdateHelper: MusicProgressViewUpdateHelper? = null
|
||||
private var _binding: FragmentCardPlayerPlaybackControlsBinding? = null
|
||||
private val binding get() = _binding!!
|
||||
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
@ -55,30 +59,37 @@ class CardPlaybackControlsFragment :
|
|||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
_binding = FragmentCardPlayerPlaybackControlsBinding.bind(view)
|
||||
setUpMusicControllers()
|
||||
|
||||
playPauseButton.setOnClickListener {
|
||||
binding.mediaButton.playPauseButton.setOnClickListener {
|
||||
if (MusicPlayerRemote.isPlaying) {
|
||||
MusicPlayerRemote.pauseSong()
|
||||
} else {
|
||||
MusicPlayerRemote.resumePlaying()
|
||||
}
|
||||
showBonceAnimation(playPauseButton)
|
||||
showBounceAnimation(binding.mediaButton.playPauseButton)
|
||||
}
|
||||
binding.title.isSelected = true
|
||||
binding.text.isSelected = true
|
||||
binding.title.setOnClickListener {
|
||||
goToAlbum(requireActivity())
|
||||
}
|
||||
binding.text.setOnClickListener {
|
||||
goToArtist(requireActivity())
|
||||
}
|
||||
title.isSelected = true
|
||||
text.isSelected = true
|
||||
}
|
||||
|
||||
private fun updateSong() {
|
||||
val song = MusicPlayerRemote.currentSong
|
||||
title.text = song.title
|
||||
text.text = song.artistName
|
||||
binding.title.text = song.title
|
||||
binding.text.text = song.artistName
|
||||
|
||||
if (PreferenceUtil.isSongInfo) {
|
||||
songInfo.text = getSongInfo(MusicPlayerRemote.currentSong)
|
||||
songInfo.show()
|
||||
binding.songInfo.text = getSongInfo(MusicPlayerRemote.currentSong)
|
||||
binding.songInfo.show()
|
||||
} else {
|
||||
songInfo.hide()
|
||||
binding.songInfo.hide()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -139,13 +150,13 @@ class CardPlaybackControlsFragment :
|
|||
} else {
|
||||
ThemeStore.accentColor(requireContext()).ripAlpha()
|
||||
}
|
||||
image.setColorFilter(colorFinal, PorterDuff.Mode.SRC_IN)
|
||||
binding.image.setColorFilter(colorFinal, PorterDuff.Mode.SRC_IN)
|
||||
TintHelper.setTintAuto(
|
||||
playPauseButton,
|
||||
binding.mediaButton.playPauseButton,
|
||||
MaterialValueHelper.getPrimaryTextColor(context, ColorUtil.isColorLight(colorFinal)),
|
||||
false
|
||||
)
|
||||
TintHelper.setTintAuto(playPauseButton, colorFinal, true)
|
||||
TintHelper.setTintAuto(binding.mediaButton.playPauseButton, colorFinal, true)
|
||||
|
||||
volumeFragment?.setTintable(colorFinal)
|
||||
}
|
||||
|
@ -155,14 +166,14 @@ class CardPlaybackControlsFragment :
|
|||
}
|
||||
|
||||
private fun setUpPlayPauseFab() {
|
||||
playPauseButton.setOnClickListener(PlayPauseButtonOnClickHandler())
|
||||
binding.mediaButton.playPauseButton.setOnClickListener(PlayPauseButtonOnClickHandler())
|
||||
}
|
||||
|
||||
private fun updatePlayPauseDrawableState() {
|
||||
if (MusicPlayerRemote.isPlaying) {
|
||||
playPauseButton.setImageResource(R.drawable.ic_pause)
|
||||
binding.mediaButton.playPauseButton.setImageResource(R.drawable.ic_pause)
|
||||
} else {
|
||||
playPauseButton.setImageResource(R.drawable.ic_play_arrow_white_32dp)
|
||||
binding.mediaButton.playPauseButton.setImageResource(R.drawable.ic_play_arrow_white_32dp)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -176,26 +187,32 @@ class CardPlaybackControlsFragment :
|
|||
|
||||
private fun setUpPrevNext() {
|
||||
updatePrevNextColor()
|
||||
nextButton.setOnClickListener { MusicPlayerRemote.playNextSong() }
|
||||
previousButton.setOnClickListener { MusicPlayerRemote.back() }
|
||||
binding.mediaButton.nextButton.setOnClickListener { MusicPlayerRemote.playNextSong() }
|
||||
binding.mediaButton.previousButton.setOnClickListener { MusicPlayerRemote.back() }
|
||||
}
|
||||
|
||||
private fun updatePrevNextColor() {
|
||||
nextButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
|
||||
previousButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
|
||||
binding.mediaButton.nextButton.setColorFilter(
|
||||
lastPlaybackControlsColor,
|
||||
PorterDuff.Mode.SRC_IN
|
||||
)
|
||||
binding.mediaButton.previousButton.setColorFilter(
|
||||
lastPlaybackControlsColor,
|
||||
PorterDuff.Mode.SRC_IN
|
||||
)
|
||||
}
|
||||
|
||||
private fun setUpShuffleButton() {
|
||||
shuffleButton.setOnClickListener { MusicPlayerRemote.toggleShuffleMode() }
|
||||
binding.mediaButton.shuffleButton.setOnClickListener { MusicPlayerRemote.toggleShuffleMode() }
|
||||
}
|
||||
|
||||
override fun updateShuffleState() {
|
||||
when (MusicPlayerRemote.shuffleMode) {
|
||||
MusicService.SHUFFLE_MODE_SHUFFLE -> shuffleButton.setColorFilter(
|
||||
MusicService.SHUFFLE_MODE_SHUFFLE -> binding.mediaButton.shuffleButton.setColorFilter(
|
||||
lastPlaybackControlsColor,
|
||||
PorterDuff.Mode.SRC_IN
|
||||
)
|
||||
else -> shuffleButton.setColorFilter(
|
||||
else -> binding.mediaButton.shuffleButton.setColorFilter(
|
||||
lastDisabledPlaybackControlsColor,
|
||||
PorterDuff.Mode.SRC_IN
|
||||
)
|
||||
|
@ -203,45 +220,51 @@ class CardPlaybackControlsFragment :
|
|||
}
|
||||
|
||||
private fun setUpRepeatButton() {
|
||||
repeatButton.setOnClickListener { MusicPlayerRemote.cycleRepeatMode() }
|
||||
binding.mediaButton.repeatButton.setOnClickListener { MusicPlayerRemote.cycleRepeatMode() }
|
||||
}
|
||||
|
||||
override fun updateRepeatState() {
|
||||
when (MusicPlayerRemote.repeatMode) {
|
||||
MusicService.REPEAT_MODE_NONE -> {
|
||||
repeatButton.setImageResource(R.drawable.ic_repeat)
|
||||
repeatButton.setColorFilter(
|
||||
binding.mediaButton.repeatButton.setImageResource(R.drawable.ic_repeat)
|
||||
binding.mediaButton.repeatButton.setColorFilter(
|
||||
lastDisabledPlaybackControlsColor,
|
||||
PorterDuff.Mode.SRC_IN
|
||||
)
|
||||
}
|
||||
MusicService.REPEAT_MODE_ALL -> {
|
||||
repeatButton.setImageResource(R.drawable.ic_repeat)
|
||||
repeatButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
|
||||
binding.mediaButton.repeatButton.setImageResource(R.drawable.ic_repeat)
|
||||
binding.mediaButton.repeatButton.setColorFilter(
|
||||
lastPlaybackControlsColor,
|
||||
PorterDuff.Mode.SRC_IN
|
||||
)
|
||||
}
|
||||
MusicService.REPEAT_MODE_THIS -> {
|
||||
repeatButton.setImageResource(R.drawable.ic_repeat_one)
|
||||
repeatButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
|
||||
binding.mediaButton.repeatButton.setImageResource(R.drawable.ic_repeat_one)
|
||||
binding.mediaButton.repeatButton.setColorFilter(
|
||||
lastPlaybackControlsColor,
|
||||
PorterDuff.Mode.SRC_IN
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onUpdateProgressViews(progress: Int, total: Int) {
|
||||
progressSlider.max = total
|
||||
binding.progressSlider.max = total
|
||||
|
||||
val animator = ObjectAnimator.ofInt(progressSlider, "progress", progress)
|
||||
val animator = ObjectAnimator.ofInt(binding.progressSlider, "progress", progress)
|
||||
animator.duration = SLIDER_ANIMATION_TIME
|
||||
animator.interpolator = LinearInterpolator()
|
||||
animator.start()
|
||||
|
||||
songTotalTime.text = MusicUtil.getReadableDurationString(total.toLong())
|
||||
songCurrentProgress.text = MusicUtil.getReadableDurationString(progress.toLong())
|
||||
binding.songTotalTime.text = MusicUtil.getReadableDurationString(total.toLong())
|
||||
binding.songCurrentProgress.text = MusicUtil.getReadableDurationString(progress.toLong())
|
||||
}
|
||||
|
||||
private fun updateProgressTextColor() {
|
||||
val color = MaterialValueHelper.getPrimaryTextColor(context, false)
|
||||
songTotalTime!!.setTextColor(color)
|
||||
songCurrentProgress!!.setTextColor(color)
|
||||
binding.songTotalTime.setTextColor(color)
|
||||
binding.songCurrentProgress.setTextColor(color)
|
||||
}
|
||||
|
||||
public override fun show() {
|
||||
|
@ -253,7 +276,7 @@ class CardPlaybackControlsFragment :
|
|||
}
|
||||
|
||||
override fun setUpProgressSlider() {
|
||||
progressSlider.setOnSeekBarChangeListener(object : SimpleOnSeekbarChangeListener() {
|
||||
binding.progressSlider.setOnSeekBarChangeListener(object : SimpleOnSeekbarChangeListener() {
|
||||
override fun onProgressChanged(seekBar: SeekBar, progress: Int, fromUser: Boolean) {
|
||||
if (fromUser) {
|
||||
MusicPlayerRemote.seekTo(progress)
|
||||
|
@ -265,4 +288,10 @@ class CardPlaybackControlsFragment :
|
|||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
_binding = null
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,22 +23,22 @@ import androidx.preference.PreferenceManager
|
|||
import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper
|
||||
import code.name.monkey.retromusic.NEW_BLUR_AMOUNT
|
||||
import code.name.monkey.retromusic.R
|
||||
import code.name.monkey.retromusic.databinding.FragmentCardBlurPlayerBinding
|
||||
import code.name.monkey.retromusic.fragments.base.AbsPlayerFragment
|
||||
import code.name.monkey.retromusic.fragments.player.PlayerAlbumCoverFragment
|
||||
import code.name.monkey.retromusic.fragments.player.normal.PlayerFragment
|
||||
import code.name.monkey.retromusic.glide.BlurTransformation
|
||||
import code.name.monkey.retromusic.glide.GlideApp
|
||||
import code.name.monkey.retromusic.glide.RetroGlideExtension
|
||||
import code.name.monkey.retromusic.glide.RetroMusicColoredTarget
|
||||
import code.name.monkey.retromusic.glide.SongGlideRequest
|
||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote
|
||||
import code.name.monkey.retromusic.model.Song
|
||||
import code.name.monkey.retromusic.util.color.MediaNotificationProcessor
|
||||
import com.bumptech.glide.Glide
|
||||
import kotlinx.android.synthetic.main.fragment_card_blur_player.*
|
||||
|
||||
class CardBlurFragment : AbsPlayerFragment(R.layout.fragment_card_blur_player),
|
||||
SharedPreferences.OnSharedPreferenceChangeListener {
|
||||
override fun playerToolbar(): Toolbar {
|
||||
return playerToolbar
|
||||
return binding.playerToolbar
|
||||
}
|
||||
|
||||
private var lastColor: Int = 0
|
||||
|
@ -46,6 +46,9 @@ class CardBlurFragment : AbsPlayerFragment(R.layout.fragment_card_blur_player),
|
|||
get() = lastColor
|
||||
private lateinit var playbackControlsFragment: CardBlurPlaybackControlsFragment
|
||||
|
||||
private var _binding: FragmentCardBlurPlayerBinding? = null
|
||||
private val binding get() = _binding!!
|
||||
|
||||
override fun onShow() {
|
||||
playbackControlsFragment.show()
|
||||
}
|
||||
|
@ -67,10 +70,10 @@ class CardBlurFragment : AbsPlayerFragment(R.layout.fragment_card_blur_player),
|
|||
playbackControlsFragment.setColor(color)
|
||||
lastColor = color.backgroundColor
|
||||
libraryViewModel.updateColor(color.backgroundColor)
|
||||
ToolbarContentTintHelper.colorizeToolbar(playerToolbar, Color.WHITE, activity)
|
||||
ToolbarContentTintHelper.colorizeToolbar(binding.playerToolbar, Color.WHITE, activity)
|
||||
|
||||
playerToolbar.setTitleTextColor(Color.WHITE)
|
||||
playerToolbar.setSubtitleTextColor(Color.WHITE)
|
||||
binding.playerToolbar.setTitleTextColor(Color.WHITE)
|
||||
binding.playerToolbar.setSubtitleTextColor(Color.WHITE)
|
||||
}
|
||||
|
||||
override fun toggleFavorite(song: Song) {
|
||||
|
@ -86,6 +89,7 @@ class CardBlurFragment : AbsPlayerFragment(R.layout.fragment_card_blur_player),
|
|||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
_binding = FragmentCardBlurPlayerBinding.bind(view)
|
||||
setUpSubFragments()
|
||||
setUpPlayerToolbar()
|
||||
}
|
||||
|
@ -99,12 +103,12 @@ class CardBlurFragment : AbsPlayerFragment(R.layout.fragment_card_blur_player),
|
|||
}
|
||||
|
||||
private fun setUpPlayerToolbar() {
|
||||
playerToolbar.apply {
|
||||
binding.playerToolbar.apply {
|
||||
inflateMenu(R.menu.menu_player)
|
||||
setNavigationOnClickListener { requireActivity().onBackPressed() }
|
||||
setTitleTextColor(Color.WHITE)
|
||||
setSubtitleTextColor(Color.WHITE)
|
||||
ToolbarContentTintHelper.colorizeToolbar(playerToolbar, Color.WHITE, activity)
|
||||
ToolbarContentTintHelper.colorizeToolbar(binding.playerToolbar, Color.WHITE, activity)
|
||||
}.setOnMenuItemClickListener(this)
|
||||
}
|
||||
|
||||
|
@ -122,7 +126,7 @@ class CardBlurFragment : AbsPlayerFragment(R.layout.fragment_card_blur_player),
|
|||
|
||||
private fun updateSong() {
|
||||
val song = MusicPlayerRemote.currentSong
|
||||
playerToolbar.apply {
|
||||
binding.playerToolbar.apply {
|
||||
title = song.title
|
||||
subtitle = song.artistName
|
||||
}
|
||||
|
@ -131,19 +135,19 @@ class CardBlurFragment : AbsPlayerFragment(R.layout.fragment_card_blur_player),
|
|||
private fun updateBlur() {
|
||||
val blurAmount = PreferenceManager.getDefaultSharedPreferences(requireContext())
|
||||
.getInt(NEW_BLUR_AMOUNT, 25)
|
||||
colorBackground!!.clearColorFilter()
|
||||
SongGlideRequest.Builder.from(Glide.with(requireActivity()), MusicPlayerRemote.currentSong)
|
||||
.checkIgnoreMediaStore(requireContext())
|
||||
.generatePalette(requireContext()).build()
|
||||
binding.colorBackground.clearColorFilter()
|
||||
GlideApp.with(requireActivity()).asBitmapPalette()
|
||||
.songCoverOptions(MusicPlayerRemote.currentSong)
|
||||
.load(RetroGlideExtension.getSongModel(MusicPlayerRemote.currentSong))
|
||||
.dontAnimate()
|
||||
.transform(
|
||||
BlurTransformation.Builder(requireContext()).blurRadius(blurAmount.toFloat())
|
||||
.build()
|
||||
)
|
||||
.into(object : RetroMusicColoredTarget(colorBackground) {
|
||||
.into(object : RetroMusicColoredTarget(binding.colorBackground) {
|
||||
override fun onColorReady(colors: MediaNotificationProcessor) {
|
||||
if (colors.backgroundColor == defaultFooterColor) {
|
||||
colorBackground.setColorFilter(colors.backgroundColor)
|
||||
binding.colorBackground.setColorFilter(colors.backgroundColor)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
@ -159,6 +163,7 @@ class CardBlurFragment : AbsPlayerFragment(R.layout.fragment_card_blur_player),
|
|||
super.onDestroyView()
|
||||
PreferenceManager.getDefaultSharedPreferences(requireContext())
|
||||
.unregisterOnSharedPreferenceChangeListener(this)
|
||||
_binding = null
|
||||
}
|
||||
|
||||
override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences?, key: String?) {
|
||||
|
|
|
@ -25,6 +25,7 @@ import android.widget.SeekBar
|
|||
import code.name.monkey.appthemehelper.util.ColorUtil
|
||||
import code.name.monkey.appthemehelper.util.TintHelper
|
||||
import code.name.monkey.retromusic.R
|
||||
import code.name.monkey.retromusic.databinding.FragmentCardBlurPlayerPlaybackControlsBinding
|
||||
import code.name.monkey.retromusic.extensions.applyColor
|
||||
import code.name.monkey.retromusic.extensions.hide
|
||||
import code.name.monkey.retromusic.extensions.show
|
||||
|
@ -37,8 +38,6 @@ import code.name.monkey.retromusic.service.MusicService
|
|||
import code.name.monkey.retromusic.util.MusicUtil
|
||||
import code.name.monkey.retromusic.util.PreferenceUtil
|
||||
import code.name.monkey.retromusic.util.color.MediaNotificationProcessor
|
||||
import kotlinx.android.synthetic.main.fragment_card_blur_player_playback_controls.*
|
||||
import kotlinx.android.synthetic.main.media_button.*
|
||||
|
||||
class CardBlurPlaybackControlsFragment :
|
||||
AbsPlayerControlsFragment(R.layout.fragment_card_blur_player_playback_controls) {
|
||||
|
@ -47,6 +46,10 @@ class CardBlurPlaybackControlsFragment :
|
|||
private var lastDisabledPlaybackControlsColor: Int = 0
|
||||
private lateinit var progressViewUpdateHelper: MusicProgressViewUpdateHelper
|
||||
|
||||
private var _binding: FragmentCardBlurPlayerPlaybackControlsBinding? = null
|
||||
private val binding get() = _binding!!
|
||||
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
progressViewUpdateHelper = MusicProgressViewUpdateHelper(this)
|
||||
|
@ -54,6 +57,7 @@ class CardBlurPlaybackControlsFragment :
|
|||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
_binding = FragmentCardBlurPlayerPlaybackControlsBinding.bind(view)
|
||||
setUpMusicControllers()
|
||||
}
|
||||
|
||||
|
@ -70,7 +74,7 @@ class CardBlurPlaybackControlsFragment :
|
|||
}
|
||||
|
||||
private fun setUpPlayPauseFab() {
|
||||
playPauseButton.apply {
|
||||
binding.mediaButton.playPauseButton.apply {
|
||||
TintHelper.setTintAuto(this, Color.WHITE, true)
|
||||
TintHelper.setTintAuto(this, Color.BLACK, false)
|
||||
setOnClickListener(PlayPauseButtonOnClickHandler())
|
||||
|
@ -79,16 +83,16 @@ class CardBlurPlaybackControlsFragment :
|
|||
|
||||
private fun updatePlayPauseDrawableState() {
|
||||
when {
|
||||
MusicPlayerRemote.isPlaying -> playPauseButton.setImageResource(R.drawable.ic_pause)
|
||||
else -> playPauseButton.setImageResource(R.drawable.ic_play_arrow_white_32dp)
|
||||
MusicPlayerRemote.isPlaying -> binding.mediaButton.playPauseButton.setImageResource(R.drawable.ic_pause)
|
||||
else -> binding.mediaButton.playPauseButton.setImageResource(R.drawable.ic_play_arrow_white_32dp)
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateProgressTextColor() {
|
||||
val color = Color.WHITE
|
||||
songTotalTime.setTextColor(color)
|
||||
songCurrentProgress.setTextColor(color)
|
||||
songInfo.setTextColor(color)
|
||||
binding.songTotalTime.setTextColor(color)
|
||||
binding.songCurrentProgress.setTextColor(color)
|
||||
binding.songInfo.setTextColor(color)
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
|
@ -115,10 +119,10 @@ class CardBlurPlaybackControlsFragment :
|
|||
|
||||
private fun updateSong() {
|
||||
if (PreferenceUtil.isSongInfo) {
|
||||
songInfo.text = getSongInfo(MusicPlayerRemote.currentSong)
|
||||
songInfo.show()
|
||||
binding.songInfo.text = getSongInfo(MusicPlayerRemote.currentSong)
|
||||
binding.songInfo.show()
|
||||
} else {
|
||||
songInfo.hide()
|
||||
binding.songInfo.hide()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -144,26 +148,32 @@ class CardBlurPlaybackControlsFragment :
|
|||
|
||||
private fun setUpPrevNext() {
|
||||
updatePrevNextColor()
|
||||
nextButton.setOnClickListener { MusicPlayerRemote.playNextSong() }
|
||||
previousButton.setOnClickListener { MusicPlayerRemote.back() }
|
||||
binding.mediaButton.nextButton.setOnClickListener { MusicPlayerRemote.playNextSong() }
|
||||
binding.mediaButton.previousButton.setOnClickListener { MusicPlayerRemote.back() }
|
||||
}
|
||||
|
||||
private fun updatePrevNextColor() {
|
||||
nextButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
|
||||
previousButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
|
||||
binding.mediaButton.nextButton.setColorFilter(
|
||||
lastPlaybackControlsColor,
|
||||
PorterDuff.Mode.SRC_IN
|
||||
)
|
||||
binding.mediaButton.previousButton.setColorFilter(
|
||||
lastPlaybackControlsColor,
|
||||
PorterDuff.Mode.SRC_IN
|
||||
)
|
||||
}
|
||||
|
||||
private fun setUpShuffleButton() {
|
||||
shuffleButton.setOnClickListener { MusicPlayerRemote.toggleShuffleMode() }
|
||||
binding.mediaButton.shuffleButton.setOnClickListener { MusicPlayerRemote.toggleShuffleMode() }
|
||||
}
|
||||
|
||||
override fun updateShuffleState() {
|
||||
when (MusicPlayerRemote.shuffleMode) {
|
||||
MusicService.SHUFFLE_MODE_SHUFFLE -> shuffleButton.setColorFilter(
|
||||
MusicService.SHUFFLE_MODE_SHUFFLE -> binding.mediaButton.shuffleButton.setColorFilter(
|
||||
lastPlaybackControlsColor,
|
||||
PorterDuff.Mode.SRC_IN
|
||||
)
|
||||
else -> shuffleButton.setColorFilter(
|
||||
else -> binding.mediaButton.shuffleButton.setColorFilter(
|
||||
lastDisabledPlaybackControlsColor,
|
||||
PorterDuff.Mode.SRC_IN
|
||||
)
|
||||
|
@ -171,31 +181,37 @@ class CardBlurPlaybackControlsFragment :
|
|||
}
|
||||
|
||||
private fun setUpRepeatButton() {
|
||||
repeatButton.setOnClickListener { MusicPlayerRemote.cycleRepeatMode() }
|
||||
binding.mediaButton.repeatButton.setOnClickListener { MusicPlayerRemote.cycleRepeatMode() }
|
||||
}
|
||||
|
||||
override fun updateRepeatState() {
|
||||
when (MusicPlayerRemote.repeatMode) {
|
||||
MusicService.REPEAT_MODE_NONE -> {
|
||||
repeatButton.setImageResource(R.drawable.ic_repeat)
|
||||
repeatButton.setColorFilter(
|
||||
binding.mediaButton.repeatButton.setImageResource(R.drawable.ic_repeat)
|
||||
binding.mediaButton.repeatButton.setColorFilter(
|
||||
lastDisabledPlaybackControlsColor,
|
||||
PorterDuff.Mode.SRC_IN
|
||||
)
|
||||
}
|
||||
MusicService.REPEAT_MODE_ALL -> {
|
||||
repeatButton.setImageResource(R.drawable.ic_repeat)
|
||||
repeatButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
|
||||
binding.mediaButton.repeatButton.setImageResource(R.drawable.ic_repeat)
|
||||
binding.mediaButton.repeatButton.setColorFilter(
|
||||
lastPlaybackControlsColor,
|
||||
PorterDuff.Mode.SRC_IN
|
||||
)
|
||||
}
|
||||
MusicService.REPEAT_MODE_THIS -> {
|
||||
repeatButton.setImageResource(R.drawable.ic_repeat_one)
|
||||
repeatButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
|
||||
binding.mediaButton.repeatButton.setImageResource(R.drawable.ic_repeat_one)
|
||||
binding.mediaButton.repeatButton.setColorFilter(
|
||||
lastPlaybackControlsColor,
|
||||
PorterDuff.Mode.SRC_IN
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override fun show() {
|
||||
playPauseButton!!.animate()
|
||||
binding.mediaButton.playPauseButton.animate()
|
||||
.scaleX(1f)
|
||||
.scaleY(1f)
|
||||
.rotation(360f)
|
||||
|
@ -204,18 +220,16 @@ class CardBlurPlaybackControlsFragment :
|
|||
}
|
||||
|
||||
public override fun hide() {
|
||||
if (playPauseButton != null) {
|
||||
playPauseButton!!.apply {
|
||||
scaleX = 0f
|
||||
scaleY = 0f
|
||||
rotation = 0f
|
||||
}
|
||||
binding.mediaButton.playPauseButton.apply {
|
||||
scaleX = 0f
|
||||
scaleY = 0f
|
||||
rotation = 0f
|
||||
}
|
||||
}
|
||||
|
||||
override fun setUpProgressSlider() {
|
||||
progressSlider.applyColor(Color.WHITE)
|
||||
progressSlider.setOnSeekBarChangeListener(object : SimpleOnSeekbarChangeListener() {
|
||||
binding.progressSlider.applyColor(Color.WHITE)
|
||||
binding.progressSlider.setOnSeekBarChangeListener(object : SimpleOnSeekbarChangeListener() {
|
||||
override fun onProgressChanged(seekBar: SeekBar, progress: Int, fromUser: Boolean) {
|
||||
if (fromUser) {
|
||||
MusicPlayerRemote.seekTo(progress)
|
||||
|
@ -229,14 +243,19 @@ class CardBlurPlaybackControlsFragment :
|
|||
}
|
||||
|
||||
override fun onUpdateProgressViews(progress: Int, total: Int) {
|
||||
progressSlider.max = total
|
||||
binding.progressSlider.max = total
|
||||
|
||||
val animator = ObjectAnimator.ofInt(progressSlider, "progress", progress)
|
||||
val animator = ObjectAnimator.ofInt(binding.progressSlider, "progress", progress)
|
||||
animator.duration = SLIDER_ANIMATION_TIME
|
||||
animator.interpolator = LinearInterpolator()
|
||||
animator.start()
|
||||
|
||||
songTotalTime.text = MusicUtil.getReadableDurationString(total.toLong())
|
||||
songCurrentProgress.text = MusicUtil.getReadableDurationString(progress.toLong())
|
||||
binding.songTotalTime.text = MusicUtil.getReadableDurationString(total.toLong())
|
||||
binding.songCurrentProgress.text = MusicUtil.getReadableDurationString(progress.toLong())
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
_binding = null
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,12 +32,15 @@ import code.name.monkey.appthemehelper.util.ColorUtil
|
|||
import code.name.monkey.appthemehelper.util.TintHelper
|
||||
import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper
|
||||
import code.name.monkey.retromusic.R
|
||||
import code.name.monkey.retromusic.databinding.FragmentCirclePlayerBinding
|
||||
import code.name.monkey.retromusic.extensions.accentColor
|
||||
import code.name.monkey.retromusic.extensions.applyColor
|
||||
import code.name.monkey.retromusic.extensions.hide
|
||||
import code.name.monkey.retromusic.extensions.show
|
||||
import code.name.monkey.retromusic.fragments.base.AbsPlayerControlsFragment
|
||||
import code.name.monkey.retromusic.fragments.base.AbsPlayerFragment
|
||||
import code.name.monkey.retromusic.fragments.base.goToAlbum
|
||||
import code.name.monkey.retromusic.fragments.base.goToArtist
|
||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote
|
||||
import code.name.monkey.retromusic.helper.MusicProgressViewUpdateHelper
|
||||
import code.name.monkey.retromusic.helper.MusicProgressViewUpdateHelper.Callback
|
||||
|
@ -51,7 +54,6 @@ import code.name.monkey.retromusic.views.SeekArc
|
|||
import code.name.monkey.retromusic.views.SeekArc.OnSeekArcChangeListener
|
||||
import code.name.monkey.retromusic.volume.AudioVolumeObserver
|
||||
import code.name.monkey.retromusic.volume.OnAudioVolumeChangedListener
|
||||
import kotlinx.android.synthetic.main.fragment_circle_player.*
|
||||
|
||||
/**
|
||||
* Created by hemanths on 2020-01-06.
|
||||
|
@ -67,6 +69,9 @@ class CirclePlayerFragment : AbsPlayerFragment(R.layout.fragment_circle_player),
|
|||
private val audioManager: AudioManager?
|
||||
get() = requireContext().getSystemService(Context.AUDIO_SERVICE) as AudioManager
|
||||
|
||||
private var _binding: FragmentCirclePlayerBinding? = null
|
||||
private val binding get() = _binding!!
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
progressViewUpdateHelper = MusicProgressViewUpdateHelper(this)
|
||||
|
@ -76,18 +81,25 @@ class CirclePlayerFragment : AbsPlayerFragment(R.layout.fragment_circle_player),
|
|||
inflater: LayoutInflater,
|
||||
container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View? {
|
||||
return inflater.inflate(R.layout.fragment_circle_player, container, false)
|
||||
): View {
|
||||
_binding = FragmentCirclePlayerBinding.inflate(inflater, container, false)
|
||||
return binding.root
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
setupViews()
|
||||
title.isSelected = true
|
||||
binding.title.isSelected = true
|
||||
binding.title.setOnClickListener {
|
||||
goToAlbum(requireActivity())
|
||||
}
|
||||
binding.text.setOnClickListener {
|
||||
goToArtist(requireActivity())
|
||||
}
|
||||
}
|
||||
|
||||
private fun setUpPlayerToolbar() {
|
||||
playerToolbar.apply {
|
||||
binding.playerToolbar.apply {
|
||||
inflateMenu(R.menu.menu_player)
|
||||
setNavigationOnClickListener { requireActivity().onBackPressed() }
|
||||
setOnMenuItemClickListener(this@CirclePlayerFragment)
|
||||
|
@ -102,12 +114,12 @@ class CirclePlayerFragment : AbsPlayerFragment(R.layout.fragment_circle_player),
|
|||
private fun setupViews() {
|
||||
setUpProgressSlider()
|
||||
ViewUtil.setProgressDrawable(
|
||||
progressSlider,
|
||||
binding.progressSlider,
|
||||
ThemeStore.accentColor(requireContext()),
|
||||
false
|
||||
)
|
||||
volumeSeekBar.progressColor = accentColor()
|
||||
volumeSeekBar.arcColor = ColorUtil.withAlpha(accentColor(), 0.25f)
|
||||
binding.volumeSeekBar.progressColor = accentColor()
|
||||
binding.volumeSeekBar.arcColor = ColorUtil.withAlpha(accentColor(), 0.25f)
|
||||
setUpPlayPauseFab()
|
||||
setUpPrevNext()
|
||||
setUpPlayerToolbar()
|
||||
|
@ -115,19 +127,23 @@ class CirclePlayerFragment : AbsPlayerFragment(R.layout.fragment_circle_player),
|
|||
|
||||
private fun setUpPrevNext() {
|
||||
updatePrevNextColor()
|
||||
nextButton.setOnClickListener { MusicPlayerRemote.playNextSong() }
|
||||
previousButton.setOnClickListener { MusicPlayerRemote.back() }
|
||||
binding.nextButton.setOnClickListener { MusicPlayerRemote.playNextSong() }
|
||||
binding.previousButton.setOnClickListener { MusicPlayerRemote.back() }
|
||||
}
|
||||
|
||||
private fun updatePrevNextColor() {
|
||||
val accentColor = ThemeStore.accentColor(requireContext())
|
||||
nextButton.setColorFilter(accentColor, PorterDuff.Mode.SRC_IN)
|
||||
previousButton.setColorFilter(accentColor, PorterDuff.Mode.SRC_IN)
|
||||
binding.nextButton.setColorFilter(accentColor, PorterDuff.Mode.SRC_IN)
|
||||
binding.previousButton.setColorFilter(accentColor, PorterDuff.Mode.SRC_IN)
|
||||
}
|
||||
|
||||
private fun setUpPlayPauseFab() {
|
||||
TintHelper.setTintAuto(playPauseButton, ThemeStore.accentColor(requireContext()), false)
|
||||
playPauseButton.setOnClickListener(PlayPauseButtonOnClickHandler())
|
||||
TintHelper.setTintAuto(
|
||||
binding.playPauseButton,
|
||||
ThemeStore.accentColor(requireContext()),
|
||||
false
|
||||
)
|
||||
binding.playPauseButton.setOnClickListener(PlayPauseButtonOnClickHandler())
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
|
@ -140,10 +156,10 @@ class CirclePlayerFragment : AbsPlayerFragment(R.layout.fragment_circle_player),
|
|||
|
||||
val audioManager = audioManager
|
||||
if (audioManager != null) {
|
||||
volumeSeekBar.max = audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC)
|
||||
volumeSeekBar.progress = audioManager.getStreamVolume(AudioManager.STREAM_MUSIC)
|
||||
binding.volumeSeekBar.max = audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC)
|
||||
binding.volumeSeekBar.progress = audioManager.getStreamVolume(AudioManager.STREAM_MUSIC)
|
||||
}
|
||||
volumeSeekBar.setOnSeekArcChangeListener(this)
|
||||
binding.volumeSeekBar.setOnSeekArcChangeListener(this)
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
|
@ -151,8 +167,8 @@ class CirclePlayerFragment : AbsPlayerFragment(R.layout.fragment_circle_player),
|
|||
progressViewUpdateHelper.stop()
|
||||
}
|
||||
|
||||
override fun playerToolbar(): Toolbar? {
|
||||
return playerToolbar
|
||||
override fun playerToolbar(): Toolbar {
|
||||
return binding.playerToolbar
|
||||
}
|
||||
|
||||
override fun onShow() {
|
||||
|
@ -192,30 +208,27 @@ class CirclePlayerFragment : AbsPlayerFragment(R.layout.fragment_circle_player),
|
|||
|
||||
private fun updateSong() {
|
||||
val song = MusicPlayerRemote.currentSong
|
||||
title.text = song.title
|
||||
text.text = song.artistName
|
||||
binding.title.text = song.title
|
||||
binding.text.text = song.artistName
|
||||
|
||||
if (PreferenceUtil.isSongInfo) {
|
||||
songInfo.text = getSongInfo(song)
|
||||
songInfo.show()
|
||||
binding.songInfo.text = getSongInfo(song)
|
||||
binding.songInfo.show()
|
||||
} else {
|
||||
songInfo.hide()
|
||||
binding.songInfo.hide()
|
||||
}
|
||||
}
|
||||
|
||||
private fun updatePlayPauseDrawableState() {
|
||||
when {
|
||||
MusicPlayerRemote.isPlaying -> playPauseButton.setImageResource(R.drawable.ic_pause)
|
||||
else -> playPauseButton.setImageResource(R.drawable.ic_play_arrow)
|
||||
MusicPlayerRemote.isPlaying -> binding.playPauseButton.setImageResource(R.drawable.ic_pause)
|
||||
else -> binding.playPauseButton.setImageResource(R.drawable.ic_play_arrow)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onAudioVolumeChanged(currentVolume: Int, maxVolume: Int) {
|
||||
if (volumeSeekBar == null) {
|
||||
return
|
||||
}
|
||||
volumeSeekBar.max = maxVolume
|
||||
volumeSeekBar.progress = currentVolume
|
||||
_binding?.volumeSeekBar?.max = maxVolume
|
||||
_binding?.volumeSeekBar?.progress = currentVolume
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
|
@ -223,6 +236,7 @@ class CirclePlayerFragment : AbsPlayerFragment(R.layout.fragment_circle_player),
|
|||
if (audioVolumeObserver != null) {
|
||||
audioVolumeObserver!!.unregister()
|
||||
}
|
||||
_binding = null
|
||||
}
|
||||
|
||||
override fun onProgressChanged(seekArc: SeekArc?, progress: Int, fromUser: Boolean) {
|
||||
|
@ -237,8 +251,8 @@ class CirclePlayerFragment : AbsPlayerFragment(R.layout.fragment_circle_player),
|
|||
}
|
||||
|
||||
fun setUpProgressSlider() {
|
||||
progressSlider.applyColor(accentColor())
|
||||
progressSlider.setOnSeekBarChangeListener(object : SimpleOnSeekbarChangeListener() {
|
||||
binding.progressSlider.applyColor(accentColor())
|
||||
binding.progressSlider.setOnSeekBarChangeListener(object : SimpleOnSeekbarChangeListener() {
|
||||
override fun onProgressChanged(seekBar: SeekBar, progress: Int, fromUser: Boolean) {
|
||||
if (fromUser) {
|
||||
MusicPlayerRemote.seekTo(progress)
|
||||
|
@ -252,14 +266,14 @@ class CirclePlayerFragment : AbsPlayerFragment(R.layout.fragment_circle_player),
|
|||
}
|
||||
|
||||
override fun onUpdateProgressViews(progress: Int, total: Int) {
|
||||
progressSlider.max = total
|
||||
binding.progressSlider.max = total
|
||||
|
||||
val animator = ObjectAnimator.ofInt(progressSlider, "progress", progress)
|
||||
val animator = ObjectAnimator.ofInt(binding.progressSlider, "progress", progress)
|
||||
animator.duration = AbsPlayerControlsFragment.SLIDER_ANIMATION_TIME
|
||||
animator.interpolator = LinearInterpolator()
|
||||
animator.start()
|
||||
|
||||
songTotalTime.text = MusicUtil.getReadableDurationString(total.toLong())
|
||||
songCurrentProgress.text = MusicUtil.getReadableDurationString(progress.toLong())
|
||||
binding.songTotalTime.text = MusicUtil.getReadableDurationString(total.toLong())
|
||||
binding.songCurrentProgress.text = MusicUtil.getReadableDurationString(progress.toLong())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,11 +35,14 @@ import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper
|
|||
import code.name.monkey.retromusic.R
|
||||
import code.name.monkey.retromusic.RetroBottomSheetBehavior
|
||||
import code.name.monkey.retromusic.adapter.song.PlayingQueueAdapter
|
||||
import code.name.monkey.retromusic.databinding.FragmentClassicPlayerBinding
|
||||
import code.name.monkey.retromusic.extensions.hide
|
||||
import code.name.monkey.retromusic.extensions.show
|
||||
import code.name.monkey.retromusic.fragments.VolumeFragment
|
||||
import code.name.monkey.retromusic.fragments.base.AbsPlayerControlsFragment
|
||||
import code.name.monkey.retromusic.fragments.base.AbsPlayerFragment
|
||||
import code.name.monkey.retromusic.fragments.base.goToAlbum
|
||||
import code.name.monkey.retromusic.fragments.base.goToArtist
|
||||
import code.name.monkey.retromusic.fragments.player.PlayerAlbumCoverFragment
|
||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote
|
||||
import code.name.monkey.retromusic.helper.MusicProgressViewUpdateHelper
|
||||
|
@ -60,13 +63,14 @@ import com.h6ah4i.android.widget.advrecyclerview.draggable.RecyclerViewDragDropM
|
|||
import com.h6ah4i.android.widget.advrecyclerview.swipeable.RecyclerViewSwipeManager
|
||||
import com.h6ah4i.android.widget.advrecyclerview.touchguard.RecyclerViewTouchActionGuardManager
|
||||
import com.h6ah4i.android.widget.advrecyclerview.utils.WrapperAdapterUtils
|
||||
import kotlinx.android.synthetic.main.fragment_classic_controls.*
|
||||
import kotlinx.android.synthetic.main.fragment_classic_player.*
|
||||
|
||||
class ClassicPlayerFragment : AbsPlayerFragment(R.layout.fragment_classic_player),
|
||||
View.OnLayoutChangeListener,
|
||||
MusicProgressViewUpdateHelper.Callback {
|
||||
|
||||
private var _binding: FragmentClassicPlayerBinding? = null
|
||||
private val binding get() = _binding!!
|
||||
|
||||
private var lastColor: Int = 0
|
||||
private var lastPlaybackControlsColor: Int = 0
|
||||
private var lastDisabledPlaybackControlsColor: Int = 0
|
||||
|
@ -83,11 +87,11 @@ class ClassicPlayerFragment : AbsPlayerFragment(R.layout.fragment_classic_player
|
|||
private val bottomSheetCallbackList = object : BottomSheetBehavior.BottomSheetCallback() {
|
||||
override fun onSlide(bottomSheet: View, slideOffset: Float) {
|
||||
mainActivity.getBottomSheetBehavior().setAllowDragging(false)
|
||||
playerQueueSheet.setContentPadding(
|
||||
playerQueueSheet.contentPaddingLeft,
|
||||
(slideOffset * status_bar.height).toInt(),
|
||||
playerQueueSheet.contentPaddingRight,
|
||||
playerQueueSheet.contentPaddingBottom
|
||||
binding.playerQueueSheet.setContentPadding(
|
||||
binding.playerQueueSheet.contentPaddingLeft,
|
||||
(slideOffset * binding.statusBar.height).toInt(),
|
||||
binding.playerQueueSheet.contentPaddingRight,
|
||||
binding.playerQueueSheet.contentPaddingBottom
|
||||
)
|
||||
|
||||
shapeDrawable.interpolation = 1 - slideOffset
|
||||
|
@ -118,6 +122,7 @@ class ClassicPlayerFragment : AbsPlayerFragment(R.layout.fragment_classic_player
|
|||
@SuppressLint("ClickableViewAccessibility")
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
_binding = FragmentClassicPlayerBinding.bind(view)
|
||||
setupPanel()
|
||||
setUpMusicControllers()
|
||||
setUpPlayerToolbar()
|
||||
|
@ -139,19 +144,25 @@ class ClassicPlayerFragment : AbsPlayerFragment(R.layout.fragment_classic_player
|
|||
)
|
||||
shapeDrawable.fillColor =
|
||||
ColorStateList.valueOf(ATHUtil.resolveColor(requireContext(), R.attr.colorSurface))
|
||||
playerQueueSheet.background = shapeDrawable
|
||||
binding.playerQueueSheet.background = shapeDrawable
|
||||
|
||||
playerQueueSheet.setOnTouchListener { _, _ ->
|
||||
binding.playerQueueSheet.setOnTouchListener { _, _ ->
|
||||
mainActivity.getBottomSheetBehavior().setAllowDragging(false)
|
||||
getQueuePanel().setAllowDragging(true)
|
||||
return@setOnTouchListener false
|
||||
}
|
||||
|
||||
ToolbarContentTintHelper.colorizeToolbar(
|
||||
playerToolbar,
|
||||
binding.playerToolbar,
|
||||
Color.WHITE,
|
||||
requireActivity()
|
||||
)
|
||||
binding.title.setOnClickListener {
|
||||
goToAlbum(requireActivity())
|
||||
}
|
||||
binding.text.setOnClickListener {
|
||||
goToArtist(requireActivity())
|
||||
}
|
||||
}
|
||||
|
||||
private fun hideVolumeIfAvailable() {
|
||||
|
@ -179,18 +190,19 @@ class ClassicPlayerFragment : AbsPlayerFragment(R.layout.fragment_classic_player
|
|||
}
|
||||
|
||||
WrapperAdapterUtils.releaseAll(wrappedAdapter)
|
||||
_binding = null
|
||||
}
|
||||
|
||||
private fun updateSong() {
|
||||
val song = MusicPlayerRemote.currentSong
|
||||
title.text = song.title
|
||||
text.text = song.artistName
|
||||
binding.title.text = song.title
|
||||
binding.text.text = song.artistName
|
||||
|
||||
if (PreferenceUtil.isSongInfo) {
|
||||
songInfo.text = getSongInfo(song)
|
||||
songInfo.show()
|
||||
binding.playerControlsContainer.songInfo.text = getSongInfo(song)
|
||||
binding.playerControlsContainer.songInfo.show()
|
||||
} else {
|
||||
songInfo.hide()
|
||||
binding.playerControlsContainer.songInfo.hide()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -236,7 +248,7 @@ class ClassicPlayerFragment : AbsPlayerFragment(R.layout.fragment_classic_player
|
|||
}
|
||||
|
||||
override fun playerToolbar(): Toolbar? {
|
||||
return playerToolbar
|
||||
return binding.playerToolbar
|
||||
}
|
||||
|
||||
override fun onShow() {
|
||||
|
@ -269,25 +281,37 @@ class ClassicPlayerFragment : AbsPlayerFragment(R.layout.fragment_classic_player
|
|||
lastPlaybackControlsColor = color.primaryTextColor
|
||||
lastDisabledPlaybackControlsColor = ColorUtil.withAlpha(color.primaryTextColor, 0.3f)
|
||||
|
||||
playerContainer.setBackgroundColor(color.backgroundColor)
|
||||
songInfo.setTextColor(color.primaryTextColor)
|
||||
player_queue_sub_header.setTextColor(color.primaryTextColor)
|
||||
binding.playerContainer.setBackgroundColor(color.backgroundColor)
|
||||
binding.playerControlsContainer.songInfo.setTextColor(color.primaryTextColor)
|
||||
binding.playerQueueSubHeader.setTextColor(color.primaryTextColor)
|
||||
|
||||
songCurrentProgress.setTextColor(lastPlaybackControlsColor)
|
||||
songTotalTime.setTextColor(lastPlaybackControlsColor)
|
||||
binding.playerControlsContainer.songCurrentProgress.setTextColor(lastPlaybackControlsColor)
|
||||
binding.playerControlsContainer.songTotalTime.setTextColor(lastPlaybackControlsColor)
|
||||
|
||||
ViewUtil.setProgressDrawable(progressSlider, color.primaryTextColor, true)
|
||||
ViewUtil.setProgressDrawable(
|
||||
binding.playerControlsContainer.progressSlider,
|
||||
color.primaryTextColor,
|
||||
true
|
||||
)
|
||||
volumeFragment?.setTintableColor(color.primaryTextColor)
|
||||
|
||||
TintHelper.setTintAuto(playPauseButton, color.primaryTextColor, true)
|
||||
TintHelper.setTintAuto(playPauseButton, color.backgroundColor, false)
|
||||
TintHelper.setTintAuto(
|
||||
binding.playerControlsContainer.playPauseButton,
|
||||
color.primaryTextColor,
|
||||
true
|
||||
)
|
||||
TintHelper.setTintAuto(
|
||||
binding.playerControlsContainer.playPauseButton,
|
||||
color.backgroundColor,
|
||||
false
|
||||
)
|
||||
|
||||
updateRepeatState()
|
||||
updateShuffleState()
|
||||
updatePrevNextColor()
|
||||
|
||||
ToolbarContentTintHelper.colorizeToolbar(
|
||||
playerToolbar,
|
||||
binding.playerToolbar,
|
||||
Color.WHITE,
|
||||
requireActivity()
|
||||
)
|
||||
|
@ -305,15 +329,21 @@ class ClassicPlayerFragment : AbsPlayerFragment(R.layout.fragment_classic_player
|
|||
}
|
||||
|
||||
override fun onUpdateProgressViews(progress: Int, total: Int) {
|
||||
progressSlider.max = total
|
||||
binding.playerControlsContainer.progressSlider.max = total
|
||||
|
||||
val animator = ObjectAnimator.ofInt(progressSlider, "progress", progress)
|
||||
val animator = ObjectAnimator.ofInt(
|
||||
binding.playerControlsContainer.progressSlider,
|
||||
"progress",
|
||||
progress
|
||||
)
|
||||
animator.duration = AbsPlayerControlsFragment.SLIDER_ANIMATION_TIME
|
||||
animator.interpolator = LinearInterpolator()
|
||||
animator.start()
|
||||
|
||||
songTotalTime.text = MusicUtil.getReadableDurationString(total.toLong())
|
||||
songCurrentProgress.text = MusicUtil.getReadableDurationString(progress.toLong())
|
||||
binding.playerControlsContainer.songTotalTime.text =
|
||||
MusicUtil.getReadableDurationString(total.toLong())
|
||||
binding.playerControlsContainer.songCurrentProgress.text =
|
||||
MusicUtil.getReadableDurationString(progress.toLong())
|
||||
}
|
||||
|
||||
private fun updateQueuePosition() {
|
||||
|
@ -327,33 +357,33 @@ class ClassicPlayerFragment : AbsPlayerFragment(R.layout.fragment_classic_player
|
|||
}
|
||||
|
||||
private fun resetToCurrentPosition() {
|
||||
recyclerView.stopScroll()
|
||||
binding.recyclerView.stopScroll()
|
||||
linearLayoutManager.scrollToPositionWithOffset(MusicPlayerRemote.position + 1, 0)
|
||||
}
|
||||
|
||||
private fun getQueuePanel(): RetroBottomSheetBehavior<MaterialCardView> {
|
||||
return RetroBottomSheetBehavior.from(playerQueueSheet) as RetroBottomSheetBehavior<MaterialCardView>
|
||||
return RetroBottomSheetBehavior.from(binding.playerQueueSheet) as RetroBottomSheetBehavior<MaterialCardView>
|
||||
}
|
||||
|
||||
private fun setupPanel() {
|
||||
if (!ViewCompat.isLaidOut(playerContainer) || playerContainer.isLayoutRequested) {
|
||||
playerContainer.addOnLayoutChangeListener(this)
|
||||
if (!ViewCompat.isLaidOut(binding.playerContainer) || binding.playerContainer.isLayoutRequested) {
|
||||
binding.playerContainer.addOnLayoutChangeListener(this)
|
||||
return
|
||||
}
|
||||
val height = playerContainer.height
|
||||
val width = playerContainer.width
|
||||
val height = binding.playerContainer.height
|
||||
val width = binding.playerContainer.width
|
||||
val finalHeight = height - width
|
||||
val panel = getQueuePanel()
|
||||
panel.peekHeight = finalHeight
|
||||
}
|
||||
|
||||
private fun setUpPlayerToolbar() {
|
||||
playerToolbar.inflateMenu(R.menu.menu_player)
|
||||
playerToolbar.setNavigationOnClickListener { requireActivity().onBackPressed() }
|
||||
playerToolbar.setOnMenuItemClickListener(this)
|
||||
binding.playerToolbar.inflateMenu(R.menu.menu_player)
|
||||
binding.playerToolbar.setNavigationOnClickListener { requireActivity().onBackPressed() }
|
||||
binding.playerToolbar.setOnMenuItemClickListener(this)
|
||||
|
||||
ToolbarContentTintHelper.colorizeToolbar(
|
||||
playerToolbar,
|
||||
binding.playerToolbar,
|
||||
Color.WHITE,
|
||||
requireActivity()
|
||||
)
|
||||
|
@ -377,18 +407,19 @@ class ClassicPlayerFragment : AbsPlayerFragment(R.layout.fragment_classic_player
|
|||
recyclerViewDragDropManager?.createWrappedAdapter(playingQueueAdapter!!) as RecyclerView.Adapter<*>
|
||||
wrappedAdapter =
|
||||
recyclerViewSwipeManager?.createWrappedAdapter(wrappedAdapter) as RecyclerView.Adapter<*>
|
||||
recyclerView.layoutManager = linearLayoutManager
|
||||
recyclerView.adapter = wrappedAdapter
|
||||
recyclerView.itemAnimator = animator
|
||||
recyclerViewTouchActionGuardManager?.attachRecyclerView(recyclerView)
|
||||
recyclerViewDragDropManager?.attachRecyclerView(recyclerView)
|
||||
recyclerViewSwipeManager?.attachRecyclerView(recyclerView)
|
||||
binding.recyclerView.layoutManager = linearLayoutManager
|
||||
binding.recyclerView.adapter = wrappedAdapter
|
||||
binding.recyclerView.itemAnimator = animator
|
||||
recyclerViewTouchActionGuardManager?.attachRecyclerView(binding.recyclerView)
|
||||
recyclerViewDragDropManager?.attachRecyclerView(binding.recyclerView)
|
||||
recyclerViewSwipeManager?.attachRecyclerView(binding.recyclerView)
|
||||
|
||||
linearLayoutManager.scrollToPositionWithOffset(MusicPlayerRemote.position + 1, 0)
|
||||
}
|
||||
|
||||
fun setUpProgressSlider() {
|
||||
progressSlider.setOnSeekBarChangeListener(object : SimpleOnSeekbarChangeListener() {
|
||||
binding.playerControlsContainer.progressSlider.setOnSeekBarChangeListener(object :
|
||||
SimpleOnSeekbarChangeListener() {
|
||||
override fun onProgressChanged(seekBar: SeekBar, progress: Int, fromUser: Boolean) {
|
||||
if (fromUser) {
|
||||
MusicPlayerRemote.seekTo(progress)
|
||||
|
@ -402,14 +433,16 @@ class ClassicPlayerFragment : AbsPlayerFragment(R.layout.fragment_classic_player
|
|||
}
|
||||
|
||||
private fun setUpPlayPauseFab() {
|
||||
playPauseButton.setOnClickListener(PlayPauseButtonOnClickHandler())
|
||||
binding.playerControlsContainer.playPauseButton.setOnClickListener(
|
||||
PlayPauseButtonOnClickHandler()
|
||||
)
|
||||
}
|
||||
|
||||
private fun updatePlayPauseDrawableState() {
|
||||
if (MusicPlayerRemote.isPlaying) {
|
||||
playPauseButton.setImageResource(R.drawable.ic_pause)
|
||||
binding.playerControlsContainer.playPauseButton.setImageResource(R.drawable.ic_pause)
|
||||
} else {
|
||||
playPauseButton.setImageResource(R.drawable.ic_play_arrow)
|
||||
binding.playerControlsContainer.playPauseButton.setImageResource(R.drawable.ic_play_arrow)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -423,27 +456,33 @@ class ClassicPlayerFragment : AbsPlayerFragment(R.layout.fragment_classic_player
|
|||
|
||||
private fun setUpPrevNext() {
|
||||
updatePrevNextColor()
|
||||
nextButton.setOnClickListener { MusicPlayerRemote.playNextSong() }
|
||||
previousButton.setOnClickListener { MusicPlayerRemote.back() }
|
||||
binding.playerControlsContainer.nextButton.setOnClickListener { MusicPlayerRemote.playNextSong() }
|
||||
binding.playerControlsContainer.previousButton.setOnClickListener { MusicPlayerRemote.back() }
|
||||
}
|
||||
|
||||
private fun updatePrevNextColor() {
|
||||
nextButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
|
||||
previousButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
|
||||
binding.playerControlsContainer.nextButton.setColorFilter(
|
||||
lastPlaybackControlsColor,
|
||||
PorterDuff.Mode.SRC_IN
|
||||
)
|
||||
binding.playerControlsContainer.previousButton.setColorFilter(
|
||||
lastPlaybackControlsColor,
|
||||
PorterDuff.Mode.SRC_IN
|
||||
)
|
||||
}
|
||||
|
||||
private fun setUpShuffleButton() {
|
||||
shuffleButton.setOnClickListener { MusicPlayerRemote.toggleShuffleMode() }
|
||||
binding.playerControlsContainer.shuffleButton.setOnClickListener { MusicPlayerRemote.toggleShuffleMode() }
|
||||
}
|
||||
|
||||
fun updateShuffleState() {
|
||||
when (MusicPlayerRemote.shuffleMode) {
|
||||
MusicService.SHUFFLE_MODE_SHUFFLE ->
|
||||
shuffleButton.setColorFilter(
|
||||
binding.playerControlsContainer.shuffleButton.setColorFilter(
|
||||
lastPlaybackControlsColor,
|
||||
PorterDuff.Mode.SRC_IN
|
||||
)
|
||||
else -> shuffleButton.setColorFilter(
|
||||
else -> binding.playerControlsContainer.shuffleButton.setColorFilter(
|
||||
lastDisabledPlaybackControlsColor,
|
||||
PorterDuff.Mode.SRC_IN
|
||||
)
|
||||
|
@ -451,25 +490,31 @@ class ClassicPlayerFragment : AbsPlayerFragment(R.layout.fragment_classic_player
|
|||
}
|
||||
|
||||
private fun setUpRepeatButton() {
|
||||
repeatButton.setOnClickListener { MusicPlayerRemote.cycleRepeatMode() }
|
||||
binding.playerControlsContainer.repeatButton.setOnClickListener { MusicPlayerRemote.cycleRepeatMode() }
|
||||
}
|
||||
|
||||
fun updateRepeatState() {
|
||||
when (MusicPlayerRemote.repeatMode) {
|
||||
MusicService.REPEAT_MODE_NONE -> {
|
||||
repeatButton.setImageResource(R.drawable.ic_repeat)
|
||||
repeatButton.setColorFilter(
|
||||
binding.playerControlsContainer.repeatButton.setImageResource(R.drawable.ic_repeat)
|
||||
binding.playerControlsContainer.repeatButton.setColorFilter(
|
||||
lastDisabledPlaybackControlsColor,
|
||||
PorterDuff.Mode.SRC_IN
|
||||
)
|
||||
}
|
||||
MusicService.REPEAT_MODE_ALL -> {
|
||||
repeatButton.setImageResource(R.drawable.ic_repeat)
|
||||
repeatButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
|
||||
binding.playerControlsContainer.repeatButton.setImageResource(R.drawable.ic_repeat)
|
||||
binding.playerControlsContainer.repeatButton.setColorFilter(
|
||||
lastPlaybackControlsColor,
|
||||
PorterDuff.Mode.SRC_IN
|
||||
)
|
||||
}
|
||||
MusicService.REPEAT_MODE_THIS -> {
|
||||
repeatButton.setImageResource(R.drawable.ic_repeat_one)
|
||||
repeatButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
|
||||
binding.playerControlsContainer.repeatButton.setImageResource(R.drawable.ic_repeat_one)
|
||||
binding.playerControlsContainer.repeatButton.setColorFilter(
|
||||
lastPlaybackControlsColor,
|
||||
PorterDuff.Mode.SRC_IN
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -485,9 +530,9 @@ class ClassicPlayerFragment : AbsPlayerFragment(R.layout.fragment_classic_player
|
|||
oldRight: Int,
|
||||
oldBottom: Int
|
||||
) {
|
||||
val height = playerContainer.height
|
||||
val width = playerContainer.width
|
||||
val finalHeight = height - (playerControlsContainer.height + width)
|
||||
val height = binding.playerContainer.height
|
||||
val width = binding.playerContainer.width
|
||||
val finalHeight = height - (binding.playerControlsContainer.root.height + width)
|
||||
val panel = getQueuePanel()
|
||||
panel.peekHeight = finalHeight
|
||||
}
|
||||
|
|
|
@ -19,16 +19,17 @@ import android.os.Bundle
|
|||
import android.os.Handler
|
||||
import android.view.View
|
||||
import androidx.appcompat.widget.Toolbar
|
||||
import androidx.core.animation.doOnEnd
|
||||
import code.name.monkey.appthemehelper.util.ATHUtil
|
||||
import code.name.monkey.appthemehelper.util.ColorUtil
|
||||
import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper
|
||||
import code.name.monkey.retromusic.R
|
||||
import code.name.monkey.retromusic.databinding.FragmentColorPlayerBinding
|
||||
import code.name.monkey.retromusic.fragments.base.AbsPlayerFragment
|
||||
import code.name.monkey.retromusic.fragments.player.PlayerAlbumCoverFragment
|
||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote
|
||||
import code.name.monkey.retromusic.model.Song
|
||||
import code.name.monkey.retromusic.util.color.MediaNotificationProcessor
|
||||
import kotlinx.android.synthetic.main.fragment_color_player.*
|
||||
|
||||
class ColorFragment : AbsPlayerFragment(R.layout.fragment_color_player) {
|
||||
|
||||
|
@ -36,9 +37,12 @@ class ColorFragment : AbsPlayerFragment(R.layout.fragment_color_player) {
|
|||
private var navigationColor: Int = 0
|
||||
private lateinit var playbackControlsFragment: ColorPlaybackControlsFragment
|
||||
private var valueAnimator: ValueAnimator? = null
|
||||
private var _binding: FragmentColorPlayerBinding? = null
|
||||
private val binding get() = _binding!!
|
||||
|
||||
|
||||
override fun playerToolbar(): Toolbar {
|
||||
return playerToolbar
|
||||
return binding.playerToolbar
|
||||
}
|
||||
|
||||
override val paletteColor: Int
|
||||
|
@ -50,11 +54,17 @@ class ColorFragment : AbsPlayerFragment(R.layout.fragment_color_player) {
|
|||
playbackControlsFragment.setColor(color)
|
||||
navigationColor = color.backgroundColor
|
||||
|
||||
colorGradientBackground?.setBackgroundColor(color.backgroundColor)
|
||||
binding.colorGradientBackground.setBackgroundColor(color.backgroundColor)
|
||||
val animator =
|
||||
playbackControlsFragment.createRevealAnimator(binding.colorGradientBackground)
|
||||
animator.doOnEnd {
|
||||
_binding?.root?.setBackgroundColor(color.backgroundColor)
|
||||
}
|
||||
animator.start()
|
||||
serviceActivity?.setLightNavigationBar(ColorUtil.isColorLight(color.backgroundColor))
|
||||
Handler().post {
|
||||
ToolbarContentTintHelper.colorizeToolbar(
|
||||
playerToolbar,
|
||||
binding.playerToolbar,
|
||||
color.secondaryTextColor,
|
||||
requireActivity()
|
||||
)
|
||||
|
@ -95,10 +105,12 @@ class ColorFragment : AbsPlayerFragment(R.layout.fragment_color_player) {
|
|||
valueAnimator!!.cancel()
|
||||
valueAnimator = null
|
||||
}
|
||||
_binding = null
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
_binding = FragmentColorPlayerBinding.bind(view)
|
||||
setUpSubFragments()
|
||||
setUpPlayerToolbar()
|
||||
val playerAlbumCoverFragment =
|
||||
|
@ -112,7 +124,7 @@ class ColorFragment : AbsPlayerFragment(R.layout.fragment_color_player) {
|
|||
}
|
||||
|
||||
private fun setUpPlayerToolbar() {
|
||||
playerToolbar.apply {
|
||||
binding.playerToolbar.apply {
|
||||
inflateMenu(R.menu.menu_player)
|
||||
setNavigationOnClickListener { requireActivity().onBackPressed() }
|
||||
setOnMenuItemClickListener(this@ColorFragment)
|
||||
|
|
|
@ -14,23 +14,29 @@
|
|||
*/
|
||||
package code.name.monkey.retromusic.fragments.player.color
|
||||
|
||||
import android.animation.Animator
|
||||
import android.animation.ObjectAnimator
|
||||
import android.graphics.Color
|
||||
import android.graphics.PorterDuff
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewAnimationUtils
|
||||
import android.view.ViewGroup
|
||||
import android.view.animation.AccelerateInterpolator
|
||||
import android.view.animation.DecelerateInterpolator
|
||||
import android.view.animation.LinearInterpolator
|
||||
import android.widget.SeekBar
|
||||
import code.name.monkey.appthemehelper.util.ColorUtil
|
||||
import code.name.monkey.appthemehelper.util.TintHelper
|
||||
import code.name.monkey.retromusic.R
|
||||
import code.name.monkey.retromusic.databinding.FragmentColorPlayerPlaybackControlsBinding
|
||||
import code.name.monkey.retromusic.extensions.applyColor
|
||||
import code.name.monkey.retromusic.extensions.hide
|
||||
import code.name.monkey.retromusic.extensions.show
|
||||
import code.name.monkey.retromusic.fragments.base.AbsPlayerControlsFragment
|
||||
import code.name.monkey.retromusic.fragments.base.goToAlbum
|
||||
import code.name.monkey.retromusic.fragments.base.goToArtist
|
||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote
|
||||
import code.name.monkey.retromusic.helper.MusicProgressViewUpdateHelper
|
||||
import code.name.monkey.retromusic.helper.PlayPauseButtonOnClickHandler
|
||||
|
@ -39,7 +45,7 @@ import code.name.monkey.retromusic.service.MusicService
|
|||
import code.name.monkey.retromusic.util.MusicUtil
|
||||
import code.name.monkey.retromusic.util.PreferenceUtil
|
||||
import code.name.monkey.retromusic.util.color.MediaNotificationProcessor
|
||||
import kotlinx.android.synthetic.main.fragment_color_player_playback_controls.*
|
||||
import kotlin.math.sqrt
|
||||
|
||||
class ColorPlaybackControlsFragment :
|
||||
AbsPlayerControlsFragment(R.layout.fragment_adaptive_player_playback_controls) {
|
||||
|
@ -47,6 +53,9 @@ class ColorPlaybackControlsFragment :
|
|||
private var lastPlaybackControlsColor: Int = 0
|
||||
private var lastDisabledPlaybackControlsColor: Int = 0
|
||||
private lateinit var progressViewUpdateHelper: MusicProgressViewUpdateHelper
|
||||
private var _binding: FragmentColorPlayerPlaybackControlsBinding? = null
|
||||
private val binding get() = _binding!!
|
||||
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
@ -57,8 +66,9 @@ class ColorPlaybackControlsFragment :
|
|||
inflater: LayoutInflater,
|
||||
container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View? {
|
||||
return inflater.inflate(R.layout.fragment_color_player_playback_controls, container, false)
|
||||
): View {
|
||||
_binding = FragmentColorPlayerPlaybackControlsBinding.inflate(inflater, container, false)
|
||||
return binding.root
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
|
@ -74,20 +84,26 @@ class ColorPlaybackControlsFragment :
|
|||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
setUpMusicControllers()
|
||||
title.isSelected = true
|
||||
text.isSelected = true
|
||||
binding.title.isSelected = true
|
||||
binding.text.isSelected = true
|
||||
binding.title.setOnClickListener {
|
||||
goToAlbum(requireActivity())
|
||||
}
|
||||
binding.text.setOnClickListener {
|
||||
goToArtist(requireActivity())
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateSong() {
|
||||
val song = MusicPlayerRemote.currentSong
|
||||
title.text = song.title
|
||||
text.text = song.artistName
|
||||
binding.title.text = song.title
|
||||
binding.text.text = song.artistName
|
||||
|
||||
if (PreferenceUtil.isSongInfo) {
|
||||
songInfo.text = getSongInfo(song)
|
||||
songInfo.show()
|
||||
binding.songInfo.text = getSongInfo(song)
|
||||
binding.songInfo.show()
|
||||
} else {
|
||||
songInfo.hide()
|
||||
binding.songInfo.hide()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -116,15 +132,15 @@ class ColorPlaybackControlsFragment :
|
|||
}
|
||||
|
||||
override fun setColor(color: MediaNotificationProcessor) {
|
||||
TintHelper.setTintAuto(playPauseButton, color.primaryTextColor, true)
|
||||
TintHelper.setTintAuto(playPauseButton, color.backgroundColor, false)
|
||||
progressSlider.applyColor(color.primaryTextColor)
|
||||
TintHelper.setTintAuto(binding.playPauseButton, color.primaryTextColor, true)
|
||||
TintHelper.setTintAuto(binding.playPauseButton, color.backgroundColor, false)
|
||||
binding.progressSlider.applyColor(color.primaryTextColor)
|
||||
|
||||
title.setTextColor(color.primaryTextColor)
|
||||
text.setTextColor(color.secondaryTextColor)
|
||||
songInfo.setTextColor(color.secondaryTextColor)
|
||||
songCurrentProgress.setTextColor(color.secondaryTextColor)
|
||||
songTotalTime.setTextColor(color.secondaryTextColor)
|
||||
binding.title.setTextColor(color.primaryTextColor)
|
||||
binding.text.setTextColor(color.secondaryTextColor)
|
||||
binding.songInfo.setTextColor(color.secondaryTextColor)
|
||||
binding.songCurrentProgress.setTextColor(color.secondaryTextColor)
|
||||
binding.songTotalTime.setTextColor(color.secondaryTextColor)
|
||||
volumeFragment?.setTintableColor(color.primaryTextColor)
|
||||
|
||||
lastPlaybackControlsColor = color.secondaryTextColor
|
||||
|
@ -136,15 +152,15 @@ class ColorPlaybackControlsFragment :
|
|||
}
|
||||
|
||||
private fun setUpPlayPauseFab() {
|
||||
TintHelper.setTintAuto(playPauseButton, Color.WHITE, true)
|
||||
TintHelper.setTintAuto(playPauseButton, Color.BLACK, false)
|
||||
playPauseButton.setOnClickListener(PlayPauseButtonOnClickHandler())
|
||||
TintHelper.setTintAuto(binding.playPauseButton, Color.WHITE, true)
|
||||
TintHelper.setTintAuto(binding.playPauseButton, Color.BLACK, false)
|
||||
binding.playPauseButton.setOnClickListener(PlayPauseButtonOnClickHandler())
|
||||
}
|
||||
|
||||
private fun updatePlayPauseDrawableState() {
|
||||
when {
|
||||
MusicPlayerRemote.isPlaying -> playPauseButton.setImageResource(R.drawable.ic_pause)
|
||||
else -> playPauseButton.setImageResource(R.drawable.ic_play_arrow)
|
||||
MusicPlayerRemote.isPlaying -> binding.playPauseButton.setImageResource(R.drawable.ic_pause)
|
||||
else -> binding.playPauseButton.setImageResource(R.drawable.ic_play_arrow)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -158,26 +174,26 @@ class ColorPlaybackControlsFragment :
|
|||
|
||||
private fun setUpPrevNext() {
|
||||
updatePrevNextColor()
|
||||
nextButton.setOnClickListener { MusicPlayerRemote.playNextSong() }
|
||||
previousButton.setOnClickListener { MusicPlayerRemote.back() }
|
||||
binding.nextButton.setOnClickListener { MusicPlayerRemote.playNextSong() }
|
||||
binding.previousButton.setOnClickListener { MusicPlayerRemote.back() }
|
||||
}
|
||||
|
||||
private fun updatePrevNextColor() {
|
||||
nextButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
|
||||
previousButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
|
||||
binding.nextButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
|
||||
binding.previousButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
|
||||
}
|
||||
|
||||
private fun setUpShuffleButton() {
|
||||
shuffleButton.setOnClickListener { MusicPlayerRemote.toggleShuffleMode() }
|
||||
binding.shuffleButton.setOnClickListener { MusicPlayerRemote.toggleShuffleMode() }
|
||||
}
|
||||
|
||||
override fun updateShuffleState() {
|
||||
when (MusicPlayerRemote.shuffleMode) {
|
||||
MusicService.SHUFFLE_MODE_SHUFFLE -> shuffleButton.setColorFilter(
|
||||
MusicService.SHUFFLE_MODE_SHUFFLE -> binding.shuffleButton.setColorFilter(
|
||||
lastPlaybackControlsColor,
|
||||
PorterDuff.Mode.SRC_IN
|
||||
)
|
||||
else -> shuffleButton.setColorFilter(
|
||||
else -> binding.shuffleButton.setColorFilter(
|
||||
lastDisabledPlaybackControlsColor,
|
||||
PorterDuff.Mode.SRC_IN
|
||||
)
|
||||
|
@ -185,31 +201,37 @@ class ColorPlaybackControlsFragment :
|
|||
}
|
||||
|
||||
private fun setUpRepeatButton() {
|
||||
repeatButton.setOnClickListener { MusicPlayerRemote.cycleRepeatMode() }
|
||||
binding.repeatButton.setOnClickListener { MusicPlayerRemote.cycleRepeatMode() }
|
||||
}
|
||||
|
||||
override fun updateRepeatState() {
|
||||
when (MusicPlayerRemote.repeatMode) {
|
||||
MusicService.REPEAT_MODE_NONE -> {
|
||||
repeatButton.setImageResource(R.drawable.ic_repeat)
|
||||
repeatButton.setColorFilter(
|
||||
binding.repeatButton.setImageResource(R.drawable.ic_repeat)
|
||||
binding.repeatButton.setColorFilter(
|
||||
lastDisabledPlaybackControlsColor,
|
||||
PorterDuff.Mode.SRC_IN
|
||||
)
|
||||
}
|
||||
MusicService.REPEAT_MODE_ALL -> {
|
||||
repeatButton.setImageResource(R.drawable.ic_repeat)
|
||||
repeatButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
|
||||
binding.repeatButton.setImageResource(R.drawable.ic_repeat)
|
||||
binding.repeatButton.setColorFilter(
|
||||
lastPlaybackControlsColor,
|
||||
PorterDuff.Mode.SRC_IN
|
||||
)
|
||||
}
|
||||
MusicService.REPEAT_MODE_THIS -> {
|
||||
repeatButton.setImageResource(R.drawable.ic_repeat_one)
|
||||
repeatButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
|
||||
binding.repeatButton.setImageResource(R.drawable.ic_repeat_one)
|
||||
binding.repeatButton.setColorFilter(
|
||||
lastPlaybackControlsColor,
|
||||
PorterDuff.Mode.SRC_IN
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override fun show() {
|
||||
playPauseButton!!.animate()
|
||||
binding.playPauseButton.animate()
|
||||
.scaleX(1f)
|
||||
.scaleY(1f)
|
||||
.rotation(360f)
|
||||
|
@ -218,7 +240,7 @@ class ColorPlaybackControlsFragment :
|
|||
}
|
||||
|
||||
public override fun hide() {
|
||||
playPauseButton.apply {
|
||||
binding.playPauseButton.apply {
|
||||
scaleX = 0f
|
||||
scaleY = 0f
|
||||
rotation = 0f
|
||||
|
@ -226,7 +248,7 @@ class ColorPlaybackControlsFragment :
|
|||
}
|
||||
|
||||
override fun setUpProgressSlider() {
|
||||
progressSlider.setOnSeekBarChangeListener(object : SimpleOnSeekbarChangeListener() {
|
||||
binding.progressSlider.setOnSeekBarChangeListener(object : SimpleOnSeekbarChangeListener() {
|
||||
override fun onProgressChanged(seekBar: SeekBar, progress: Int, fromUser: Boolean) {
|
||||
if (fromUser) {
|
||||
MusicPlayerRemote.seekTo(progress)
|
||||
|
@ -240,14 +262,37 @@ class ColorPlaybackControlsFragment :
|
|||
}
|
||||
|
||||
override fun onUpdateProgressViews(progress: Int, total: Int) {
|
||||
progressSlider.max = total
|
||||
binding.progressSlider.max = total
|
||||
|
||||
val animator = ObjectAnimator.ofInt(progressSlider, "progress", progress)
|
||||
val animator = ObjectAnimator.ofInt(binding.progressSlider, "progress", progress)
|
||||
animator.duration = SLIDER_ANIMATION_TIME
|
||||
animator.interpolator = LinearInterpolator()
|
||||
animator.start()
|
||||
|
||||
songTotalTime.text = MusicUtil.getReadableDurationString(total.toLong())
|
||||
songCurrentProgress.text = MusicUtil.getReadableDurationString(progress.toLong())
|
||||
binding.songTotalTime.text = MusicUtil.getReadableDurationString(total.toLong())
|
||||
binding.songCurrentProgress.text = MusicUtil.getReadableDurationString(progress.toLong())
|
||||
}
|
||||
|
||||
fun createRevealAnimator(view: View): Animator {
|
||||
val location = IntArray(2)
|
||||
binding.playPauseButton.getLocationOnScreen(location)
|
||||
val x = (location[0] + binding.playPauseButton.measuredWidth / 2)
|
||||
val y = (location[1] + binding.playPauseButton.measuredHeight / 2)
|
||||
val endRadius = sqrt((x * x + y * y).toFloat())
|
||||
val startRadius =
|
||||
binding.playPauseButton.measuredWidth.coerceAtMost(binding.playPauseButton.measuredHeight)
|
||||
return ViewAnimationUtils.createCircularReveal(
|
||||
view, x, y, startRadius.toFloat(),
|
||||
endRadius
|
||||
).apply {
|
||||
duration = 300
|
||||
interpolator = AccelerateInterpolator()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
_binding = null
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,16 +20,19 @@ import androidx.appcompat.widget.Toolbar
|
|||
import code.name.monkey.appthemehelper.util.ATHUtil
|
||||
import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper
|
||||
import code.name.monkey.retromusic.R
|
||||
import code.name.monkey.retromusic.databinding.FragmentFitBinding
|
||||
import code.name.monkey.retromusic.fragments.base.AbsPlayerFragment
|
||||
import code.name.monkey.retromusic.fragments.player.PlayerAlbumCoverFragment
|
||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote
|
||||
import code.name.monkey.retromusic.model.Song
|
||||
import code.name.monkey.retromusic.util.color.MediaNotificationProcessor
|
||||
import kotlinx.android.synthetic.main.fragment_fit.*
|
||||
|
||||
class FitFragment : AbsPlayerFragment(R.layout.fragment_fit) {
|
||||
private var _binding: FragmentFitBinding? = null
|
||||
private val binding get() = _binding!!
|
||||
|
||||
override fun playerToolbar(): Toolbar {
|
||||
return playerToolbar
|
||||
return binding.playerToolbar
|
||||
}
|
||||
|
||||
private var lastColor: Int = 0
|
||||
|
@ -60,7 +63,7 @@ class FitFragment : AbsPlayerFragment(R.layout.fragment_fit) {
|
|||
lastColor = color.primaryTextColor
|
||||
libraryViewModel.updateColor(color.primaryTextColor)
|
||||
ToolbarContentTintHelper.colorizeToolbar(
|
||||
playerToolbar,
|
||||
binding.playerToolbar,
|
||||
ATHUtil.resolveColor(requireContext(), R.attr.colorControlNormal),
|
||||
requireActivity()
|
||||
)
|
||||
|
@ -79,6 +82,7 @@ class FitFragment : AbsPlayerFragment(R.layout.fragment_fit) {
|
|||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
_binding = FragmentFitBinding.bind(view)
|
||||
setUpSubFragments()
|
||||
setUpPlayerToolbar()
|
||||
}
|
||||
|
@ -92,7 +96,7 @@ class FitFragment : AbsPlayerFragment(R.layout.fragment_fit) {
|
|||
}
|
||||
|
||||
private fun setUpPlayerToolbar() {
|
||||
playerToolbar.apply {
|
||||
binding.playerToolbar.apply {
|
||||
inflateMenu(R.menu.menu_player)
|
||||
setNavigationOnClickListener { requireActivity().onBackPressed() }
|
||||
setOnMenuItemClickListener(this@FitFragment)
|
||||
|
@ -112,6 +116,11 @@ class FitFragment : AbsPlayerFragment(R.layout.fragment_fit) {
|
|||
updateIsFavorite()
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
_binding = null
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun newInstance(): FitFragment {
|
||||
return FitFragment()
|
||||
|
|
|
@ -28,10 +28,13 @@ import code.name.monkey.appthemehelper.util.ColorUtil
|
|||
import code.name.monkey.appthemehelper.util.MaterialValueHelper
|
||||
import code.name.monkey.appthemehelper.util.TintHelper
|
||||
import code.name.monkey.retromusic.R
|
||||
import code.name.monkey.retromusic.databinding.FragmentFitPlaybackControlsBinding
|
||||
import code.name.monkey.retromusic.extensions.hide
|
||||
import code.name.monkey.retromusic.extensions.ripAlpha
|
||||
import code.name.monkey.retromusic.extensions.show
|
||||
import code.name.monkey.retromusic.fragments.base.AbsPlayerControlsFragment
|
||||
import code.name.monkey.retromusic.fragments.base.goToAlbum
|
||||
import code.name.monkey.retromusic.fragments.base.goToArtist
|
||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote
|
||||
import code.name.monkey.retromusic.helper.MusicProgressViewUpdateHelper
|
||||
import code.name.monkey.retromusic.helper.PlayPauseButtonOnClickHandler
|
||||
|
@ -40,10 +43,12 @@ import code.name.monkey.retromusic.service.MusicService
|
|||
import code.name.monkey.retromusic.util.MusicUtil
|
||||
import code.name.monkey.retromusic.util.PreferenceUtil
|
||||
import code.name.monkey.retromusic.util.color.MediaNotificationProcessor
|
||||
import kotlinx.android.synthetic.main.fragment_fit_playback_controls.*
|
||||
|
||||
class FitPlaybackControlsFragment :
|
||||
AbsPlayerControlsFragment(R.layout.fragment_fit_playback_controls) {
|
||||
private var _binding: FragmentFitPlaybackControlsBinding? = null
|
||||
private val binding get() = _binding!!
|
||||
|
||||
|
||||
private var lastPlaybackControlsColor: Int = 0
|
||||
private var lastDisabledPlaybackControlsColor: Int = 0
|
||||
|
@ -56,30 +61,38 @@ class FitPlaybackControlsFragment :
|
|||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
_binding = FragmentFitPlaybackControlsBinding.bind(view)
|
||||
setUpMusicControllers()
|
||||
|
||||
title.isSelected = true
|
||||
text.isSelected = true
|
||||
binding.title.isSelected = true
|
||||
binding.text.isSelected = true
|
||||
|
||||
playPauseButton.setOnClickListener {
|
||||
binding.title.setOnClickListener {
|
||||
goToAlbum(requireActivity())
|
||||
}
|
||||
binding.text.setOnClickListener {
|
||||
goToArtist(requireActivity())
|
||||
}
|
||||
|
||||
binding.playPauseButton.setOnClickListener {
|
||||
if (MusicPlayerRemote.isPlaying) {
|
||||
MusicPlayerRemote.pauseSong()
|
||||
} else {
|
||||
MusicPlayerRemote.resumePlaying()
|
||||
}
|
||||
showBonceAnimation()
|
||||
showBounceAnimation()
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateSong() {
|
||||
val song = MusicPlayerRemote.currentSong
|
||||
title.text = song.title
|
||||
text.text = song.artistName
|
||||
binding.title.text = song.title
|
||||
binding.text.text = song.artistName
|
||||
if (PreferenceUtil.isSongInfo) {
|
||||
songInfo.text = getSongInfo(song)
|
||||
songInfo.show()
|
||||
binding.songInfo.text = getSongInfo(song)
|
||||
binding.songInfo.show()
|
||||
} else {
|
||||
songInfo.hide()
|
||||
binding.songInfo.hide()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -146,22 +159,22 @@ class FitPlaybackControlsFragment :
|
|||
|
||||
private fun setFabColor(i: Int) {
|
||||
TintHelper.setTintAuto(
|
||||
playPauseButton,
|
||||
binding.playPauseButton,
|
||||
MaterialValueHelper.getPrimaryTextColor(context, ColorUtil.isColorLight(i)),
|
||||
false
|
||||
)
|
||||
TintHelper.setTintAuto(playPauseButton, i, true)
|
||||
TintHelper.setTintAuto(binding.playPauseButton, i, true)
|
||||
}
|
||||
|
||||
private fun setUpPlayPauseFab() {
|
||||
playPauseButton.setOnClickListener(PlayPauseButtonOnClickHandler())
|
||||
binding.playPauseButton.setOnClickListener(PlayPauseButtonOnClickHandler())
|
||||
}
|
||||
|
||||
private fun updatePlayPauseDrawableState() {
|
||||
if (MusicPlayerRemote.isPlaying) {
|
||||
playPauseButton.setImageResource(R.drawable.ic_pause)
|
||||
binding.playPauseButton.setImageResource(R.drawable.ic_pause)
|
||||
} else {
|
||||
playPauseButton.setImageResource(R.drawable.ic_play_arrow_white_32dp)
|
||||
binding.playPauseButton.setImageResource(R.drawable.ic_play_arrow_white_32dp)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -175,26 +188,26 @@ class FitPlaybackControlsFragment :
|
|||
|
||||
private fun setUpPrevNext() {
|
||||
updatePrevNextColor()
|
||||
nextButton.setOnClickListener { MusicPlayerRemote.playNextSong() }
|
||||
previousButton.setOnClickListener { MusicPlayerRemote.back() }
|
||||
binding.nextButton.setOnClickListener { MusicPlayerRemote.playNextSong() }
|
||||
binding.previousButton.setOnClickListener { MusicPlayerRemote.back() }
|
||||
}
|
||||
|
||||
private fun updatePrevNextColor() {
|
||||
nextButton!!.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
|
||||
previousButton!!.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
|
||||
binding.nextButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
|
||||
binding.previousButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
|
||||
}
|
||||
|
||||
private fun setUpShuffleButton() {
|
||||
shuffleButton.setOnClickListener { MusicPlayerRemote.toggleShuffleMode() }
|
||||
binding.shuffleButton.setOnClickListener { MusicPlayerRemote.toggleShuffleMode() }
|
||||
}
|
||||
|
||||
override fun updateShuffleState() {
|
||||
when (MusicPlayerRemote.shuffleMode) {
|
||||
MusicService.SHUFFLE_MODE_SHUFFLE -> shuffleButton.setColorFilter(
|
||||
MusicService.SHUFFLE_MODE_SHUFFLE -> binding.shuffleButton.setColorFilter(
|
||||
lastPlaybackControlsColor,
|
||||
PorterDuff.Mode.SRC_IN
|
||||
)
|
||||
else -> shuffleButton.setColorFilter(
|
||||
else -> binding.shuffleButton.setColorFilter(
|
||||
lastDisabledPlaybackControlsColor,
|
||||
PorterDuff.Mode.SRC_IN
|
||||
)
|
||||
|
@ -202,31 +215,37 @@ class FitPlaybackControlsFragment :
|
|||
}
|
||||
|
||||
private fun setUpRepeatButton() {
|
||||
repeatButton.setOnClickListener { MusicPlayerRemote.cycleRepeatMode() }
|
||||
binding.repeatButton.setOnClickListener { MusicPlayerRemote.cycleRepeatMode() }
|
||||
}
|
||||
|
||||
override fun updateRepeatState() {
|
||||
when (MusicPlayerRemote.repeatMode) {
|
||||
MusicService.REPEAT_MODE_NONE -> {
|
||||
repeatButton.setImageResource(R.drawable.ic_repeat)
|
||||
repeatButton.setColorFilter(
|
||||
binding.repeatButton.setImageResource(R.drawable.ic_repeat)
|
||||
binding.repeatButton.setColorFilter(
|
||||
lastDisabledPlaybackControlsColor,
|
||||
PorterDuff.Mode.SRC_IN
|
||||
)
|
||||
}
|
||||
MusicService.REPEAT_MODE_ALL -> {
|
||||
repeatButton.setImageResource(R.drawable.ic_repeat)
|
||||
repeatButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
|
||||
binding.repeatButton.setImageResource(R.drawable.ic_repeat)
|
||||
binding.repeatButton.setColorFilter(
|
||||
lastPlaybackControlsColor,
|
||||
PorterDuff.Mode.SRC_IN
|
||||
)
|
||||
}
|
||||
MusicService.REPEAT_MODE_THIS -> {
|
||||
repeatButton.setImageResource(R.drawable.ic_repeat_one)
|
||||
repeatButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
|
||||
binding.repeatButton.setImageResource(R.drawable.ic_repeat_one)
|
||||
binding.repeatButton.setColorFilter(
|
||||
lastPlaybackControlsColor,
|
||||
PorterDuff.Mode.SRC_IN
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override fun show() {
|
||||
playPauseButton!!.animate()
|
||||
binding.playPauseButton.animate()
|
||||
.scaleX(1f)
|
||||
.scaleY(1f)
|
||||
.rotation(360f)
|
||||
|
@ -235,17 +254,15 @@ class FitPlaybackControlsFragment :
|
|||
}
|
||||
|
||||
public override fun hide() {
|
||||
if (playPauseButton != null) {
|
||||
playPauseButton!!.apply {
|
||||
scaleX = 0f
|
||||
scaleY = 0f
|
||||
rotation = 0f
|
||||
}
|
||||
binding.playPauseButton.apply {
|
||||
scaleX = 0f
|
||||
scaleY = 0f
|
||||
rotation = 0f
|
||||
}
|
||||
}
|
||||
|
||||
private fun showBonceAnimation() {
|
||||
playPauseButton.apply {
|
||||
private fun showBounceAnimation() {
|
||||
binding.playPauseButton.apply {
|
||||
clearAnimation()
|
||||
scaleX = 0.9f
|
||||
scaleY = 0.9f
|
||||
|
@ -268,7 +285,7 @@ class FitPlaybackControlsFragment :
|
|||
}
|
||||
|
||||
override fun setUpProgressSlider() {
|
||||
progressSlider.setOnSeekBarChangeListener(object : SimpleOnSeekbarChangeListener() {
|
||||
binding.progressSlider.setOnSeekBarChangeListener(object : SimpleOnSeekbarChangeListener() {
|
||||
override fun onProgressChanged(seekBar: SeekBar, progress: Int, fromUser: Boolean) {
|
||||
if (fromUser) {
|
||||
MusicPlayerRemote.seekTo(progress)
|
||||
|
@ -282,14 +299,19 @@ class FitPlaybackControlsFragment :
|
|||
}
|
||||
|
||||
override fun onUpdateProgressViews(progress: Int, total: Int) {
|
||||
progressSlider.max = total
|
||||
binding.progressSlider.max = total
|
||||
|
||||
val animator = ObjectAnimator.ofInt(progressSlider, "progress", progress)
|
||||
val animator = ObjectAnimator.ofInt(binding.progressSlider, "progress", progress)
|
||||
animator.duration = SLIDER_ANIMATION_TIME
|
||||
animator.interpolator = LinearInterpolator()
|
||||
animator.start()
|
||||
|
||||
songTotalTime.text = MusicUtil.getReadableDurationString(total.toLong())
|
||||
songCurrentProgress.text = MusicUtil.getReadableDurationString(progress.toLong())
|
||||
binding.songTotalTime.text = MusicUtil.getReadableDurationString(total.toLong())
|
||||
binding.songCurrentProgress.text = MusicUtil.getReadableDurationString(progress.toLong())
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
_binding = null
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,11 +27,14 @@ import code.name.monkey.appthemehelper.util.ColorUtil
|
|||
import code.name.monkey.appthemehelper.util.MaterialValueHelper
|
||||
import code.name.monkey.appthemehelper.util.TintHelper
|
||||
import code.name.monkey.retromusic.R
|
||||
import code.name.monkey.retromusic.databinding.FragmentFlatPlayerPlaybackControlsBinding
|
||||
import code.name.monkey.retromusic.extensions.applyColor
|
||||
import code.name.monkey.retromusic.extensions.hide
|
||||
import code.name.monkey.retromusic.extensions.ripAlpha
|
||||
import code.name.monkey.retromusic.extensions.show
|
||||
import code.name.monkey.retromusic.fragments.base.AbsPlayerControlsFragment
|
||||
import code.name.monkey.retromusic.fragments.base.goToAlbum
|
||||
import code.name.monkey.retromusic.fragments.base.goToArtist
|
||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote
|
||||
import code.name.monkey.retromusic.helper.MusicProgressViewUpdateHelper
|
||||
import code.name.monkey.retromusic.helper.MusicProgressViewUpdateHelper.Callback
|
||||
|
@ -41,7 +44,6 @@ import code.name.monkey.retromusic.service.MusicService
|
|||
import code.name.monkey.retromusic.util.MusicUtil
|
||||
import code.name.monkey.retromusic.util.PreferenceUtil
|
||||
import code.name.monkey.retromusic.util.color.MediaNotificationProcessor
|
||||
import kotlinx.android.synthetic.main.fragment_flat_player_playback_controls.*
|
||||
|
||||
class FlatPlaybackControlsFragment :
|
||||
AbsPlayerControlsFragment(R.layout.fragment_flat_player_playback_controls), Callback {
|
||||
|
@ -49,6 +51,9 @@ class FlatPlaybackControlsFragment :
|
|||
private var lastPlaybackControlsColor: Int = 0
|
||||
private var lastDisabledPlaybackControlsColor: Int = 0
|
||||
private lateinit var progressViewUpdateHelper: MusicProgressViewUpdateHelper
|
||||
private var _binding: FragmentFlatPlayerPlaybackControlsBinding? = null
|
||||
private val binding get() = _binding!!
|
||||
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
@ -57,9 +62,16 @@ class FlatPlaybackControlsFragment :
|
|||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
_binding = FragmentFlatPlayerPlaybackControlsBinding.bind(view)
|
||||
setUpMusicControllers()
|
||||
title.isSelected = true
|
||||
text.isSelected = true
|
||||
binding.title.isSelected = true
|
||||
binding.text.isSelected = true
|
||||
binding.title.setOnClickListener {
|
||||
goToAlbum(requireActivity())
|
||||
}
|
||||
binding.text.setOnClickListener {
|
||||
goToArtist(requireActivity())
|
||||
}
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
|
@ -73,7 +85,7 @@ class FlatPlaybackControlsFragment :
|
|||
}
|
||||
|
||||
public override fun show() {
|
||||
playPauseButton!!.animate()
|
||||
binding.playPauseButton.animate()
|
||||
.scaleX(1f)
|
||||
.scaleY(1f)
|
||||
.setInterpolator(DecelerateInterpolator())
|
||||
|
@ -81,7 +93,7 @@ class FlatPlaybackControlsFragment :
|
|||
}
|
||||
|
||||
public override fun hide() {
|
||||
playPauseButton!!.apply {
|
||||
binding.playPauseButton.apply {
|
||||
scaleX = 0f
|
||||
scaleY = 0f
|
||||
rotation = 0f
|
||||
|
@ -109,7 +121,7 @@ class FlatPlaybackControlsFragment :
|
|||
|
||||
updateTextColors(colorFinal)
|
||||
volumeFragment?.setTintable(colorFinal)
|
||||
progressSlider.applyColor(colorFinal)
|
||||
binding.progressSlider.applyColor(colorFinal)
|
||||
updateRepeatState()
|
||||
updateShuffleState()
|
||||
}
|
||||
|
@ -121,15 +133,15 @@ class FlatPlaybackControlsFragment :
|
|||
val colorSecondary =
|
||||
MaterialValueHelper.getSecondaryTextColor(context, ColorUtil.isColorLight(darkColor))
|
||||
|
||||
TintHelper.setTintAuto(playPauseButton, colorPrimary, false)
|
||||
TintHelper.setTintAuto(playPauseButton, color, true)
|
||||
TintHelper.setTintAuto(binding.playPauseButton, colorPrimary, false)
|
||||
TintHelper.setTintAuto(binding.playPauseButton, color, true)
|
||||
|
||||
title.setBackgroundColor(color)
|
||||
title.setTextColor(colorPrimary)
|
||||
text.setBackgroundColor(darkColor)
|
||||
text.setTextColor(colorSecondary)
|
||||
songInfo.setBackgroundColor(darkColor)
|
||||
songInfo.setTextColor(colorSecondary)
|
||||
binding.title.setBackgroundColor(color)
|
||||
binding.title.setTextColor(colorPrimary)
|
||||
binding.text.setBackgroundColor(darkColor)
|
||||
binding.text.setTextColor(colorSecondary)
|
||||
binding.songInfo.setBackgroundColor(darkColor)
|
||||
binding.songInfo.setTextColor(colorSecondary)
|
||||
}
|
||||
|
||||
override fun onServiceConnected() {
|
||||
|
@ -149,14 +161,14 @@ class FlatPlaybackControlsFragment :
|
|||
}
|
||||
|
||||
private fun setUpPlayPauseFab() {
|
||||
playPauseButton.setOnClickListener(PlayPauseButtonOnClickHandler())
|
||||
binding.playPauseButton.setOnClickListener(PlayPauseButtonOnClickHandler())
|
||||
}
|
||||
|
||||
private fun updatePlayPauseDrawableState() {
|
||||
if (MusicPlayerRemote.isPlaying) {
|
||||
playPauseButton.setImageResource(R.drawable.ic_pause)
|
||||
binding.playPauseButton.setImageResource(R.drawable.ic_pause)
|
||||
} else {
|
||||
playPauseButton.setImageResource(R.drawable.ic_play_arrow_white_32dp)
|
||||
binding.playPauseButton.setImageResource(R.drawable.ic_play_arrow_white_32dp)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -169,13 +181,13 @@ class FlatPlaybackControlsFragment :
|
|||
|
||||
private fun updateSong() {
|
||||
val song = MusicPlayerRemote.currentSong
|
||||
title.text = song.title
|
||||
text.text = song.artistName
|
||||
binding.title.text = song.title
|
||||
binding.text.text = song.artistName
|
||||
if (PreferenceUtil.isSongInfo) {
|
||||
songInfo.text = getSongInfo(song)
|
||||
songInfo.show()
|
||||
binding.songInfo.text = getSongInfo(song)
|
||||
binding.songInfo.show()
|
||||
} else {
|
||||
songInfo.hide()
|
||||
binding.songInfo.hide()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -188,40 +200,46 @@ class FlatPlaybackControlsFragment :
|
|||
}
|
||||
|
||||
private fun setUpRepeatButton() {
|
||||
repeatButton.setOnClickListener { MusicPlayerRemote.cycleRepeatMode() }
|
||||
binding.repeatButton.setOnClickListener { MusicPlayerRemote.cycleRepeatMode() }
|
||||
}
|
||||
|
||||
override fun updateRepeatState() {
|
||||
when (MusicPlayerRemote.repeatMode) {
|
||||
MusicService.REPEAT_MODE_NONE -> {
|
||||
repeatButton.setImageResource(R.drawable.ic_repeat)
|
||||
repeatButton.setColorFilter(
|
||||
binding.repeatButton.setImageResource(R.drawable.ic_repeat)
|
||||
binding.repeatButton.setColorFilter(
|
||||
lastDisabledPlaybackControlsColor,
|
||||
PorterDuff.Mode.SRC_IN
|
||||
)
|
||||
}
|
||||
MusicService.REPEAT_MODE_ALL -> {
|
||||
repeatButton.setImageResource(R.drawable.ic_repeat)
|
||||
repeatButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
|
||||
binding.repeatButton.setImageResource(R.drawable.ic_repeat)
|
||||
binding.repeatButton.setColorFilter(
|
||||
lastPlaybackControlsColor,
|
||||
PorterDuff.Mode.SRC_IN
|
||||
)
|
||||
}
|
||||
MusicService.REPEAT_MODE_THIS -> {
|
||||
repeatButton.setImageResource(R.drawable.ic_repeat_one)
|
||||
repeatButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
|
||||
binding.repeatButton.setImageResource(R.drawable.ic_repeat_one)
|
||||
binding.repeatButton.setColorFilter(
|
||||
lastPlaybackControlsColor,
|
||||
PorterDuff.Mode.SRC_IN
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun setUpShuffleButton() {
|
||||
shuffleButton.setOnClickListener { MusicPlayerRemote.toggleShuffleMode() }
|
||||
binding.shuffleButton.setOnClickListener { MusicPlayerRemote.toggleShuffleMode() }
|
||||
}
|
||||
|
||||
override fun updateShuffleState() {
|
||||
when (MusicPlayerRemote.shuffleMode) {
|
||||
MusicService.SHUFFLE_MODE_SHUFFLE -> shuffleButton.setColorFilter(
|
||||
MusicService.SHUFFLE_MODE_SHUFFLE -> binding.shuffleButton.setColorFilter(
|
||||
lastPlaybackControlsColor,
|
||||
PorterDuff.Mode.SRC_IN
|
||||
)
|
||||
else -> shuffleButton.setColorFilter(
|
||||
else -> binding.shuffleButton.setColorFilter(
|
||||
lastDisabledPlaybackControlsColor,
|
||||
PorterDuff.Mode.SRC_IN
|
||||
)
|
||||
|
@ -229,7 +247,7 @@ class FlatPlaybackControlsFragment :
|
|||
}
|
||||
|
||||
override fun setUpProgressSlider() {
|
||||
progressSlider.setOnSeekBarChangeListener(object : SimpleOnSeekbarChangeListener() {
|
||||
binding.progressSlider.setOnSeekBarChangeListener(object : SimpleOnSeekbarChangeListener() {
|
||||
override fun onProgressChanged(seekBar: SeekBar, progress: Int, fromUser: Boolean) {
|
||||
if (fromUser) {
|
||||
MusicPlayerRemote.seekTo(progress)
|
||||
|
@ -243,14 +261,19 @@ class FlatPlaybackControlsFragment :
|
|||
}
|
||||
|
||||
override fun onUpdateProgressViews(progress: Int, total: Int) {
|
||||
progressSlider.max = total
|
||||
binding.progressSlider.max = total
|
||||
|
||||
val animator = ObjectAnimator.ofInt(progressSlider, "progress", progress)
|
||||
val animator = ObjectAnimator.ofInt(binding.progressSlider, "progress", progress)
|
||||
animator.duration = SLIDER_ANIMATION_TIME
|
||||
animator.interpolator = LinearInterpolator()
|
||||
animator.start()
|
||||
|
||||
songTotalTime.text = MusicUtil.getReadableDurationString(total.toLong())
|
||||
songCurrentProgress.text = MusicUtil.getReadableDurationString(progress.toLong())
|
||||
binding.songTotalTime.text = MusicUtil.getReadableDurationString(total.toLong())
|
||||
binding.songCurrentProgress.text = MusicUtil.getReadableDurationString(progress.toLong())
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
_binding = null
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@ import code.name.monkey.appthemehelper.util.ColorUtil
|
|||
import code.name.monkey.appthemehelper.util.MaterialValueHelper
|
||||
import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper
|
||||
import code.name.monkey.retromusic.R
|
||||
import code.name.monkey.retromusic.databinding.FragmentFlatPlayerBinding
|
||||
import code.name.monkey.retromusic.fragments.base.AbsPlayerFragment
|
||||
import code.name.monkey.retromusic.fragments.player.PlayerAlbumCoverFragment
|
||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote
|
||||
|
@ -33,11 +34,10 @@ import code.name.monkey.retromusic.util.PreferenceUtil
|
|||
import code.name.monkey.retromusic.util.ViewUtil
|
||||
import code.name.monkey.retromusic.util.color.MediaNotificationProcessor
|
||||
import code.name.monkey.retromusic.views.DrawableGradient
|
||||
import kotlinx.android.synthetic.main.fragment_flat_player.*
|
||||
|
||||
class FlatPlayerFragment : AbsPlayerFragment(R.layout.fragment_flat_player) {
|
||||
override fun playerToolbar(): Toolbar {
|
||||
return playerToolbar
|
||||
return binding.playerToolbar
|
||||
}
|
||||
|
||||
private var valueAnimator: ValueAnimator? = null
|
||||
|
@ -46,6 +46,10 @@ class FlatPlayerFragment : AbsPlayerFragment(R.layout.fragment_flat_player) {
|
|||
override val paletteColor: Int
|
||||
get() = lastColor
|
||||
|
||||
private var _binding: FragmentFlatPlayerBinding? = null
|
||||
private val binding get() = _binding!!
|
||||
|
||||
|
||||
private fun setUpSubFragments() {
|
||||
controlsFragment =
|
||||
childFragmentManager.findFragmentById(R.id.playbackControlsFragment) as FlatPlaybackControlsFragment
|
||||
|
@ -55,11 +59,11 @@ class FlatPlayerFragment : AbsPlayerFragment(R.layout.fragment_flat_player) {
|
|||
}
|
||||
|
||||
private fun setUpPlayerToolbar() {
|
||||
playerToolbar.inflateMenu(R.menu.menu_player)
|
||||
playerToolbar.setNavigationOnClickListener { _ -> requireActivity().onBackPressed() }
|
||||
playerToolbar.setOnMenuItemClickListener(this)
|
||||
binding.playerToolbar.inflateMenu(R.menu.menu_player)
|
||||
binding.playerToolbar.setNavigationOnClickListener { requireActivity().onBackPressed() }
|
||||
binding.playerToolbar.setOnMenuItemClickListener(this)
|
||||
ToolbarContentTintHelper.colorizeToolbar(
|
||||
playerToolbar,
|
||||
binding.playerToolbar,
|
||||
ATHUtil.resolveColor(requireContext(), R.attr.colorControlNormal),
|
||||
requireActivity()
|
||||
)
|
||||
|
@ -76,13 +80,14 @@ class FlatPlayerFragment : AbsPlayerFragment(R.layout.fragment_flat_player) {
|
|||
GradientDrawable.Orientation.TOP_BOTTOM,
|
||||
intArrayOf(animation.animatedValue as Int, android.R.color.transparent), 0
|
||||
)
|
||||
colorGradientBackground?.background = drawable
|
||||
binding.colorGradientBackground.background = drawable
|
||||
}
|
||||
valueAnimator?.setDuration(ViewUtil.RETRO_MUSIC_ANIM_TIME.toLong())?.start()
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
_binding = FragmentFlatPlayerBinding.bind(view)
|
||||
setUpPlayerToolbar()
|
||||
setUpSubFragments()
|
||||
}
|
||||
|
@ -117,7 +122,11 @@ class FlatPlayerFragment : AbsPlayerFragment(R.layout.fragment_flat_player) {
|
|||
MaterialValueHelper.getPrimaryTextColor(requireContext(), isLight)
|
||||
else
|
||||
ATHUtil.resolveColor(requireContext(), R.attr.colorControlNormal)
|
||||
ToolbarContentTintHelper.colorizeToolbar(playerToolbar, iconColor, requireActivity())
|
||||
ToolbarContentTintHelper.colorizeToolbar(
|
||||
binding.playerToolbar,
|
||||
iconColor,
|
||||
requireActivity()
|
||||
)
|
||||
if (PreferenceUtil.isAdaptiveColor) {
|
||||
colorize(color.backgroundColor)
|
||||
}
|
||||
|
@ -133,4 +142,9 @@ class FlatPlayerFragment : AbsPlayerFragment(R.layout.fragment_flat_player) {
|
|||
updateIsFavorite()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
_binding = null
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,13 +15,12 @@
|
|||
package code.name.monkey.retromusic.fragments.player.full
|
||||
|
||||
import android.animation.ObjectAnimator
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Intent
|
||||
import android.content.res.ColorStateList
|
||||
import android.graphics.Color
|
||||
import android.graphics.PorterDuff
|
||||
import android.graphics.drawable.AnimatedVectorDrawable
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.os.AsyncTask
|
||||
import android.os.Bundle
|
||||
import android.view.MenuItem
|
||||
import android.view.View
|
||||
|
@ -31,8 +30,8 @@ import android.widget.PopupMenu
|
|||
import android.widget.SeekBar
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import code.name.monkey.appthemehelper.util.ColorUtil
|
||||
import code.name.monkey.appthemehelper.util.TintHelper
|
||||
import code.name.monkey.retromusic.R
|
||||
import code.name.monkey.retromusic.databinding.FragmentFullPlayerControlsBinding
|
||||
import code.name.monkey.retromusic.db.PlaylistEntity
|
||||
import code.name.monkey.retromusic.db.SongEntity
|
||||
import code.name.monkey.retromusic.db.toSongEntity
|
||||
|
@ -42,6 +41,8 @@ import code.name.monkey.retromusic.extensions.show
|
|||
import code.name.monkey.retromusic.fragments.LibraryViewModel
|
||||
import code.name.monkey.retromusic.fragments.ReloadType
|
||||
import code.name.monkey.retromusic.fragments.base.AbsPlayerControlsFragment
|
||||
import code.name.monkey.retromusic.fragments.base.goToAlbum
|
||||
import code.name.monkey.retromusic.fragments.base.goToArtist
|
||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote
|
||||
import code.name.monkey.retromusic.helper.MusicProgressViewUpdateHelper
|
||||
import code.name.monkey.retromusic.helper.PlayPauseButtonOnClickHandler
|
||||
|
@ -52,7 +53,6 @@ import code.name.monkey.retromusic.util.MusicUtil
|
|||
import code.name.monkey.retromusic.util.PreferenceUtil
|
||||
import code.name.monkey.retromusic.util.RetroUtil
|
||||
import code.name.monkey.retromusic.util.color.MediaNotificationProcessor
|
||||
import kotlinx.android.synthetic.main.fragment_full_player_controls.*
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
|
@ -70,6 +70,8 @@ class FullPlaybackControlsFragment :
|
|||
private var lastDisabledPlaybackControlsColor: Int = 0
|
||||
private lateinit var progressViewUpdateHelper: MusicProgressViewUpdateHelper
|
||||
private val libraryViewModel: LibraryViewModel by sharedViewModel()
|
||||
private var _binding: FragmentFullPlayerControlsBinding? = null
|
||||
private val binding get() = _binding!!
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
@ -78,11 +80,18 @@ class FullPlaybackControlsFragment :
|
|||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
setUpMusicControllers()
|
||||
_binding = FragmentFullPlayerControlsBinding.bind(view)
|
||||
|
||||
songTotalTime.setTextColor(Color.WHITE)
|
||||
songCurrentProgress.setTextColor(Color.WHITE)
|
||||
title.isSelected = true
|
||||
setUpMusicControllers()
|
||||
binding.songTotalTime.setTextColor(Color.WHITE)
|
||||
binding.songCurrentProgress.setTextColor(Color.WHITE)
|
||||
binding.title.isSelected = true
|
||||
binding.title.setOnClickListener {
|
||||
goToAlbum(requireActivity())
|
||||
}
|
||||
binding.text.setOnClickListener {
|
||||
goToArtist(requireActivity())
|
||||
}
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
|
@ -96,7 +105,7 @@ class FullPlaybackControlsFragment :
|
|||
}
|
||||
|
||||
public override fun show() {
|
||||
playPauseButton!!.animate()
|
||||
binding.playPauseButton.animate()
|
||||
.scaleX(1f)
|
||||
.scaleY(1f)
|
||||
.setInterpolator(DecelerateInterpolator())
|
||||
|
@ -104,7 +113,7 @@ class FullPlaybackControlsFragment :
|
|||
}
|
||||
|
||||
public override fun hide() {
|
||||
playPauseButton.apply {
|
||||
binding.playPauseButton.apply {
|
||||
scaleX = 0f
|
||||
scaleY = 0f
|
||||
rotation = 0f
|
||||
|
@ -116,18 +125,18 @@ class FullPlaybackControlsFragment :
|
|||
lastDisabledPlaybackControlsColor = ColorUtil.withAlpha(color.primaryTextColor, 0.3f)
|
||||
|
||||
val tintList = ColorStateList.valueOf(color.primaryTextColor)
|
||||
playerMenu.imageTintList = tintList
|
||||
songFavourite.imageTintList = tintList
|
||||
binding.playerMenu.imageTintList = tintList
|
||||
binding.songFavourite.imageTintList = tintList
|
||||
volumeFragment?.setTintableColor(color.primaryTextColor)
|
||||
progressSlider.applyColor(color.primaryTextColor)
|
||||
title.setTextColor(color.primaryTextColor)
|
||||
text.setTextColor(color.secondaryTextColor)
|
||||
songInfo.setTextColor(color.secondaryTextColor)
|
||||
songCurrentProgress.setTextColor(color.secondaryTextColor)
|
||||
songTotalTime.setTextColor(color.secondaryTextColor)
|
||||
binding.progressSlider.applyColor(color.primaryTextColor)
|
||||
binding.title.setTextColor(color.primaryTextColor)
|
||||
binding.text.setTextColor(color.secondaryTextColor)
|
||||
binding.songInfo.setTextColor(color.secondaryTextColor)
|
||||
binding.songCurrentProgress.setTextColor(color.secondaryTextColor)
|
||||
binding.songTotalTime.setTextColor(color.secondaryTextColor)
|
||||
|
||||
playPauseButton.backgroundTintList = tintList
|
||||
playPauseButton.imageTintList = ColorStateList.valueOf(color.backgroundColor)
|
||||
binding.playPauseButton.backgroundTintList = tintList
|
||||
binding.playPauseButton.imageTintList = ColorStateList.valueOf(color.backgroundColor)
|
||||
|
||||
updateRepeatState()
|
||||
updateShuffleState()
|
||||
|
@ -143,14 +152,14 @@ class FullPlaybackControlsFragment :
|
|||
|
||||
private fun updateSong() {
|
||||
val song = MusicPlayerRemote.currentSong
|
||||
title.text = song.title
|
||||
text.text = song.artistName
|
||||
binding.title.text = song.title
|
||||
binding.text.text = song.artistName
|
||||
updateIsFavorite()
|
||||
if (PreferenceUtil.isSongInfo) {
|
||||
songInfo.text = getSongInfo(song)
|
||||
songInfo.show()
|
||||
binding.songInfo.text = getSongInfo(song)
|
||||
binding.songInfo.show()
|
||||
} else {
|
||||
songInfo.hide()
|
||||
binding.songInfo.hide()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -165,19 +174,17 @@ class FullPlaybackControlsFragment :
|
|||
|
||||
private fun updatePlayPauseDrawableState() {
|
||||
if (MusicPlayerRemote.isPlaying) {
|
||||
playPauseButton.setImageResource(R.drawable.ic_pause)
|
||||
binding.playPauseButton.setImageResource(R.drawable.ic_pause)
|
||||
} else {
|
||||
playPauseButton.setImageResource(R.drawable.ic_play_arrow_white_32dp)
|
||||
binding.playPauseButton.setImageResource(R.drawable.ic_play_arrow_white_32dp)
|
||||
}
|
||||
}
|
||||
|
||||
private fun setUpPlayPauseFab() {
|
||||
playPauseButton.setOnClickListener(PlayPauseButtonOnClickHandler())
|
||||
playPauseButton.post {
|
||||
if (playPauseButton != null) {
|
||||
playPauseButton.pivotX = (playPauseButton.width / 2).toFloat()
|
||||
playPauseButton.pivotY = (playPauseButton.height / 2).toFloat()
|
||||
}
|
||||
binding.playPauseButton.setOnClickListener(PlayPauseButtonOnClickHandler())
|
||||
binding.playPauseButton.post {
|
||||
binding.playPauseButton.pivotX = (binding.playPauseButton.width / 2).toFloat()
|
||||
binding.playPauseButton.pivotY = (binding.playPauseButton.height / 2).toFloat()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -192,10 +199,11 @@ class FullPlaybackControlsFragment :
|
|||
}
|
||||
|
||||
private fun setupMenu() {
|
||||
playerMenu.setOnClickListener {
|
||||
binding.playerMenu.setOnClickListener {
|
||||
val popupMenu = PopupMenu(requireContext(), it)
|
||||
popupMenu.setOnMenuItemClickListener(this)
|
||||
popupMenu.inflate(R.menu.menu_player)
|
||||
popupMenu.menu.findItem(R.id.action_toggle_favorite).isVisible = false
|
||||
popupMenu.show()
|
||||
}
|
||||
}
|
||||
|
@ -206,17 +214,17 @@ class FullPlaybackControlsFragment :
|
|||
|
||||
private fun setUpPrevNext() {
|
||||
updatePrevNextColor()
|
||||
nextButton.setOnClickListener { MusicPlayerRemote.playNextSong() }
|
||||
previousButton.setOnClickListener { MusicPlayerRemote.back() }
|
||||
binding.nextButton.setOnClickListener { MusicPlayerRemote.playNextSong() }
|
||||
binding.previousButton.setOnClickListener { MusicPlayerRemote.back() }
|
||||
}
|
||||
|
||||
private fun updatePrevNextColor() {
|
||||
nextButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
|
||||
previousButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
|
||||
binding.nextButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
|
||||
binding.previousButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
|
||||
}
|
||||
|
||||
override fun setUpProgressSlider() {
|
||||
progressSlider.setOnSeekBarChangeListener(object : SimpleOnSeekbarChangeListener() {
|
||||
binding.progressSlider.setOnSeekBarChangeListener(object : SimpleOnSeekbarChangeListener() {
|
||||
override fun onProgressChanged(seekBar: SeekBar, progress: Int, fromUser: Boolean) {
|
||||
if (fromUser) {
|
||||
MusicPlayerRemote.seekTo(progress)
|
||||
|
@ -230,15 +238,15 @@ class FullPlaybackControlsFragment :
|
|||
}
|
||||
|
||||
override fun onUpdateProgressViews(progress: Int, total: Int) {
|
||||
progressSlider.max = total
|
||||
binding.progressSlider.max = total
|
||||
|
||||
val animator = ObjectAnimator.ofInt(progressSlider, "progress", progress)
|
||||
val animator = ObjectAnimator.ofInt(binding.progressSlider, "progress", progress)
|
||||
animator.duration = SLIDER_ANIMATION_TIME
|
||||
animator.interpolator = LinearInterpolator()
|
||||
animator.start()
|
||||
|
||||
songTotalTime.text = MusicUtil.getReadableDurationString(total.toLong())
|
||||
songCurrentProgress.text = MusicUtil.getReadableDurationString(progress.toLong())
|
||||
binding.songTotalTime.text = MusicUtil.getReadableDurationString(total.toLong())
|
||||
binding.songCurrentProgress.text = MusicUtil.getReadableDurationString(progress.toLong())
|
||||
}
|
||||
|
||||
override fun onRepeatModeChanged() {
|
||||
|
@ -250,16 +258,16 @@ class FullPlaybackControlsFragment :
|
|||
}
|
||||
|
||||
private fun setUpShuffleButton() {
|
||||
shuffleButton.setOnClickListener { MusicPlayerRemote.toggleShuffleMode() }
|
||||
binding.shuffleButton.setOnClickListener { MusicPlayerRemote.toggleShuffleMode() }
|
||||
}
|
||||
|
||||
override fun updateShuffleState() {
|
||||
when (MusicPlayerRemote.shuffleMode) {
|
||||
MusicService.SHUFFLE_MODE_SHUFFLE -> shuffleButton.setColorFilter(
|
||||
MusicService.SHUFFLE_MODE_SHUFFLE -> binding.shuffleButton.setColorFilter(
|
||||
lastPlaybackControlsColor,
|
||||
PorterDuff.Mode.SRC_IN
|
||||
)
|
||||
else -> shuffleButton.setColorFilter(
|
||||
else -> binding.shuffleButton.setColorFilter(
|
||||
lastDisabledPlaybackControlsColor,
|
||||
PorterDuff.Mode.SRC_IN
|
||||
)
|
||||
|
@ -267,36 +275,46 @@ class FullPlaybackControlsFragment :
|
|||
}
|
||||
|
||||
private fun setUpRepeatButton() {
|
||||
repeatButton.setOnClickListener { MusicPlayerRemote.cycleRepeatMode() }
|
||||
binding.repeatButton.setOnClickListener { MusicPlayerRemote.cycleRepeatMode() }
|
||||
}
|
||||
|
||||
override fun updateRepeatState() {
|
||||
when (MusicPlayerRemote.repeatMode) {
|
||||
MusicService.REPEAT_MODE_NONE -> {
|
||||
repeatButton.setImageResource(R.drawable.ic_repeat)
|
||||
repeatButton.setColorFilter(
|
||||
binding.repeatButton.setImageResource(R.drawable.ic_repeat)
|
||||
binding.repeatButton.setColorFilter(
|
||||
lastDisabledPlaybackControlsColor,
|
||||
PorterDuff.Mode.SRC_IN
|
||||
)
|
||||
}
|
||||
MusicService.REPEAT_MODE_ALL -> {
|
||||
repeatButton.setImageResource(R.drawable.ic_repeat)
|
||||
repeatButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
|
||||
binding.repeatButton.setImageResource(R.drawable.ic_repeat)
|
||||
binding.repeatButton.setColorFilter(
|
||||
lastPlaybackControlsColor,
|
||||
PorterDuff.Mode.SRC_IN
|
||||
)
|
||||
}
|
||||
MusicService.REPEAT_MODE_THIS -> {
|
||||
repeatButton.setImageResource(R.drawable.ic_repeat_one)
|
||||
repeatButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
|
||||
binding.repeatButton.setImageResource(R.drawable.ic_repeat_one)
|
||||
binding.repeatButton.setColorFilter(
|
||||
lastPlaybackControlsColor,
|
||||
PorterDuff.Mode.SRC_IN
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun setupFavourite() {
|
||||
songFavourite?.setOnClickListener {
|
||||
binding.songFavourite.setOnClickListener {
|
||||
toggleFavorite(MusicPlayerRemote.currentSong)
|
||||
}
|
||||
}
|
||||
|
||||
fun updateIsFavorite() {
|
||||
override fun onFavoriteStateChanged() {
|
||||
updateIsFavorite(animate = true)
|
||||
}
|
||||
|
||||
fun updateIsFavorite(animate: Boolean = false) {
|
||||
lifecycleScope.launch(Dispatchers.IO) {
|
||||
val playlist: PlaylistEntity? = libraryViewModel.favoritePlaylist()
|
||||
if (playlist != null) {
|
||||
|
@ -304,19 +322,30 @@ class FullPlaybackControlsFragment :
|
|||
MusicPlayerRemote.currentSong.toSongEntity(playlist.playListId)
|
||||
val isFavorite: Boolean = libraryViewModel.isFavoriteSong(song).isNotEmpty()
|
||||
withContext(Dispatchers.Main) {
|
||||
val icon =
|
||||
val icon = if (animate) {
|
||||
if (isFavorite) R.drawable.avd_favorite else R.drawable.avd_unfavorite
|
||||
} else {
|
||||
if (isFavorite) R.drawable.ic_favorite else R.drawable.ic_favorite_border
|
||||
val drawable = TintHelper.createTintedDrawable(activity, icon, Color.WHITE)
|
||||
songFavourite?.setImageDrawable(drawable)
|
||||
}
|
||||
val drawable: Drawable? = RetroUtil.getTintedVectorDrawable(
|
||||
requireContext(),
|
||||
icon,
|
||||
Color.WHITE
|
||||
)
|
||||
binding.songFavourite.apply {
|
||||
setImageDrawable(drawable)
|
||||
getDrawable().also {
|
||||
if (it is AnimatedVectorDrawable) {
|
||||
it.start()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun toggleFavorite(song: Song) {
|
||||
if (song.id == MusicPlayerRemote.currentSong.id) {
|
||||
updateIsFavorite()
|
||||
}
|
||||
lifecycleScope.launch(Dispatchers.IO) {
|
||||
val playlist: PlaylistEntity? = libraryViewModel.favoritePlaylist()
|
||||
if (playlist != null) {
|
||||
|
@ -336,4 +365,9 @@ class FullPlaybackControlsFragment :
|
|||
fun onFavoriteToggled() {
|
||||
toggleFavorite(MusicPlayerRemote.currentSong)
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
_binding = null
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,119 +18,29 @@ import android.content.res.ColorStateList
|
|||
import android.graphics.Color
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import android.widget.FrameLayout
|
||||
import android.widget.TextView
|
||||
import androidx.appcompat.widget.Toolbar
|
||||
import androidx.core.os.bundleOf
|
||||
import androidx.navigation.fragment.findNavController
|
||||
import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper
|
||||
import code.name.monkey.retromusic.EXTRA_ARTIST_ID
|
||||
import code.name.monkey.retromusic.R
|
||||
import code.name.monkey.retromusic.databinding.FragmentFullBinding
|
||||
import code.name.monkey.retromusic.extensions.hide
|
||||
import code.name.monkey.retromusic.extensions.show
|
||||
import code.name.monkey.retromusic.extensions.whichFragment
|
||||
import code.name.monkey.retromusic.fragments.base.AbsPlayerFragment
|
||||
import code.name.monkey.retromusic.fragments.base.goToArtist
|
||||
import code.name.monkey.retromusic.fragments.player.PlayerAlbumCoverFragment
|
||||
import code.name.monkey.retromusic.glide.ArtistGlideRequest
|
||||
import code.name.monkey.retromusic.glide.GlideApp
|
||||
import code.name.monkey.retromusic.glide.RetroGlideExtension
|
||||
import code.name.monkey.retromusic.glide.RetroMusicColoredTarget
|
||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote
|
||||
import code.name.monkey.retromusic.helper.MusicProgressViewUpdateHelper
|
||||
import code.name.monkey.retromusic.model.Song
|
||||
import code.name.monkey.retromusic.model.lyrics.AbsSynchronizedLyrics
|
||||
import code.name.monkey.retromusic.model.lyrics.Lyrics
|
||||
import code.name.monkey.retromusic.util.color.MediaNotificationProcessor
|
||||
import com.bumptech.glide.Glide
|
||||
import kotlinx.android.synthetic.main.fragment_full.*
|
||||
|
||||
class FullPlayerFragment : AbsPlayerFragment(R.layout.fragment_full),
|
||||
MusicProgressViewUpdateHelper.Callback {
|
||||
private lateinit var lyricsLayout: FrameLayout
|
||||
private lateinit var lyricsLine1: TextView
|
||||
private lateinit var lyricsLine2: TextView
|
||||
|
||||
private var lyrics: Lyrics? = null
|
||||
private lateinit var progressViewUpdateHelper: MusicProgressViewUpdateHelper
|
||||
|
||||
override fun onUpdateProgressViews(progress: Int, total: Int) {
|
||||
if (!isLyricsLayoutBound()) return
|
||||
|
||||
if (!isLyricsLayoutVisible()) {
|
||||
hideLyricsLayout()
|
||||
return
|
||||
}
|
||||
|
||||
if (lyrics !is AbsSynchronizedLyrics) return
|
||||
val synchronizedLyrics = lyrics as AbsSynchronizedLyrics
|
||||
|
||||
lyricsLayout.visibility = View.VISIBLE
|
||||
lyricsLayout.alpha = 1f
|
||||
|
||||
val oldLine = lyricsLine2.text.toString()
|
||||
val line = synchronizedLyrics.getLine(progress)
|
||||
|
||||
if (oldLine != line || oldLine.isEmpty()) {
|
||||
lyricsLine1.text = oldLine
|
||||
lyricsLine2.text = line
|
||||
|
||||
lyricsLine1.visibility = View.VISIBLE
|
||||
lyricsLine2.visibility = View.VISIBLE
|
||||
|
||||
lyricsLine2.measure(
|
||||
View.MeasureSpec.makeMeasureSpec(
|
||||
lyricsLine2.measuredWidth,
|
||||
View.MeasureSpec.EXACTLY
|
||||
),
|
||||
View.MeasureSpec.UNSPECIFIED
|
||||
)
|
||||
val h: Float = lyricsLine2.measuredHeight.toFloat()
|
||||
|
||||
lyricsLine1.alpha = 1f
|
||||
lyricsLine1.translationY = 0f
|
||||
lyricsLine1.animate().alpha(0f).translationY(-h).duration = VISIBILITY_ANIM_DURATION
|
||||
|
||||
lyricsLine2.alpha = 0f
|
||||
lyricsLine2.translationY = h
|
||||
lyricsLine2.animate().alpha(1f).translationY(0f).duration = VISIBILITY_ANIM_DURATION
|
||||
}
|
||||
}
|
||||
|
||||
private fun isLyricsLayoutVisible(): Boolean {
|
||||
return lyrics != null && lyrics!!.isSynchronized && lyrics!!.isValid
|
||||
}
|
||||
|
||||
private fun isLyricsLayoutBound(): Boolean {
|
||||
return lyricsLayout != null && lyricsLine1 != null && lyricsLine2 != null
|
||||
}
|
||||
|
||||
private fun hideLyricsLayout() {
|
||||
lyricsLayout.animate().alpha(0f).setDuration(VISIBILITY_ANIM_DURATION)
|
||||
.withEndAction(Runnable {
|
||||
if (!isLyricsLayoutBound()) return@Runnable
|
||||
lyricsLayout.visibility = View.GONE
|
||||
lyricsLine1.text = null
|
||||
lyricsLine2.text = null
|
||||
})
|
||||
}
|
||||
|
||||
override fun setLyrics(l: Lyrics?) {
|
||||
lyrics = l
|
||||
|
||||
if (!isLyricsLayoutBound()) return
|
||||
|
||||
if (!isLyricsLayoutVisible()) {
|
||||
hideLyricsLayout()
|
||||
return
|
||||
}
|
||||
|
||||
lyricsLine1.text = null
|
||||
lyricsLine2.text = null
|
||||
|
||||
lyricsLayout.visibility = View.VISIBLE
|
||||
lyricsLayout.animate().alpha(1f).duration = VISIBILITY_ANIM_DURATION
|
||||
}
|
||||
class FullPlayerFragment : AbsPlayerFragment(R.layout.fragment_full) {
|
||||
private var _binding: FragmentFullBinding? = null
|
||||
private val binding get() = _binding!!
|
||||
|
||||
override fun playerToolbar(): Toolbar {
|
||||
return playerToolbar
|
||||
return binding.playerToolbar
|
||||
}
|
||||
|
||||
private var lastColor: Int = 0
|
||||
|
@ -139,33 +49,24 @@ class FullPlayerFragment : AbsPlayerFragment(R.layout.fragment_full),
|
|||
private lateinit var controlsFragment: FullPlaybackControlsFragment
|
||||
|
||||
private fun setUpPlayerToolbar() {
|
||||
playerToolbar.apply {
|
||||
binding.playerToolbar.apply {
|
||||
setNavigationOnClickListener { requireActivity().onBackPressed() }
|
||||
}
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
lyricsLayout = view.findViewById(R.id.playerLyrics)
|
||||
lyricsLine1 = view.findViewById(R.id.player_lyrics_line1)
|
||||
lyricsLine2 = view.findViewById(R.id.player_lyrics_line2)
|
||||
_binding = FragmentFullBinding.bind(view)
|
||||
|
||||
setUpSubFragments()
|
||||
setUpPlayerToolbar()
|
||||
setupArtist()
|
||||
nextSong.isSelected = true
|
||||
|
||||
progressViewUpdateHelper = MusicProgressViewUpdateHelper(this, 500, 1000)
|
||||
progressViewUpdateHelper.start()
|
||||
binding.nextSong.isSelected = true
|
||||
}
|
||||
|
||||
private fun setupArtist() {
|
||||
artistImage.setOnClickListener {
|
||||
mainActivity.collapsePanel()
|
||||
findNavController().navigate(
|
||||
R.id.artistDetailsFragment,
|
||||
bundleOf(EXTRA_ARTIST_ID to MusicPlayerRemote.currentSong.artistId),
|
||||
)
|
||||
binding.artistImage.setOnClickListener {
|
||||
goToArtist(mainActivity)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -192,10 +93,10 @@ class FullPlayerFragment : AbsPlayerFragment(R.layout.fragment_full),
|
|||
|
||||
override fun onColorChanged(color: MediaNotificationProcessor) {
|
||||
lastColor = color.backgroundColor
|
||||
mask.backgroundTintList = ColorStateList.valueOf(color.backgroundColor)
|
||||
binding.mask.backgroundTintList = ColorStateList.valueOf(color.backgroundColor)
|
||||
controlsFragment.setColor(color)
|
||||
libraryViewModel.updateColor(color.backgroundColor)
|
||||
ToolbarContentTintHelper.colorizeToolbar(playerToolbar, Color.WHITE, activity)
|
||||
ToolbarContentTintHelper.colorizeToolbar(binding.playerToolbar, Color.WHITE, activity)
|
||||
}
|
||||
|
||||
override fun onFavoriteToggled() {
|
||||
|
@ -224,16 +125,15 @@ class FullPlayerFragment : AbsPlayerFragment(R.layout.fragment_full),
|
|||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
progressViewUpdateHelper.stop()
|
||||
_binding = null
|
||||
}
|
||||
|
||||
private fun updateArtistImage() {
|
||||
libraryViewModel.artist(MusicPlayerRemote.currentSong.artistId)
|
||||
.observe(viewLifecycleOwner, { artist ->
|
||||
ArtistGlideRequest.Builder.from(Glide.with(requireContext()), artist)
|
||||
.generatePalette(requireContext())
|
||||
.build()
|
||||
.into(object : RetroMusicColoredTarget(artistImage) {
|
||||
GlideApp.with(requireActivity()).asBitmapPalette().artistImageOptions(artist)
|
||||
.load(RetroGlideExtension.getArtistModel(artist))
|
||||
.into(object : RetroMusicColoredTarget(binding.artistImage) {
|
||||
override fun onColorReady(colors: MediaNotificationProcessor) {
|
||||
}
|
||||
})
|
||||
|
@ -248,12 +148,12 @@ class FullPlayerFragment : AbsPlayerFragment(R.layout.fragment_full),
|
|||
private fun updateLabel() {
|
||||
(MusicPlayerRemote.playingQueue.size - 1).apply {
|
||||
if (this == (MusicPlayerRemote.position)) {
|
||||
nextSongLabel.setText(R.string.last_song)
|
||||
nextSong.hide()
|
||||
binding.nextSongLabel.setText(R.string.last_song)
|
||||
binding.nextSong.hide()
|
||||
} else {
|
||||
val title = MusicPlayerRemote.playingQueue[MusicPlayerRemote.position + 1].title
|
||||
nextSongLabel.setText(R.string.next_song)
|
||||
nextSong.apply {
|
||||
binding.nextSongLabel.setText(R.string.next_song)
|
||||
binding.nextSong.apply {
|
||||
text = title
|
||||
show()
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@ import android.annotation.SuppressLint
|
|||
import android.content.res.ColorStateList
|
||||
import android.graphics.Color
|
||||
import android.graphics.PorterDuff
|
||||
import android.graphics.drawable.AnimatedVectorDrawable
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import android.view.animation.LinearInterpolator
|
||||
|
@ -35,6 +36,7 @@ import code.name.monkey.appthemehelper.util.ColorUtil
|
|||
import code.name.monkey.retromusic.R
|
||||
import code.name.monkey.retromusic.RetroBottomSheetBehavior
|
||||
import code.name.monkey.retromusic.adapter.song.PlayingQueueAdapter
|
||||
import code.name.monkey.retromusic.databinding.FragmentGradientPlayerBinding
|
||||
import code.name.monkey.retromusic.db.PlaylistEntity
|
||||
import code.name.monkey.retromusic.db.SongEntity
|
||||
import code.name.monkey.retromusic.db.toSongEntity
|
||||
|
@ -44,11 +46,12 @@ import code.name.monkey.retromusic.extensions.show
|
|||
import code.name.monkey.retromusic.fragments.VolumeFragment
|
||||
import code.name.monkey.retromusic.fragments.base.AbsPlayerControlsFragment
|
||||
import code.name.monkey.retromusic.fragments.base.AbsPlayerFragment
|
||||
import code.name.monkey.retromusic.fragments.base.goToAlbum
|
||||
import code.name.monkey.retromusic.fragments.base.goToArtist
|
||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote
|
||||
import code.name.monkey.retromusic.helper.MusicProgressViewUpdateHelper
|
||||
import code.name.monkey.retromusic.helper.PlayPauseButtonOnClickHandler
|
||||
import code.name.monkey.retromusic.misc.SimpleOnSeekbarChangeListener
|
||||
import code.name.monkey.retromusic.model.Song
|
||||
import code.name.monkey.retromusic.service.MusicService
|
||||
import code.name.monkey.retromusic.util.MusicUtil
|
||||
import code.name.monkey.retromusic.util.PreferenceUtil
|
||||
|
@ -60,9 +63,6 @@ import com.h6ah4i.android.widget.advrecyclerview.draggable.RecyclerViewDragDropM
|
|||
import com.h6ah4i.android.widget.advrecyclerview.swipeable.RecyclerViewSwipeManager
|
||||
import com.h6ah4i.android.widget.advrecyclerview.touchguard.RecyclerViewTouchActionGuardManager
|
||||
import com.h6ah4i.android.widget.advrecyclerview.utils.WrapperAdapterUtils
|
||||
import kotlinx.android.synthetic.main.fragment_gradient_controls.*
|
||||
import kotlinx.android.synthetic.main.fragment_gradient_player.*
|
||||
import kotlinx.android.synthetic.main.status_bar.*
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
|
@ -82,14 +82,17 @@ class GradientPlayerFragment : AbsPlayerFragment(R.layout.fragment_gradient_play
|
|||
private var playingQueueAdapter: PlayingQueueAdapter? = null
|
||||
private lateinit var linearLayoutManager: LinearLayoutManager
|
||||
|
||||
private var _binding: FragmentGradientPlayerBinding? = null
|
||||
private val binding get() = _binding!!
|
||||
|
||||
private val bottomSheetCallbackList = object : BottomSheetCallback() {
|
||||
override fun onSlide(bottomSheet: View, slideOffset: Float) {
|
||||
mainActivity.getBottomSheetBehavior().setAllowDragging(false)
|
||||
playerQueueSheet.setPadding(
|
||||
playerQueueSheet.paddingLeft,
|
||||
(slideOffset * status_bar.height).toInt(),
|
||||
playerQueueSheet.paddingRight,
|
||||
playerQueueSheet.paddingBottom
|
||||
binding.playerQueueSheet.setPadding(
|
||||
binding.playerQueueSheet.paddingLeft,
|
||||
(slideOffset * binding.statusBarLayout.statusBar.height).toInt(),
|
||||
binding.playerQueueSheet.paddingRight,
|
||||
binding.playerQueueSheet.paddingBottom
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -111,23 +114,24 @@ class GradientPlayerFragment : AbsPlayerFragment(R.layout.fragment_gradient_play
|
|||
}
|
||||
|
||||
private fun setupFavourite() {
|
||||
songFavourite.setOnClickListener {
|
||||
binding.playbackControlsFragment.songFavourite.setOnClickListener {
|
||||
toggleFavorite(MusicPlayerRemote.currentSong)
|
||||
}
|
||||
}
|
||||
|
||||
private fun setupMenu() {
|
||||
playerMenu.setOnClickListener {
|
||||
binding.playbackControlsFragment.playerMenu.setOnClickListener {
|
||||
val popupMenu = PopupMenu(requireContext(), it)
|
||||
popupMenu.setOnMenuItemClickListener(this)
|
||||
popupMenu.inflate(R.menu.menu_player)
|
||||
popupMenu.menu.findItem(R.id.action_toggle_favorite).isVisible = false
|
||||
popupMenu.show()
|
||||
}
|
||||
}
|
||||
|
||||
private fun setupPanel() {
|
||||
if (!ViewCompat.isLaidOut(colorBackground) || colorBackground.isLayoutRequested) {
|
||||
colorBackground.addOnLayoutChangeListener(this)
|
||||
if (!ViewCompat.isLaidOut(binding.colorBackground) || binding.colorBackground.isLayoutRequested) {
|
||||
binding.colorBackground.addOnLayoutChangeListener(this)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
@ -139,6 +143,7 @@ class GradientPlayerFragment : AbsPlayerFragment(R.layout.fragment_gradient_play
|
|||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
_binding = FragmentGradientPlayerBinding.bind(view)
|
||||
hideVolumeIfAvailable()
|
||||
setUpMusicControllers()
|
||||
setupPanel()
|
||||
|
@ -146,12 +151,18 @@ class GradientPlayerFragment : AbsPlayerFragment(R.layout.fragment_gradient_play
|
|||
setupSheet()
|
||||
setupMenu()
|
||||
setupFavourite()
|
||||
binding.playbackControlsFragment.title.setOnClickListener {
|
||||
goToAlbum(requireActivity())
|
||||
}
|
||||
binding.playbackControlsFragment.text.setOnClickListener {
|
||||
goToArtist(requireActivity())
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressLint("ClickableViewAccessibility")
|
||||
private fun setupSheet() {
|
||||
getQueuePanel().addBottomSheetCallback(bottomSheetCallbackList)
|
||||
playerQueueSheet.setOnTouchListener { _, _ ->
|
||||
binding.playerQueueSheet.setOnTouchListener { _, _ ->
|
||||
mainActivity.getBottomSheetBehavior().setAllowDragging(false)
|
||||
getQueuePanel().setAllowDragging(true)
|
||||
return@setOnTouchListener false
|
||||
|
@ -159,7 +170,7 @@ class GradientPlayerFragment : AbsPlayerFragment(R.layout.fragment_gradient_play
|
|||
}
|
||||
|
||||
private fun getQueuePanel(): RetroBottomSheetBehavior<ConstraintLayout> {
|
||||
return RetroBottomSheetBehavior.from(playerQueueSheet) as RetroBottomSheetBehavior<ConstraintLayout>
|
||||
return RetroBottomSheetBehavior.from(binding.playerQueueSheet) as RetroBottomSheetBehavior<ConstraintLayout>
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
|
@ -184,6 +195,7 @@ class GradientPlayerFragment : AbsPlayerFragment(R.layout.fragment_gradient_play
|
|||
}
|
||||
|
||||
override fun onBackPressed(): Boolean {
|
||||
println("OK")
|
||||
var wasExpanded = false
|
||||
if (getQueuePanel().state == STATE_EXPANDED) {
|
||||
wasExpanded = getQueuePanel().state == STATE_EXPANDED
|
||||
|
@ -203,46 +215,62 @@ class GradientPlayerFragment : AbsPlayerFragment(R.layout.fragment_gradient_play
|
|||
override fun onColorChanged(color: MediaNotificationProcessor) {
|
||||
lastColor = color.backgroundColor
|
||||
libraryViewModel.updateColor(color.backgroundColor)
|
||||
mask.backgroundTintList = ColorStateList.valueOf(color.backgroundColor)
|
||||
colorBackground.setBackgroundColor(color.backgroundColor)
|
||||
playerQueueSheet.setBackgroundColor(ColorUtil.darkenColor(color.backgroundColor))
|
||||
binding.mask.backgroundTintList = ColorStateList.valueOf(color.backgroundColor)
|
||||
binding.colorBackground.setBackgroundColor(color.backgroundColor)
|
||||
binding.playerQueueSheet.setBackgroundColor(ColorUtil.darkenColor(color.backgroundColor))
|
||||
|
||||
lastPlaybackControlsColor = color.primaryTextColor
|
||||
lastDisabledPlaybackControlsColor = ColorUtil.withAlpha(color.primaryTextColor, 0.3f)
|
||||
|
||||
title.setTextColor(lastPlaybackControlsColor)
|
||||
text.setTextColor(lastDisabledPlaybackControlsColor)
|
||||
playPauseButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
|
||||
nextButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
|
||||
previousButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
|
||||
songFavourite.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
|
||||
queueIcon.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
|
||||
playerMenu.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
|
||||
songCurrentProgress.setTextColor(lastDisabledPlaybackControlsColor)
|
||||
songTotalTime.setTextColor(lastDisabledPlaybackControlsColor)
|
||||
nextSong.setTextColor(lastPlaybackControlsColor)
|
||||
songInfo.setTextColor(lastDisabledPlaybackControlsColor)
|
||||
binding.playbackControlsFragment.title.setTextColor(lastPlaybackControlsColor)
|
||||
binding.playbackControlsFragment.text.setTextColor(lastDisabledPlaybackControlsColor)
|
||||
binding.playbackControlsFragment.playPauseButton.setColorFilter(
|
||||
lastPlaybackControlsColor,
|
||||
PorterDuff.Mode.SRC_IN
|
||||
)
|
||||
binding.playbackControlsFragment.nextButton.setColorFilter(
|
||||
lastPlaybackControlsColor,
|
||||
PorterDuff.Mode.SRC_IN
|
||||
)
|
||||
binding.playbackControlsFragment.previousButton.setColorFilter(
|
||||
lastPlaybackControlsColor,
|
||||
PorterDuff.Mode.SRC_IN
|
||||
)
|
||||
binding.playbackControlsFragment.songFavourite.setColorFilter(
|
||||
lastPlaybackControlsColor,
|
||||
PorterDuff.Mode.SRC_IN
|
||||
)
|
||||
binding.queueIcon.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
|
||||
binding.playbackControlsFragment.playerMenu.setColorFilter(
|
||||
lastPlaybackControlsColor,
|
||||
PorterDuff.Mode.SRC_IN
|
||||
)
|
||||
binding.playbackControlsFragment.songCurrentProgress.setTextColor(
|
||||
lastDisabledPlaybackControlsColor
|
||||
)
|
||||
binding.playbackControlsFragment.songTotalTime.setTextColor(
|
||||
lastDisabledPlaybackControlsColor
|
||||
)
|
||||
binding.nextSong.setTextColor(lastPlaybackControlsColor)
|
||||
binding.playbackControlsFragment.songInfo.setTextColor(lastDisabledPlaybackControlsColor)
|
||||
|
||||
volumeFragment?.setTintableColor(lastPlaybackControlsColor.ripAlpha())
|
||||
ViewUtil.setProgressDrawable(progressSlider, lastPlaybackControlsColor.ripAlpha(), true)
|
||||
ViewUtil.setProgressDrawable(
|
||||
binding.playbackControlsFragment.progressSlider,
|
||||
lastPlaybackControlsColor.ripAlpha(),
|
||||
true
|
||||
)
|
||||
|
||||
updateRepeatState()
|
||||
updateShuffleState()
|
||||
updatePrevNextColor()
|
||||
}
|
||||
|
||||
override fun toggleFavorite(song: Song) {
|
||||
super.toggleFavorite(song)
|
||||
if (song.id == MusicPlayerRemote.currentSong.id) {
|
||||
updateIsFavoriteIcon()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onFavoriteToggled() {
|
||||
toggleFavorite(MusicPlayerRemote.currentSong)
|
||||
}
|
||||
|
||||
private fun updateIsFavoriteIcon() {
|
||||
private fun updateIsFavoriteIcon(animate: Boolean = false) {
|
||||
lifecycleScope.launch(Dispatchers.IO) {
|
||||
val playlist: PlaylistEntity? = libraryViewModel.favoritePlaylist()
|
||||
if (playlist != null) {
|
||||
|
@ -250,10 +278,19 @@ class GradientPlayerFragment : AbsPlayerFragment(R.layout.fragment_gradient_play
|
|||
MusicPlayerRemote.currentSong.toSongEntity(playlist.playListId)
|
||||
val isFavorite: Boolean = libraryViewModel.isFavoriteSong(song).isNotEmpty()
|
||||
withContext(Dispatchers.Main) {
|
||||
val icon =
|
||||
if (isFavorite) R.drawable.ic_favorite
|
||||
else R.drawable.ic_favorite_border
|
||||
songFavourite.setImageResource(icon)
|
||||
val icon = if (animate) {
|
||||
if (isFavorite) R.drawable.avd_favorite else R.drawable.avd_unfavorite
|
||||
} else {
|
||||
if (isFavorite) R.drawable.ic_favorite else R.drawable.ic_favorite_border
|
||||
}
|
||||
binding.playbackControlsFragment.songFavourite.apply {
|
||||
setImageResource(icon)
|
||||
drawable.also {
|
||||
if (it is AnimatedVectorDrawable) {
|
||||
it.start()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -298,6 +335,10 @@ class GradientPlayerFragment : AbsPlayerFragment(R.layout.fragment_gradient_play
|
|||
updateIsFavoriteIcon()
|
||||
}
|
||||
|
||||
override fun onFavoriteStateChanged() {
|
||||
updateIsFavoriteIcon(animate = true)
|
||||
}
|
||||
|
||||
override fun onQueueChanged() {
|
||||
super.onQueueChanged()
|
||||
updateLabel()
|
||||
|
@ -306,14 +347,14 @@ class GradientPlayerFragment : AbsPlayerFragment(R.layout.fragment_gradient_play
|
|||
|
||||
private fun updateSong() {
|
||||
val song = MusicPlayerRemote.currentSong
|
||||
title.text = song.title
|
||||
text.text = song.artistName
|
||||
binding.playbackControlsFragment.title.text = song.title
|
||||
binding.playbackControlsFragment.text.text = song.artistName
|
||||
updateLabel()
|
||||
if (PreferenceUtil.isSongInfo) {
|
||||
songInfo.text = getSongInfo(song)
|
||||
songInfo.show()
|
||||
binding.playbackControlsFragment.songInfo.text = getSongInfo(song)
|
||||
binding.playbackControlsFragment.songInfo.show()
|
||||
} else {
|
||||
songInfo.hide()
|
||||
binding.playbackControlsFragment.songInfo.hide()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -323,45 +364,53 @@ class GradientPlayerFragment : AbsPlayerFragment(R.layout.fragment_gradient_play
|
|||
setUpRepeatButton()
|
||||
setUpShuffleButton()
|
||||
setUpProgressSlider()
|
||||
title.isSelected = true
|
||||
text.isSelected = true
|
||||
binding.playbackControlsFragment.title.isSelected = true
|
||||
binding.playbackControlsFragment.text.isSelected = true
|
||||
}
|
||||
|
||||
private fun updatePlayPauseDrawableState() {
|
||||
if (MusicPlayerRemote.isPlaying) {
|
||||
playPauseButton.setImageResource(R.drawable.ic_pause_white_64dp)
|
||||
binding.playbackControlsFragment.playPauseButton.setImageResource(R.drawable.ic_pause_white_64dp)
|
||||
} else {
|
||||
playPauseButton.setImageResource(R.drawable.ic_play_arrow_white_64dp)
|
||||
binding.playbackControlsFragment.playPauseButton.setImageResource(R.drawable.ic_play_arrow_white_64dp)
|
||||
}
|
||||
}
|
||||
|
||||
private fun setUpPlayPauseFab() {
|
||||
playPauseButton.setOnClickListener(PlayPauseButtonOnClickHandler())
|
||||
binding.playbackControlsFragment.playPauseButton.setOnClickListener(
|
||||
PlayPauseButtonOnClickHandler()
|
||||
)
|
||||
}
|
||||
|
||||
private fun setUpPrevNext() {
|
||||
updatePrevNextColor()
|
||||
nextButton.setOnClickListener { MusicPlayerRemote.playNextSong() }
|
||||
previousButton.setOnClickListener { MusicPlayerRemote.back() }
|
||||
binding.playbackControlsFragment.nextButton.setOnClickListener { MusicPlayerRemote.playNextSong() }
|
||||
binding.playbackControlsFragment.previousButton.setOnClickListener { MusicPlayerRemote.back() }
|
||||
}
|
||||
|
||||
private fun updatePrevNextColor() {
|
||||
nextButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
|
||||
previousButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
|
||||
binding.playbackControlsFragment.nextButton.setColorFilter(
|
||||
lastPlaybackControlsColor,
|
||||
PorterDuff.Mode.SRC_IN
|
||||
)
|
||||
binding.playbackControlsFragment.previousButton.setColorFilter(
|
||||
lastPlaybackControlsColor,
|
||||
PorterDuff.Mode.SRC_IN
|
||||
)
|
||||
}
|
||||
|
||||
private fun setUpShuffleButton() {
|
||||
shuffleButton.setOnClickListener { MusicPlayerRemote.toggleShuffleMode() }
|
||||
binding.shuffleButton.setOnClickListener { MusicPlayerRemote.toggleShuffleMode() }
|
||||
}
|
||||
|
||||
fun updateShuffleState() {
|
||||
when (MusicPlayerRemote.shuffleMode) {
|
||||
MusicService.SHUFFLE_MODE_SHUFFLE ->
|
||||
shuffleButton.setColorFilter(
|
||||
binding.shuffleButton.setColorFilter(
|
||||
lastPlaybackControlsColor,
|
||||
PorterDuff.Mode.SRC_IN
|
||||
)
|
||||
else -> shuffleButton.setColorFilter(
|
||||
else -> binding.shuffleButton.setColorFilter(
|
||||
lastDisabledPlaybackControlsColor,
|
||||
PorterDuff.Mode.SRC_IN
|
||||
)
|
||||
|
@ -369,25 +418,31 @@ class GradientPlayerFragment : AbsPlayerFragment(R.layout.fragment_gradient_play
|
|||
}
|
||||
|
||||
private fun setUpRepeatButton() {
|
||||
repeatButton.setOnClickListener { MusicPlayerRemote.cycleRepeatMode() }
|
||||
binding.repeatButton.setOnClickListener { MusicPlayerRemote.cycleRepeatMode() }
|
||||
}
|
||||
|
||||
fun updateRepeatState() {
|
||||
when (MusicPlayerRemote.repeatMode) {
|
||||
MusicService.REPEAT_MODE_NONE -> {
|
||||
repeatButton.setImageResource(R.drawable.ic_repeat)
|
||||
repeatButton.setColorFilter(
|
||||
binding.repeatButton.setImageResource(R.drawable.ic_repeat)
|
||||
binding.repeatButton.setColorFilter(
|
||||
lastDisabledPlaybackControlsColor,
|
||||
PorterDuff.Mode.SRC_IN
|
||||
)
|
||||
}
|
||||
MusicService.REPEAT_MODE_ALL -> {
|
||||
repeatButton.setImageResource(R.drawable.ic_repeat)
|
||||
repeatButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
|
||||
binding.repeatButton.setImageResource(R.drawable.ic_repeat)
|
||||
binding.repeatButton.setColorFilter(
|
||||
lastPlaybackControlsColor,
|
||||
PorterDuff.Mode.SRC_IN
|
||||
)
|
||||
}
|
||||
MusicService.REPEAT_MODE_THIS -> {
|
||||
repeatButton.setImageResource(R.drawable.ic_repeat_one)
|
||||
repeatButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
|
||||
binding.repeatButton.setImageResource(R.drawable.ic_repeat_one)
|
||||
binding.repeatButton.setColorFilter(
|
||||
lastPlaybackControlsColor,
|
||||
PorterDuff.Mode.SRC_IN
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -395,10 +450,10 @@ class GradientPlayerFragment : AbsPlayerFragment(R.layout.fragment_gradient_play
|
|||
private fun updateLabel() {
|
||||
(MusicPlayerRemote.playingQueue.size - 1).apply {
|
||||
if (this == (MusicPlayerRemote.position)) {
|
||||
nextSong.text = "Last song"
|
||||
binding.nextSong.text = "Last song"
|
||||
} else {
|
||||
val title = MusicPlayerRemote.playingQueue[MusicPlayerRemote.position + 1].title
|
||||
nextSong.text = title
|
||||
binding.nextSong.text = title
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -415,7 +470,7 @@ class GradientPlayerFragment : AbsPlayerFragment(R.layout.fragment_gradient_play
|
|||
oldBottom: Int
|
||||
) {
|
||||
val panel = getQueuePanel()
|
||||
panel.peekHeight = container.height
|
||||
panel.peekHeight = binding.container.height
|
||||
}
|
||||
|
||||
private fun setupRecyclerView() {
|
||||
|
@ -436,12 +491,14 @@ class GradientPlayerFragment : AbsPlayerFragment(R.layout.fragment_gradient_play
|
|||
recyclerViewDragDropManager?.createWrappedAdapter(playingQueueAdapter!!) as RecyclerView.Adapter<*>
|
||||
wrappedAdapter =
|
||||
recyclerViewSwipeManager?.createWrappedAdapter(wrappedAdapter) as RecyclerView.Adapter<*>
|
||||
recyclerView.layoutManager = linearLayoutManager
|
||||
recyclerView.adapter = wrappedAdapter
|
||||
recyclerView.itemAnimator = animator
|
||||
recyclerViewTouchActionGuardManager?.attachRecyclerView(recyclerView)
|
||||
recyclerViewDragDropManager?.attachRecyclerView(recyclerView)
|
||||
recyclerViewSwipeManager?.attachRecyclerView(recyclerView)
|
||||
binding.recyclerView.apply {
|
||||
layoutManager = linearLayoutManager
|
||||
adapter = wrappedAdapter
|
||||
itemAnimator = animator
|
||||
recyclerViewTouchActionGuardManager?.attachRecyclerView(this)
|
||||
recyclerViewDragDropManager?.attachRecyclerView(this)
|
||||
recyclerViewSwipeManager?.attachRecyclerView(this)
|
||||
}
|
||||
|
||||
linearLayoutManager.scrollToPositionWithOffset(MusicPlayerRemote.position + 1, 0)
|
||||
}
|
||||
|
@ -460,6 +517,7 @@ class GradientPlayerFragment : AbsPlayerFragment(R.layout.fragment_gradient_play
|
|||
}
|
||||
|
||||
WrapperAdapterUtils.releaseAll(wrappedAdapter)
|
||||
_binding = null
|
||||
}
|
||||
|
||||
private fun updateQueuePosition() {
|
||||
|
@ -473,12 +531,13 @@ class GradientPlayerFragment : AbsPlayerFragment(R.layout.fragment_gradient_play
|
|||
}
|
||||
|
||||
private fun resetToCurrentPosition() {
|
||||
recyclerView.stopScroll()
|
||||
binding.recyclerView.stopScroll()
|
||||
linearLayoutManager.scrollToPositionWithOffset(MusicPlayerRemote.position + 1, 0)
|
||||
}
|
||||
|
||||
fun setUpProgressSlider() {
|
||||
progressSlider.setOnSeekBarChangeListener(object : SimpleOnSeekbarChangeListener() {
|
||||
binding.playbackControlsFragment.progressSlider.setOnSeekBarChangeListener(object :
|
||||
SimpleOnSeekbarChangeListener() {
|
||||
override fun onProgressChanged(seekBar: SeekBar, progress: Int, fromUser: Boolean) {
|
||||
if (fromUser) {
|
||||
MusicPlayerRemote.seekTo(progress)
|
||||
|
@ -492,12 +551,18 @@ class GradientPlayerFragment : AbsPlayerFragment(R.layout.fragment_gradient_play
|
|||
}
|
||||
|
||||
override fun onUpdateProgressViews(progress: Int, total: Int) {
|
||||
progressSlider.max = total
|
||||
val animator = ObjectAnimator.ofInt(progressSlider, "progress", progress)
|
||||
binding.playbackControlsFragment.progressSlider.max = total
|
||||
val animator = ObjectAnimator.ofInt(
|
||||
binding.playbackControlsFragment.progressSlider,
|
||||
"progress",
|
||||
progress
|
||||
)
|
||||
animator.duration = AbsPlayerControlsFragment.SLIDER_ANIMATION_TIME
|
||||
animator.interpolator = LinearInterpolator()
|
||||
animator.start()
|
||||
songTotalTime.text = MusicUtil.getReadableDurationString(total.toLong())
|
||||
songCurrentProgress.text = MusicUtil.getReadableDurationString(progress.toLong())
|
||||
binding.playbackControlsFragment.songTotalTime.text =
|
||||
MusicUtil.getReadableDurationString(total.toLong())
|
||||
binding.playbackControlsFragment.songCurrentProgress.text =
|
||||
MusicUtil.getReadableDurationString(progress.toLong())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,19 +21,23 @@ import androidx.appcompat.widget.Toolbar
|
|||
import code.name.monkey.appthemehelper.util.ATHUtil
|
||||
import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper
|
||||
import code.name.monkey.retromusic.R
|
||||
import code.name.monkey.retromusic.databinding.FragmentHomePlayerBinding
|
||||
import code.name.monkey.retromusic.fragments.base.AbsPlayerFragment
|
||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote
|
||||
import code.name.monkey.retromusic.helper.MusicProgressViewUpdateHelper
|
||||
import code.name.monkey.retromusic.model.Song
|
||||
import code.name.monkey.retromusic.util.MusicUtil
|
||||
import code.name.monkey.retromusic.util.color.MediaNotificationProcessor
|
||||
import kotlinx.android.synthetic.main.fragment_home_player.*
|
||||
|
||||
class HomePlayerFragment : AbsPlayerFragment(R.layout.fragment_home_player),
|
||||
MusicProgressViewUpdateHelper.Callback {
|
||||
private var lastColor: Int = 0
|
||||
private lateinit var progressViewUpdateHelper: MusicProgressViewUpdateHelper
|
||||
|
||||
private var _binding: FragmentHomePlayerBinding? = null
|
||||
private val binding get() = _binding!!
|
||||
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
progressViewUpdateHelper = MusicProgressViewUpdateHelper(this)
|
||||
|
@ -41,6 +45,7 @@ class HomePlayerFragment : AbsPlayerFragment(R.layout.fragment_home_player),
|
|||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
_binding = FragmentHomePlayerBinding.bind(view)
|
||||
setUpPlayerToolbar()
|
||||
}
|
||||
|
||||
|
@ -54,8 +59,8 @@ class HomePlayerFragment : AbsPlayerFragment(R.layout.fragment_home_player),
|
|||
progressViewUpdateHelper.stop()
|
||||
}
|
||||
|
||||
override fun playerToolbar(): Toolbar? {
|
||||
return playerToolbar
|
||||
override fun playerToolbar(): Toolbar {
|
||||
return binding.playerToolbar
|
||||
}
|
||||
|
||||
override fun onShow() {
|
||||
|
@ -76,8 +81,8 @@ class HomePlayerFragment : AbsPlayerFragment(R.layout.fragment_home_player),
|
|||
|
||||
private fun updateSong() {
|
||||
val song = MusicPlayerRemote.currentSong
|
||||
title.text = song.title
|
||||
text.text = song.artistName
|
||||
binding.title.text = song.title
|
||||
binding.text.text = song.artistName
|
||||
}
|
||||
|
||||
override fun onBackPressed(): Boolean {
|
||||
|
@ -95,7 +100,7 @@ class HomePlayerFragment : AbsPlayerFragment(R.layout.fragment_home_player),
|
|||
lastColor = color.backgroundColor
|
||||
libraryViewModel.updateColor(color.backgroundColor)
|
||||
ToolbarContentTintHelper.colorizeToolbar(
|
||||
playerToolbar,
|
||||
binding.playerToolbar,
|
||||
Color.WHITE,
|
||||
requireActivity()
|
||||
)
|
||||
|
@ -113,18 +118,23 @@ class HomePlayerFragment : AbsPlayerFragment(R.layout.fragment_home_player),
|
|||
}
|
||||
|
||||
override fun onUpdateProgressViews(progress: Int, total: Int) {
|
||||
songTotalTime.text = MusicUtil.getReadableDurationString(progress.toLong())
|
||||
binding.songTotalTime.text = MusicUtil.getReadableDurationString(progress.toLong())
|
||||
}
|
||||
|
||||
private fun setUpPlayerToolbar() {
|
||||
playerToolbar.inflateMenu(R.menu.menu_player)
|
||||
playerToolbar.setNavigationOnClickListener { requireActivity().onBackPressed() }
|
||||
playerToolbar.setOnMenuItemClickListener(this)
|
||||
binding.playerToolbar.inflateMenu(R.menu.menu_player)
|
||||
binding.playerToolbar.setNavigationOnClickListener { requireActivity().onBackPressed() }
|
||||
binding.playerToolbar.setOnMenuItemClickListener(this)
|
||||
|
||||
ToolbarContentTintHelper.colorizeToolbar(
|
||||
playerToolbar,
|
||||
binding.playerToolbar,
|
||||
ATHUtil.resolveColor(requireContext(), R.attr.colorControlNormal),
|
||||
requireActivity()
|
||||
)
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
_binding = null
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@ import code.name.monkey.appthemehelper.util.ColorUtil
|
|||
import code.name.monkey.appthemehelper.util.MaterialValueHelper
|
||||
import code.name.monkey.appthemehelper.util.TintHelper
|
||||
import code.name.monkey.retromusic.R
|
||||
import code.name.monkey.retromusic.databinding.FragmentLockScreenPlaybackControlsBinding
|
||||
import code.name.monkey.retromusic.extensions.applyColor
|
||||
import code.name.monkey.retromusic.extensions.ripAlpha
|
||||
import code.name.monkey.retromusic.extensions.textColorSecondary
|
||||
|
@ -38,7 +39,6 @@ import code.name.monkey.retromusic.service.MusicService
|
|||
import code.name.monkey.retromusic.util.MusicUtil
|
||||
import code.name.monkey.retromusic.util.PreferenceUtil
|
||||
import code.name.monkey.retromusic.util.color.MediaNotificationProcessor
|
||||
import kotlinx.android.synthetic.main.fragment_lock_screen_playback_controls.*
|
||||
|
||||
/**
|
||||
* @author Hemanth S (h4h13).
|
||||
|
@ -50,6 +50,10 @@ class LockScreenControlsFragment :
|
|||
private var lastPlaybackControlsColor: Int = 0
|
||||
private var lastDisabledPlaybackControlsColor: Int = 0
|
||||
|
||||
private var _binding: FragmentLockScreenPlaybackControlsBinding? = null
|
||||
private val binding get() = _binding!!
|
||||
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
progressViewUpdateHelper = MusicProgressViewUpdateHelper(this)
|
||||
|
@ -57,14 +61,15 @@ class LockScreenControlsFragment :
|
|||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
_binding = FragmentLockScreenPlaybackControlsBinding.bind(view)
|
||||
setUpMusicControllers()
|
||||
title.isSelected = true
|
||||
binding.title.isSelected = true
|
||||
}
|
||||
|
||||
private fun updateSong() {
|
||||
val song = MusicPlayerRemote.currentSong
|
||||
title.text = song.title
|
||||
text.text = String.format("%s - %s", song.artistName, song.albumName)
|
||||
binding.title.text = song.title
|
||||
binding.text.text = String.format("%s - %s", song.artistName, song.albumName)
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
|
@ -123,32 +128,32 @@ class LockScreenControlsFragment :
|
|||
}.ripAlpha()
|
||||
|
||||
volumeFragment?.setTintable(colorFinal)
|
||||
progressSlider.applyColor(colorFinal)
|
||||
binding.progressSlider.applyColor(colorFinal)
|
||||
|
||||
updateRepeatState()
|
||||
updateShuffleState()
|
||||
updatePrevNextColor()
|
||||
|
||||
val isDark = ColorUtil.isColorLight(colorFinal)
|
||||
text.setTextColor(colorFinal)
|
||||
binding.text.setTextColor(colorFinal)
|
||||
|
||||
TintHelper.setTintAuto(
|
||||
playPauseButton,
|
||||
binding.playPauseButton,
|
||||
MaterialValueHelper.getPrimaryTextColor(requireContext(), isDark),
|
||||
false
|
||||
)
|
||||
TintHelper.setTintAuto(playPauseButton, colorFinal, true)
|
||||
TintHelper.setTintAuto(binding.playPauseButton, colorFinal, true)
|
||||
}
|
||||
|
||||
private fun setUpPlayPauseFab() {
|
||||
playPauseButton.setOnClickListener(PlayPauseButtonOnClickHandler())
|
||||
binding.playPauseButton.setOnClickListener(PlayPauseButtonOnClickHandler())
|
||||
}
|
||||
|
||||
private fun updatePlayPauseDrawableState() {
|
||||
if (MusicPlayerRemote.isPlaying) {
|
||||
playPauseButton.setImageResource(R.drawable.ic_pause)
|
||||
binding.playPauseButton.setImageResource(R.drawable.ic_pause)
|
||||
} else {
|
||||
playPauseButton.setImageResource(R.drawable.ic_play_arrow_white_32dp)
|
||||
binding.playPauseButton.setImageResource(R.drawable.ic_play_arrow_white_32dp)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -162,26 +167,26 @@ class LockScreenControlsFragment :
|
|||
|
||||
private fun setUpPrevNext() {
|
||||
updatePrevNextColor()
|
||||
nextButton.setOnClickListener { MusicPlayerRemote.playNextSong() }
|
||||
previousButton.setOnClickListener { MusicPlayerRemote.back() }
|
||||
binding.nextButton.setOnClickListener { MusicPlayerRemote.playNextSong() }
|
||||
binding.previousButton.setOnClickListener { MusicPlayerRemote.back() }
|
||||
}
|
||||
|
||||
private fun updatePrevNextColor() {
|
||||
nextButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
|
||||
previousButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
|
||||
binding.nextButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
|
||||
binding.previousButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
|
||||
}
|
||||
|
||||
private fun setUpShuffleButton() {
|
||||
shuffleButton.setOnClickListener { MusicPlayerRemote.toggleShuffleMode() }
|
||||
binding.shuffleButton.setOnClickListener { MusicPlayerRemote.toggleShuffleMode() }
|
||||
}
|
||||
|
||||
override fun updateShuffleState() {
|
||||
when (MusicPlayerRemote.shuffleMode) {
|
||||
MusicService.SHUFFLE_MODE_SHUFFLE -> shuffleButton.setColorFilter(
|
||||
MusicService.SHUFFLE_MODE_SHUFFLE -> binding.shuffleButton.setColorFilter(
|
||||
lastPlaybackControlsColor,
|
||||
PorterDuff.Mode.SRC_IN
|
||||
)
|
||||
else -> shuffleButton.setColorFilter(
|
||||
else -> binding.shuffleButton.setColorFilter(
|
||||
lastDisabledPlaybackControlsColor,
|
||||
PorterDuff.Mode.SRC_IN
|
||||
)
|
||||
|
@ -189,31 +194,37 @@ class LockScreenControlsFragment :
|
|||
}
|
||||
|
||||
private fun setUpRepeatButton() {
|
||||
repeatButton.setOnClickListener { MusicPlayerRemote.cycleRepeatMode() }
|
||||
binding.repeatButton.setOnClickListener { MusicPlayerRemote.cycleRepeatMode() }
|
||||
}
|
||||
|
||||
override fun updateRepeatState() {
|
||||
when (MusicPlayerRemote.repeatMode) {
|
||||
MusicService.REPEAT_MODE_NONE -> {
|
||||
repeatButton.setImageResource(R.drawable.ic_repeat)
|
||||
repeatButton.setColorFilter(
|
||||
binding.repeatButton.setImageResource(R.drawable.ic_repeat)
|
||||
binding.repeatButton.setColorFilter(
|
||||
lastDisabledPlaybackControlsColor,
|
||||
PorterDuff.Mode.SRC_IN
|
||||
)
|
||||
}
|
||||
MusicService.REPEAT_MODE_ALL -> {
|
||||
repeatButton.setImageResource(R.drawable.ic_repeat)
|
||||
repeatButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
|
||||
binding.repeatButton.setImageResource(R.drawable.ic_repeat)
|
||||
binding.repeatButton.setColorFilter(
|
||||
lastPlaybackControlsColor,
|
||||
PorterDuff.Mode.SRC_IN
|
||||
)
|
||||
}
|
||||
MusicService.REPEAT_MODE_THIS -> {
|
||||
repeatButton.setImageResource(R.drawable.ic_repeat_one)
|
||||
repeatButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
|
||||
binding.repeatButton.setImageResource(R.drawable.ic_repeat_one)
|
||||
binding.repeatButton.setColorFilter(
|
||||
lastPlaybackControlsColor,
|
||||
PorterDuff.Mode.SRC_IN
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override fun show() {
|
||||
playPauseButton!!.animate()
|
||||
binding.playPauseButton.animate()
|
||||
.scaleX(1f)
|
||||
.scaleY(1f)
|
||||
.rotation(360f)
|
||||
|
@ -222,17 +233,15 @@ class LockScreenControlsFragment :
|
|||
}
|
||||
|
||||
public override fun hide() {
|
||||
if (playPauseButton != null) {
|
||||
playPauseButton!!.apply {
|
||||
scaleX = 0f
|
||||
scaleY = 0f
|
||||
rotation = 0f
|
||||
}
|
||||
binding.playPauseButton.apply {
|
||||
scaleX = 0f
|
||||
scaleY = 0f
|
||||
rotation = 0f
|
||||
}
|
||||
}
|
||||
|
||||
override fun setUpProgressSlider() {
|
||||
progressSlider.setOnSeekBarChangeListener(object : SimpleOnSeekbarChangeListener() {
|
||||
binding.progressSlider.setOnSeekBarChangeListener(object : SimpleOnSeekbarChangeListener() {
|
||||
override fun onProgressChanged(seekBar: SeekBar, progress: Int, fromUser: Boolean) {
|
||||
if (fromUser) {
|
||||
MusicPlayerRemote.seekTo(progress)
|
||||
|
@ -246,14 +255,19 @@ class LockScreenControlsFragment :
|
|||
}
|
||||
|
||||
override fun onUpdateProgressViews(progress: Int, total: Int) {
|
||||
progressSlider.max = total
|
||||
binding.progressSlider.max = total
|
||||
|
||||
val animator = ObjectAnimator.ofInt(progressSlider, "progress", progress)
|
||||
val animator = ObjectAnimator.ofInt(binding.progressSlider, "progress", progress)
|
||||
animator.duration = SLIDER_ANIMATION_TIME
|
||||
animator.interpolator = LinearInterpolator()
|
||||
animator.start()
|
||||
|
||||
songTotalTime.text = MusicUtil.getReadableDurationString(total.toLong())
|
||||
songCurrentProgress.text = MusicUtil.getReadableDurationString(progress.toLong())
|
||||
binding.songTotalTime.text = MusicUtil.getReadableDurationString(total.toLong())
|
||||
binding.songCurrentProgress.text = MusicUtil.getReadableDurationString(progress.toLong())
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
_binding = null
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,11 +20,15 @@ import android.os.Bundle
|
|||
import android.view.View
|
||||
import android.view.animation.LinearInterpolator
|
||||
import android.widget.SeekBar
|
||||
import androidx.core.content.ContextCompat
|
||||
import code.name.monkey.appthemehelper.util.ATHUtil
|
||||
import code.name.monkey.appthemehelper.util.MaterialValueHelper
|
||||
import code.name.monkey.retromusic.R
|
||||
import code.name.monkey.retromusic.databinding.FragmentMaterialPlaybackControlsBinding
|
||||
import code.name.monkey.retromusic.extensions.*
|
||||
import code.name.monkey.retromusic.fragments.base.AbsPlayerControlsFragment
|
||||
import code.name.monkey.retromusic.fragments.base.goToAlbum
|
||||
import code.name.monkey.retromusic.fragments.base.goToArtist
|
||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote
|
||||
import code.name.monkey.retromusic.helper.MusicProgressViewUpdateHelper
|
||||
import code.name.monkey.retromusic.helper.PlayPauseButtonOnClickHandler
|
||||
|
@ -33,7 +37,6 @@ import code.name.monkey.retromusic.service.MusicService
|
|||
import code.name.monkey.retromusic.util.MusicUtil
|
||||
import code.name.monkey.retromusic.util.PreferenceUtil
|
||||
import code.name.monkey.retromusic.util.color.MediaNotificationProcessor
|
||||
import kotlinx.android.synthetic.main.fragment_material_playback_controls.*
|
||||
|
||||
/**
|
||||
* @author Hemanth S (h4h13).
|
||||
|
@ -44,6 +47,9 @@ class MaterialControlsFragment :
|
|||
private var lastPlaybackControlsColor: Int = 0
|
||||
private var lastDisabledPlaybackControlsColor: Int = 0
|
||||
private lateinit var progressViewUpdateHelper: MusicProgressViewUpdateHelper
|
||||
private var _binding: FragmentMaterialPlaybackControlsBinding? = null
|
||||
private val binding get() = _binding!!
|
||||
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
@ -52,21 +58,28 @@ class MaterialControlsFragment :
|
|||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
_binding = FragmentMaterialPlaybackControlsBinding.bind(view)
|
||||
setUpMusicControllers()
|
||||
title.isSelected = true
|
||||
text.isSelected = true
|
||||
binding.title.isSelected = true
|
||||
binding.text.isSelected = true
|
||||
binding.title.setOnClickListener {
|
||||
goToAlbum(requireActivity())
|
||||
}
|
||||
binding.text.setOnClickListener {
|
||||
goToArtist(requireActivity())
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateSong() {
|
||||
val song = MusicPlayerRemote.currentSong
|
||||
title.text = song.title
|
||||
text.text = song.artistName
|
||||
binding.title.text = song.title
|
||||
binding.text.text = song.artistName
|
||||
|
||||
if (PreferenceUtil.isSongInfo) {
|
||||
songInfo.text = getSongInfo(song)
|
||||
songInfo.show()
|
||||
binding.songInfo.text = getSongInfo(song)
|
||||
binding.songInfo.show()
|
||||
} else {
|
||||
songInfo.hide()
|
||||
binding.songInfo.hide()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -125,8 +138,8 @@ class MaterialControlsFragment :
|
|||
textColorSecondary()
|
||||
}.ripAlpha()
|
||||
|
||||
text.setTextColor(colorFinal)
|
||||
progressSlider.applyColor(colorFinal)
|
||||
binding.text.setTextColor(colorFinal)
|
||||
binding.progressSlider.applyColor(colorFinal)
|
||||
|
||||
volumeFragment?.setTintable(colorFinal)
|
||||
|
||||
|
@ -137,18 +150,28 @@ class MaterialControlsFragment :
|
|||
}
|
||||
|
||||
private fun updatePlayPauseColor() {
|
||||
playPauseButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
|
||||
binding.playPauseButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
|
||||
}
|
||||
|
||||
private fun setUpPlayPauseFab() {
|
||||
playPauseButton.setOnClickListener(PlayPauseButtonOnClickHandler())
|
||||
binding.playPauseButton.setOnClickListener(PlayPauseButtonOnClickHandler())
|
||||
}
|
||||
|
||||
private fun updatePlayPauseDrawableState() {
|
||||
if (MusicPlayerRemote.isPlaying) {
|
||||
playPauseButton.setImageResource(R.drawable.ic_pause_sharp_white_64dp)
|
||||
} else {
|
||||
playPauseButton.setImageResource(R.drawable.ic_play_arrow_sharp_white_64dp)
|
||||
binding.playPauseButton.setImageDrawable(
|
||||
ContextCompat.getDrawable(
|
||||
requireContext(),
|
||||
R.drawable.ic_pause_outline
|
||||
)
|
||||
)
|
||||
} else if (!MusicPlayerRemote.isPlaying) {
|
||||
binding.playPauseButton.setImageDrawable(
|
||||
ContextCompat.getDrawable(
|
||||
requireContext(),
|
||||
R.drawable.ic_play_arrow_outline
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -162,26 +185,26 @@ class MaterialControlsFragment :
|
|||
|
||||
private fun setUpPrevNext() {
|
||||
updatePrevNextColor()
|
||||
nextButton.setOnClickListener { MusicPlayerRemote.playNextSong() }
|
||||
previousButton.setOnClickListener { MusicPlayerRemote.back() }
|
||||
binding.nextButton.setOnClickListener { MusicPlayerRemote.playNextSong() }
|
||||
binding.previousButton.setOnClickListener { MusicPlayerRemote.back() }
|
||||
}
|
||||
|
||||
private fun updatePrevNextColor() {
|
||||
nextButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
|
||||
previousButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
|
||||
binding.nextButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
|
||||
binding.previousButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
|
||||
}
|
||||
|
||||
private fun setUpShuffleButton() {
|
||||
shuffleButton.setOnClickListener { MusicPlayerRemote.toggleShuffleMode() }
|
||||
binding.shuffleButton.setOnClickListener { MusicPlayerRemote.toggleShuffleMode() }
|
||||
}
|
||||
|
||||
override fun updateShuffleState() {
|
||||
when (MusicPlayerRemote.shuffleMode) {
|
||||
MusicService.SHUFFLE_MODE_SHUFFLE -> shuffleButton.setColorFilter(
|
||||
MusicService.SHUFFLE_MODE_SHUFFLE -> binding.shuffleButton.setColorFilter(
|
||||
lastPlaybackControlsColor,
|
||||
PorterDuff.Mode.SRC_IN
|
||||
)
|
||||
else -> shuffleButton.setColorFilter(
|
||||
else -> binding.shuffleButton.setColorFilter(
|
||||
lastDisabledPlaybackControlsColor,
|
||||
PorterDuff.Mode.SRC_IN
|
||||
)
|
||||
|
@ -189,25 +212,31 @@ class MaterialControlsFragment :
|
|||
}
|
||||
|
||||
private fun setUpRepeatButton() {
|
||||
repeatButton.setOnClickListener { MusicPlayerRemote.cycleRepeatMode() }
|
||||
binding.repeatButton.setOnClickListener { MusicPlayerRemote.cycleRepeatMode() }
|
||||
}
|
||||
|
||||
override fun updateRepeatState() {
|
||||
when (MusicPlayerRemote.repeatMode) {
|
||||
MusicService.REPEAT_MODE_NONE -> {
|
||||
repeatButton.setImageResource(R.drawable.ic_repeat_sharp)
|
||||
repeatButton.setColorFilter(
|
||||
binding.repeatButton.setImageResource(R.drawable.ic_repeat_sharp)
|
||||
binding.repeatButton.setColorFilter(
|
||||
lastDisabledPlaybackControlsColor,
|
||||
PorterDuff.Mode.SRC_IN
|
||||
)
|
||||
}
|
||||
MusicService.REPEAT_MODE_ALL -> {
|
||||
repeatButton.setImageResource(R.drawable.ic_repeat_sharp)
|
||||
repeatButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
|
||||
binding.repeatButton.setImageResource(R.drawable.ic_repeat_sharp)
|
||||
binding.repeatButton.setColorFilter(
|
||||
lastPlaybackControlsColor,
|
||||
PorterDuff.Mode.SRC_IN
|
||||
)
|
||||
}
|
||||
MusicService.REPEAT_MODE_THIS -> {
|
||||
repeatButton.setImageResource(R.drawable.ic_repeat_one_sharp)
|
||||
repeatButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
|
||||
binding.repeatButton.setImageResource(R.drawable.ic_repeat_one_sharp)
|
||||
binding.repeatButton.setColorFilter(
|
||||
lastPlaybackControlsColor,
|
||||
PorterDuff.Mode.SRC_IN
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -219,7 +248,7 @@ class MaterialControlsFragment :
|
|||
}
|
||||
|
||||
override fun setUpProgressSlider() {
|
||||
progressSlider.setOnSeekBarChangeListener(object : SimpleOnSeekbarChangeListener() {
|
||||
binding.progressSlider.setOnSeekBarChangeListener(object : SimpleOnSeekbarChangeListener() {
|
||||
override fun onProgressChanged(seekBar: SeekBar, progress: Int, fromUser: Boolean) {
|
||||
if (fromUser) {
|
||||
MusicPlayerRemote.seekTo(progress)
|
||||
|
@ -233,14 +262,19 @@ class MaterialControlsFragment :
|
|||
}
|
||||
|
||||
override fun onUpdateProgressViews(progress: Int, total: Int) {
|
||||
progressSlider.max = total
|
||||
binding.progressSlider.max = total
|
||||
|
||||
val animator = ObjectAnimator.ofInt(progressSlider, "progress", progress)
|
||||
val animator = ObjectAnimator.ofInt(binding.progressSlider, "progress", progress)
|
||||
animator.duration = SLIDER_ANIMATION_TIME
|
||||
animator.interpolator = LinearInterpolator()
|
||||
animator.start()
|
||||
|
||||
songTotalTime.text = MusicUtil.getReadableDurationString(total.toLong())
|
||||
songCurrentProgress.text = MusicUtil.getReadableDurationString(progress.toLong())
|
||||
binding.songTotalTime.text = MusicUtil.getReadableDurationString(total.toLong())
|
||||
binding.songCurrentProgress.text = MusicUtil.getReadableDurationString(progress.toLong())
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
_binding = null
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,13 +20,13 @@ import androidx.appcompat.widget.Toolbar
|
|||
import code.name.monkey.appthemehelper.util.ATHUtil
|
||||
import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper
|
||||
import code.name.monkey.retromusic.R
|
||||
import code.name.monkey.retromusic.databinding.FragmentMaterialBinding
|
||||
import code.name.monkey.retromusic.fragments.base.AbsPlayerFragment
|
||||
import code.name.monkey.retromusic.fragments.player.PlayerAlbumCoverFragment
|
||||
import code.name.monkey.retromusic.fragments.player.normal.PlayerFragment
|
||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote
|
||||
import code.name.monkey.retromusic.model.Song
|
||||
import code.name.monkey.retromusic.util.color.MediaNotificationProcessor
|
||||
import kotlinx.android.synthetic.main.fragment_material.*
|
||||
|
||||
/**
|
||||
* @author Hemanth S (h4h13).
|
||||
|
@ -34,7 +34,7 @@ import kotlinx.android.synthetic.main.fragment_material.*
|
|||
class MaterialFragment : AbsPlayerFragment(R.layout.fragment_material) {
|
||||
|
||||
override fun playerToolbar(): Toolbar {
|
||||
return playerToolbar
|
||||
return binding.playerToolbar
|
||||
}
|
||||
|
||||
private var lastColor: Int = 0
|
||||
|
@ -44,6 +44,10 @@ class MaterialFragment : AbsPlayerFragment(R.layout.fragment_material) {
|
|||
|
||||
private lateinit var playbackControlsFragment: MaterialControlsFragment
|
||||
|
||||
private var _binding: FragmentMaterialBinding? = null
|
||||
private val binding get() = _binding!!
|
||||
|
||||
|
||||
override fun onShow() {
|
||||
playbackControlsFragment.show()
|
||||
}
|
||||
|
@ -67,7 +71,7 @@ class MaterialFragment : AbsPlayerFragment(R.layout.fragment_material) {
|
|||
libraryViewModel.updateColor(color.backgroundColor)
|
||||
|
||||
ToolbarContentTintHelper.colorizeToolbar(
|
||||
playerToolbar,
|
||||
binding.playerToolbar,
|
||||
ATHUtil.resolveColor(requireContext(), R.attr.colorControlNormal),
|
||||
requireActivity()
|
||||
)
|
||||
|
@ -86,6 +90,7 @@ class MaterialFragment : AbsPlayerFragment(R.layout.fragment_material) {
|
|||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
_binding = FragmentMaterialBinding.bind(view)
|
||||
setUpSubFragments()
|
||||
setUpPlayerToolbar()
|
||||
}
|
||||
|
@ -99,7 +104,7 @@ class MaterialFragment : AbsPlayerFragment(R.layout.fragment_material) {
|
|||
}
|
||||
|
||||
private fun setUpPlayerToolbar() {
|
||||
playerToolbar.apply {
|
||||
binding.playerToolbar.apply {
|
||||
inflateMenu(R.menu.menu_player)
|
||||
setNavigationOnClickListener { requireActivity().onBackPressed() }
|
||||
setOnMenuItemClickListener(this@MaterialFragment)
|
||||
|
@ -125,4 +130,9 @@ class MaterialFragment : AbsPlayerFragment(R.layout.fragment_material) {
|
|||
return PlayerFragment()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
_binding = null
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ import androidx.appcompat.widget.Toolbar
|
|||
import code.name.monkey.appthemehelper.util.ATHUtil
|
||||
import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper
|
||||
import code.name.monkey.retromusic.R
|
||||
import code.name.monkey.retromusic.databinding.FragmentPlayerBinding
|
||||
import code.name.monkey.retromusic.fragments.base.AbsPlayerFragment
|
||||
import code.name.monkey.retromusic.fragments.player.PlayerAlbumCoverFragment
|
||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote
|
||||
|
@ -31,7 +32,6 @@ import code.name.monkey.retromusic.util.PreferenceUtil
|
|||
import code.name.monkey.retromusic.util.ViewUtil
|
||||
import code.name.monkey.retromusic.util.color.MediaNotificationProcessor
|
||||
import code.name.monkey.retromusic.views.DrawableGradient
|
||||
import kotlinx.android.synthetic.main.fragment_player.*
|
||||
|
||||
class PlayerFragment : AbsPlayerFragment(R.layout.fragment_player) {
|
||||
|
||||
|
@ -42,6 +42,10 @@ class PlayerFragment : AbsPlayerFragment(R.layout.fragment_player) {
|
|||
private lateinit var controlsFragment: PlayerPlaybackControlsFragment
|
||||
private var valueAnimator: ValueAnimator? = null
|
||||
|
||||
private var _binding: FragmentPlayerBinding? = null
|
||||
private val binding get() = _binding!!
|
||||
|
||||
|
||||
private fun colorize(i: Int) {
|
||||
if (valueAnimator != null) {
|
||||
valueAnimator?.cancel()
|
||||
|
@ -61,7 +65,7 @@ class PlayerFragment : AbsPlayerFragment(R.layout.fragment_player) {
|
|||
ATHUtil.resolveColor(requireContext(), R.attr.colorSurface)
|
||||
), 0
|
||||
)
|
||||
colorGradientBackground?.background = drawable
|
||||
binding.colorGradientBackground.background = drawable
|
||||
}
|
||||
}
|
||||
valueAnimator?.setDuration(ViewUtil.RETRO_MUSIC_ANIM_TIME.toLong())?.start()
|
||||
|
@ -90,7 +94,7 @@ class PlayerFragment : AbsPlayerFragment(R.layout.fragment_player) {
|
|||
libraryViewModel.updateColor(color.backgroundColor)
|
||||
|
||||
ToolbarContentTintHelper.colorizeToolbar(
|
||||
playerToolbar,
|
||||
binding.playerToolbar,
|
||||
ATHUtil.resolveColor(requireContext(), R.attr.colorControlNormal),
|
||||
requireActivity()
|
||||
)
|
||||
|
@ -113,10 +117,16 @@ class PlayerFragment : AbsPlayerFragment(R.layout.fragment_player) {
|
|||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
_binding = FragmentPlayerBinding.bind(view)
|
||||
setUpSubFragments()
|
||||
setUpPlayerToolbar()
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
_binding = null
|
||||
}
|
||||
|
||||
private fun setUpSubFragments() {
|
||||
controlsFragment =
|
||||
childFragmentManager.findFragmentById(R.id.playbackControlsFragment) as PlayerPlaybackControlsFragment
|
||||
|
@ -126,12 +136,13 @@ class PlayerFragment : AbsPlayerFragment(R.layout.fragment_player) {
|
|||
}
|
||||
|
||||
private fun setUpPlayerToolbar() {
|
||||
playerToolbar.inflateMenu(R.menu.menu_player)
|
||||
playerToolbar.setNavigationOnClickListener { requireActivity().onBackPressed() }
|
||||
playerToolbar.setOnMenuItemClickListener(this)
|
||||
binding.playerToolbar.inflateMenu(R.menu.menu_player)
|
||||
//binding.playerToolbar.menu.setUpWithIcons()
|
||||
binding.playerToolbar.setNavigationOnClickListener { requireActivity().onBackPressed() }
|
||||
binding.playerToolbar.setOnMenuItemClickListener(this)
|
||||
|
||||
ToolbarContentTintHelper.colorizeToolbar(
|
||||
playerToolbar,
|
||||
binding.playerToolbar,
|
||||
ATHUtil.resolveColor(requireContext(), R.attr.colorControlNormal),
|
||||
requireActivity()
|
||||
)
|
||||
|
@ -146,7 +157,7 @@ class PlayerFragment : AbsPlayerFragment(R.layout.fragment_player) {
|
|||
}
|
||||
|
||||
override fun playerToolbar(): Toolbar {
|
||||
return playerToolbar
|
||||
return binding.playerToolbar
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
|
|
@ -27,11 +27,14 @@ import code.name.monkey.appthemehelper.util.ColorUtil
|
|||
import code.name.monkey.appthemehelper.util.MaterialValueHelper
|
||||
import code.name.monkey.appthemehelper.util.TintHelper
|
||||
import code.name.monkey.retromusic.R
|
||||
import code.name.monkey.retromusic.databinding.FragmentPlayerPlaybackControlsBinding
|
||||
import code.name.monkey.retromusic.extensions.applyColor
|
||||
import code.name.monkey.retromusic.extensions.hide
|
||||
import code.name.monkey.retromusic.extensions.ripAlpha
|
||||
import code.name.monkey.retromusic.extensions.show
|
||||
import code.name.monkey.retromusic.fragments.base.AbsPlayerControlsFragment
|
||||
import code.name.monkey.retromusic.fragments.base.goToAlbum
|
||||
import code.name.monkey.retromusic.fragments.base.goToArtist
|
||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote
|
||||
import code.name.monkey.retromusic.helper.MusicProgressViewUpdateHelper
|
||||
import code.name.monkey.retromusic.helper.PlayPauseButtonOnClickHandler
|
||||
|
@ -40,7 +43,6 @@ import code.name.monkey.retromusic.service.MusicService
|
|||
import code.name.monkey.retromusic.util.MusicUtil
|
||||
import code.name.monkey.retromusic.util.PreferenceUtil
|
||||
import code.name.monkey.retromusic.util.color.MediaNotificationProcessor
|
||||
import kotlinx.android.synthetic.main.fragment_player_playback_controls.*
|
||||
|
||||
class PlayerPlaybackControlsFragment :
|
||||
AbsPlayerControlsFragment(R.layout.fragment_player_playback_controls) {
|
||||
|
@ -48,6 +50,8 @@ class PlayerPlaybackControlsFragment :
|
|||
private var lastPlaybackControlsColor: Int = 0
|
||||
private var lastDisabledPlaybackControlsColor: Int = 0
|
||||
private lateinit var progressViewUpdateHelper: MusicProgressViewUpdateHelper
|
||||
private var _binding: FragmentPlayerPlaybackControlsBinding? = null
|
||||
private val binding get() = _binding!!
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
@ -56,17 +60,24 @@ class PlayerPlaybackControlsFragment :
|
|||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
_binding = FragmentPlayerPlaybackControlsBinding.bind(view)
|
||||
setUpMusicControllers()
|
||||
playPauseButton.setOnClickListener {
|
||||
binding.playPauseButton.setOnClickListener {
|
||||
if (MusicPlayerRemote.isPlaying) {
|
||||
MusicPlayerRemote.pauseSong()
|
||||
} else {
|
||||
MusicPlayerRemote.resumePlaying()
|
||||
}
|
||||
showBonceAnimation(playPauseButton)
|
||||
showBounceAnimation(binding.playPauseButton)
|
||||
}
|
||||
binding.title.isSelected = true
|
||||
binding.text.isSelected = true
|
||||
binding.title.setOnClickListener {
|
||||
goToAlbum(requireActivity())
|
||||
}
|
||||
binding.text.setOnClickListener {
|
||||
goToArtist(requireActivity())
|
||||
}
|
||||
title.isSelected = true
|
||||
text.isSelected = true
|
||||
}
|
||||
|
||||
override fun setColor(color: MediaNotificationProcessor) {
|
||||
|
@ -90,15 +101,15 @@ class PlayerPlaybackControlsFragment :
|
|||
}.ripAlpha()
|
||||
|
||||
TintHelper.setTintAuto(
|
||||
playPauseButton,
|
||||
binding.playPauseButton,
|
||||
MaterialValueHelper.getPrimaryTextColor(
|
||||
requireContext(),
|
||||
ColorUtil.isColorLight(colorFinal)
|
||||
),
|
||||
false
|
||||
)
|
||||
TintHelper.setTintAuto(playPauseButton, colorFinal, true)
|
||||
progressSlider.applyColor(colorFinal)
|
||||
TintHelper.setTintAuto(binding.playPauseButton, colorFinal, true)
|
||||
binding.progressSlider.applyColor(colorFinal)
|
||||
volumeFragment?.setTintable(colorFinal)
|
||||
updateRepeatState()
|
||||
updateShuffleState()
|
||||
|
@ -107,14 +118,14 @@ class PlayerPlaybackControlsFragment :
|
|||
|
||||
private fun updateSong() {
|
||||
val song = MusicPlayerRemote.currentSong
|
||||
title.text = song.title
|
||||
text.text = song.artistName
|
||||
binding.title.text = song.title
|
||||
binding.text.text = song.artistName
|
||||
|
||||
if (PreferenceUtil.isSongInfo) {
|
||||
songInfo.text = getSongInfo(song)
|
||||
songInfo.show()
|
||||
binding.songInfo.text = getSongInfo(song)
|
||||
binding.songInfo.show()
|
||||
} else {
|
||||
songInfo.hide()
|
||||
binding.songInfo.hide()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -153,14 +164,14 @@ class PlayerPlaybackControlsFragment :
|
|||
}
|
||||
|
||||
private fun setUpPlayPauseFab() {
|
||||
playPauseButton.setOnClickListener(PlayPauseButtonOnClickHandler())
|
||||
binding.playPauseButton.setOnClickListener(PlayPauseButtonOnClickHandler())
|
||||
}
|
||||
|
||||
private fun updatePlayPauseDrawableState() {
|
||||
if (MusicPlayerRemote.isPlaying) {
|
||||
playPauseButton.setImageResource(R.drawable.ic_pause)
|
||||
binding.playPauseButton.setImageResource(R.drawable.ic_pause)
|
||||
} else {
|
||||
playPauseButton.setImageResource(R.drawable.ic_play_arrow)
|
||||
binding.playPauseButton.setImageResource(R.drawable.ic_play_arrow)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -174,26 +185,26 @@ class PlayerPlaybackControlsFragment :
|
|||
|
||||
private fun setUpPrevNext() {
|
||||
updatePrevNextColor()
|
||||
nextButton.setOnClickListener { MusicPlayerRemote.playNextSong() }
|
||||
previousButton.setOnClickListener { MusicPlayerRemote.back() }
|
||||
binding.nextButton.setOnClickListener { MusicPlayerRemote.playNextSong() }
|
||||
binding.previousButton.setOnClickListener { MusicPlayerRemote.back() }
|
||||
}
|
||||
|
||||
private fun updatePrevNextColor() {
|
||||
nextButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
|
||||
previousButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
|
||||
binding.nextButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
|
||||
binding.previousButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
|
||||
}
|
||||
|
||||
private fun setUpShuffleButton() {
|
||||
shuffleButton.setOnClickListener { MusicPlayerRemote.toggleShuffleMode() }
|
||||
binding.shuffleButton.setOnClickListener { MusicPlayerRemote.toggleShuffleMode() }
|
||||
}
|
||||
|
||||
override fun updateShuffleState() {
|
||||
when (MusicPlayerRemote.shuffleMode) {
|
||||
MusicService.SHUFFLE_MODE_SHUFFLE -> shuffleButton.setColorFilter(
|
||||
MusicService.SHUFFLE_MODE_SHUFFLE -> binding.shuffleButton.setColorFilter(
|
||||
lastPlaybackControlsColor,
|
||||
PorterDuff.Mode.SRC_IN
|
||||
)
|
||||
else -> shuffleButton.setColorFilter(
|
||||
else -> binding.shuffleButton.setColorFilter(
|
||||
lastDisabledPlaybackControlsColor,
|
||||
PorterDuff.Mode.SRC_IN
|
||||
)
|
||||
|
@ -201,31 +212,37 @@ class PlayerPlaybackControlsFragment :
|
|||
}
|
||||
|
||||
private fun setUpRepeatButton() {
|
||||
repeatButton.setOnClickListener { MusicPlayerRemote.cycleRepeatMode() }
|
||||
binding.repeatButton.setOnClickListener { MusicPlayerRemote.cycleRepeatMode() }
|
||||
}
|
||||
|
||||
override fun updateRepeatState() {
|
||||
when (MusicPlayerRemote.repeatMode) {
|
||||
MusicService.REPEAT_MODE_NONE -> {
|
||||
repeatButton.setImageResource(R.drawable.ic_repeat)
|
||||
repeatButton.setColorFilter(
|
||||
binding.repeatButton.setImageResource(R.drawable.ic_repeat)
|
||||
binding.repeatButton.setColorFilter(
|
||||
lastDisabledPlaybackControlsColor,
|
||||
PorterDuff.Mode.SRC_IN
|
||||
)
|
||||
}
|
||||
MusicService.REPEAT_MODE_ALL -> {
|
||||
repeatButton.setImageResource(R.drawable.ic_repeat)
|
||||
repeatButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
|
||||
binding.repeatButton.setImageResource(R.drawable.ic_repeat)
|
||||
binding.repeatButton.setColorFilter(
|
||||
lastPlaybackControlsColor,
|
||||
PorterDuff.Mode.SRC_IN
|
||||
)
|
||||
}
|
||||
MusicService.REPEAT_MODE_THIS -> {
|
||||
repeatButton.setImageResource(R.drawable.ic_repeat_one)
|
||||
repeatButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
|
||||
binding.repeatButton.setImageResource(R.drawable.ic_repeat_one)
|
||||
binding.repeatButton.setColorFilter(
|
||||
lastPlaybackControlsColor,
|
||||
PorterDuff.Mode.SRC_IN
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override fun show() {
|
||||
playPauseButton.animate()
|
||||
binding.playPauseButton.animate()
|
||||
.scaleX(1f)
|
||||
.scaleY(1f)
|
||||
.rotation(360f)
|
||||
|
@ -234,7 +251,7 @@ class PlayerPlaybackControlsFragment :
|
|||
}
|
||||
|
||||
public override fun hide() {
|
||||
playPauseButton.apply {
|
||||
binding.playPauseButton.apply {
|
||||
scaleX = 0f
|
||||
scaleY = 0f
|
||||
rotation = 0f
|
||||
|
@ -242,7 +259,7 @@ class PlayerPlaybackControlsFragment :
|
|||
}
|
||||
|
||||
override fun setUpProgressSlider() {
|
||||
progressSlider.setOnSeekBarChangeListener(object : SimpleOnSeekbarChangeListener() {
|
||||
binding.progressSlider.setOnSeekBarChangeListener(object : SimpleOnSeekbarChangeListener() {
|
||||
override fun onProgressChanged(seekBar: SeekBar, progress: Int, fromUser: Boolean) {
|
||||
if (fromUser) {
|
||||
MusicPlayerRemote.seekTo(progress)
|
||||
|
@ -256,14 +273,19 @@ class PlayerPlaybackControlsFragment :
|
|||
}
|
||||
|
||||
override fun onUpdateProgressViews(progress: Int, total: Int) {
|
||||
progressSlider.max = total
|
||||
binding.progressSlider.max = total
|
||||
|
||||
val animator = ObjectAnimator.ofInt(progressSlider, "progress", progress)
|
||||
val animator = ObjectAnimator.ofInt(binding.progressSlider, "progress", progress)
|
||||
animator.duration = SLIDER_ANIMATION_TIME
|
||||
animator.interpolator = LinearInterpolator()
|
||||
animator.start()
|
||||
|
||||
songTotalTime.text = MusicUtil.getReadableDurationString(total.toLong())
|
||||
songCurrentProgress.text = MusicUtil.getReadableDurationString(progress.toLong())
|
||||
binding.songTotalTime.text = MusicUtil.getReadableDurationString(total.toLong())
|
||||
binding.songCurrentProgress.text = MusicUtil.getReadableDurationString(progress.toLong())
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
_binding = null
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@ import code.name.monkey.appthemehelper.util.ATHUtil
|
|||
import code.name.monkey.appthemehelper.util.MaterialValueHelper
|
||||
import code.name.monkey.appthemehelper.util.TintHelper
|
||||
import code.name.monkey.retromusic.R
|
||||
import code.name.monkey.retromusic.databinding.FragmentPeakControlPlayerBinding
|
||||
import code.name.monkey.retromusic.extensions.applyColor
|
||||
import code.name.monkey.retromusic.fragments.base.AbsPlayerControlsFragment
|
||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote
|
||||
|
@ -36,7 +37,6 @@ import code.name.monkey.retromusic.service.MusicService
|
|||
import code.name.monkey.retromusic.util.MusicUtil
|
||||
import code.name.monkey.retromusic.util.PreferenceUtil
|
||||
import code.name.monkey.retromusic.util.color.MediaNotificationProcessor
|
||||
import kotlinx.android.synthetic.main.fragment_peak_control_player.*
|
||||
|
||||
/**
|
||||
* Created by hemanths on 2019-10-04.
|
||||
|
@ -47,6 +47,8 @@ class PeakPlayerControlFragment : AbsPlayerControlsFragment(R.layout.fragment_pe
|
|||
private lateinit var progressViewUpdateHelper: MusicProgressViewUpdateHelper
|
||||
private var lastPlaybackControlsColor: Int = 0
|
||||
private var lastDisabledPlaybackControlsColor: Int = 0
|
||||
private var _binding: FragmentPeakControlPlayerBinding? = null
|
||||
private val binding get() = _binding!!
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
@ -68,6 +70,7 @@ class PeakPlayerControlFragment : AbsPlayerControlsFragment(R.layout.fragment_pe
|
|||
savedInstanceState: Bundle?
|
||||
) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
_binding = FragmentPeakControlPlayerBinding.bind(view)
|
||||
setUpMusicControllers()
|
||||
}
|
||||
|
||||
|
@ -84,11 +87,11 @@ class PeakPlayerControlFragment : AbsPlayerControlsFragment(R.layout.fragment_pe
|
|||
} else {
|
||||
ThemeStore.accentColor(requireContext())
|
||||
}
|
||||
progressSlider.applyColor(controlsColor)
|
||||
binding.progressSlider.applyColor(controlsColor)
|
||||
volumeFragment?.setTintableColor(controlsColor)
|
||||
playPauseButton.setColorFilter(controlsColor, PorterDuff.Mode.SRC_IN)
|
||||
nextButton.setColorFilter(controlsColor, PorterDuff.Mode.SRC_IN)
|
||||
previousButton.setColorFilter(controlsColor, PorterDuff.Mode.SRC_IN)
|
||||
binding.playPauseButton.setColorFilter(controlsColor, PorterDuff.Mode.SRC_IN)
|
||||
binding.nextButton.setColorFilter(controlsColor, PorterDuff.Mode.SRC_IN)
|
||||
binding.previousButton.setColorFilter(controlsColor, PorterDuff.Mode.SRC_IN)
|
||||
|
||||
if (!ATHUtil.isWindowBackgroundDark(requireContext())) {
|
||||
lastPlaybackControlsColor =
|
||||
|
@ -107,9 +110,9 @@ class PeakPlayerControlFragment : AbsPlayerControlsFragment(R.layout.fragment_pe
|
|||
|
||||
private fun updatePlayPauseDrawableState() {
|
||||
if (MusicPlayerRemote.isPlaying) {
|
||||
playPauseButton.setImageResource(R.drawable.ic_pause)
|
||||
binding.playPauseButton.setImageResource(R.drawable.ic_pause)
|
||||
} else {
|
||||
playPauseButton.setImageResource(R.drawable.ic_play_arrow_white_32dp)
|
||||
binding.playPauseButton.setImageResource(R.drawable.ic_play_arrow_white_32dp)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -122,19 +125,19 @@ class PeakPlayerControlFragment : AbsPlayerControlsFragment(R.layout.fragment_pe
|
|||
}
|
||||
|
||||
private fun setUpShuffleButton() {
|
||||
shuffleButton.setOnClickListener {
|
||||
binding.shuffleButton.setOnClickListener {
|
||||
MusicPlayerRemote.toggleShuffleMode()
|
||||
}
|
||||
}
|
||||
|
||||
private fun setUpRepeatButton() {
|
||||
repeatButton.setOnClickListener {
|
||||
binding.repeatButton.setOnClickListener {
|
||||
MusicPlayerRemote.cycleRepeatMode()
|
||||
}
|
||||
}
|
||||
|
||||
override fun setUpProgressSlider() {
|
||||
progressSlider.setOnSeekBarChangeListener(object : SimpleOnSeekbarChangeListener() {
|
||||
binding.progressSlider.setOnSeekBarChangeListener(object : SimpleOnSeekbarChangeListener() {
|
||||
override fun onProgressChanged(seekBar: SeekBar, progress: Int, fromUser: Boolean) {
|
||||
if (fromUser) {
|
||||
MusicPlayerRemote.seekTo(progress)
|
||||
|
@ -148,41 +151,41 @@ class PeakPlayerControlFragment : AbsPlayerControlsFragment(R.layout.fragment_pe
|
|||
}
|
||||
|
||||
override fun onUpdateProgressViews(progress: Int, total: Int) {
|
||||
progressSlider.max = total
|
||||
binding.progressSlider.max = total
|
||||
|
||||
val animator = ObjectAnimator.ofInt(progressSlider, "progress", progress)
|
||||
val animator = ObjectAnimator.ofInt(binding.progressSlider, "progress", progress)
|
||||
animator.duration = SLIDER_ANIMATION_TIME
|
||||
animator.interpolator = LinearInterpolator()
|
||||
animator.start()
|
||||
|
||||
songTotalTime.text = MusicUtil.getReadableDurationString(total.toLong())
|
||||
songCurrentProgress.text = MusicUtil.getReadableDurationString(progress.toLong())
|
||||
binding.songTotalTime.text = MusicUtil.getReadableDurationString(total.toLong())
|
||||
binding.songCurrentProgress.text = MusicUtil.getReadableDurationString(progress.toLong())
|
||||
}
|
||||
|
||||
private fun setUpPlayPauseFab() {
|
||||
TintHelper.setTintAuto(playPauseButton, Color.WHITE, true)
|
||||
TintHelper.setTintAuto(playPauseButton, Color.BLACK, false)
|
||||
playPauseButton.setOnClickListener(PlayPauseButtonOnClickHandler())
|
||||
TintHelper.setTintAuto(binding.playPauseButton, Color.WHITE, true)
|
||||
TintHelper.setTintAuto(binding.playPauseButton, Color.BLACK, false)
|
||||
binding.playPauseButton.setOnClickListener(PlayPauseButtonOnClickHandler())
|
||||
}
|
||||
|
||||
private fun setUpPrevNext() {
|
||||
updatePrevNextColor()
|
||||
nextButton.setOnClickListener { MusicPlayerRemote.playNextSong() }
|
||||
previousButton.setOnClickListener { MusicPlayerRemote.back() }
|
||||
binding.nextButton.setOnClickListener { MusicPlayerRemote.playNextSong() }
|
||||
binding.previousButton.setOnClickListener { MusicPlayerRemote.back() }
|
||||
}
|
||||
|
||||
private fun updatePrevNextColor() {
|
||||
nextButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
|
||||
previousButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
|
||||
binding.nextButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
|
||||
binding.previousButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
|
||||
}
|
||||
|
||||
override fun updateShuffleState() {
|
||||
when (MusicPlayerRemote.shuffleMode) {
|
||||
MusicService.SHUFFLE_MODE_SHUFFLE -> shuffleButton.setColorFilter(
|
||||
MusicService.SHUFFLE_MODE_SHUFFLE -> binding.shuffleButton.setColorFilter(
|
||||
lastPlaybackControlsColor,
|
||||
PorterDuff.Mode.SRC_IN
|
||||
)
|
||||
else -> shuffleButton.setColorFilter(
|
||||
else -> binding.shuffleButton.setColorFilter(
|
||||
lastDisabledPlaybackControlsColor,
|
||||
PorterDuff.Mode.SRC_IN
|
||||
)
|
||||
|
@ -192,19 +195,25 @@ class PeakPlayerControlFragment : AbsPlayerControlsFragment(R.layout.fragment_pe
|
|||
override fun updateRepeatState() {
|
||||
when (MusicPlayerRemote.repeatMode) {
|
||||
MusicService.REPEAT_MODE_NONE -> {
|
||||
repeatButton.setImageResource(R.drawable.ic_repeat)
|
||||
repeatButton.setColorFilter(
|
||||
binding.repeatButton.setImageResource(R.drawable.ic_repeat)
|
||||
binding.repeatButton.setColorFilter(
|
||||
lastDisabledPlaybackControlsColor,
|
||||
PorterDuff.Mode.SRC_IN
|
||||
)
|
||||
}
|
||||
MusicService.REPEAT_MODE_ALL -> {
|
||||
repeatButton.setImageResource(R.drawable.ic_repeat)
|
||||
repeatButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
|
||||
binding.repeatButton.setImageResource(R.drawable.ic_repeat)
|
||||
binding.repeatButton.setColorFilter(
|
||||
lastPlaybackControlsColor,
|
||||
PorterDuff.Mode.SRC_IN
|
||||
)
|
||||
}
|
||||
MusicService.REPEAT_MODE_THIS -> {
|
||||
repeatButton.setImageResource(R.drawable.ic_repeat_one)
|
||||
repeatButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
|
||||
binding.repeatButton.setImageResource(R.drawable.ic_repeat_one)
|
||||
binding.repeatButton.setColorFilter(
|
||||
lastPlaybackControlsColor,
|
||||
PorterDuff.Mode.SRC_IN
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -226,4 +235,9 @@ class PeakPlayerControlFragment : AbsPlayerControlsFragment(R.layout.fragment_pe
|
|||
override fun onShuffleModeChanged() {
|
||||
updateShuffleState()
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
_binding = null
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,14 +20,16 @@ import androidx.appcompat.widget.Toolbar
|
|||
import code.name.monkey.appthemehelper.util.ATHUtil
|
||||
import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper
|
||||
import code.name.monkey.retromusic.R
|
||||
import code.name.monkey.retromusic.databinding.FragmentPeakPlayerBinding
|
||||
import code.name.monkey.retromusic.extensions.hide
|
||||
import code.name.monkey.retromusic.extensions.show
|
||||
import code.name.monkey.retromusic.fragments.base.AbsPlayerFragment
|
||||
import code.name.monkey.retromusic.fragments.base.goToAlbum
|
||||
import code.name.monkey.retromusic.fragments.base.goToArtist
|
||||
import code.name.monkey.retromusic.fragments.player.PlayerAlbumCoverFragment
|
||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote
|
||||
import code.name.monkey.retromusic.util.PreferenceUtil
|
||||
import code.name.monkey.retromusic.util.color.MediaNotificationProcessor
|
||||
import kotlinx.android.synthetic.main.fragment_peak_player.*
|
||||
|
||||
/**
|
||||
* Created by hemanths on 2019-10-03.
|
||||
|
@ -37,12 +39,22 @@ class PeakPlayerFragment : AbsPlayerFragment(R.layout.fragment_peak_player) {
|
|||
|
||||
private lateinit var controlsFragment: PeakPlayerControlFragment
|
||||
private var lastColor: Int = 0
|
||||
private var _binding: FragmentPeakPlayerBinding? = null
|
||||
private val binding get() = _binding!!
|
||||
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
_binding = FragmentPeakPlayerBinding.bind(view)
|
||||
setUpPlayerToolbar()
|
||||
setUpSubFragments()
|
||||
title.isSelected = true
|
||||
binding.title.isSelected = true
|
||||
binding.title.setOnClickListener {
|
||||
goToAlbum(requireActivity())
|
||||
}
|
||||
binding.text.setOnClickListener {
|
||||
goToArtist(requireActivity())
|
||||
}
|
||||
}
|
||||
|
||||
private fun setUpSubFragments() {
|
||||
|
@ -55,7 +67,7 @@ class PeakPlayerFragment : AbsPlayerFragment(R.layout.fragment_peak_player) {
|
|||
}
|
||||
|
||||
private fun setUpPlayerToolbar() {
|
||||
playerToolbar.apply {
|
||||
binding.playerToolbar.apply {
|
||||
inflateMenu(R.menu.menu_player)
|
||||
setNavigationOnClickListener { requireActivity().onBackPressed() }
|
||||
setOnMenuItemClickListener(this@PeakPlayerFragment)
|
||||
|
@ -68,7 +80,7 @@ class PeakPlayerFragment : AbsPlayerFragment(R.layout.fragment_peak_player) {
|
|||
}
|
||||
|
||||
override fun playerToolbar(): Toolbar {
|
||||
return playerToolbar
|
||||
return binding.playerToolbar
|
||||
}
|
||||
|
||||
override fun onShow() {
|
||||
|
@ -99,14 +111,14 @@ class PeakPlayerFragment : AbsPlayerFragment(R.layout.fragment_peak_player) {
|
|||
|
||||
private fun updateSong() {
|
||||
val song = MusicPlayerRemote.currentSong
|
||||
title.text = song.title
|
||||
text.text = song.artistName
|
||||
binding.title.text = song.title
|
||||
binding.text.text = song.artistName
|
||||
|
||||
if (PreferenceUtil.isSongInfo) {
|
||||
songInfo.text = getSongInfo(song)
|
||||
songInfo.show()
|
||||
binding.songInfo.text = getSongInfo(song)
|
||||
binding.songInfo.show()
|
||||
} else {
|
||||
songInfo.hide()
|
||||
binding.songInfo.hide()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -119,4 +131,9 @@ class PeakPlayerFragment : AbsPlayerFragment(R.layout.fragment_peak_player) {
|
|||
super.onPlayingMetaChanged()
|
||||
updateSong()
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
_binding = null
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,6 +28,7 @@ import code.name.monkey.appthemehelper.util.ColorUtil
|
|||
import code.name.monkey.appthemehelper.util.MaterialValueHelper
|
||||
import code.name.monkey.appthemehelper.util.TintHelper
|
||||
import code.name.monkey.retromusic.R
|
||||
import code.name.monkey.retromusic.databinding.FragmentPlainControlsFragmentBinding
|
||||
import code.name.monkey.retromusic.extensions.applyColor
|
||||
import code.name.monkey.retromusic.extensions.hide
|
||||
import code.name.monkey.retromusic.extensions.show
|
||||
|
@ -40,15 +41,6 @@ import code.name.monkey.retromusic.service.MusicService
|
|||
import code.name.monkey.retromusic.util.MusicUtil
|
||||
import code.name.monkey.retromusic.util.PreferenceUtil
|
||||
import code.name.monkey.retromusic.util.color.MediaNotificationProcessor
|
||||
import kotlinx.android.synthetic.main.fragment_adaptive_player_playback_controls.*
|
||||
import kotlinx.android.synthetic.main.fragment_plain_controls_fragment.nextButton
|
||||
import kotlinx.android.synthetic.main.fragment_plain_controls_fragment.playPauseButton
|
||||
import kotlinx.android.synthetic.main.fragment_plain_controls_fragment.previousButton
|
||||
import kotlinx.android.synthetic.main.fragment_plain_controls_fragment.progressSlider
|
||||
import kotlinx.android.synthetic.main.fragment_plain_controls_fragment.repeatButton
|
||||
import kotlinx.android.synthetic.main.fragment_plain_controls_fragment.shuffleButton
|
||||
import kotlinx.android.synthetic.main.fragment_plain_controls_fragment.songCurrentProgress
|
||||
import kotlinx.android.synthetic.main.fragment_plain_controls_fragment.songTotalTime
|
||||
|
||||
/**
|
||||
* @author Hemanth S (h4h13).
|
||||
|
@ -60,6 +52,8 @@ class PlainPlaybackControlsFragment :
|
|||
private var lastPlaybackControlsColor: Int = 0
|
||||
private var lastDisabledPlaybackControlsColor: Int = 0
|
||||
private lateinit var progressViewUpdateHelper: MusicProgressViewUpdateHelper
|
||||
private var _binding: FragmentPlainControlsFragmentBinding? = null
|
||||
private val binding get() = _binding!!
|
||||
|
||||
override fun onPlayStateChanged() {
|
||||
updatePlayPauseDrawableState()
|
||||
|
@ -87,10 +81,10 @@ class PlainPlaybackControlsFragment :
|
|||
|
||||
private fun updateSong() {
|
||||
if (PreferenceUtil.isSongInfo) {
|
||||
songInfo.text = getSongInfo(MusicPlayerRemote.currentSong)
|
||||
songInfo.show()
|
||||
binding.songInfo.text = getSongInfo(MusicPlayerRemote.currentSong)
|
||||
binding.songInfo.show()
|
||||
} else {
|
||||
songInfo.hide()
|
||||
binding.songInfo.hide()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -111,20 +105,21 @@ class PlainPlaybackControlsFragment :
|
|||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
_binding = FragmentPlainControlsFragmentBinding.bind(view)
|
||||
setUpMusicControllers()
|
||||
|
||||
playPauseButton.setOnClickListener {
|
||||
binding.playPauseButton.setOnClickListener {
|
||||
if (MusicPlayerRemote.isPlaying) {
|
||||
MusicPlayerRemote.pauseSong()
|
||||
} else {
|
||||
MusicPlayerRemote.resumePlaying()
|
||||
}
|
||||
showBonceAnimation()
|
||||
showBounceAnimation()
|
||||
}
|
||||
}
|
||||
|
||||
private fun setUpPlayPauseFab() {
|
||||
playPauseButton.setOnClickListener(PlayPauseButtonOnClickHandler())
|
||||
binding.playPauseButton.setOnClickListener(PlayPauseButtonOnClickHandler())
|
||||
}
|
||||
|
||||
private fun setUpMusicControllers() {
|
||||
|
@ -137,13 +132,13 @@ class PlainPlaybackControlsFragment :
|
|||
|
||||
private fun setUpPrevNext() {
|
||||
updatePrevNextColor()
|
||||
nextButton.setOnClickListener { MusicPlayerRemote.playNextSong() }
|
||||
previousButton.setOnClickListener { MusicPlayerRemote.back() }
|
||||
binding.nextButton.setOnClickListener { MusicPlayerRemote.playNextSong() }
|
||||
binding.previousButton.setOnClickListener { MusicPlayerRemote.back() }
|
||||
}
|
||||
|
||||
private fun updatePrevNextColor() {
|
||||
nextButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
|
||||
previousButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
|
||||
binding.nextButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
|
||||
binding.previousButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
|
||||
}
|
||||
|
||||
override fun setColor(color: MediaNotificationProcessor) {
|
||||
|
@ -166,17 +161,17 @@ class PlainPlaybackControlsFragment :
|
|||
ThemeStore.accentColor(requireContext())
|
||||
}
|
||||
volumeFragment?.setTintable(colorFinal)
|
||||
progressSlider.applyColor(colorFinal)
|
||||
binding.progressSlider.applyColor(colorFinal)
|
||||
|
||||
TintHelper.setTintAuto(
|
||||
playPauseButton,
|
||||
binding.playPauseButton,
|
||||
MaterialValueHelper.getPrimaryTextColor(
|
||||
requireContext(),
|
||||
ColorUtil.isColorLight(colorFinal)
|
||||
),
|
||||
false
|
||||
)
|
||||
TintHelper.setTintAuto(playPauseButton, colorFinal, true)
|
||||
TintHelper.setTintAuto(binding.playPauseButton, colorFinal, true)
|
||||
|
||||
updateRepeatState()
|
||||
updateShuffleState()
|
||||
|
@ -184,16 +179,16 @@ class PlainPlaybackControlsFragment :
|
|||
}
|
||||
|
||||
private fun setUpShuffleButton() {
|
||||
shuffleButton.setOnClickListener { MusicPlayerRemote.toggleShuffleMode() }
|
||||
binding.shuffleButton.setOnClickListener { MusicPlayerRemote.toggleShuffleMode() }
|
||||
}
|
||||
|
||||
override fun updateShuffleState() {
|
||||
when (MusicPlayerRemote.shuffleMode) {
|
||||
MusicService.SHUFFLE_MODE_SHUFFLE -> shuffleButton.setColorFilter(
|
||||
MusicService.SHUFFLE_MODE_SHUFFLE -> binding.shuffleButton.setColorFilter(
|
||||
lastPlaybackControlsColor,
|
||||
PorterDuff.Mode.SRC_IN
|
||||
)
|
||||
else -> shuffleButton.setColorFilter(
|
||||
else -> binding.shuffleButton.setColorFilter(
|
||||
lastDisabledPlaybackControlsColor,
|
||||
PorterDuff.Mode.SRC_IN
|
||||
)
|
||||
|
@ -201,31 +196,37 @@ class PlainPlaybackControlsFragment :
|
|||
}
|
||||
|
||||
private fun setUpRepeatButton() {
|
||||
repeatButton.setOnClickListener { MusicPlayerRemote.cycleRepeatMode() }
|
||||
binding.repeatButton.setOnClickListener { MusicPlayerRemote.cycleRepeatMode() }
|
||||
}
|
||||
|
||||
override fun updateRepeatState() {
|
||||
when (MusicPlayerRemote.repeatMode) {
|
||||
MusicService.REPEAT_MODE_NONE -> {
|
||||
repeatButton.setImageResource(R.drawable.ic_repeat)
|
||||
repeatButton.setColorFilter(
|
||||
binding.repeatButton.setImageResource(R.drawable.ic_repeat)
|
||||
binding.repeatButton.setColorFilter(
|
||||
lastDisabledPlaybackControlsColor,
|
||||
PorterDuff.Mode.SRC_IN
|
||||
)
|
||||
}
|
||||
MusicService.REPEAT_MODE_ALL -> {
|
||||
repeatButton.setImageResource(R.drawable.ic_repeat)
|
||||
repeatButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
|
||||
binding.repeatButton.setImageResource(R.drawable.ic_repeat)
|
||||
binding.repeatButton.setColorFilter(
|
||||
lastPlaybackControlsColor,
|
||||
PorterDuff.Mode.SRC_IN
|
||||
)
|
||||
}
|
||||
MusicService.REPEAT_MODE_THIS -> {
|
||||
repeatButton.setImageResource(R.drawable.ic_repeat_one)
|
||||
repeatButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
|
||||
binding.repeatButton.setImageResource(R.drawable.ic_repeat_one)
|
||||
binding.repeatButton.setColorFilter(
|
||||
lastPlaybackControlsColor,
|
||||
PorterDuff.Mode.SRC_IN
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override fun show() {
|
||||
playPauseButton!!.animate()
|
||||
binding.playPauseButton.animate()
|
||||
.scaleX(1f)
|
||||
.scaleY(1f)
|
||||
.rotation(360f)
|
||||
|
@ -234,17 +235,15 @@ class PlainPlaybackControlsFragment :
|
|||
}
|
||||
|
||||
public override fun hide() {
|
||||
if (playPauseButton != null) {
|
||||
playPauseButton!!.apply {
|
||||
scaleX = 0f
|
||||
scaleY = 0f
|
||||
rotation = 0f
|
||||
}
|
||||
binding.playPauseButton.apply {
|
||||
scaleX = 0f
|
||||
scaleY = 0f
|
||||
rotation = 0f
|
||||
}
|
||||
}
|
||||
|
||||
private fun showBonceAnimation() {
|
||||
playPauseButton.apply {
|
||||
private fun showBounceAnimation() {
|
||||
binding.playPauseButton.apply {
|
||||
clearAnimation()
|
||||
scaleX = 0.9f
|
||||
scaleY = 0.9f
|
||||
|
@ -268,14 +267,14 @@ class PlainPlaybackControlsFragment :
|
|||
|
||||
private fun updatePlayPauseDrawableState() {
|
||||
if (MusicPlayerRemote.isPlaying) {
|
||||
playPauseButton.setImageResource(R.drawable.ic_pause)
|
||||
binding.playPauseButton.setImageResource(R.drawable.ic_pause)
|
||||
} else {
|
||||
playPauseButton.setImageResource(R.drawable.ic_play_arrow_white_32dp)
|
||||
binding.playPauseButton.setImageResource(R.drawable.ic_play_arrow_white_32dp)
|
||||
}
|
||||
}
|
||||
|
||||
override fun setUpProgressSlider() {
|
||||
progressSlider.setOnSeekBarChangeListener(object : SimpleOnSeekbarChangeListener() {
|
||||
binding.progressSlider.setOnSeekBarChangeListener(object : SimpleOnSeekbarChangeListener() {
|
||||
override fun onProgressChanged(seekBar: SeekBar, progress: Int, fromUser: Boolean) {
|
||||
if (fromUser) {
|
||||
MusicPlayerRemote.seekTo(progress)
|
||||
|
@ -289,14 +288,19 @@ class PlainPlaybackControlsFragment :
|
|||
}
|
||||
|
||||
override fun onUpdateProgressViews(progress: Int, total: Int) {
|
||||
progressSlider.max = total
|
||||
binding.progressSlider.max = total
|
||||
|
||||
val animator = ObjectAnimator.ofInt(progressSlider, "progress", progress)
|
||||
val animator = ObjectAnimator.ofInt(binding.progressSlider, "progress", progress)
|
||||
animator.duration = SLIDER_ANIMATION_TIME
|
||||
animator.interpolator = LinearInterpolator()
|
||||
animator.start()
|
||||
|
||||
songTotalTime.text = MusicUtil.getReadableDurationString(total.toLong())
|
||||
songCurrentProgress.text = MusicUtil.getReadableDurationString(progress.toLong())
|
||||
binding.songTotalTime.text = MusicUtil.getReadableDurationString(total.toLong())
|
||||
binding.songCurrentProgress.text = MusicUtil.getReadableDurationString(progress.toLong())
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
_binding = null
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,22 +20,27 @@ import androidx.appcompat.widget.Toolbar
|
|||
import code.name.monkey.appthemehelper.util.ATHUtil
|
||||
import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper
|
||||
import code.name.monkey.retromusic.R
|
||||
import code.name.monkey.retromusic.databinding.FragmentPlainPlayerBinding
|
||||
import code.name.monkey.retromusic.fragments.base.AbsPlayerFragment
|
||||
import code.name.monkey.retromusic.fragments.base.goToAlbum
|
||||
import code.name.monkey.retromusic.fragments.base.goToArtist
|
||||
import code.name.monkey.retromusic.fragments.player.PlayerAlbumCoverFragment
|
||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote
|
||||
import code.name.monkey.retromusic.model.Song
|
||||
import code.name.monkey.retromusic.util.color.MediaNotificationProcessor
|
||||
import kotlinx.android.synthetic.main.fragment_plain_player.*
|
||||
|
||||
class PlainPlayerFragment : AbsPlayerFragment(R.layout.fragment_plain_player) {
|
||||
override fun playerToolbar(): Toolbar {
|
||||
return playerToolbar
|
||||
return binding.playerToolbar
|
||||
}
|
||||
|
||||
private lateinit var plainPlaybackControlsFragment: PlainPlaybackControlsFragment
|
||||
private var lastColor: Int = 0
|
||||
override val paletteColor: Int
|
||||
get() = lastColor
|
||||
private var _binding: FragmentPlainPlayerBinding? = null
|
||||
private val binding get() = _binding!!
|
||||
|
||||
|
||||
override fun onPlayingMetaChanged() {
|
||||
super.onPlayingMetaChanged()
|
||||
|
@ -44,8 +49,8 @@ class PlainPlayerFragment : AbsPlayerFragment(R.layout.fragment_plain_player) {
|
|||
|
||||
private fun updateSong() {
|
||||
val song = MusicPlayerRemote.currentSong
|
||||
title.text = song.title
|
||||
text.text = song.artistName
|
||||
binding.title.text = song.title
|
||||
binding.text.text = song.artistName
|
||||
}
|
||||
|
||||
override fun onServiceConnected() {
|
||||
|
@ -54,7 +59,7 @@ class PlainPlayerFragment : AbsPlayerFragment(R.layout.fragment_plain_player) {
|
|||
}
|
||||
|
||||
private fun setUpPlayerToolbar() {
|
||||
playerToolbar.apply {
|
||||
binding.playerToolbar.apply {
|
||||
inflateMenu(R.menu.menu_player)
|
||||
setNavigationOnClickListener { requireActivity().onBackPressed() }
|
||||
setOnMenuItemClickListener(this@PlainPlayerFragment)
|
||||
|
@ -68,10 +73,17 @@ class PlainPlayerFragment : AbsPlayerFragment(R.layout.fragment_plain_player) {
|
|||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
_binding = FragmentPlainPlayerBinding.bind(view)
|
||||
setUpSubFragments()
|
||||
setUpPlayerToolbar()
|
||||
title.isSelected = true
|
||||
text.isSelected = true
|
||||
binding.title.isSelected = true
|
||||
binding.text.isSelected = true
|
||||
binding.title.setOnClickListener {
|
||||
goToAlbum(requireActivity())
|
||||
}
|
||||
binding.text.setOnClickListener {
|
||||
goToArtist(requireActivity())
|
||||
}
|
||||
}
|
||||
|
||||
private fun setUpSubFragments() {
|
||||
|
@ -104,7 +116,7 @@ class PlainPlayerFragment : AbsPlayerFragment(R.layout.fragment_plain_player) {
|
|||
lastColor = color.primaryTextColor
|
||||
libraryViewModel.updateColor(color.primaryTextColor)
|
||||
ToolbarContentTintHelper.colorizeToolbar(
|
||||
playerToolbar,
|
||||
binding.playerToolbar,
|
||||
ATHUtil.resolveColor(requireContext(), R.attr.colorControlNormal),
|
||||
requireActivity()
|
||||
)
|
||||
|
@ -120,4 +132,9 @@ class PlainPlayerFragment : AbsPlayerFragment(R.layout.fragment_plain_player) {
|
|||
updateIsFavorite()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
_binding = null
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,9 +24,12 @@ import code.name.monkey.appthemehelper.util.ColorUtil
|
|||
import code.name.monkey.appthemehelper.util.MaterialValueHelper
|
||||
import code.name.monkey.appthemehelper.util.TintHelper
|
||||
import code.name.monkey.retromusic.R
|
||||
import code.name.monkey.retromusic.databinding.FragmentSimpleControlsFragmentBinding
|
||||
import code.name.monkey.retromusic.extensions.hide
|
||||
import code.name.monkey.retromusic.extensions.show
|
||||
import code.name.monkey.retromusic.fragments.base.AbsPlayerControlsFragment
|
||||
import code.name.monkey.retromusic.fragments.base.goToAlbum
|
||||
import code.name.monkey.retromusic.fragments.base.goToArtist
|
||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote
|
||||
import code.name.monkey.retromusic.helper.MusicProgressViewUpdateHelper
|
||||
import code.name.monkey.retromusic.helper.PlayPauseButtonOnClickHandler
|
||||
|
@ -34,7 +37,6 @@ import code.name.monkey.retromusic.service.MusicService
|
|||
import code.name.monkey.retromusic.util.MusicUtil
|
||||
import code.name.monkey.retromusic.util.PreferenceUtil
|
||||
import code.name.monkey.retromusic.util.color.MediaNotificationProcessor
|
||||
import kotlinx.android.synthetic.main.fragment_simple_controls_fragment.*
|
||||
|
||||
/**
|
||||
* @author Hemanth S (h4h13).
|
||||
|
@ -43,6 +45,10 @@ import kotlinx.android.synthetic.main.fragment_simple_controls_fragment.*
|
|||
class SimplePlaybackControlsFragment :
|
||||
AbsPlayerControlsFragment(R.layout.fragment_simple_controls_fragment) {
|
||||
|
||||
private var _binding: FragmentSimpleControlsFragmentBinding? = null
|
||||
private val binding get() = _binding!!
|
||||
|
||||
|
||||
private var lastPlaybackControlsColor: Int = 0
|
||||
private var lastDisabledPlaybackControlsColor: Int = 0
|
||||
private lateinit var progressViewUpdateHelper: MusicProgressViewUpdateHelper
|
||||
|
@ -83,15 +89,25 @@ class SimplePlaybackControlsFragment :
|
|||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
_binding = FragmentSimpleControlsFragmentBinding.bind(view)
|
||||
setUpMusicControllers()
|
||||
title.isSelected = true
|
||||
playPauseButton.setOnClickListener {
|
||||
binding.title.isSelected = true
|
||||
binding.text.setOnClickListener {
|
||||
goToArtist(requireActivity())
|
||||
}
|
||||
binding.playPauseButton.setOnClickListener {
|
||||
if (MusicPlayerRemote.isPlaying) {
|
||||
MusicPlayerRemote.pauseSong()
|
||||
} else {
|
||||
MusicPlayerRemote.resumePlaying()
|
||||
}
|
||||
showBonceAnimation(playPauseButton)
|
||||
showBounceAnimation(binding.playPauseButton)
|
||||
}
|
||||
binding.title.setOnClickListener {
|
||||
goToAlbum(requireActivity())
|
||||
}
|
||||
binding.text.setOnClickListener {
|
||||
goToArtist(requireActivity())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -105,26 +121,26 @@ class SimplePlaybackControlsFragment :
|
|||
|
||||
private fun setUpPrevNext() {
|
||||
updatePrevNextColor()
|
||||
nextButton.setOnClickListener { MusicPlayerRemote.playNextSong() }
|
||||
previousButton.setOnClickListener { MusicPlayerRemote.back() }
|
||||
binding.nextButton.setOnClickListener { MusicPlayerRemote.playNextSong() }
|
||||
binding.previousButton.setOnClickListener { MusicPlayerRemote.back() }
|
||||
}
|
||||
|
||||
private fun updatePrevNextColor() {
|
||||
nextButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
|
||||
previousButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
|
||||
binding.nextButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
|
||||
binding.previousButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
|
||||
}
|
||||
|
||||
private fun setUpShuffleButton() {
|
||||
shuffleButton.setOnClickListener { MusicPlayerRemote.toggleShuffleMode() }
|
||||
binding.shuffleButton.setOnClickListener { MusicPlayerRemote.toggleShuffleMode() }
|
||||
}
|
||||
|
||||
override fun updateShuffleState() {
|
||||
when (MusicPlayerRemote.shuffleMode) {
|
||||
MusicService.SHUFFLE_MODE_SHUFFLE -> shuffleButton.setColorFilter(
|
||||
MusicService.SHUFFLE_MODE_SHUFFLE -> binding.shuffleButton.setColorFilter(
|
||||
lastPlaybackControlsColor,
|
||||
PorterDuff.Mode.SRC_IN
|
||||
)
|
||||
else -> shuffleButton.setColorFilter(
|
||||
else -> binding.shuffleButton.setColorFilter(
|
||||
lastDisabledPlaybackControlsColor,
|
||||
PorterDuff.Mode.SRC_IN
|
||||
)
|
||||
|
@ -132,39 +148,45 @@ class SimplePlaybackControlsFragment :
|
|||
}
|
||||
|
||||
private fun setUpRepeatButton() {
|
||||
repeatButton.setOnClickListener { MusicPlayerRemote.cycleRepeatMode() }
|
||||
binding.repeatButton.setOnClickListener { MusicPlayerRemote.cycleRepeatMode() }
|
||||
}
|
||||
|
||||
override fun updateRepeatState() {
|
||||
when (MusicPlayerRemote.repeatMode) {
|
||||
MusicService.REPEAT_MODE_NONE -> {
|
||||
repeatButton.setImageResource(R.drawable.ic_repeat)
|
||||
repeatButton.setColorFilter(
|
||||
binding.repeatButton.setImageResource(R.drawable.ic_repeat)
|
||||
binding.repeatButton.setColorFilter(
|
||||
lastDisabledPlaybackControlsColor,
|
||||
PorterDuff.Mode.SRC_IN
|
||||
)
|
||||
}
|
||||
MusicService.REPEAT_MODE_ALL -> {
|
||||
repeatButton.setImageResource(R.drawable.ic_repeat)
|
||||
repeatButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
|
||||
binding.repeatButton.setImageResource(R.drawable.ic_repeat)
|
||||
binding.repeatButton.setColorFilter(
|
||||
lastPlaybackControlsColor,
|
||||
PorterDuff.Mode.SRC_IN
|
||||
)
|
||||
}
|
||||
MusicService.REPEAT_MODE_THIS -> {
|
||||
repeatButton.setImageResource(R.drawable.ic_repeat_one)
|
||||
repeatButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
|
||||
binding.repeatButton.setImageResource(R.drawable.ic_repeat_one)
|
||||
binding.repeatButton.setColorFilter(
|
||||
lastPlaybackControlsColor,
|
||||
PorterDuff.Mode.SRC_IN
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateSong() {
|
||||
val song = MusicPlayerRemote.currentSong
|
||||
title.text = song.title
|
||||
text.text = song.artistName
|
||||
binding.title.text = song.title
|
||||
binding.text.text = song.artistName
|
||||
|
||||
if (PreferenceUtil.isSongInfo) {
|
||||
songInfo.text = getSongInfo(song)
|
||||
songInfo.show()
|
||||
binding.songInfo.text = getSongInfo(song)
|
||||
binding.songInfo.show()
|
||||
} else {
|
||||
songInfo.hide()
|
||||
binding.songInfo.hide()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -174,7 +196,7 @@ class SimplePlaybackControlsFragment :
|
|||
}
|
||||
|
||||
public override fun show() {
|
||||
playPauseButton!!.animate()
|
||||
binding.playPauseButton.animate()
|
||||
.scaleX(1f)
|
||||
.scaleY(1f)
|
||||
.rotation(360f)
|
||||
|
@ -183,12 +205,10 @@ class SimplePlaybackControlsFragment :
|
|||
}
|
||||
|
||||
public override fun hide() {
|
||||
if (playPauseButton != null) {
|
||||
playPauseButton!!.apply {
|
||||
scaleX = 0f
|
||||
scaleY = 0f
|
||||
rotation = 0f
|
||||
}
|
||||
binding.playPauseButton.apply {
|
||||
scaleX = 0f
|
||||
scaleY = 0f
|
||||
rotation = 0f
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -196,7 +216,7 @@ class SimplePlaybackControlsFragment :
|
|||
}
|
||||
|
||||
override fun onUpdateProgressViews(progress: Int, total: Int) {
|
||||
songCurrentProgress!!.text = String.format(
|
||||
binding.songCurrentProgress.text = String.format(
|
||||
"%s / %s",
|
||||
MusicUtil.getReadableDurationString(progress.toLong()),
|
||||
MusicUtil.getReadableDurationString(total.toLong())
|
||||
|
@ -226,15 +246,15 @@ class SimplePlaybackControlsFragment :
|
|||
volumeFragment?.setTintable(colorFinal)
|
||||
|
||||
TintHelper.setTintAuto(
|
||||
playPauseButton,
|
||||
binding.playPauseButton,
|
||||
MaterialValueHelper.getPrimaryTextColor(
|
||||
requireContext(),
|
||||
ColorUtil.isColorLight(colorFinal)
|
||||
),
|
||||
false
|
||||
)
|
||||
TintHelper.setTintAuto(playPauseButton, colorFinal, true)
|
||||
text.setTextColor(colorFinal)
|
||||
TintHelper.setTintAuto(binding.playPauseButton, colorFinal, true)
|
||||
binding.text.setTextColor(colorFinal)
|
||||
|
||||
updateRepeatState()
|
||||
updateShuffleState()
|
||||
|
@ -242,14 +262,19 @@ class SimplePlaybackControlsFragment :
|
|||
}
|
||||
|
||||
private fun setUpPlayPauseFab() {
|
||||
playPauseButton.setOnClickListener(PlayPauseButtonOnClickHandler())
|
||||
binding.playPauseButton.setOnClickListener(PlayPauseButtonOnClickHandler())
|
||||
}
|
||||
|
||||
private fun updatePlayPauseDrawableState() {
|
||||
if (MusicPlayerRemote.isPlaying) {
|
||||
playPauseButton.setImageResource(R.drawable.ic_pause)
|
||||
binding.playPauseButton.setImageResource(R.drawable.ic_pause)
|
||||
} else {
|
||||
playPauseButton.setImageResource(R.drawable.ic_play_arrow_white_32dp)
|
||||
binding.playPauseButton.setImageResource(R.drawable.ic_play_arrow_white_32dp)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
_binding = null
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,12 +20,12 @@ import androidx.appcompat.widget.Toolbar
|
|||
import code.name.monkey.appthemehelper.util.ATHUtil
|
||||
import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper
|
||||
import code.name.monkey.retromusic.R
|
||||
import code.name.monkey.retromusic.databinding.FragmentSimplePlayerBinding
|
||||
import code.name.monkey.retromusic.fragments.base.AbsPlayerFragment
|
||||
import code.name.monkey.retromusic.fragments.player.PlayerAlbumCoverFragment
|
||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote
|
||||
import code.name.monkey.retromusic.model.Song
|
||||
import code.name.monkey.retromusic.util.color.MediaNotificationProcessor
|
||||
import kotlinx.android.synthetic.main.fragment_simple_player.*
|
||||
|
||||
/**
|
||||
* @author Hemanth S (h4h13).
|
||||
|
@ -33,8 +33,11 @@ import kotlinx.android.synthetic.main.fragment_simple_player.*
|
|||
|
||||
class SimplePlayerFragment : AbsPlayerFragment(R.layout.fragment_simple_player) {
|
||||
|
||||
private var _binding: FragmentSimplePlayerBinding? = null
|
||||
private val binding get() = _binding!!
|
||||
|
||||
override fun playerToolbar(): Toolbar {
|
||||
return playerToolbar
|
||||
return binding.playerToolbar
|
||||
}
|
||||
|
||||
private var lastColor: Int = 0
|
||||
|
@ -45,6 +48,7 @@ class SimplePlayerFragment : AbsPlayerFragment(R.layout.fragment_simple_player)
|
|||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
_binding = FragmentSimplePlayerBinding.bind(view)
|
||||
setUpSubFragments()
|
||||
setUpPlayerToolbar()
|
||||
}
|
||||
|
@ -78,7 +82,7 @@ class SimplePlayerFragment : AbsPlayerFragment(R.layout.fragment_simple_player)
|
|||
libraryViewModel.updateColor(color.backgroundColor)
|
||||
controlsFragment.setColor(color)
|
||||
ToolbarContentTintHelper.colorizeToolbar(
|
||||
playerToolbar,
|
||||
binding.playerToolbar,
|
||||
ATHUtil.resolveColor(requireContext(), R.attr.colorControlNormal),
|
||||
requireActivity()
|
||||
)
|
||||
|
@ -96,13 +100,18 @@ class SimplePlayerFragment : AbsPlayerFragment(R.layout.fragment_simple_player)
|
|||
}
|
||||
|
||||
private fun setUpPlayerToolbar() {
|
||||
playerToolbar.inflateMenu(R.menu.menu_player)
|
||||
playerToolbar.setNavigationOnClickListener { requireActivity().onBackPressed() }
|
||||
playerToolbar.setOnMenuItemClickListener(this)
|
||||
binding.playerToolbar.inflateMenu(R.menu.menu_player)
|
||||
binding.playerToolbar.setNavigationOnClickListener { requireActivity().onBackPressed() }
|
||||
binding.playerToolbar.setOnMenuItemClickListener(this)
|
||||
ToolbarContentTintHelper.colorizeToolbar(
|
||||
playerToolbar,
|
||||
binding.playerToolbar,
|
||||
ATHUtil.resolveColor(requireContext(), R.attr.colorControlNormal),
|
||||
requireActivity()
|
||||
)
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
_binding = null
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,14 +19,16 @@ import android.os.Bundle
|
|||
import android.view.View
|
||||
import code.name.monkey.appthemehelper.util.ColorUtil
|
||||
import code.name.monkey.retromusic.R
|
||||
import code.name.monkey.retromusic.databinding.FragmentTinyControlsFragmentBinding
|
||||
import code.name.monkey.retromusic.fragments.base.AbsPlayerControlsFragment
|
||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote
|
||||
import code.name.monkey.retromusic.service.MusicService
|
||||
import code.name.monkey.retromusic.util.color.MediaNotificationProcessor
|
||||
import kotlinx.android.synthetic.main.fragment_tiny_controls_fragment.*
|
||||
|
||||
class TinyPlaybackControlsFragment :
|
||||
AbsPlayerControlsFragment(R.layout.fragment_tiny_controls_fragment) {
|
||||
private var _binding: FragmentTinyControlsFragmentBinding? = null
|
||||
private val binding get() = _binding!!
|
||||
|
||||
override fun show() {
|
||||
}
|
||||
|
@ -53,6 +55,7 @@ class TinyPlaybackControlsFragment :
|
|||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
_binding = FragmentTinyControlsFragmentBinding.bind(view)
|
||||
setUpMusicControllers()
|
||||
}
|
||||
|
||||
|
@ -63,20 +66,20 @@ class TinyPlaybackControlsFragment :
|
|||
}
|
||||
|
||||
private fun setUpShuffleButton() {
|
||||
playerShuffleButton.setOnClickListener { MusicPlayerRemote.toggleShuffleMode() }
|
||||
binding.playerShuffleButton.setOnClickListener { MusicPlayerRemote.toggleShuffleMode() }
|
||||
}
|
||||
|
||||
private fun setUpRepeatButton() {
|
||||
playerRepeatButton.setOnClickListener { MusicPlayerRemote.cycleRepeatMode() }
|
||||
binding.playerRepeatButton.setOnClickListener { MusicPlayerRemote.cycleRepeatMode() }
|
||||
}
|
||||
|
||||
override fun updateShuffleState() {
|
||||
when (MusicPlayerRemote.shuffleMode) {
|
||||
MusicService.SHUFFLE_MODE_SHUFFLE -> playerShuffleButton.setColorFilter(
|
||||
MusicService.SHUFFLE_MODE_SHUFFLE -> binding.playerShuffleButton.setColorFilter(
|
||||
lastPlaybackControlsColor,
|
||||
PorterDuff.Mode.SRC_IN
|
||||
)
|
||||
else -> playerShuffleButton.setColorFilter(
|
||||
else -> binding.playerShuffleButton.setColorFilter(
|
||||
lastDisabledPlaybackControlsColor,
|
||||
PorterDuff.Mode.SRC_IN
|
||||
)
|
||||
|
@ -86,19 +89,25 @@ class TinyPlaybackControlsFragment :
|
|||
override fun updateRepeatState() {
|
||||
when (MusicPlayerRemote.repeatMode) {
|
||||
MusicService.REPEAT_MODE_NONE -> {
|
||||
playerRepeatButton.setImageResource(R.drawable.ic_repeat)
|
||||
playerRepeatButton.setColorFilter(
|
||||
binding.playerRepeatButton.setImageResource(R.drawable.ic_repeat)
|
||||
binding.playerRepeatButton.setColorFilter(
|
||||
lastDisabledPlaybackControlsColor,
|
||||
PorterDuff.Mode.SRC_IN
|
||||
)
|
||||
}
|
||||
MusicService.REPEAT_MODE_ALL -> {
|
||||
playerRepeatButton.setImageResource(R.drawable.ic_repeat)
|
||||
playerRepeatButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
|
||||
binding.playerRepeatButton.setImageResource(R.drawable.ic_repeat)
|
||||
binding.playerRepeatButton.setColorFilter(
|
||||
lastPlaybackControlsColor,
|
||||
PorterDuff.Mode.SRC_IN
|
||||
)
|
||||
}
|
||||
MusicService.REPEAT_MODE_THIS -> {
|
||||
playerRepeatButton.setImageResource(R.drawable.ic_repeat_one)
|
||||
playerRepeatButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
|
||||
binding.playerRepeatButton.setImageResource(R.drawable.ic_repeat_one)
|
||||
binding.playerRepeatButton.setColorFilter(
|
||||
lastPlaybackControlsColor,
|
||||
PorterDuff.Mode.SRC_IN
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -115,4 +124,9 @@ class TinyPlaybackControlsFragment :
|
|||
override fun onShuffleModeChanged() {
|
||||
updateShuffleState()
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
_binding = null
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,17 +16,22 @@ package code.name.monkey.retromusic.fragments.player.tiny
|
|||
|
||||
import android.animation.AnimatorSet
|
||||
import android.animation.ObjectAnimator
|
||||
import android.os.Bundle
|
||||
import android.os.Handler
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Context
|
||||
import android.os.*
|
||||
import android.view.GestureDetector
|
||||
import android.view.MotionEvent
|
||||
import android.view.View
|
||||
import android.view.animation.LinearInterpolator
|
||||
import androidx.appcompat.widget.Toolbar
|
||||
import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper
|
||||
import code.name.monkey.retromusic.R
|
||||
import code.name.monkey.retromusic.databinding.FragmentTinyPlayerBinding
|
||||
import code.name.monkey.retromusic.extensions.hide
|
||||
import code.name.monkey.retromusic.extensions.show
|
||||
import code.name.monkey.retromusic.fragments.MiniPlayerFragment
|
||||
import code.name.monkey.retromusic.fragments.base.AbsPlayerFragment
|
||||
import code.name.monkey.retromusic.fragments.base.goToAlbum
|
||||
import code.name.monkey.retromusic.fragments.base.goToArtist
|
||||
import code.name.monkey.retromusic.fragments.player.PlayerAlbumCoverFragment
|
||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote
|
||||
import code.name.monkey.retromusic.helper.MusicProgressViewUpdateHelper
|
||||
|
@ -36,15 +41,20 @@ import code.name.monkey.retromusic.util.MusicUtil
|
|||
import code.name.monkey.retromusic.util.PreferenceUtil
|
||||
import code.name.monkey.retromusic.util.ViewUtil
|
||||
import code.name.monkey.retromusic.util.color.MediaNotificationProcessor
|
||||
import kotlinx.android.synthetic.main.fragment_tiny_player.*
|
||||
import kotlin.math.abs
|
||||
|
||||
class TinyPlayerFragment : AbsPlayerFragment(R.layout.fragment_tiny_player),
|
||||
MusicProgressViewUpdateHelper.Callback {
|
||||
private var _binding: FragmentTinyPlayerBinding? = null
|
||||
private val binding get() = _binding!!
|
||||
|
||||
private var lastColor: Int = 0
|
||||
private var toolbarColor: Int = 0
|
||||
private var isDragEnabled = false
|
||||
lateinit var animator: ObjectAnimator
|
||||
|
||||
override fun playerToolbar(): Toolbar {
|
||||
return playerToolbar
|
||||
return binding.playerToolbar
|
||||
}
|
||||
|
||||
override fun onShow() {
|
||||
|
@ -70,21 +80,22 @@ class TinyPlayerFragment : AbsPlayerFragment(R.layout.fragment_tiny_player),
|
|||
toolbarColor = color.secondaryTextColor
|
||||
controlsFragment.setColor(color)
|
||||
|
||||
title.setTextColor(color.primaryTextColor)
|
||||
playerSongTotalTime.setTextColor(color.primaryTextColor)
|
||||
text.setTextColor(color.secondaryTextColor)
|
||||
songInfo.setTextColor(color.secondaryTextColor)
|
||||
ViewUtil.setProgressDrawable(progressBar, color.backgroundColor)
|
||||
binding.title.setTextColor(color.primaryTextColor)
|
||||
binding.playerSongTotalTime.setTextColor(color.primaryTextColor)
|
||||
binding.text.setTextColor(color.secondaryTextColor)
|
||||
binding.songInfo.setTextColor(color.secondaryTextColor)
|
||||
ViewUtil.setProgressDrawable(binding.progressBar, color.backgroundColor)
|
||||
|
||||
Handler().post {
|
||||
Handler(Looper.myLooper()!!).post {
|
||||
ToolbarContentTintHelper.colorizeToolbar(
|
||||
playerToolbar,
|
||||
binding.playerToolbar,
|
||||
color.secondaryTextColor,
|
||||
requireActivity()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
override fun onFavoriteToggled() {
|
||||
toggleFavorite(MusicPlayerRemote.currentSong)
|
||||
}
|
||||
|
@ -109,25 +120,33 @@ class TinyPlayerFragment : AbsPlayerFragment(R.layout.fragment_tiny_player),
|
|||
|
||||
private fun updateSong() {
|
||||
val song = MusicPlayerRemote.currentSong
|
||||
title.text = song.title
|
||||
text.text = String.format("%s \nby - %s", song.albumName, song.artistName)
|
||||
binding.title.text = song.title
|
||||
binding.text.text = String.format("%s \nby - %s", song.albumName, song.artistName)
|
||||
|
||||
if (PreferenceUtil.isSongInfo) {
|
||||
songInfo.text = getSongInfo(song)
|
||||
songInfo.show()
|
||||
binding.songInfo.text = getSongInfo(song)
|
||||
binding.songInfo.show()
|
||||
} else {
|
||||
songInfo.hide()
|
||||
binding.songInfo.hide()
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressLint("ClickableViewAccessibility")
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
title.isSelected = true
|
||||
progressBar.setOnClickListener(PlayPauseButtonOnClickHandler())
|
||||
progressBar.setOnTouchListener(MiniPlayerFragment.FlingPlayBackController(requireContext()))
|
||||
_binding = FragmentTinyPlayerBinding.bind(view)
|
||||
binding.title.isSelected = true
|
||||
binding.progressBar.setOnClickListener(PlayPauseButtonOnClickHandler())
|
||||
binding.progressBar.setOnTouchListener(ProgressHelper(requireContext()))
|
||||
|
||||
setUpPlayerToolbar()
|
||||
setUpSubFragments()
|
||||
binding.title.setOnClickListener {
|
||||
goToAlbum(requireActivity())
|
||||
}
|
||||
binding.text.setOnClickListener {
|
||||
goToArtist(requireActivity())
|
||||
}
|
||||
}
|
||||
|
||||
private fun setUpSubFragments() {
|
||||
|
@ -139,7 +158,7 @@ class TinyPlayerFragment : AbsPlayerFragment(R.layout.fragment_tiny_player),
|
|||
}
|
||||
|
||||
private fun setUpPlayerToolbar() {
|
||||
playerToolbar.apply {
|
||||
binding.playerToolbar.apply {
|
||||
inflateMenu(R.menu.menu_player)
|
||||
setNavigationOnClickListener { requireActivity().onBackPressed() }
|
||||
setOnMenuItemClickListener(this@TinyPlayerFragment)
|
||||
|
@ -164,20 +183,113 @@ class TinyPlayerFragment : AbsPlayerFragment(R.layout.fragment_tiny_player),
|
|||
}
|
||||
|
||||
override fun onUpdateProgressViews(progress: Int, total: Int) {
|
||||
progressBar.max = total
|
||||
binding.progressBar.max = total
|
||||
|
||||
val animator = ObjectAnimator.ofInt(progressBar, "progress", progress)
|
||||
if (isDragEnabled) {
|
||||
binding.progressBar.progress = progress
|
||||
} else {
|
||||
animator = ObjectAnimator.ofInt(binding.progressBar, "progress", progress)
|
||||
|
||||
val animatorSet = AnimatorSet()
|
||||
animatorSet.playSequentially(animator)
|
||||
val animatorSet = AnimatorSet()
|
||||
animatorSet.playSequentially(animator)
|
||||
|
||||
animatorSet.duration = 1500
|
||||
animatorSet.interpolator = LinearInterpolator()
|
||||
animatorSet.start()
|
||||
|
||||
playerSongTotalTime.text = String.format(
|
||||
animatorSet.duration = 1500
|
||||
animatorSet.interpolator = LinearInterpolator()
|
||||
animatorSet.start()
|
||||
}
|
||||
binding.playerSongTotalTime.text = String.format(
|
||||
"%s/%s", MusicUtil.getReadableDurationString(total.toLong()),
|
||||
MusicUtil.getReadableDurationString(progress.toLong())
|
||||
)
|
||||
}
|
||||
|
||||
inner class ProgressHelper(context: Context) : View.OnTouchListener {
|
||||
private var initialY: Int = 0
|
||||
private var initialProgress = 0
|
||||
private var progress: Int = 0
|
||||
private val displayHeight = resources.displayMetrics.heightPixels
|
||||
private var gestureDetector: GestureDetector
|
||||
|
||||
init {
|
||||
gestureDetector = GestureDetector(context, object :
|
||||
GestureDetector.SimpleOnGestureListener() {
|
||||
|
||||
override fun onLongPress(e: MotionEvent?) {
|
||||
if (abs(e!!.y - initialY) <= 2) {
|
||||
vibrate()
|
||||
isDragEnabled = true
|
||||
binding.progressBar.parent.requestDisallowInterceptTouchEvent(true)
|
||||
animator.pause()
|
||||
}
|
||||
super.onLongPress(e)
|
||||
}
|
||||
|
||||
override fun onFling(
|
||||
e1: MotionEvent,
|
||||
e2: MotionEvent,
|
||||
velocityX: Float,
|
||||
velocityY: Float
|
||||
): Boolean {
|
||||
if (abs(velocityX) > abs(velocityY)) {
|
||||
if (velocityX < 0) {
|
||||
MusicPlayerRemote.playNextSong()
|
||||
return true
|
||||
} else if (velocityX > 0) {
|
||||
MusicPlayerRemote.playPreviousSong()
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@SuppressLint("ClickableViewAccessibility")
|
||||
override fun onTouch(v: View, event: MotionEvent): Boolean {
|
||||
when (event.actionMasked) {
|
||||
MotionEvent.ACTION_DOWN -> {
|
||||
initialProgress = MusicPlayerRemote.songProgressMillis
|
||||
initialY = event.y.toInt()
|
||||
progressViewUpdateHelper.stop()
|
||||
}
|
||||
MotionEvent.ACTION_UP,
|
||||
MotionEvent.ACTION_CANCEL -> {
|
||||
progressViewUpdateHelper.start()
|
||||
if (isDragEnabled) {
|
||||
MusicPlayerRemote.seekTo(progress)
|
||||
isDragEnabled = false
|
||||
return true
|
||||
}
|
||||
}
|
||||
MotionEvent.ACTION_MOVE -> {
|
||||
if (isDragEnabled) {
|
||||
val diffY = (initialY - event.y).toInt()
|
||||
progress =
|
||||
initialProgress + diffY * (binding.progressBar.max / displayHeight) // Multiplier
|
||||
if (progress > 0 && progress < binding.progressBar.max) {
|
||||
onUpdateProgressViews(
|
||||
progress,
|
||||
MusicPlayerRemote.songDurationMillis
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return gestureDetector.onTouchEvent(event)
|
||||
}
|
||||
|
||||
private fun vibrate() {
|
||||
val v = requireContext().getSystemService(Context.VIBRATOR_SERVICE) as Vibrator?
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
v!!.vibrate(VibrationEffect.createOneShot(10, VibrationEffect.DEFAULT_AMPLITUDE))
|
||||
} else {
|
||||
v!!.vibrate(10)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
_binding = null
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,77 +1,101 @@
|
|||
package code.name.monkey.retromusic.fragments.playlists
|
||||
|
||||
import android.graphics.Color
|
||||
import android.os.Bundle
|
||||
import android.util.Log
|
||||
import android.view.Menu
|
||||
import android.view.MenuInflater
|
||||
import android.view.MenuItem
|
||||
import android.view.View
|
||||
import androidx.activity.addCallback
|
||||
import androidx.core.view.ViewCompat
|
||||
import androidx.core.view.doOnPreDraw
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.navigation.fragment.navArgs
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import code.name.monkey.appthemehelper.util.ATHUtil
|
||||
import code.name.monkey.retromusic.R
|
||||
import code.name.monkey.retromusic.adapter.song.ShuffleButtonSongAdapter
|
||||
import code.name.monkey.retromusic.adapter.song.OrderablePlaylistSongAdapter
|
||||
import code.name.monkey.retromusic.databinding.FragmentPlaylistDetailBinding
|
||||
import code.name.monkey.retromusic.db.PlaylistWithSongs
|
||||
import code.name.monkey.retromusic.db.toSongs
|
||||
import code.name.monkey.retromusic.extensions.dipToPix
|
||||
import code.name.monkey.retromusic.extensions.resolveColor
|
||||
import code.name.monkey.retromusic.extensions.surfaceColor
|
||||
import code.name.monkey.retromusic.fragments.base.AbsMainActivityFragment
|
||||
import code.name.monkey.retromusic.helper.menu.PlaylistMenuHelper
|
||||
import code.name.monkey.retromusic.interfaces.ICabHolder
|
||||
import code.name.monkey.retromusic.model.Song
|
||||
import com.google.android.material.transition.MaterialArcMotion
|
||||
import com.google.android.material.transition.MaterialContainerTransform
|
||||
import kotlinx.android.synthetic.main.fragment_playlist_detail.*
|
||||
import code.name.monkey.retromusic.util.RetroColorUtil
|
||||
import com.afollestad.materialcab.MaterialCab
|
||||
import com.google.android.material.transition.MaterialSharedAxis
|
||||
import com.h6ah4i.android.widget.advrecyclerview.animator.DraggableItemAnimator
|
||||
import com.h6ah4i.android.widget.advrecyclerview.animator.GeneralItemAnimator
|
||||
import com.h6ah4i.android.widget.advrecyclerview.draggable.RecyclerViewDragDropManager
|
||||
import org.koin.androidx.viewmodel.ext.android.viewModel
|
||||
import org.koin.core.parameter.parametersOf
|
||||
|
||||
class PlaylistDetailsFragment : AbsMainActivityFragment(R.layout.fragment_playlist_detail) {
|
||||
|
||||
class PlaylistDetailsFragment : AbsMainActivityFragment(R.layout.fragment_playlist_detail),
|
||||
ICabHolder {
|
||||
private val arguments by navArgs<PlaylistDetailsFragmentArgs>()
|
||||
private val viewModel by viewModel<PlaylistDetailsViewModel> {
|
||||
parametersOf(arguments.extraPlaylist)
|
||||
}
|
||||
|
||||
private lateinit var playlist: PlaylistWithSongs
|
||||
private lateinit var playlistSongAdapter: ShuffleButtonSongAdapter
|
||||
private var _binding: FragmentPlaylistDetailBinding? = null
|
||||
private val binding get() = _binding!!
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
sharedElementEnterTransition = MaterialContainerTransform().apply {
|
||||
drawingViewId = R.id.fragment_container
|
||||
duration = 300L
|
||||
scrimColor = Color.TRANSPARENT
|
||||
setAllContainerColors(requireContext().resolveColor(R.attr.colorSurface))
|
||||
setPathMotion(MaterialArcMotion())
|
||||
}
|
||||
}
|
||||
|
||||
private lateinit var playlist: PlaylistWithSongs
|
||||
private lateinit var playlistSongAdapter: OrderablePlaylistSongAdapter
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
_binding = FragmentPlaylistDetailBinding.bind(view)
|
||||
enterTransition = MaterialSharedAxis(MaterialSharedAxis.Z, true).addTarget(view)
|
||||
returnTransition = MaterialSharedAxis(MaterialSharedAxis.Z, false)
|
||||
setHasOptionsMenu(true)
|
||||
mainActivity.setBottomBarVisibility(false)
|
||||
mainActivity.addMusicServiceEventListener(viewModel)
|
||||
mainActivity.setSupportActionBar(toolbar)
|
||||
ViewCompat.setTransitionName(container, "playlist")
|
||||
mainActivity.setSupportActionBar(binding.toolbar)
|
||||
ViewCompat.setTransitionName(binding.container, "playlist")
|
||||
playlist = arguments.extraPlaylist
|
||||
toolbar.title = playlist.playlistEntity.playlistName
|
||||
binding.toolbar.title = playlist.playlistEntity.playlistName
|
||||
setUpRecyclerView()
|
||||
viewModel.getSongs().observe(viewLifecycleOwner, {
|
||||
songs(it.toSongs())
|
||||
})
|
||||
postponeEnterTransition()
|
||||
requireView().doOnPreDraw { startPostponedEnterTransition() }
|
||||
requireActivity().onBackPressedDispatcher.addCallback(viewLifecycleOwner) {
|
||||
if (!handleBackPress()) {
|
||||
remove()
|
||||
requireActivity().onBackPressed()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun setUpRecyclerView() {
|
||||
playlistSongAdapter = ShuffleButtonSongAdapter(
|
||||
playlistSongAdapter = OrderablePlaylistSongAdapter(
|
||||
playlist.playlistEntity,
|
||||
requireActivity(),
|
||||
ArrayList(),
|
||||
R.layout.item_list,
|
||||
null,
|
||||
this
|
||||
)
|
||||
recyclerView.apply {
|
||||
|
||||
val dragDropManager = RecyclerViewDragDropManager()
|
||||
|
||||
val wrappedAdapter: RecyclerView.Adapter<*> =
|
||||
dragDropManager.createWrappedAdapter(playlistSongAdapter)
|
||||
|
||||
|
||||
val animator: GeneralItemAnimator = DraggableItemAnimator()
|
||||
binding.recyclerView.itemAnimator = animator
|
||||
|
||||
dragDropManager.attachRecyclerView(binding.recyclerView)
|
||||
|
||||
binding.recyclerView.apply {
|
||||
layoutManager = LinearLayoutManager(requireContext())
|
||||
adapter = playlistSongAdapter
|
||||
binding.recyclerView.adapter = wrappedAdapter
|
||||
}
|
||||
playlistSongAdapter.registerAdapterDataObserver(object :
|
||||
RecyclerView.AdapterDataObserver() {
|
||||
|
@ -93,32 +117,70 @@ class PlaylistDetailsFragment : AbsMainActivityFragment(R.layout.fragment_playli
|
|||
|
||||
private fun checkForPadding() {
|
||||
val height = dipToPix(52f)
|
||||
recyclerView.setPadding(0, 0, 0, height.toInt())
|
||||
binding.recyclerView.setPadding(0, 0, 0, height.toInt())
|
||||
}
|
||||
|
||||
private fun checkIsEmpty() {
|
||||
checkForPadding()
|
||||
empty.isVisible = playlistSongAdapter.itemCount == 0
|
||||
emptyText.isVisible = playlistSongAdapter.itemCount == 0
|
||||
binding.empty.isVisible = playlistSongAdapter.itemCount == 0
|
||||
binding.emptyText.isVisible = playlistSongAdapter.itemCount == 0
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
recyclerView?.itemAnimator = null
|
||||
recyclerView?.adapter = null
|
||||
super.onDestroy()
|
||||
_binding = null
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
playlistSongAdapter.saveSongs(playlist.playlistEntity)
|
||||
super.onPause()
|
||||
}
|
||||
|
||||
private fun showEmptyView() {
|
||||
empty.visibility = View.VISIBLE
|
||||
emptyText.visibility = View.VISIBLE
|
||||
binding.empty.visibility = View.VISIBLE
|
||||
binding.emptyText.visibility = View.VISIBLE
|
||||
}
|
||||
|
||||
fun songs(songs: List<Song>) {
|
||||
progressIndicator.hide()
|
||||
binding.progressIndicator.hide()
|
||||
if (songs.isNotEmpty()) {
|
||||
Log.i("Updated", songs[0].title)
|
||||
playlistSongAdapter.swapDataSet(songs)
|
||||
} else {
|
||||
showEmptyView()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
_binding = null
|
||||
}
|
||||
|
||||
private fun handleBackPress(): Boolean {
|
||||
cab?.let {
|
||||
if (it.isActive) {
|
||||
it.finish()
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
private var cab: MaterialCab? = null
|
||||
|
||||
override fun openCab(menuRes: Int, callback: MaterialCab.Callback): MaterialCab {
|
||||
cab?.let {
|
||||
println("Cab")
|
||||
if (it.isActive) {
|
||||
it.finish()
|
||||
}
|
||||
}
|
||||
cab = MaterialCab(mainActivity, R.id.cab_stub)
|
||||
.setMenu(menuRes)
|
||||
.setCloseDrawableRes(R.drawable.ic_close)
|
||||
.setBackgroundColor(RetroColorUtil.shiftBackgroundColorForLightText(surfaceColor()))
|
||||
.start(callback)
|
||||
return cab as MaterialCab
|
||||
}
|
||||
|
||||
}
|
|
@ -41,4 +41,5 @@ class PlaylistDetailsViewModel(
|
|||
override fun onPlayStateChanged() {}
|
||||
override fun onRepeatModeChanged() {}
|
||||
override fun onShuffleModeChanged() {}
|
||||
override fun onFavoriteStateChanged() {}
|
||||
}
|
||||
|
|
|
@ -15,17 +15,11 @@
|
|||
package code.name.monkey.retromusic.fragments.playlists
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.Menu
|
||||
import android.view.MenuInflater
|
||||
import android.view.MenuItem
|
||||
import android.view.SubMenu
|
||||
import android.view.View
|
||||
import android.view.*
|
||||
import androidx.core.os.bundleOf
|
||||
import androidx.core.view.MenuCompat
|
||||
import androidx.navigation.fragment.FragmentNavigatorExtras
|
||||
import androidx.navigation.fragment.findNavController
|
||||
import androidx.recyclerview.widget.GridLayoutManager
|
||||
import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper
|
||||
import code.name.monkey.retromusic.EXTRA_PLAYLIST
|
||||
import code.name.monkey.retromusic.R
|
||||
import code.name.monkey.retromusic.adapter.playlist.PlaylistAdapter
|
||||
|
@ -35,12 +29,13 @@ import code.name.monkey.retromusic.fragments.base.AbsRecyclerViewCustomGridSizeF
|
|||
import code.name.monkey.retromusic.helper.SortOrder.PlaylistSortOrder
|
||||
import code.name.monkey.retromusic.interfaces.IPlaylistClickListener
|
||||
import code.name.monkey.retromusic.util.PreferenceUtil
|
||||
import com.google.android.material.transition.MaterialElevationScale
|
||||
import kotlinx.android.synthetic.main.fragment_library.*
|
||||
import com.google.android.gms.cast.framework.CastButtonFactory
|
||||
import com.google.android.material.transition.MaterialSharedAxis
|
||||
|
||||
class PlaylistsFragment :
|
||||
AbsRecyclerViewCustomGridSizeFragment<PlaylistAdapter, GridLayoutManager>(),
|
||||
IPlaylistClickListener {
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
libraryViewModel.getPlaylists().observe(viewLifecycleOwner, {
|
||||
|
@ -51,6 +46,8 @@ class PlaylistsFragment :
|
|||
})
|
||||
}
|
||||
|
||||
override val titleRes: Int
|
||||
get() = R.string.playlists
|
||||
override val emptyMessage: Int
|
||||
get() = R.string.no_playlists
|
||||
|
||||
|
@ -68,11 +65,6 @@ class PlaylistsFragment :
|
|||
)
|
||||
}
|
||||
|
||||
override fun onPrepareOptionsMenu(menu: Menu) {
|
||||
super.onPrepareOptionsMenu(menu)
|
||||
ToolbarContentTintHelper.handleOnPrepareOptionsMenu(requireActivity(), toolbar)
|
||||
}
|
||||
|
||||
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
|
||||
super.onCreateOptionsMenu(menu, inflater)
|
||||
menu.removeItem(R.id.action_grid_size)
|
||||
|
@ -81,7 +73,9 @@ class PlaylistsFragment :
|
|||
menu.add(0, R.id.action_import_playlist, 0, R.string.import_playlist)
|
||||
menu.findItem(R.id.action_settings).setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER)
|
||||
setUpSortOrderMenu(menu.findItem(R.id.action_sort_order).subMenu)
|
||||
MenuCompat.setGroupDividerEnabled(menu, true);
|
||||
MenuCompat.setGroupDividerEnabled(menu, true)
|
||||
//Setting up cast button
|
||||
CastButtonFactory.setUpMediaRouteButton(requireContext(), menu, R.id.action_cast)
|
||||
}
|
||||
|
||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||
|
@ -160,7 +154,7 @@ class PlaylistsFragment :
|
|||
}
|
||||
|
||||
override fun loadGridSize(): Int {
|
||||
return 1
|
||||
return 2
|
||||
}
|
||||
|
||||
override fun saveGridSize(gridColumns: Int) {
|
||||
|
@ -168,7 +162,7 @@ class PlaylistsFragment :
|
|||
}
|
||||
|
||||
override fun loadGridSizeLand(): Int {
|
||||
return 2
|
||||
return 4
|
||||
}
|
||||
|
||||
override fun saveGridSizeLand(gridColumns: Int) {
|
||||
|
@ -176,7 +170,7 @@ class PlaylistsFragment :
|
|||
}
|
||||
|
||||
override fun loadLayoutRes(): Int {
|
||||
return R.layout.item_list
|
||||
return R.layout.item_card
|
||||
}
|
||||
|
||||
override fun saveLayoutRes(layoutRes: Int) {
|
||||
|
@ -184,17 +178,13 @@ class PlaylistsFragment :
|
|||
}
|
||||
|
||||
override fun onPlaylistClick(playlistWithSongs: PlaylistWithSongs, view: View) {
|
||||
exitTransition = MaterialElevationScale(false).apply {
|
||||
duration = 300L
|
||||
}
|
||||
reenterTransition = MaterialElevationScale(true).apply {
|
||||
duration = 300L
|
||||
}
|
||||
exitTransition = MaterialSharedAxis(MaterialSharedAxis.Z, true).addTarget(requireView())
|
||||
reenterTransition = MaterialSharedAxis(MaterialSharedAxis.Z, false)
|
||||
findNavController().navigate(
|
||||
R.id.playlistDetailsFragment,
|
||||
bundleOf(EXTRA_PLAYLIST to playlistWithSongs),
|
||||
null,
|
||||
FragmentNavigatorExtras(view to "playlist")
|
||||
null
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,7 +28,6 @@ import com.h6ah4i.android.widget.advrecyclerview.draggable.RecyclerViewDragDropM
|
|||
import com.h6ah4i.android.widget.advrecyclerview.swipeable.RecyclerViewSwipeManager
|
||||
import com.h6ah4i.android.widget.advrecyclerview.touchguard.RecyclerViewTouchActionGuardManager
|
||||
import com.h6ah4i.android.widget.advrecyclerview.utils.WrapperAdapterUtils
|
||||
import kotlinx.android.synthetic.main.activity_playing_queue.*
|
||||
|
||||
/**
|
||||
* Created by hemanths on 2019-12-08.
|
||||
|
@ -39,6 +38,8 @@ class PlayingQueueFragment : AbsRecyclerViewFragment<PlayingQueueAdapter, Linear
|
|||
private var recyclerViewDragDropManager: RecyclerViewDragDropManager? = null
|
||||
private var recyclerViewSwipeManager: RecyclerViewSwipeManager? = null
|
||||
private var recyclerViewTouchActionGuardManager: RecyclerViewTouchActionGuardManager? = null
|
||||
override val titleRes: Int
|
||||
get() = R.string.now_playing_queue
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
@ -59,9 +60,9 @@ class PlayingQueueFragment : AbsRecyclerViewFragment<PlayingQueueAdapter, Linear
|
|||
recyclerView().layoutManager = layoutManager
|
||||
recyclerView().adapter = wrappedAdapter
|
||||
recyclerView().itemAnimator = animator
|
||||
recyclerViewTouchActionGuardManager?.attachRecyclerView(recyclerView)
|
||||
recyclerViewDragDropManager?.attachRecyclerView(recyclerView)
|
||||
recyclerViewSwipeManager?.attachRecyclerView(recyclerView)
|
||||
recyclerViewTouchActionGuardManager?.attachRecyclerView(recyclerView())
|
||||
recyclerViewDragDropManager?.attachRecyclerView(recyclerView())
|
||||
recyclerViewSwipeManager?.attachRecyclerView(recyclerView())
|
||||
|
||||
layoutManager?.scrollToPositionWithOffset(MusicPlayerRemote.position + 1, 0)
|
||||
}
|
||||
|
@ -104,7 +105,7 @@ class PlayingQueueFragment : AbsRecyclerViewFragment<PlayingQueueAdapter, Linear
|
|||
}
|
||||
|
||||
private fun resetToCurrentPosition() {
|
||||
recyclerView.stopScroll()
|
||||
recyclerView().stopScroll()
|
||||
layoutManager?.scrollToPositionWithOffset(MusicPlayerRemote.position + 1, 0)
|
||||
}
|
||||
|
||||
|
|
|
@ -17,66 +17,65 @@ package code.name.monkey.retromusic.fragments.search
|
|||
import android.content.ActivityNotFoundException
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.graphics.Color
|
||||
import android.content.res.ColorStateList
|
||||
import android.os.Bundle
|
||||
import android.speech.RecognizerIntent
|
||||
import android.text.Editable
|
||||
import android.text.TextWatcher
|
||||
import android.view.View
|
||||
import android.view.inputmethod.InputMethodManager
|
||||
import android.widget.CompoundButton
|
||||
import androidx.core.view.children
|
||||
import androidx.core.view.doOnPreDraw
|
||||
import androidx.core.view.isGone
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import androidx.transition.TransitionManager
|
||||
import code.name.monkey.appthemehelper.ThemeStore
|
||||
import code.name.monkey.retromusic.R
|
||||
import code.name.monkey.retromusic.adapter.SearchAdapter
|
||||
import code.name.monkey.retromusic.databinding.FragmentSearchBinding
|
||||
import code.name.monkey.retromusic.extensions.*
|
||||
import code.name.monkey.retromusic.fragments.base.AbsMainActivityFragment
|
||||
import com.google.android.material.chip.Chip
|
||||
import com.google.android.material.textfield.TextInputEditText
|
||||
import com.google.android.material.transition.MaterialArcMotion
|
||||
import com.google.android.material.transition.MaterialContainerTransform
|
||||
import kotlinx.android.synthetic.main.fragment_search.*
|
||||
import com.google.android.material.transition.MaterialSharedAxis
|
||||
import java.util.*
|
||||
import kotlin.collections.ArrayList
|
||||
|
||||
class SearchFragment : AbsMainActivityFragment(R.layout.fragment_search), TextWatcher {
|
||||
class SearchFragment : AbsMainActivityFragment(R.layout.fragment_search), TextWatcher,
|
||||
CompoundButton.OnCheckedChangeListener {
|
||||
companion object {
|
||||
const val QUERY = "query"
|
||||
const val REQ_CODE_SPEECH_INPUT = 9001
|
||||
}
|
||||
|
||||
private var _binding: FragmentSearchBinding? = null
|
||||
private val binding get() = _binding!!
|
||||
|
||||
private lateinit var searchAdapter: SearchAdapter
|
||||
private var query: String? = null
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
sharedElementEnterTransition = MaterialContainerTransform().apply {
|
||||
drawingViewId = R.id.fragment_container
|
||||
duration = 300L
|
||||
scrimColor = Color.TRANSPARENT
|
||||
setAllContainerColors(requireContext().resolveColor(R.attr.colorSurface))
|
||||
setPathMotion(MaterialArcMotion())
|
||||
}
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
mainActivity.setBottomBarVisibility(false)
|
||||
mainActivity.setSupportActionBar(toolbar)
|
||||
enterTransition = MaterialSharedAxis(MaterialSharedAxis.Z, true).addTarget(view)
|
||||
returnTransition = MaterialSharedAxis(MaterialSharedAxis.Z, false)
|
||||
_binding = FragmentSearchBinding.bind(view)
|
||||
mainActivity.setSupportActionBar(binding.toolbar)
|
||||
libraryViewModel.clearSearchResult()
|
||||
setupRecyclerView()
|
||||
|
||||
voiceSearch.setOnClickListener { startMicSearch() }
|
||||
clearText.setOnClickListener { searchView.clearText() }
|
||||
searchView.apply {
|
||||
binding.voiceSearch.setOnClickListener { startMicSearch() }
|
||||
binding.clearText.setOnClickListener { binding.searchView.clearText() }
|
||||
binding.searchView.apply {
|
||||
addTextChangedListener(this@SearchFragment)
|
||||
focusAndShowKeyboard()
|
||||
}
|
||||
keyboardPopup.apply {
|
||||
binding.keyboardPopup.apply {
|
||||
accentColor()
|
||||
setOnClickListener {
|
||||
searchView.focusAndShowKeyboard()
|
||||
binding.searchView.focusAndShowKeyboard()
|
||||
}
|
||||
}
|
||||
if (savedInstanceState != null) {
|
||||
|
@ -85,6 +84,36 @@ class SearchFragment : AbsMainActivityFragment(R.layout.fragment_search), TextWa
|
|||
libraryViewModel.getSearchResult().observe(viewLifecycleOwner, {
|
||||
showData(it)
|
||||
})
|
||||
setupChips()
|
||||
postponeEnterTransition()
|
||||
view.doOnPreDraw {
|
||||
startPostponedEnterTransition()
|
||||
}
|
||||
}
|
||||
|
||||
private fun setupChips() {
|
||||
val chips = binding.searchFilterGroup.children.map { it as Chip }
|
||||
val states = arrayOf(
|
||||
intArrayOf(-android.R.attr.state_checked),
|
||||
intArrayOf(android.R.attr.state_checked)
|
||||
)
|
||||
|
||||
val colors = intArrayOf(
|
||||
android.R.color.transparent,
|
||||
ThemeStore.accentColor(requireContext())
|
||||
)
|
||||
|
||||
chips.forEach {
|
||||
it.chipBackgroundColor = ColorStateList(states, colors)
|
||||
it.chipIconTint = ColorStateList.valueOf(ThemeStore.textColorPrimary(requireContext()))
|
||||
it.chipStrokeColor =
|
||||
ColorStateList.valueOf(ThemeStore.textColorSecondary(requireContext()))
|
||||
.withAlpha(30)
|
||||
it.closeIconTint =
|
||||
ColorStateList.valueOf(ThemeStore.textColorPrimaryInverse(requireContext()))
|
||||
it.chipStrokeWidth = 2F
|
||||
it.setOnCheckedChangeListener(this)
|
||||
}
|
||||
}
|
||||
|
||||
private fun showData(data: List<Any>) {
|
||||
|
@ -100,21 +129,21 @@ class SearchFragment : AbsMainActivityFragment(R.layout.fragment_search), TextWa
|
|||
searchAdapter.registerAdapterDataObserver(object : RecyclerView.AdapterDataObserver() {
|
||||
override fun onChanged() {
|
||||
super.onChanged()
|
||||
empty.isVisible = searchAdapter.itemCount < 1
|
||||
binding.empty.isVisible = searchAdapter.itemCount < 1
|
||||
val height = dipToPix(52f)
|
||||
recyclerView.setPadding(0, 0, 0, height.toInt())
|
||||
binding.recyclerView.setPadding(0, 0, 0, height.toInt())
|
||||
}
|
||||
})
|
||||
recyclerView.apply {
|
||||
binding.recyclerView.apply {
|
||||
layoutManager = LinearLayoutManager(requireContext())
|
||||
adapter = searchAdapter
|
||||
addOnScrollListener(object : RecyclerView.OnScrollListener() {
|
||||
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
|
||||
super.onScrolled(recyclerView, dx, dy)
|
||||
if (dy > 0) {
|
||||
keyboardPopup.shrink()
|
||||
binding.keyboardPopup.shrink()
|
||||
} else if (dy < 0) {
|
||||
keyboardPopup.extend()
|
||||
binding.keyboardPopup.extend()
|
||||
}
|
||||
}
|
||||
})
|
||||
|
@ -122,7 +151,7 @@ class SearchFragment : AbsMainActivityFragment(R.layout.fragment_search), TextWa
|
|||
}
|
||||
|
||||
override fun afterTextChanged(newText: Editable?) {
|
||||
search(newText.toString())
|
||||
if (!newText.isNullOrEmpty()) search(newText.toString())
|
||||
}
|
||||
|
||||
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
|
||||
|
@ -133,10 +162,17 @@ class SearchFragment : AbsMainActivityFragment(R.layout.fragment_search), TextWa
|
|||
|
||||
private fun search(query: String) {
|
||||
this.query = query
|
||||
TransitionManager.beginDelayedTransition(appBarLayout)
|
||||
voiceSearch.isGone = query.isNotEmpty()
|
||||
clearText.isVisible = query.isNotEmpty()
|
||||
libraryViewModel.search(query)
|
||||
TransitionManager.beginDelayedTransition(binding.appBarLayout)
|
||||
binding.voiceSearch.isGone = query.isNotEmpty()
|
||||
binding.clearText.isVisible = query.isNotEmpty()
|
||||
val filters = getFilters()
|
||||
libraryViewModel.search(query, filters)
|
||||
}
|
||||
|
||||
private fun getFilters(): List<Boolean> {
|
||||
return binding.searchFilterGroup.children.toList().map {
|
||||
(it as Chip).isChecked
|
||||
}
|
||||
}
|
||||
|
||||
private fun startMicSearch() {
|
||||
|
@ -161,6 +197,17 @@ class SearchFragment : AbsMainActivityFragment(R.layout.fragment_search), TextWa
|
|||
override fun onDestroyView() {
|
||||
hideKeyboard(view)
|
||||
super.onDestroyView()
|
||||
_binding = null
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
hideKeyboard(view)
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
mainActivity.setBottomBarVisibility(false)
|
||||
}
|
||||
|
||||
private fun hideKeyboard(view: View?) {
|
||||
|
@ -170,6 +217,27 @@ class SearchFragment : AbsMainActivityFragment(R.layout.fragment_search), TextWa
|
|||
imm.hideSoftInputFromWindow(view.windowToken, 0)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCheckedChanged(buttonView: CompoundButton?, isChecked: Boolean) {
|
||||
val checkedChip = (buttonView as Chip)
|
||||
checkedChip.isCloseIconVisible = isChecked
|
||||
if (isChecked) {
|
||||
val color = ThemeStore.textColorPrimaryInverse(requireContext())
|
||||
checkedChip.apply {
|
||||
setTextColor(color)
|
||||
chipIconTint = ColorStateList.valueOf(color)
|
||||
chipStrokeWidth = 0F
|
||||
}
|
||||
} else {
|
||||
val color = ThemeStore.textColorPrimary(requireContext())
|
||||
checkedChip.apply {
|
||||
setTextColor(color)
|
||||
chipIconTint = ColorStateList.valueOf(color)
|
||||
chipStrokeWidth = 2F
|
||||
}
|
||||
}
|
||||
search(binding.searchView.text.toString())
|
||||
}
|
||||
}
|
||||
|
||||
fun TextInputEditText.clearText() {
|
||||
|
|
|
@ -87,6 +87,10 @@ abstract class AbsSettingsFragment : ATEPreferenceFragmentCompat() {
|
|||
val fragment = BlacklistPreferenceDialog.newInstance()
|
||||
fragment.show(childFragmentManager, preference.key)
|
||||
}
|
||||
is DurationPreference -> {
|
||||
val fragment = DurationPreferenceDialog.newInstance()
|
||||
fragment.show(childFragmentManager, preference.key)
|
||||
}
|
||||
else -> super.onDisplayPreferenceDialog(preference)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,12 +24,17 @@ import androidx.navigation.fragment.findNavController
|
|||
import code.name.monkey.appthemehelper.ThemeStore
|
||||
import code.name.monkey.retromusic.App
|
||||
import code.name.monkey.retromusic.R
|
||||
import code.name.monkey.retromusic.databinding.FragmentMainSettingsBinding
|
||||
import code.name.monkey.retromusic.extensions.hide
|
||||
import code.name.monkey.retromusic.extensions.show
|
||||
import code.name.monkey.retromusic.util.NavigationUtil
|
||||
import kotlinx.android.synthetic.main.fragment_main_settings.*
|
||||
|
||||
class MainSettingsFragment : Fragment(), View.OnClickListener {
|
||||
|
||||
private var _binding: FragmentMainSettingsBinding? = null
|
||||
private val binding get() = _binding!!
|
||||
|
||||
|
||||
override fun onClick(view: View) {
|
||||
when (view.id) {
|
||||
R.id.generalSettings -> findNavController().navigate(R.id.action_mainSettingsFragment_to_themeSettingsFragment)
|
||||
|
@ -47,34 +52,40 @@ class MainSettingsFragment : Fragment(), View.OnClickListener {
|
|||
inflater: LayoutInflater,
|
||||
container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View? {
|
||||
return inflater.inflate(R.layout.fragment_main_settings, container, false)
|
||||
): View {
|
||||
_binding = FragmentMainSettingsBinding.inflate(inflater, container, false)
|
||||
return binding.root
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
generalSettings.setOnClickListener(this)
|
||||
audioSettings.setOnClickListener(this)
|
||||
nowPlayingSettings.setOnClickListener(this)
|
||||
personalizeSettings.setOnClickListener(this)
|
||||
imageSettings.setOnClickListener(this)
|
||||
notificationSettings.setOnClickListener(this)
|
||||
otherSettings.setOnClickListener(this)
|
||||
aboutSettings.setOnClickListener(this)
|
||||
binding.generalSettings.setOnClickListener(this)
|
||||
binding.audioSettings.setOnClickListener(this)
|
||||
binding.nowPlayingSettings.setOnClickListener(this)
|
||||
binding.personalizeSettings.setOnClickListener(this)
|
||||
binding.imageSettings.setOnClickListener(this)
|
||||
binding.notificationSettings.setOnClickListener(this)
|
||||
binding.otherSettings.setOnClickListener(this)
|
||||
binding.aboutSettings.setOnClickListener(this)
|
||||
|
||||
buyProContainer.apply {
|
||||
binding.buyProContainer.apply {
|
||||
if (App.isProVersion()) hide() else show()
|
||||
setOnClickListener {
|
||||
NavigationUtil.goToProVersion(requireContext())
|
||||
}
|
||||
}
|
||||
buyPremium.setOnClickListener {
|
||||
binding.buyPremium.setOnClickListener {
|
||||
NavigationUtil.goToProVersion(requireContext())
|
||||
}
|
||||
ThemeStore.accentColor(requireContext()).let {
|
||||
buyPremium.setTextColor(it)
|
||||
diamondIcon.imageTintList = ColorStateList.valueOf(it)
|
||||
binding.buyPremium.setTextColor(it)
|
||||
binding.diamondIcon.imageTintList = ColorStateList.valueOf(it)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
_binding = null
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,7 +23,10 @@ import code.name.monkey.retromusic.LAST_ADDED_CUTOFF
|
|||
import code.name.monkey.retromusic.R
|
||||
import code.name.monkey.retromusic.fragments.LibraryViewModel
|
||||
import code.name.monkey.retromusic.fragments.ReloadType.HomeSections
|
||||
import com.google.android.play.core.splitinstall.SplitInstallManagerFactory
|
||||
import com.google.android.play.core.splitinstall.SplitInstallRequest
|
||||
import org.koin.androidx.viewmodel.ext.android.sharedViewModel
|
||||
import java.util.*
|
||||
|
||||
/**
|
||||
* @author Hemanth S (h4h13).
|
||||
|
@ -35,6 +38,7 @@ class OtherSettingsFragment : AbsSettingsFragment() {
|
|||
override fun invalidateSettings() {
|
||||
val languagePreference: ATEListPreference? = findPreference(LANGUAGE_NAME)
|
||||
languagePreference?.setOnPreferenceChangeListener { _, _ ->
|
||||
println("Invalidated")
|
||||
requireActivity().recreate()
|
||||
return@setOnPreferenceChangeListener true
|
||||
}
|
||||
|
@ -55,6 +59,21 @@ class OtherSettingsFragment : AbsSettingsFragment() {
|
|||
val languagePreference: Preference? = findPreference(LANGUAGE_NAME)
|
||||
languagePreference?.setOnPreferenceChangeListener { prefs, newValue ->
|
||||
setSummary(prefs, newValue)
|
||||
val code = newValue.toString()
|
||||
val manager = SplitInstallManagerFactory.create(requireContext())
|
||||
if (code != "auto") {
|
||||
// Try to download language resources
|
||||
val request =
|
||||
SplitInstallRequest.newBuilder().addLanguage(Locale.forLanguageTag(code))
|
||||
.build()
|
||||
manager.startInstall(request)
|
||||
// Recreate the activity on download complete
|
||||
.addOnCompleteListener {
|
||||
activity?.recreate()
|
||||
}
|
||||
} else {
|
||||
requireActivity().recreate()
|
||||
}
|
||||
true
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,6 +18,8 @@ import android.os.Build
|
|||
import android.os.Bundle
|
||||
import androidx.preference.Preference
|
||||
import androidx.preference.TwoStatePreference
|
||||
import code.name.monkey.appthemehelper.ACCENT_COLORS
|
||||
import code.name.monkey.appthemehelper.ACCENT_COLORS_SUB
|
||||
import code.name.monkey.appthemehelper.ThemeStore
|
||||
import code.name.monkey.appthemehelper.common.prefs.supportv7.ATEColorPreference
|
||||
import code.name.monkey.appthemehelper.common.prefs.supportv7.ATESwitchPreference
|
||||
|
@ -26,7 +28,8 @@ import code.name.monkey.appthemehelper.util.VersionUtils
|
|||
import code.name.monkey.retromusic.*
|
||||
import code.name.monkey.retromusic.appshortcuts.DynamicShortcutManager
|
||||
import code.name.monkey.retromusic.util.PreferenceUtil
|
||||
import com.afollestad.materialdialogs.color.ColorChooserDialog
|
||||
import com.afollestad.materialdialogs.MaterialDialog
|
||||
import com.afollestad.materialdialogs.color.colorChooser
|
||||
|
||||
/**
|
||||
* @author Hemanth S (h4h13).
|
||||
|
@ -55,12 +58,19 @@ class ThemeSettingsFragment : AbsSettingsFragment() {
|
|||
val accentColor = ThemeStore.accentColor(requireContext())
|
||||
accentColorPref?.setColor(accentColor, ColorUtil.darkenColor(accentColor))
|
||||
accentColorPref?.setOnPreferenceClickListener {
|
||||
ColorChooserDialog.Builder(requireContext(), R.string.accent_color)
|
||||
.accentMode(true)
|
||||
.allowUserColorInput(true)
|
||||
.allowUserColorInputAlpha(false)
|
||||
.preselect(accentColor)
|
||||
.show(requireActivity())
|
||||
MaterialDialog(requireContext()).show {
|
||||
colorChooser(
|
||||
initialSelection = accentColor,
|
||||
showAlphaSelector = false,
|
||||
colors = ACCENT_COLORS,
|
||||
subColors = ACCENT_COLORS_SUB, allowCustomArgb = true
|
||||
) { _, color ->
|
||||
ThemeStore.editTheme(requireContext()).accentColor(color).commit()
|
||||
if (VersionUtils.hasNougatMR())
|
||||
DynamicShortcutManager(requireContext()).updateDynamicShortcuts()
|
||||
requireActivity().recreate()
|
||||
}
|
||||
}
|
||||
return@setOnPreferenceClickListener true
|
||||
}
|
||||
val blackTheme: ATESwitchPreference? = findPreference(BLACK_THEME)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2020 Hemanth Savarla.
|
||||
* Cop()yright (c) 2020 Hemanth Savarla.
|
||||
*
|
||||
* Licensed under the GNU General Public License v3
|
||||
*
|
||||
|
@ -16,8 +16,8 @@ package code.name.monkey.retromusic.fragments.songs
|
|||
|
||||
import android.os.Bundle
|
||||
import android.view.*
|
||||
import androidx.activity.addCallback
|
||||
import androidx.annotation.LayoutRes
|
||||
import androidx.lifecycle.Observer
|
||||
import androidx.recyclerview.widget.GridLayoutManager
|
||||
import code.name.monkey.retromusic.R
|
||||
import code.name.monkey.retromusic.adapter.song.ShuffleButtonSongAdapter
|
||||
|
@ -31,6 +31,7 @@ import code.name.monkey.retromusic.util.PreferenceUtil
|
|||
import code.name.monkey.retromusic.util.RetroColorUtil
|
||||
import code.name.monkey.retromusic.util.RetroUtil
|
||||
import com.afollestad.materialcab.MaterialCab
|
||||
import com.google.android.gms.cast.framework.CastButtonFactory
|
||||
|
||||
class SongsFragment : AbsRecyclerViewCustomGridSizeFragment<SongAdapter, GridLayoutManager>(),
|
||||
ICabHolder {
|
||||
|
@ -42,13 +43,29 @@ class SongsFragment : AbsRecyclerViewCustomGridSizeFragment<SongAdapter, GridLay
|
|||
else
|
||||
adapter?.swapDataSet(listOf())
|
||||
})
|
||||
requireActivity().onBackPressedDispatcher.addCallback(viewLifecycleOwner) {
|
||||
if (!handleBackPress()) {
|
||||
remove()
|
||||
requireActivity().onBackPressed()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
override val titleRes: Int
|
||||
get() = R.string.songs
|
||||
|
||||
override val emptyMessage: Int
|
||||
get() = R.string.no_songs
|
||||
|
||||
override fun createLayoutManager(): GridLayoutManager {
|
||||
return GridLayoutManager(requireActivity(), getGridSize())
|
||||
return GridLayoutManager(requireActivity(), getGridSize()).apply {
|
||||
spanSizeLookup = object : GridLayoutManager.SpanSizeLookup() {
|
||||
override fun getSpanSize(position: Int): Int {
|
||||
return if (position == 0) getGridSize() else 1
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun createAdapter(): SongAdapter {
|
||||
|
@ -112,6 +129,8 @@ class SongsFragment : AbsRecyclerViewCustomGridSizeFragment<SongAdapter, GridLay
|
|||
val layoutItem = menu.findItem(R.id.action_layout_type)
|
||||
setupLayoutMenu(layoutItem.subMenu)
|
||||
setUpSortOrderMenu(menu.findItem(R.id.action_sort_order).subMenu)
|
||||
//Setting up cast button
|
||||
CastButtonFactory.setUpMediaRouteButton(requireContext(), menu, R.id.action_cast)
|
||||
}
|
||||
|
||||
private fun setUpSortOrderMenu(
|
||||
|
@ -175,6 +194,13 @@ class SongsFragment : AbsRecyclerViewCustomGridSizeFragment<SongAdapter, GridLay
|
|||
R.string.sort_order_composer
|
||||
).isChecked =
|
||||
currentSortOrder == SongSortOrder.COMPOSER
|
||||
sortOrderMenu.add(
|
||||
0,
|
||||
R.id.action_song_sort_order_album_artist,
|
||||
8,
|
||||
R.string.album_artist
|
||||
).isChecked =
|
||||
currentSortOrder == SongSortOrder.SONG_ALBUM_ARTIST
|
||||
|
||||
sortOrderMenu.setGroupCheckable(0, true, true)
|
||||
}
|
||||
|
@ -249,6 +275,7 @@ class SongsFragment : AbsRecyclerViewCustomGridSizeFragment<SongAdapter, GridLay
|
|||
R.id.action_song_sort_order_asc -> SongSortOrder.SONG_A_Z
|
||||
R.id.action_song_sort_order_desc -> SongSortOrder.SONG_Z_A
|
||||
R.id.action_song_sort_order_artist -> SongSortOrder.SONG_ARTIST
|
||||
R.id.action_song_sort_order_album_artist -> SongSortOrder.SONG_ALBUM_ARTIST
|
||||
R.id.action_song_sort_order_album -> SongSortOrder.SONG_ALBUM
|
||||
R.id.action_song_sort_order_year -> SongSortOrder.SONG_YEAR
|
||||
R.id.action_song_sort_order_date -> SongSortOrder.SONG_DATE
|
||||
|
@ -306,6 +333,11 @@ class SongsFragment : AbsRecyclerViewCustomGridSizeFragment<SongAdapter, GridLay
|
|||
return false
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
libraryViewModel.forceReload(ReloadType.Songs)
|
||||
}
|
||||
|
||||
companion object {
|
||||
@JvmField
|
||||
var TAG: String = SongsFragment::class.java.simpleName
|
||||
|
@ -318,7 +350,7 @@ class SongsFragment : AbsRecyclerViewCustomGridSizeFragment<SongAdapter, GridLay
|
|||
|
||||
private var cab: MaterialCab? = null
|
||||
|
||||
fun handleBackPress(): Boolean {
|
||||
private fun handleBackPress(): Boolean {
|
||||
cab?.let {
|
||||
if (it.isActive) {
|
||||
it.finish()
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue