/* * 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.activities import android.animation.ObjectAnimator import android.graphics.Color import android.graphics.PorterDuff import android.os.Bundle import android.view.animation.LinearInterpolator import android.widget.SeekBar import code.name.monkey.appthemehelper.ThemeStore import code.name.monkey.retromusic.R import code.name.monkey.retromusic.activities.base.AbsMusicServiceActivity import code.name.monkey.retromusic.databinding.ActivityDriveModeBinding import code.name.monkey.retromusic.fragments.base.AbsPlayerControlsFragment 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.helper.MusicPlayerRemote import code.name.monkey.retromusic.helper.MusicProgressViewUpdateHelper import code.name.monkey.retromusic.helper.MusicProgressViewUpdateHelper.Callback 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.color.MediaNotificationProcessor import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import kotlinx.coroutines.withContext /** * Created by hemanths on 2020-02-02. */ class DriveModeActivity : AbsMusicServiceActivity(), Callback { private lateinit var binding: ActivityDriveModeBinding private var lastPlaybackControlsColor: Int = Color.GRAY private var lastDisabledPlaybackControlsColor: Int = Color.GRAY private lateinit var progressViewUpdateHelper: MusicProgressViewUpdateHelper override fun onCreate(savedInstanceState: Bundle?) { setDrawUnderStatusBar() super.onCreate(savedInstanceState) binding = ActivityDriveModeBinding.inflate(layoutInflater) setContentView(binding.root) setUpMusicControllers() progressViewUpdateHelper = MusicProgressViewUpdateHelper(this) lastPlaybackControlsColor = ThemeStore.accentColor(this) binding.close.setOnClickListener { onBackPressed() } } private fun setUpMusicControllers() { setUpPlayPauseFab() setUpPrevNext() setUpRepeatButton() setUpShuffleButton() setUpProgressSlider() setupFavouriteToggle() } private fun setupFavouriteToggle() { binding.songFavourite.setOnClickListener { MusicUtil.toggleFavorite( this@DriveModeActivity, MusicPlayerRemote.currentSong ) } } private fun toggleFavourite() { CoroutineScope(Dispatchers.IO).launch { val isFavourite = MusicUtil.isFavorite(this@DriveModeActivity, MusicPlayerRemote.currentSong) withContext(Dispatchers.Main) { binding.songFavourite.setImageResource(if (isFavourite) R.drawable.ic_favorite else R.drawable.ic_favorite_border) } } } private 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 onPause() { super.onPause() progressViewUpdateHelper.stop() } override fun onResume() { super.onResume() progressViewUpdateHelper.start() } private fun setUpPrevNext() { binding.nextButton.setOnClickListener { MusicPlayerRemote.playNextSong() } binding.previousButton.setOnClickListener { MusicPlayerRemote.back() } } private fun setUpShuffleButton() { binding.shuffleButton.setOnClickListener { MusicPlayerRemote.toggleShuffleMode() } } private fun setUpRepeatButton() { binding.repeatButton.setOnClickListener { MusicPlayerRemote.cycleRepeatMode() } } private fun setUpPlayPauseFab() { binding.playPauseButton.setOnClickListener(PlayPauseButtonOnClickHandler()) } override fun onRepeatModeChanged() { super.onRepeatModeChanged() updateRepeatState() } override fun onShuffleModeChanged() { super.onShuffleModeChanged() updateShuffleState() } override fun onPlayStateChanged() { super.onPlayStateChanged() updatePlayPauseDrawableState() } override fun onServiceConnected() { super.onServiceConnected() updatePlayPauseDrawableState() updateSong() updateRepeatState() updateShuffleState() toggleFavourite() } private fun updatePlayPauseDrawableState() { if (MusicPlayerRemote.isPlaying) { binding.playPauseButton.setImageResource(R.drawable.ic_pause) } else { binding.playPauseButton.setImageResource(R.drawable.ic_play_arrow) } } fun updateShuffleState() { when (MusicPlayerRemote.shuffleMode) { MusicService.SHUFFLE_MODE_SHUFFLE -> binding.shuffleButton.setColorFilter( lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN ) else -> binding.shuffleButton.setColorFilter( lastDisabledPlaybackControlsColor, PorterDuff.Mode.SRC_IN ) } } private fun updateRepeatState() { when (MusicPlayerRemote.repeatMode) { MusicService.REPEAT_MODE_NONE -> { binding.repeatButton.setImageResource(R.drawable.ic_repeat) binding.repeatButton.setColorFilter( lastDisabledPlaybackControlsColor, PorterDuff.Mode.SRC_IN ) } MusicService.REPEAT_MODE_ALL -> { binding.repeatButton.setImageResource(R.drawable.ic_repeat) binding.repeatButton.setColorFilter( lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN ) } MusicService.REPEAT_MODE_THIS -> { binding.repeatButton.setImageResource(R.drawable.ic_repeat_one) binding.repeatButton.setColorFilter( lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN ) } } } override fun onPlayingMetaChanged() { super.onPlayingMetaChanged() updateSong() toggleFavourite() } private fun updateSong() { val song = MusicPlayerRemote.currentSong binding.songTitle.text = song.title binding.songText.text = song.artistName GlideApp.with(this) .asBitmapPalette() .songCoverOptions(song) .load(RetroGlideExtension.getSongModel(song)) .transform(BlurTransformation.Builder(this).build()) .into(object : RetroMusicColoredTarget(binding.image) { override fun onColorReady(colors: MediaNotificationProcessor) { } }) } override fun onUpdateProgressViews(progress: Int, total: Int) { binding.progressSlider.max = total val animator = ObjectAnimator.ofInt(binding.progressSlider, "progress", progress) animator.duration = AbsPlayerControlsFragment.SLIDER_ANIMATION_TIME animator.interpolator = LinearInterpolator() animator.start() binding.songTotalTime.text = MusicUtil.getReadableDurationString(total.toLong()) binding.songCurrentProgress.text = MusicUtil.getReadableDurationString(progress.toLong()) } }