/* * 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.fragments.base.AbsPlayerControlsFragment import code.name.monkey.retromusic.glide.BlurTransformation 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.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 com.bumptech.glide.Glide import kotlinx.android.synthetic.main.activity_drive_mode.* 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 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) setContentView(R.layout.activity_drive_mode) setUpMusicControllers() progressViewUpdateHelper = MusicProgressViewUpdateHelper(this) lastPlaybackControlsColor = ThemeStore.accentColor(this) close.setOnClickListener { onBackPressed() } } private fun setUpMusicControllers() { setUpPlayPauseFab() setUpPrevNext() setUpRepeatButton() setUpShuffleButton() setUpProgressSlider() setupFavouriteToggle() } private fun setupFavouriteToggle() { 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) { songFavourite.setImageResource(if (isFavourite) R.drawable.ic_favorite else R.drawable.ic_favorite_border) } } } private fun setUpProgressSlider() { 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() { nextButton.setOnClickListener { MusicPlayerRemote.playNextSong() } previousButton.setOnClickListener { MusicPlayerRemote.back() } } private fun setUpShuffleButton() { shuffleButton.setOnClickListener { MusicPlayerRemote.toggleShuffleMode() } } private fun setUpRepeatButton() { repeatButton.setOnClickListener { MusicPlayerRemote.cycleRepeatMode() } } private fun setUpPlayPauseFab() { 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) { playPauseButton.setImageResource(R.drawable.ic_pause) } else { playPauseButton.setImageResource(R.drawable.ic_play_arrow) } } fun updateShuffleState() { when (MusicPlayerRemote.shuffleMode) { MusicService.SHUFFLE_MODE_SHUFFLE -> shuffleButton.setColorFilter( lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN ) else -> shuffleButton.setColorFilter( lastDisabledPlaybackControlsColor, PorterDuff.Mode.SRC_IN ) } } private fun updateRepeatState() { when (MusicPlayerRemote.repeatMode) { MusicService.REPEAT_MODE_NONE -> { repeatButton.setImageResource(R.drawable.ic_repeat) repeatButton.setColorFilter( lastDisabledPlaybackControlsColor, PorterDuff.Mode.SRC_IN ) } MusicService.REPEAT_MODE_ALL -> { repeatButton.setImageResource(R.drawable.ic_repeat) 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) } } } override fun onPlayingMetaChanged() { super.onPlayingMetaChanged() updateSong() toggleFavourite() } private fun updateSong() { val song = MusicPlayerRemote.currentSong songTitle.text = song.title songText.text = song.artistName SongGlideRequest.Builder.from(Glide.with(this), song) .checkIgnoreMediaStore(this) .generatePalette(this) .build() .transform(BlurTransformation.Builder(this).build()) .into(object : RetroMusicColoredTarget(image) { override fun onColorReady(colors: MediaNotificationProcessor) { } }) } override fun onUpdateProgressViews(progress: Int, total: Int) { progressSlider.max = total val animator = ObjectAnimator.ofInt(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()) } }