Fixed favorite toggle in DriveModeActivity

This commit is contained in:
Prathamesh More 2021-12-12 17:09:05 +05:30
parent 144fcf29bd
commit 421dc817a2
10 changed files with 125 additions and 95 deletions

View file

@ -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() {

View file

@ -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<PlaylistEntity>
fun playlist(name: String): List<PlaylistEntity>
@Query("SELECT * FROM PlaylistEntity")
suspend fun playlists(): List<PlaylistEntity>

View file

@ -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<SongEntity>) = repository.insertSongs(songs)
suspend fun removeSongFromPlaylist(songEntity: SongEntity) =
repository.removeSongFromPlaylist(songEntity)

View file

@ -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()
}
}
}

View file

@ -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()
}
}
}

View file

@ -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()
}
}
}

View file

@ -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())
})

View file

@ -72,6 +72,7 @@ interface Repository {
suspend fun genresHome(): Home
suspend fun playlists(): Home
suspend fun homeSections(): List<Home>
@ExperimentalCoroutinesApi
suspend fun homeSectionsFlow(): Flow<Result<List<Home>>>
suspend fun playlist(playlistId: Long): Playlist
@ -106,6 +107,7 @@ interface Repository {
suspend fun searchArtists(query: String): List<Artist>
suspend fun searchSongs(query: String): List<Song>
suspend fun searchAlbums(query: String): List<Album>
suspend fun isSongFavorite(songId: Long): Boolean
fun getSongByGenre(genreId: Long): Song
}
@ -133,6 +135,9 @@ class RealRepository(
override suspend fun searchAlbums(query: String): List<Album> = 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<Artist> =
@ -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<Artist> = lastAddedRepository.recentArtists()

View file

@ -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<BlackListStoreEntity>
suspend fun deleteSongs(songs: List<Song>)
suspend fun isSongFavorite(context: Context, songId: Long): Boolean
}
class RealRoomRepository(
@ -60,7 +63,7 @@ class RealRoomRepository(
@WorkerThread
override suspend fun checkPlaylistExists(playlistName: String): List<PlaylistEntity> =
playlistDao.isPlaylistExists(playlistName)
playlistDao.playlist(playlistName)
@WorkerThread
override suspend fun playlists(): List<PlaylistEntity> = 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<List<SongEntity>> =
playlistDao.favoritesSongsLiveData(
playlistDao.isPlaylistExists(favorite).first().playListId
playlistDao.playlist(favorite).first().playListId
)
override suspend fun favoritePlaylistSongs(favorite: String): List<SongEntity> =
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()
}
}

View file

@ -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()