Fixed favorite toggle in DriveModeActivity
This commit is contained in:
parent
144fcf29bd
commit
421dc817a2
10 changed files with 125 additions and 95 deletions
|
@ -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() {
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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())
|
||||
})
|
||||
|
|
|
@ -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()
|
||||
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
}
|
|
@ -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()
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue