From 421dc817a22347d2e0e90c5896d6aed87b5040ca Mon Sep 17 00:00:00 2001 From: Prathamesh More Date: Sun, 12 Dec 2021 17:09:05 +0530 Subject: [PATCH] Fixed favorite toggle in DriveModeActivity --- .../activities/DriveModeActivity.kt | 56 ++++++++++++++----- .../name/monkey/retromusic/db/PlaylistDao.kt | 2 +- .../retromusic/fragments/LibraryViewModel.kt | 1 + .../fragments/base/AbsPlayerFragment.kt | 51 ++++++++--------- .../full/FullPlaybackControlsFragment.kt | 40 ++++++------- .../player/gradient/GradientPlayerFragment.kt | 30 +++++----- .../fragments/playlists/PlaylistsFragment.kt | 2 +- .../retromusic/repository/Repository.kt | 8 ++- .../retromusic/repository/RoomRepository.kt | 24 ++++++-- .../notification/PlayingNotificationImpl.kt | 6 +- 10 files changed, 125 insertions(+), 95 deletions(-) diff --git a/app/src/main/java/code/name/monkey/retromusic/activities/DriveModeActivity.kt b/app/src/main/java/code/name/monkey/retromusic/activities/DriveModeActivity.kt index df912bcd4..1205d1bdb 100644 --- a/app/src/main/java/code/name/monkey/retromusic/activities/DriveModeActivity.kt +++ b/app/src/main/java/code/name/monkey/retromusic/activities/DriveModeActivity.kt @@ -15,16 +15,22 @@ package code.name.monkey.retromusic.activities import android.animation.ObjectAnimator +import android.content.Intent import android.graphics.Color import android.graphics.PorterDuff import android.os.Bundle import android.view.animation.LinearInterpolator import android.widget.SeekBar +import androidx.activity.viewModels +import androidx.lifecycle.lifecycleScope 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.extensions.setDrawUnderStatusBar +import code.name.monkey.retromusic.db.toSongEntity +import code.name.monkey.retromusic.extensions.drawAboveSystemBars +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.glide.BlurTransformation import code.name.monkey.retromusic.glide.GlideApp @@ -35,13 +41,16 @@ 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.model.Song +import code.name.monkey.retromusic.repository.RealRepository 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 +import org.koin.android.ext.android.inject +import org.koin.androidx.viewmodel.ext.android.viewModel /** @@ -54,9 +63,9 @@ class DriveModeActivity : AbsMusicServiceActivity(), Callback { private var lastPlaybackControlsColor: Int = Color.GRAY private var lastDisabledPlaybackControlsColor: Int = Color.GRAY private lateinit var progressViewUpdateHelper: MusicProgressViewUpdateHelper + private val repository: RealRepository by inject() override fun onCreate(savedInstanceState: Bundle?) { - setDrawUnderStatusBar() super.onCreate(savedInstanceState) binding = ActivityDriveModeBinding.inflate(layoutInflater) setContentView(binding.root) @@ -67,6 +76,7 @@ class DriveModeActivity : AbsMusicServiceActivity(), Callback { binding.close.setOnClickListener { onBackPressed() } + binding.repeatButton.drawAboveSystemBars() } private fun setUpMusicControllers() { @@ -80,19 +90,32 @@ class DriveModeActivity : AbsMusicServiceActivity(), Callback { private fun setupFavouriteToggle() { binding.songFavourite.setOnClickListener { - MusicUtil.toggleFavorite( - this@DriveModeActivity, - MusicPlayerRemote.currentSong - ) + toggleFavorite(MusicPlayerRemote.currentSong) } } - private fun toggleFavourite() { - CoroutineScope(Dispatchers.IO).launch { - val isFavourite = - MusicUtil.isFavorite(this@DriveModeActivity, MusicPlayerRemote.currentSong) + private fun toggleFavorite(song: Song) { + lifecycleScope.launch(Dispatchers.IO) { + val playlist = repository.favoritePlaylist() + if (playlist != null) { + val songEntity = song.toSongEntity(playlist.playListId) + val isFavorite = repository.isSongFavorite(song.id) + if (isFavorite) { + repository.removeSongFromPlaylist(songEntity) + } else { + repository.insertSongs(listOf(song.toSongEntity(playlist.playListId))) + } + } + sendBroadcast(Intent(MusicService.FAVORITE_STATE_CHANGED)) + } + } + + private fun updateFavorite() { + lifecycleScope.launch(Dispatchers.IO) { + val isFavorite: Boolean = + repository.isSongFavorite(MusicPlayerRemote.currentSong.id) withContext(Dispatchers.Main) { - binding.songFavourite.setImageResource(if (isFavourite) R.drawable.ic_favorite else R.drawable.ic_favorite_border) + binding.songFavourite.setImageResource(if (isFavorite) R.drawable.ic_favorite else R.drawable.ic_favorite_border) } } } @@ -160,7 +183,7 @@ class DriveModeActivity : AbsMusicServiceActivity(), Callback { updateSong() updateRepeatState() updateShuffleState() - toggleFavourite() + updateFavorite() } private fun updatePlayPauseDrawableState() { @@ -213,7 +236,12 @@ class DriveModeActivity : AbsMusicServiceActivity(), Callback { override fun onPlayingMetaChanged() { super.onPlayingMetaChanged() updateSong() - toggleFavourite() + updateFavorite() + } + + override fun onFavoriteStateChanged() { + super.onFavoriteStateChanged() + updateFavorite() } private fun updateSong() { diff --git a/app/src/main/java/code/name/monkey/retromusic/db/PlaylistDao.kt b/app/src/main/java/code/name/monkey/retromusic/db/PlaylistDao.kt index fa39a5cb4..a8369226e 100644 --- a/app/src/main/java/code/name/monkey/retromusic/db/PlaylistDao.kt +++ b/app/src/main/java/code/name/monkey/retromusic/db/PlaylistDao.kt @@ -26,7 +26,7 @@ interface PlaylistDao { suspend fun renamePlaylist(playlistId: Long, name: String) @Query("SELECT * FROM PlaylistEntity WHERE playlist_name = :name") - fun isPlaylistExists(name: String): List + fun playlist(name: String): List @Query("SELECT * FROM PlaylistEntity") suspend fun playlists(): List diff --git a/app/src/main/java/code/name/monkey/retromusic/fragments/LibraryViewModel.kt b/app/src/main/java/code/name/monkey/retromusic/fragments/LibraryViewModel.kt index 171983cdf..518bca7ac 100644 --- a/app/src/main/java/code/name/monkey/retromusic/fragments/LibraryViewModel.kt +++ b/app/src/main/java/code/name/monkey/retromusic/fragments/LibraryViewModel.kt @@ -233,6 +233,7 @@ class LibraryViewModel( suspend fun artistById(id: Long) = repository.artistById(id) suspend fun favoritePlaylist() = repository.favoritePlaylist() suspend fun isFavoriteSong(song: SongEntity) = repository.isFavoriteSong(song) + suspend fun isSongFavorite(songId: Long) = repository.isSongFavorite(songId) suspend fun insertSongs(songs: List) = repository.insertSongs(songs) suspend fun removeSongFromPlaylist(songEntity: SongEntity) = repository.removeSongFromPlaylist(songEntity) diff --git a/app/src/main/java/code/name/monkey/retromusic/fragments/base/AbsPlayerFragment.kt b/app/src/main/java/code/name/monkey/retromusic/fragments/base/AbsPlayerFragment.kt index 7acfc1112..b63fc6dc9 100644 --- a/app/src/main/java/code/name/monkey/retromusic/fragments/base/AbsPlayerFragment.kt +++ b/app/src/main/java/code/name/monkey/retromusic/fragments/base/AbsPlayerFragment.kt @@ -38,7 +38,6 @@ import androidx.core.os.bundleOf import androidx.lifecycle.lifecycleScope import androidx.navigation.findNavController import androidx.navigation.navOptions -import androidx.transition.Fade import androidx.viewpager.widget.ViewPager import code.name.monkey.retromusic.EXTRA_ALBUM_ID import code.name.monkey.retromusic.EXTRA_ARTIST_ID @@ -232,7 +231,7 @@ abstract class AbsPlayerFragment(@LayoutRes layout: Int) : AbsMainActivityFragme val playlist: PlaylistEntity = libraryViewModel.favoritePlaylist() if (playlist != null) { val songEntity = song.toSongEntity(playlist.playListId) - val isFavorite = libraryViewModel.isFavoriteSong(songEntity).isNotEmpty() + val isFavorite = libraryViewModel.isSongFavorite(song.id) if (isFavorite) { libraryViewModel.removeSongFromPlaylist(songEntity) } else { @@ -246,32 +245,28 @@ abstract class AbsPlayerFragment(@LayoutRes layout: Int) : AbsMainActivityFragme fun updateIsFavorite(animate: Boolean = false) { lifecycleScope.launch(IO) { - 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 = 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)?.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() - } + val isFavorite: Boolean = + libraryViewModel.isSongFavorite(MusicPlayerRemote.currentSong.id) + withContext(Main) { + 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)?.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() } } } diff --git a/app/src/main/java/code/name/monkey/retromusic/fragments/player/full/FullPlaybackControlsFragment.kt b/app/src/main/java/code/name/monkey/retromusic/fragments/player/full/FullPlaybackControlsFragment.kt index 324b00e8e..db751d52b 100644 --- a/app/src/main/java/code/name/monkey/retromusic/fragments/player/full/FullPlaybackControlsFragment.kt +++ b/app/src/main/java/code/name/monkey/retromusic/fragments/player/full/FullPlaybackControlsFragment.kt @@ -317,28 +317,24 @@ class FullPlaybackControlsFragment : fun updateIsFavorite(animate: Boolean = false) { lifecycleScope.launch(Dispatchers.IO) { - val playlist: PlaylistEntity = libraryViewModel.favoritePlaylist() - if (playlist != null) { - val song: SongEntity = - MusicPlayerRemote.currentSong.toSongEntity(playlist.playListId) - val isFavorite: Boolean = libraryViewModel.isFavoriteSong(song).isNotEmpty() - withContext(Dispatchers.Main) { - 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, - Color.WHITE - ) - binding.songFavourite.apply { - setImageDrawable(drawable) - getDrawable().also { - if (it is AnimatedVectorDrawable) { - it.start() - } + val isFavorite: Boolean = + libraryViewModel.isSongFavorite(MusicPlayerRemote.currentSong.id) + withContext(Dispatchers.Main) { + 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, + Color.WHITE + ) + binding.songFavourite.apply { + setImageDrawable(drawable) + getDrawable().also { + if (it is AnimatedVectorDrawable) { + it.start() } } } diff --git a/app/src/main/java/code/name/monkey/retromusic/fragments/player/gradient/GradientPlayerFragment.kt b/app/src/main/java/code/name/monkey/retromusic/fragments/player/gradient/GradientPlayerFragment.kt index 7b15c9479..d24112406 100644 --- a/app/src/main/java/code/name/monkey/retromusic/fragments/player/gradient/GradientPlayerFragment.kt +++ b/app/src/main/java/code/name/monkey/retromusic/fragments/player/gradient/GradientPlayerFragment.kt @@ -281,23 +281,19 @@ class GradientPlayerFragment : AbsPlayerFragment(R.layout.fragment_gradient_play private fun updateIsFavoriteIcon(animate: Boolean = false) { lifecycleScope.launch(Dispatchers.IO) { - val playlist: PlaylistEntity = libraryViewModel.favoritePlaylist() - if (playlist != null) { - val song: SongEntity = - MusicPlayerRemote.currentSong.toSongEntity(playlist.playListId) - val isFavorite: Boolean = libraryViewModel.isFavoriteSong(song).isNotEmpty() - withContext(Dispatchers.Main) { - 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() - } + val isFavorite: Boolean = + libraryViewModel.isSongFavorite(MusicPlayerRemote.currentSong.id) + withContext(Dispatchers.Main) { + 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() } } } diff --git a/app/src/main/java/code/name/monkey/retromusic/fragments/playlists/PlaylistsFragment.kt b/app/src/main/java/code/name/monkey/retromusic/fragments/playlists/PlaylistsFragment.kt index 47db31189..094c146bc 100644 --- a/app/src/main/java/code/name/monkey/retromusic/fragments/playlists/PlaylistsFragment.kt +++ b/app/src/main/java/code/name/monkey/retromusic/fragments/playlists/PlaylistsFragment.kt @@ -42,7 +42,7 @@ class PlaylistsFragment : super.onViewCreated(view, savedInstanceState) libraryViewModel.getPlaylists().observe(viewLifecycleOwner, { if (it.isNotEmpty()) - adapter?.swapDataSet(it.filter { playlistWithSongs-> playlistWithSongs.songs.isNotEmpty() }) + adapter?.swapDataSet(it) else adapter?.swapDataSet(listOf()) }) diff --git a/app/src/main/java/code/name/monkey/retromusic/repository/Repository.kt b/app/src/main/java/code/name/monkey/retromusic/repository/Repository.kt index 8fc822f27..0c7a3d9b0 100644 --- a/app/src/main/java/code/name/monkey/retromusic/repository/Repository.kt +++ b/app/src/main/java/code/name/monkey/retromusic/repository/Repository.kt @@ -72,6 +72,7 @@ interface Repository { suspend fun genresHome(): Home suspend fun playlists(): Home suspend fun homeSections(): List + @ExperimentalCoroutinesApi suspend fun homeSectionsFlow(): Flow>> suspend fun playlist(playlistId: Long): Playlist @@ -106,6 +107,7 @@ interface Repository { suspend fun searchArtists(query: String): List suspend fun searchSongs(query: String): List suspend fun searchAlbums(query: String): List + suspend fun isSongFavorite(songId: Long): Boolean fun getSongByGenre(genreId: Long): Song } @@ -133,6 +135,9 @@ class RealRepository( override suspend fun searchAlbums(query: String): List = albumRepository.albums(query) + override suspend fun isSongFavorite(songId: Long): Boolean = + roomRepository.isSongFavorite(context, songId) + override fun getSongByGenre(genreId: Long): Song = genreRepository.song(genreId) override suspend fun searchArtists(query: String): List = @@ -150,7 +155,8 @@ class RealRepository( override suspend fun artistById(artistId: Long): Artist = artistRepository.artist(artistId) - override suspend fun albumArtistByName(name: String): Artist = artistRepository.albumArtist(name) + override suspend fun albumArtistByName(name: String): Artist = + artistRepository.albumArtist(name) override suspend fun recentArtists(): List = lastAddedRepository.recentArtists() diff --git a/app/src/main/java/code/name/monkey/retromusic/repository/RoomRepository.kt b/app/src/main/java/code/name/monkey/retromusic/repository/RoomRepository.kt index 346dfa21f..d2b8ec619 100644 --- a/app/src/main/java/code/name/monkey/retromusic/repository/RoomRepository.kt +++ b/app/src/main/java/code/name/monkey/retromusic/repository/RoomRepository.kt @@ -1,7 +1,9 @@ package code.name.monkey.retromusic.repository +import android.content.Context import androidx.annotation.WorkerThread import androidx.lifecycle.LiveData +import code.name.monkey.retromusic.R import code.name.monkey.retromusic.db.* import code.name.monkey.retromusic.helper.SortOrder.PlaylistSortOrder.Companion.PLAYLIST_A_Z import code.name.monkey.retromusic.helper.SortOrder.PlaylistSortOrder.Companion.PLAYLIST_SONG_COUNT @@ -45,6 +47,7 @@ interface RoomRepository { suspend fun insertBlacklistPathAsync(blackListStoreEntity: BlackListStoreEntity) suspend fun blackListPaths(): List suspend fun deleteSongs(songs: List) + suspend fun isSongFavorite(context: Context, songId: Long): Boolean } class RealRoomRepository( @@ -60,7 +63,7 @@ class RealRoomRepository( @WorkerThread override suspend fun checkPlaylistExists(playlistName: String): List = - playlistDao.isPlaylistExists(playlistName) + playlistDao.playlist(playlistName) @WorkerThread override suspend fun playlists(): List = playlistDao.playlists() @@ -111,12 +114,13 @@ class RealRoomRepository( } override suspend fun favoritePlaylist(favorite: String): PlaylistEntity { - val playlist: PlaylistEntity? = playlistDao.isPlaylistExists(favorite).firstOrNull() + val playlist: PlaylistEntity? = playlistDao.playlist(favorite).firstOrNull() return if (playlist != null) { playlist } else { + println("Playlist Created") createPlaylist(PlaylistEntity(playlistName = favorite)) - playlistDao.isPlaylistExists(favorite).first() + playlistDao.playlist(favorite).first() } } @@ -145,12 +149,12 @@ class RealRoomRepository( override fun favoritePlaylistLiveData(favorite: String): LiveData> = playlistDao.favoritesSongsLiveData( - playlistDao.isPlaylistExists(favorite).first().playListId + playlistDao.playlist(favorite).first().playListId ) override suspend fun favoritePlaylistSongs(favorite: String): List = - if (playlistDao.isPlaylistExists(favorite).isNotEmpty()) playlistDao.favoritesSongs( - playlistDao.isPlaylistExists(favorite).first().playListId + if (playlistDao.playlist(favorite).isNotEmpty()) playlistDao.favoritesSongs( + playlistDao.playlist(favorite).first().playListId ) else emptyList() override suspend fun insertSongInPlayCount(playCountEntity: PlayCountEntity) = @@ -192,4 +196,12 @@ class RealRoomRepository( blackListStoreDao.deleteBlacklistPath(blackListStoreEntity) override suspend fun clearBlacklist() = blackListStoreDao.clearBlacklist() + + override suspend fun isSongFavorite(context: Context, songId: Long): Boolean { + return playlistDao.isSongExistsInPlaylist( + playlistDao.playlist(context.getString(R.string.favorites)).firstOrNull()?.playListId + ?: -1, + songId + ).isNotEmpty() + } } \ No newline at end of file diff --git a/app/src/main/java/code/name/monkey/retromusic/service/notification/PlayingNotificationImpl.kt b/app/src/main/java/code/name/monkey/retromusic/service/notification/PlayingNotificationImpl.kt index 37926da08..ab4bfb2c7 100644 --- a/app/src/main/java/code/name/monkey/retromusic/service/notification/PlayingNotificationImpl.kt +++ b/app/src/main/java/code/name/monkey/retromusic/service/notification/PlayingNotificationImpl.kt @@ -207,11 +207,7 @@ class PlayingNotificationImpl( override fun updateFavorite(song: Song, onUpdate: () -> Unit) { GlobalScope.launch(Dispatchers.IO) { - val playlist: PlaylistEntity = MusicUtil.repository.favoritePlaylist() - val isFavorite = if (playlist != null) { - val songEntity = song.toSongEntity(playlist.playListId) - MusicUtil.repository.isFavoriteSong(songEntity).isNotEmpty() - } else false + val isFavorite = MusicUtil.repository.isSongFavorite(song.id) withContext(Dispatchers.Main) { mActions[0] = buildFavoriteAction(isFavorite) onUpdate()