/* * 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.player.card import android.animation.ObjectAnimator import android.graphics.PorterDuff import android.os.Bundle import android.view.View import android.view.animation.LinearInterpolator import android.widget.SeekBar import code.name.monkey.appthemehelper.ThemeStore import code.name.monkey.appthemehelper.util.ATHUtil 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.getSongInfo 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 import code.name.monkey.retromusic.misc.SimpleOnSeekbarChangeListener 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 class CardPlaybackControlsFragment : AbsPlayerControlsFragment(R.layout.fragment_card_player_playback_controls) { 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) progressViewUpdateHelper = MusicProgressViewUpdateHelper(this) } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) _binding = FragmentCardPlayerPlaybackControlsBinding.bind(view) setUpMusicControllers() binding.mediaButton.playPauseButton.setOnClickListener { if (MusicPlayerRemote.isPlaying) { MusicPlayerRemote.pauseSong() } else { MusicPlayerRemote.resumePlaying() } showBounceAnimation(binding.mediaButton.playPauseButton) } 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 binding.title.text = song.title binding.text.text = song.artistName if (PreferenceUtil.isSongInfo) { binding.songInfo.text = getSongInfo(MusicPlayerRemote.currentSong) binding.songInfo.show() } else { binding.songInfo.hide() } } override fun onResume() { super.onResume() progressViewUpdateHelper!!.start() } override fun onPause() { super.onPause() progressViewUpdateHelper!!.stop() } override fun onServiceConnected() { updatePlayPauseDrawableState() updateRepeatState() updateShuffleState() updateSong() } override fun onPlayingMetaChanged() { super.onPlayingMetaChanged() updateSong() } override fun onPlayStateChanged() { updatePlayPauseDrawableState() } override fun onRepeatModeChanged() { updateRepeatState() } override fun onShuffleModeChanged() { updateShuffleState() } override fun setColor(color: MediaNotificationProcessor) { if (!ATHUtil.isWindowBackgroundDark(requireContext()) ) { lastPlaybackControlsColor = MaterialValueHelper.getSecondaryTextColor(activity, true) lastDisabledPlaybackControlsColor = MaterialValueHelper.getSecondaryDisabledTextColor(activity, true) } else { lastPlaybackControlsColor = MaterialValueHelper.getPrimaryTextColor(activity, false) lastDisabledPlaybackControlsColor = MaterialValueHelper.getPrimaryDisabledTextColor(activity, false) } updateRepeatState() updateShuffleState() updatePrevNextColor() updatePlayPauseColor() updateProgressTextColor() val colorFinal = if (PreferenceUtil.isAdaptiveColor) { color.primaryTextColor } else { ThemeStore.accentColor(requireContext()).ripAlpha() } binding.image.setColorFilter(colorFinal, PorterDuff.Mode.SRC_IN) TintHelper.setTintAuto( binding.mediaButton.playPauseButton, MaterialValueHelper.getPrimaryTextColor(context, ColorUtil.isColorLight(colorFinal)), false ) TintHelper.setTintAuto(binding.mediaButton.playPauseButton, colorFinal, true) volumeFragment?.setTintable(colorFinal) } private fun updatePlayPauseColor() { // playPauseButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN); } private fun setUpPlayPauseFab() { binding.mediaButton.playPauseButton.setOnClickListener(PlayPauseButtonOnClickHandler()) } private fun updatePlayPauseDrawableState() { if (MusicPlayerRemote.isPlaying) { binding.mediaButton.playPauseButton.setImageResource(R.drawable.ic_pause) } else { binding.mediaButton.playPauseButton.setImageResource(R.drawable.ic_play_arrow_white_32dp) } } private fun setUpMusicControllers() { setUpPlayPauseFab() setUpPrevNext() setUpRepeatButton() setUpShuffleButton() setUpProgressSlider() } private fun setUpPrevNext() { updatePrevNextColor() binding.mediaButton.nextButton.setOnClickListener { MusicPlayerRemote.playNextSong() } binding.mediaButton.previousButton.setOnClickListener { MusicPlayerRemote.back() } } private fun updatePrevNextColor() { binding.mediaButton.nextButton.setColorFilter( lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN ) binding.mediaButton.previousButton.setColorFilter( lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN ) } private fun setUpShuffleButton() { binding.mediaButton.shuffleButton.setOnClickListener { MusicPlayerRemote.toggleShuffleMode() } } override fun updateShuffleState() { when (MusicPlayerRemote.shuffleMode) { MusicService.SHUFFLE_MODE_SHUFFLE -> binding.mediaButton.shuffleButton.setColorFilter( lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN ) else -> binding.mediaButton.shuffleButton.setColorFilter( lastDisabledPlaybackControlsColor, PorterDuff.Mode.SRC_IN ) } } private fun setUpRepeatButton() { binding.mediaButton.repeatButton.setOnClickListener { MusicPlayerRemote.cycleRepeatMode() } } override fun updateRepeatState() { when (MusicPlayerRemote.repeatMode) { MusicService.REPEAT_MODE_NONE -> { binding.mediaButton.repeatButton.setImageResource(R.drawable.ic_repeat) binding.mediaButton.repeatButton.setColorFilter( lastDisabledPlaybackControlsColor, PorterDuff.Mode.SRC_IN ) } MusicService.REPEAT_MODE_ALL -> { binding.mediaButton.repeatButton.setImageResource(R.drawable.ic_repeat) binding.mediaButton.repeatButton.setColorFilter( lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN ) } MusicService.REPEAT_MODE_THIS -> { 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) { binding.progressSlider.max = total val animator = ObjectAnimator.ofInt(binding.progressSlider, "progress", progress) animator.duration = SLIDER_ANIMATION_TIME animator.interpolator = LinearInterpolator() animator.start() binding.songTotalTime.text = MusicUtil.getReadableDurationString(total.toLong()) binding.songCurrentProgress.text = MusicUtil.getReadableDurationString(progress.toLong()) } private fun updateProgressTextColor() { val color = MaterialValueHelper.getPrimaryTextColor(context, false) binding.songTotalTime.setTextColor(color) binding.songCurrentProgress.setTextColor(color) } public override fun show() { // Ignore } public override fun hide() { // Ignore } override fun setUpProgressSlider() { binding.progressSlider.setOnSeekBarChangeListener(object : SimpleOnSeekbarChangeListener() { override fun onProgressChanged(seekBar: SeekBar, progress: Int, fromUser: Boolean) { if (fromUser) { MusicPlayerRemote.seekTo(progress) onUpdateProgressViews( MusicPlayerRemote.songProgressMillis, MusicPlayerRemote.songDurationMillis ) } } }) } override fun onDestroyView() { super.onDestroyView() _binding = null } }