🙆🏻Ohh got AsyncTask removed finally

And Favorite playlist added yay
This commit is contained in:
Hemanth S 2020-08-21 17:13:51 +05:30
parent d5d77afaaf
commit 069d45e8df
9 changed files with 135 additions and 127 deletions

View file

@ -20,7 +20,6 @@ import code.name.monkey.appthemehelper.ThemeStore
import code.name.monkey.appthemehelper.util.VersionUtils
import code.name.monkey.retromusic.Constants.PRO_VERSION_PRODUCT_ID
import code.name.monkey.retromusic.appshortcuts.DynamicShortcutManager
import com.amitshekhar.DebugDB
import com.anjlab.android.iab.v3.BillingProcessor
import com.anjlab.android.iab.v3.TransactionDetails
import org.koin.android.ext.koin.androidContext
@ -33,7 +32,7 @@ class App : MultiDexApplication() {
override fun onCreate() {
super.onCreate()
instance = this
DebugDB.getAddressLog();
startKoin {
androidContext(this@App)
modules(appModules)

View file

@ -1,9 +1,8 @@
package code.name.monkey.retromusic
import code.name.monkey.retromusic.db.PlaylistDatabase
import androidx.room.Room
import code.name.monkey.retromusic.db.PlaylistWithSongs
import code.name.monkey.retromusic.repository.RealRoomPlaylistRepository
import code.name.monkey.retromusic.repository.RoomPlaylistRepository
import code.name.monkey.retromusic.db.RetroDatabase
import code.name.monkey.retromusic.fragments.LibraryViewModel
import code.name.monkey.retromusic.fragments.albums.AlbumDetailsViewModel
import code.name.monkey.retromusic.fragments.artists.ArtistDetailsViewModel
@ -18,6 +17,22 @@ import org.koin.androidx.viewmodel.dsl.viewModel
import org.koin.dsl.bind
import org.koin.dsl.module
private val roomModule = module {
single {
Room.databaseBuilder(androidContext(), RetroDatabase::class.java, "playlist.db")
.allowMainThreadQueries()
.fallbackToDestructiveMigration()
.build()
}
factory {
get<RetroDatabase>().playlistDao()
}
single {
RealRoomRepository(get())
} bind RoomPlaylistRepository::class
}
private val mainModule = module {
single {
androidContext().contentResolver
@ -70,14 +85,6 @@ private val dataModule = module {
get()
)
}
single {
PlaylistDatabase.getDatabase(get()).playlistDao()
}
single {
RealRoomPlaylistRepository(get())
} bind RoomPlaylistRepository::class
}
private val viewModules = module {
@ -119,4 +126,4 @@ private val viewModules = module {
}
}
val appModules = listOf(mainModule, dataModule, viewModules, networkModule)
val appModules = listOf(mainModule, dataModule, viewModules, networkModule, roomModule)

View file

@ -26,8 +26,8 @@ interface PlaylistDao {
@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun insertSongs(songEntities: List<SongEntity>)
@Query("SELECT * FROM SongEntity WHERE playlist_creator_id = :playlistName AND id = :songId")
suspend fun checkSongExistsWithPlaylistName(playlistName: String, songId: Int): List<SongEntity>
@Query("SELECT * FROM SongEntity WHERE playlist_creator_id = :playlistId AND id = :songId")
suspend fun checkSongExistsWithPlaylistId(playlistId: Int, songId: Int): List<SongEntity>
@Query("SELECT * FROM SongEntity WHERE playlist_creator_id = :playlistId")
suspend fun getSongs(playlistId: Int): List<SongEntity>
@ -41,4 +41,6 @@ interface PlaylistDao {
@Delete
suspend fun removeSongsFromPlaylist(songs: List<SongEntity>)
@Query("DELETE FROM SongEntity WHERE playlist_creator_id = :playlistId AND id = :songId")
fun removeSong(playlistId: Int, songId: Int)
}

View file

@ -1,34 +0,0 @@
package code.name.monkey.retromusic.db
import android.content.Context
import androidx.room.Database
import androidx.room.Room
import androidx.room.RoomDatabase
@Database(
entities = [PlaylistEntity::class, SongEntity::class],
version = 8,
exportSchema = false
)
abstract class PlaylistDatabase : RoomDatabase() {
abstract fun playlistDao(): PlaylistDao
companion object {
@Volatile
private var INSTANCE: PlaylistDatabase? = null
fun getDatabase(
context: Context
): PlaylistDatabase {
return INSTANCE ?: synchronized(this) {
val instance = Room.databaseBuilder(
context.applicationContext,
PlaylistDatabase::class.java,
"playlists.db"
).fallbackToDestructiveMigration().build()
INSTANCE = instance
instance
}
}
}
}

View file

@ -0,0 +1,13 @@
package code.name.monkey.retromusic.db
import androidx.room.Database
import androidx.room.RoomDatabase
@Database(
entities = [PlaylistEntity::class, SongEntity::class],
version = 8,
exportSchema = false
)
abstract class RetroDatabase : RoomDatabase() {
abstract fun playlistDao(): PlaylistDao
}

View file

@ -65,7 +65,7 @@ class RemoveSongFromPlaylistDialog : DialogFragment() {
.setMessage(pair.second)
.setPositiveButton(R.string.remove_action) { _, _ ->
lifecycleScope.launch(Dispatchers.IO) {
repository.removeSongFromPlaylist(songs)
repository.removeSongsFromPlaylist(songs)
}
/* PlaylistsUtil.removeFromPlaylist(
requireContext(),

View file

@ -4,7 +4,6 @@ import android.annotation.SuppressLint
import android.content.ContentUris
import android.content.Intent
import android.media.MediaMetadataRetriever
import android.os.AsyncTask
import android.os.Build
import android.os.Bundle
import android.provider.MediaStore
@ -22,8 +21,10 @@ import code.name.monkey.retromusic.EXTRA_ARTIST_ID
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.activities.tageditor.AbsTagEditorActivity
import code.name.monkey.retromusic.activities.tageditor.SongTagEditorActivity
import code.name.monkey.retromusic.db.PlaylistEntity
import code.name.monkey.retromusic.dialogs.*
import code.name.monkey.retromusic.extensions.hide
import code.name.monkey.retromusic.extensions.whichFragment
import code.name.monkey.retromusic.fragments.LibraryViewModel
import code.name.monkey.retromusic.fragments.player.PlayerAlbumCoverFragment
import code.name.monkey.retromusic.helper.MusicPlayerRemote
@ -31,20 +32,22 @@ import code.name.monkey.retromusic.interfaces.PaletteColorHolder
import code.name.monkey.retromusic.model.Song
import code.name.monkey.retromusic.model.lyrics.Lyrics
import code.name.monkey.retromusic.repository.RealRepository
import code.name.monkey.retromusic.service.MusicService
import code.name.monkey.retromusic.util.*
import kotlinx.android.synthetic.main.shadow_statusbar_toolbar.*
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Dispatchers.IO
import kotlinx.coroutines.Dispatchers.Main
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.koin.android.ext.android.get
import org.koin.android.ext.android.inject
import org.koin.androidx.viewmodel.ext.android.sharedViewModel
import java.io.FileNotFoundException
abstract class AbsPlayerFragment(@LayoutRes layout: Int) : AbsMainActivityFragment(layout),
Toolbar.OnMenuItemClickListener, PaletteColorHolder, PlayerAlbumCoverFragment.Callbacks {
private var updateIsFavoriteTask: AsyncTask<*, *, *>? = null
private var updateLyricsAsyncTask: AsyncTask<*, *, *>? = null
private var playerAlbumCoverFragment: PlayerAlbumCoverFragment? = null
protected val libraryViewModel by sharedViewModel<LibraryViewModel>()
@ -70,7 +73,7 @@ abstract class AbsPlayerFragment(@LayoutRes layout: Int) : AbsMainActivityFragme
return true
}
R.id.action_add_to_playlist -> {
lifecycleScope.launch(Dispatchers.IO) {
lifecycleScope.launch(IO) {
val playlists = get<RealRepository>().roomPlaylists()
withContext(Dispatchers.Main) {
AddToRetroPlaylist.create(playlists, song)
@ -159,7 +162,16 @@ abstract class AbsPlayerFragment(@LayoutRes layout: Int) : AbsMainActivityFragme
}
protected open fun toggleFavorite(song: Song) {
MusicUtil.toggleFavorite(requireActivity(), song)
lifecycleScope.launch(IO) {
val playlist: PlaylistEntity = repository.favoritePlaylist().first()
val songEntity = song.toSongEntity(playlist.playListId)
if (repository.isFavoriteSong(songEntity).isNotEmpty()) {
repository.removeSongFromPlaylist(songEntity)
} else {
repository.insertSongs(listOf(song.toSongEntity(playlist.playListId)))
}
requireContext().sendBroadcast(Intent(MusicService.FAVORITE_STATE_CHANGED))
}
}
abstract fun playerToolbar(): Toolbar?
@ -181,85 +193,65 @@ abstract class AbsPlayerFragment(@LayoutRes layout: Int) : AbsMainActivityFragme
updateIsFavorite()
updateLyrics()
}
override fun onDestroyView() {
if (updateIsFavoriteTask != null && !updateIsFavoriteTask!!.isCancelled) {
updateIsFavoriteTask!!.cancel(true)
}
if (updateLyricsAsyncTask != null && !updateLyricsAsyncTask!!.isCancelled) {
updateLyricsAsyncTask!!.cancel(true)
}
super.onDestroyView()
}
@SuppressLint("StaticFieldLeak")
fun updateIsFavorite() {
if (updateIsFavoriteTask != null) {
updateIsFavoriteTask!!.cancel(false)
}
updateIsFavoriteTask = object : AsyncTask<Song, Void, Boolean>() {
override fun doInBackground(vararg params: Song): Boolean {
return MusicUtil.isFavorite(requireActivity(), params[0])
}
override fun onPostExecute(isFavorite: Boolean) {
val res = if (isFavorite)
R.drawable.ic_favorite
else
R.drawable.ic_favorite_border
lifecycleScope.launch(IO) {
val playlist: PlaylistEntity = repository.favoritePlaylist().first()
val song = MusicPlayerRemote.currentSong.toSongEntity(playlist.playListId)
val isFavorite = repository.isFavoriteSong(song).isNotEmpty()
withContext(Dispatchers.Main) {
val icon = if (isFavorite) R.drawable.ic_favorite else R.drawable.ic_favorite_border
val drawable =
RetroUtil.getTintedVectorDrawable(requireContext(), res, toolbarIconColor())
if (playerToolbar() != null && playerToolbar()!!.menu.findItem(R.id.action_toggle_favorite) != null)
playerToolbar()!!.menu.findItem(R.id.action_toggle_favorite).setIcon(drawable)
.title =
if (isFavorite) getString(R.string.action_remove_from_favorites) else getString(
R.string.action_add_to_favorites
)
RetroUtil.getTintedVectorDrawable(requireContext(), icon, toolbarIconColor())
if (playerToolbar() != null) {
playerToolbar()?.menu?.findItem(R.id.action_toggle_favorite)
?.setIcon(drawable)?.title =
if (isFavorite) getString(R.string.action_remove_from_favorites)
else getString(R.string.action_add_to_favorites)
}
}
}.execute(MusicPlayerRemote.currentSong)
}
}
@SuppressLint("StaticFieldLeak")
private fun updateLyrics() {
if (updateLyricsAsyncTask != null) updateLyricsAsyncTask!!.cancel(false)
updateLyricsAsyncTask = object : AsyncTask<Song, Void, Lyrics>() {
override fun onPreExecute() {
super.onPreExecute()
setLyrics(null)
setLyrics(null)
lifecycleScope.launch(IO) {
val song = MusicPlayerRemote.currentSong
val lyrics = try {
var data: String? = LyricUtil.getStringFromFile(song.title, song.artistName)
if (TextUtils.isEmpty(data)) {
data = MusicUtil.getLyrics(song)
if (TextUtils.isEmpty(data)) {
null
} else {
Lyrics.parse(song, data)
}
} else Lyrics.parse(song, data!!)
} catch (err: FileNotFoundException) {
null
}
override fun doInBackground(vararg params: Song): Lyrics? {
try {
var data: String? =
LyricUtil.getStringFromFile(params[0].title, params[0].artistName)
return if (TextUtils.isEmpty(data)) {
data = MusicUtil.getLyrics(params[0])
return if (TextUtils.isEmpty(data)) {
null
} else {
Lyrics.parse(params[0], data)
}
} else Lyrics.parse(params[0], data!!)
} catch (err: FileNotFoundException) {
return null
}
withContext(Main) {
setLyrics(lyrics)
}
override fun onPostExecute(l: Lyrics?) {
setLyrics(l)
}
override fun onCancelled(s: Lyrics?) {
onPostExecute(null)
}
}.execute(MusicPlayerRemote.currentSong)
}
}
open fun setLyrics(l: Lyrics?) {
}
private val repository by inject<RealRepository>()
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
lifecycleScope.launch(IO) {
if (repository.checkPlaylistExists(getString(R.string.favorites)).isEmpty()) {
repository.createPlaylist(PlaylistEntity(getString(R.string.favorites)))
}
}
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
if (PreferenceUtil.isFullScreenMode &&
@ -267,8 +259,7 @@ abstract class AbsPlayerFragment(@LayoutRes layout: Int) : AbsMainActivityFragme
) {
view.findViewById<View>(R.id.status_bar).visibility = View.GONE
}
playerAlbumCoverFragment =
childFragmentManager.findFragmentById(R.id.playerAlbumCoverFragment) as PlayerAlbumCoverFragment?
playerAlbumCoverFragment = whichFragment(R.id.playerAlbumCoverFragment)
playerAlbumCoverFragment?.setCallbacks(this)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)

View file

@ -114,9 +114,15 @@ interface Repository {
suspend fun renameRoomPlaylist(playlistId: Int, name: String)
suspend fun removeSongFromPlaylist(songs: List<SongEntity>)
suspend fun removeSongsFromPlaylist(songs: List<SongEntity>)
suspend fun removeSongFromPlaylist(songEntity: SongEntity)
suspend fun deleteSongsFromPlaylist(playlists: List<PlaylistEntity>)
suspend fun favoritePlaylist(): List<PlaylistEntity>
suspend fun isFavoriteSong(songEntity: SongEntity): List<SongEntity>
}
class RealRepository(
@ -215,11 +221,11 @@ class RealRepository(
override suspend fun homeSections(): List<Home> {
val homeSections = mutableListOf<Home>()
val sections = listOf(
suggestionsHome(),
topArtistsHome(),
topAlbumsHome(),
recentArtistsHome(),
recentAlbumsHome(),
suggestionsHome(),
favoritePlaylistHome()
)
for (section in sections) {
@ -264,18 +270,27 @@ class RealRepository(
override suspend fun renameRoomPlaylist(playlistId: Int, name: String) =
roomPlaylistRepository.renamePlaylistEntity(playlistId, name)
override suspend fun removeSongFromPlaylist(songs: List<SongEntity>) =
override suspend fun removeSongsFromPlaylist(songs: List<SongEntity>) =
roomPlaylistRepository.removeSongsFromPlaylist(songs)
override suspend fun removeSongFromPlaylist(songEntity: SongEntity) =
roomPlaylistRepository.removeSongFromPlaylist(songEntity)
override suspend fun deleteSongsFromPlaylist(playlists: List<PlaylistEntity>) =
roomPlaylistRepository.deleteSongsFromPlaylist(playlists)
override suspend fun favoritePlaylist(): List<PlaylistEntity> =
roomPlaylistRepository.favoritePlaylist(context.getString(R.string.favorites))
override suspend fun isFavoriteSong(songEntity: SongEntity): List<SongEntity> =
roomPlaylistRepository.isFavoriteSong(songEntity)
override suspend fun suggestionsHome(): Home {
val songs =
NotPlayedPlaylist().songs().shuffled().takeIf {
it.size > 9
} ?: emptyList()
println(songs.size)
return Home(songs, SUGGESTIONS)
}

View file

@ -18,9 +18,12 @@ interface RoomPlaylistRepository {
suspend fun renamePlaylistEntity(playlistId: Int, name: String)
suspend fun removeSongsFromPlaylist(songs: List<SongEntity>)
suspend fun deleteSongsFromPlaylist(playlists: List<PlaylistEntity>)
suspend fun favoritePlaylist(favorite: String): List<PlaylistEntity>
suspend fun isFavoriteSong(songEntity: SongEntity): List<SongEntity>
suspend fun removeSongFromPlaylist(songEntity: SongEntity)
}
class RealRoomPlaylistRepository(
class RealRoomRepository(
private val playlistDao: PlaylistDao
) : RoomPlaylistRepository {
@WorkerThread
@ -68,4 +71,16 @@ class RealRoomPlaylistRepository(
}
}
override suspend fun favoritePlaylist(favorite: String): List<PlaylistEntity> =
playlistDao.checkPlaylistExists(favorite)
override suspend fun isFavoriteSong(songEntity: SongEntity): List<SongEntity> =
playlistDao.checkSongExistsWithPlaylistId(
songEntity.playlistCreatorId,
songEntity.id
)
override suspend fun removeSongFromPlaylist(songEntity: SongEntity) =
playlistDao.removeSong(songEntity.playlistCreatorId, songEntity.id)
}