Add Room for playlist

Added DAO Queries and Able insert songs to playlist
This commit is contained in:
Hemanth S 2020-08-20 12:19:08 +05:30
parent 6ace96708b
commit b5e07a31d8
16 changed files with 140 additions and 66 deletions

View file

@ -1,6 +1,8 @@
package code.name.monkey.retromusic package code.name.monkey.retromusic
import code.name.monkey.retromusic.db.PlaylistDatabase import code.name.monkey.retromusic.db.PlaylistDatabase
import code.name.monkey.retromusic.db.RealRoomPlaylistRepository
import code.name.monkey.retromusic.db.RoomPlaylistRepository
import code.name.monkey.retromusic.fragments.LibraryViewModel import code.name.monkey.retromusic.fragments.LibraryViewModel
import code.name.monkey.retromusic.fragments.albums.AlbumDetailsViewModel import code.name.monkey.retromusic.fragments.albums.AlbumDetailsViewModel
import code.name.monkey.retromusic.fragments.artists.ArtistDetailsViewModel import code.name.monkey.retromusic.fragments.artists.ArtistDetailsViewModel
@ -16,9 +18,15 @@ import org.koin.androidx.viewmodel.dsl.viewModel
import org.koin.dsl.bind import org.koin.dsl.bind
import org.koin.dsl.module import org.koin.dsl.module
private val mainModule = module {
single {
androidContext().contentResolver
}
}
private val dataModule = module { private val dataModule = module {
single { single {
RealRepository(get(), get(), get(), get(), get(), get(), get(), get(), get(), get()) RealRepository(get(), get(), get(), get(), get(), get(), get(), get(), get(), get(), get())
} bind Repository::class } bind Repository::class
single { single {
@ -64,12 +72,12 @@ private val dataModule = module {
} }
single { single {
androidContext().contentResolver PlaylistDatabase.getDatabase(get()).playlistDao()
} }
single { single {
PlaylistDatabase.getDatabase(get()) RealRoomPlaylistRepository(get())
} } bind RoomPlaylistRepository::class
} }
private val viewModules = module { private val viewModules = module {
@ -111,4 +119,4 @@ private val viewModules = module {
} }
} }
val appModules = listOf(dataModule, viewModules, networkModule) val appModules = listOf(mainModule, dataModule, viewModules, networkModule)

View file

@ -10,7 +10,7 @@ import android.view.View
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import code.name.monkey.retromusic.* import code.name.monkey.retromusic.*
import code.name.monkey.retromusic.activities.base.AbsSlidingMusicPanelActivity import code.name.monkey.retromusic.activities.base.AbsSlidingMusicPanelActivity
import code.name.monkey.retromusic.db.PlaylistDatabase import code.name.monkey.retromusic.db.RoomPlaylistRepository
import code.name.monkey.retromusic.extensions.findNavController import code.name.monkey.retromusic.extensions.findNavController
import code.name.monkey.retromusic.fragments.LibraryViewModel import code.name.monkey.retromusic.fragments.LibraryViewModel
import code.name.monkey.retromusic.helper.MusicPlayerRemote.openAndShuffleQueue import code.name.monkey.retromusic.helper.MusicPlayerRemote.openAndShuffleQueue
@ -58,11 +58,10 @@ class MainActivity : AbsSlidingMusicPanelActivity(), OnSharedPreferenceChangeLis
addMusicServiceEventListener(libraryViewModel) addMusicServiceEventListener(libraryViewModel)
updateTabs() updateTabs()
val database: PlaylistDatabase = get() val playlistRepository = get<RoomPlaylistRepository>()
lifecycleScope.launch { lifecycleScope.launch {
println("Size:${database.playlistDao().playlistsWithSong()}") println("Size:${playlistRepository.playlistWithSongs()}")
} }
} }
override fun onSupportNavigateUp(): Boolean = override fun onSupportNavigateUp(): Boolean =

View file

@ -13,22 +13,21 @@ import androidx.appcompat.widget.PopupMenu
import androidx.core.os.bundleOf import androidx.core.os.bundleOf
import androidx.fragment.app.FragmentActivity import androidx.fragment.app.FragmentActivity
import androidx.navigation.findNavController import androidx.navigation.findNavController
import code.name.monkey.appthemehelper.ThemeStore
import code.name.monkey.appthemehelper.util.ATHUtil import code.name.monkey.appthemehelper.util.ATHUtil
import code.name.monkey.appthemehelper.util.TintHelper import code.name.monkey.appthemehelper.util.TintHelper
import code.name.monkey.retromusic.EXTRA_PLAYLIST import code.name.monkey.retromusic.EXTRA_PLAYLIST
import code.name.monkey.retromusic.R import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.adapter.base.AbsMultiSelectAdapter import code.name.monkey.retromusic.adapter.base.AbsMultiSelectAdapter
import code.name.monkey.retromusic.adapter.base.MediaEntryViewHolder import code.name.monkey.retromusic.adapter.base.MediaEntryViewHolder
import code.name.monkey.retromusic.db.PlaylistEntity
import code.name.monkey.retromusic.db.PlaylistWithSongs
import code.name.monkey.retromusic.db.SongEntity
import code.name.monkey.retromusic.extensions.hide import code.name.monkey.retromusic.extensions.hide
import code.name.monkey.retromusic.extensions.show import code.name.monkey.retromusic.extensions.show
import code.name.monkey.retromusic.helper.menu.PlaylistMenuHelper
import code.name.monkey.retromusic.helper.menu.SongsMenuHelper import code.name.monkey.retromusic.helper.menu.SongsMenuHelper
import code.name.monkey.retromusic.interfaces.CabHolder import code.name.monkey.retromusic.interfaces.CabHolder
import code.name.monkey.retromusic.model.AbsCustomPlaylist
import code.name.monkey.retromusic.model.Playlist import code.name.monkey.retromusic.model.Playlist
import code.name.monkey.retromusic.model.Song import code.name.monkey.retromusic.model.Song
import code.name.monkey.retromusic.model.smartplaylist.AbsSmartPlaylist
import code.name.monkey.retromusic.repository.PlaylistSongsLoader import code.name.monkey.retromusic.repository.PlaylistSongsLoader
import code.name.monkey.retromusic.util.AutoGeneratedPlaylistBitmap import code.name.monkey.retromusic.util.AutoGeneratedPlaylistBitmap
import code.name.monkey.retromusic.util.MusicUtil import code.name.monkey.retromusic.util.MusicUtil
@ -37,10 +36,10 @@ import java.util.*
class PlaylistAdapter( class PlaylistAdapter(
private val activity: FragmentActivity, private val activity: FragmentActivity,
var dataSet: List<Playlist>, var dataSet: List<PlaylistWithSongs>,
private var itemLayoutRes: Int, private var itemLayoutRes: Int,
cabHolder: CabHolder? cabHolder: CabHolder?
) : AbsMultiSelectAdapter<PlaylistAdapter.ViewHolder, Playlist>( ) : AbsMultiSelectAdapter<PlaylistAdapter.ViewHolder, PlaylistWithSongs>(
activity, activity,
cabHolder, cabHolder,
R.menu.menu_playlists_selection R.menu.menu_playlists_selection
@ -51,13 +50,13 @@ class PlaylistAdapter(
setHasStableIds(true) setHasStableIds(true)
} }
fun swapDataSet(dataSet: List<Playlist>) { fun swapDataSet(dataSet: List<PlaylistWithSongs>) {
this.dataSet = dataSet this.dataSet = dataSet
notifyDataSetChanged() notifyDataSetChanged()
} }
override fun getItemId(position: Int): Long { override fun getItemId(position: Int): Long {
return dataSet[position].id.toLong() return dataSet[position].playlistEntity.playListId.toLong()
} }
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
@ -69,18 +68,18 @@ class PlaylistAdapter(
return ViewHolder(view) return ViewHolder(view)
} }
private fun getPlaylistTitle(playlist: Playlist): String { private fun getPlaylistTitle(playlist: PlaylistEntity): String {
return if (TextUtils.isEmpty(playlist.name)) "-" else playlist.name return if (TextUtils.isEmpty(playlist.playlistName)) "-" else playlist.playlistName
} }
private fun getPlaylistText(playlist: Playlist): String { private fun getPlaylistText(playlist: PlaylistWithSongs): String {
return MusicUtil.getPlaylistInfoString(activity, getSongs(playlist)) return MusicUtil.playlistInfoString(activity, getSongs(playlist))
} }
override fun onBindViewHolder(holder: ViewHolder, position: Int) { override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val playlist = dataSet[position] val playlist = dataSet[position]
holder.itemView.isActivated = isChecked(playlist) holder.itemView.isActivated = isChecked(playlist)
holder.title?.text = getPlaylistTitle(playlist) holder.title?.text = getPlaylistTitle(playlist.playlistEntity)
holder.text?.text = getPlaylistText(playlist) holder.text?.text = getPlaylistText(playlist)
holder.image?.setImageDrawable(getIconRes(playlist)) holder.image?.setImageDrawable(getIconRes(playlist))
val isChecked = isChecked(playlist) val isChecked = isChecked(playlist)
@ -92,37 +91,34 @@ class PlaylistAdapter(
//PlaylistBitmapLoader(this, holder, playlist).execute() //PlaylistBitmapLoader(this, holder, playlist).execute()
} }
private fun getIconRes(playlist: Playlist): Drawable { private fun getIconRes(playlist: PlaylistWithSongs): Drawable {
return if (MusicUtil.isFavoritePlaylist(activity, playlist)) return/* if (MusicUtil.isFavoritePlaylist(activity, playlist))
TintHelper.createTintedDrawable( TintHelper.createTintedDrawable(
activity, activity,
R.drawable.ic_favorite, R.drawable.ic_favorite,
ThemeStore.accentColor(activity) ThemeStore.accentColor(activity)
) )
else TintHelper.createTintedDrawable( else*/ TintHelper.createTintedDrawable(
activity, activity,
R.drawable.ic_playlist_play, R.drawable.ic_playlist_play,
ATHUtil.resolveColor(activity, R.attr.colorControlNormal) ATHUtil.resolveColor(activity, R.attr.colorControlNormal)
) )
} }
override fun getItemViewType(position: Int): Int {
return if (dataSet[position] is AbsSmartPlaylist) SMART_PLAYLIST else DEFAULT_PLAYLIST
}
override fun getItemCount(): Int { override fun getItemCount(): Int {
return dataSet.size return dataSet.size
} }
override fun getIdentifier(position: Int): Playlist? { override fun getIdentifier(position: Int): PlaylistWithSongs? {
return dataSet[position] return dataSet[position]
} }
override fun getName(playlist: Playlist): String { override fun getName(playlist: PlaylistWithSongs): String {
return playlist.name return playlist.playlistEntity.playlistName
} }
override fun onMultipleItemAction(menuItem: MenuItem, selection: List<Playlist>) { override fun onMultipleItemAction(menuItem: MenuItem, selection: List<PlaylistWithSongs>) {
when (menuItem.itemId) { when (menuItem.itemId) {
else -> SongsMenuHelper.handleMenuClick( else -> SongsMenuHelper.handleMenuClick(
activity, activity,
@ -132,25 +128,27 @@ class PlaylistAdapter(
} }
} }
private fun getSongList(playlists: List<Playlist>): List<Song> { private fun getSongList(playlists: List<PlaylistWithSongs>): List<Song> {
val songs = ArrayList<Song>() val songs = ArrayList<Song>()
for (playlist in playlists) { /* for (playlist in playlists) {
songs.addAll(playlist.songs)
if (playlist is AbsCustomPlaylist) { if (playlist is AbsCustomPlaylist) {
songs.addAll(playlist.songs()) songs.addAll(playlist.songs())
} else { } else {
songs.addAll(PlaylistSongsLoader.getPlaylistSongList(activity, playlist.id)) songs.addAll(PlaylistSongsLoader.getPlaylistSongList(activity, playlist.id))
} }
} }*/
return songs return songs
} }
private fun getSongs(playlist: Playlist): List<Song> { private fun getSongs(playlist: PlaylistWithSongs): List<SongEntity> {
val songs = ArrayList<Song>() val songs = ArrayList<SongEntity>()
if (playlist is AbsSmartPlaylist) { songs.addAll(playlist.songs)
/*if (playlist is AbsSmartPlaylist) {
songs.addAll(playlist.songs()) songs.addAll(playlist.songs())
} else { } else {
songs.addAll(playlist.getSongs()) songs.addAll(playlist.getSongs())
} }*/
return songs return songs
} }
@ -167,7 +165,7 @@ class PlaylistAdapter(
val popupMenu = PopupMenu(activity, view) val popupMenu = PopupMenu(activity, view)
popupMenu.inflate(R.menu.menu_item_playlist) popupMenu.inflate(R.menu.menu_item_playlist)
popupMenu.setOnMenuItemClickListener { item -> popupMenu.setOnMenuItemClickListener { item ->
PlaylistMenuHelper.handleMenuClick(activity, dataSet[layoutPosition], item) return@setOnMenuItemClickListener true //PlaylistMenuHelper.handleMenuClick(activity, dataSet[layoutPosition], item)
} }
popupMenu.show() popupMenu.show()
} }

View file

@ -4,6 +4,10 @@ import androidx.room.*
@Dao @Dao
interface PlaylistDao { interface PlaylistDao {
@Query("SELECT * FROM PlaylistEntity WHERE playlist_name = :name")
suspend fun checkPlaylistExists(name: String): List<PlaylistEntity>
@Insert @Insert
suspend fun createPlaylist(playlistEntity: PlaylistEntity) suspend fun createPlaylist(playlistEntity: PlaylistEntity)
@ -16,4 +20,7 @@ interface PlaylistDao {
@Insert(onConflict = OnConflictStrategy.REPLACE) @Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun insertSongs(songEntities: List<SongEntity>) suspend fun insertSongs(songEntities: List<SongEntity>)
@Query("SELECT * FROM SongEntity WHERE playlist_creator_id = :playlistName AND song_id = :songId")
suspend fun checkSongExistsWithPlaylistName(playlistName: String, songId: Int): List<SongEntity>
} }

View file

@ -7,7 +7,7 @@ import androidx.room.RoomDatabase
@Database( @Database(
entities = [PlaylistEntity::class, SongEntity::class], entities = [PlaylistEntity::class, SongEntity::class],
version = 4, version = 7,
exportSchema = false exportSchema = false
) )
abstract class PlaylistDatabase : RoomDatabase() { abstract class PlaylistDatabase : RoomDatabase() {

View file

@ -9,7 +9,10 @@ import kotlinx.android.parcel.Parcelize
@Entity @Entity
@Parcelize @Parcelize
class PlaylistEntity( class PlaylistEntity(
@PrimaryKey
@ColumnInfo(name = "playlist_name") @ColumnInfo(name = "playlist_name")
val playlistName: String val playlistName: String
) : Parcelable ) : Parcelable {
@PrimaryKey(autoGenerate = true)
@ColumnInfo(name = "playlist_id")
var playListId: Int = 0
}

View file

@ -6,7 +6,7 @@ import androidx.room.Relation
data class PlaylistWithSongs( data class PlaylistWithSongs(
@Embedded val playlistEntity: PlaylistEntity, @Embedded val playlistEntity: PlaylistEntity,
@Relation( @Relation(
parentColumn = "playlist_name", parentColumn = "playlist_id",
entityColumn = "playlist_creator_name" entityColumn = "playlist_creator_id"
) val songs: List<SongEntity> ) val songs: List<SongEntity>
) )

View file

@ -2,8 +2,39 @@ package code.name.monkey.retromusic.db
import androidx.annotation.WorkerThread import androidx.annotation.WorkerThread
class RoomPlaylistRepository(private val playlistDao: PlaylistDao) {
interface RoomPlaylistRepository {
suspend fun createPlaylist(playlistEntity: PlaylistEntity)
suspend fun checkPlaylistExists(playlistName: String): List<PlaylistEntity>
suspend fun playlists(): List<PlaylistEntity>
suspend fun playlistWithSongs(): List<PlaylistWithSongs>
suspend fun insertSongs(songs: List<SongEntity>)
}
class RealRoomPlaylistRepository(private val playlistDao: PlaylistDao) : RoomPlaylistRepository {
@WorkerThread
override suspend fun createPlaylist(playlistEntity: PlaylistEntity) =
playlistDao.createPlaylist(playlistEntity)
@WorkerThread @WorkerThread
suspend fun getPlaylistWithSongs(): List<PlaylistWithSongs> = playlistDao.playlistsWithSong() override suspend fun checkPlaylistExists(playlistName: String): List<PlaylistEntity> =
playlistDao.checkPlaylistExists(playlistName)
@WorkerThread
override suspend fun playlists(): List<PlaylistEntity> = playlistDao.playlists()
@WorkerThread
override suspend fun playlistWithSongs(): List<PlaylistWithSongs> =
playlistDao.playlistsWithSong()
@WorkerThread
override suspend fun insertSongs(songs: List<SongEntity>) {
/* val tempList = ArrayList<SongEntity>(songs)
val existingSongs = songs.map {
playlistDao.checkSongExistsWithPlaylistName(it.playlistCreatorName, it.songId)
}.first()
println("Existing ${existingSongs.size}")
tempList.removeAll(existingSongs)*/
playlistDao.insertSongs(songs)
}
} }

View file

@ -8,8 +8,8 @@ import androidx.room.PrimaryKey
class SongEntity( class SongEntity(
@ColumnInfo(name = "song_id") @ColumnInfo(name = "song_id")
val songId: Int, val songId: Int,
@ColumnInfo(name = "playlist_creator_name") @ColumnInfo(name = "playlist_creator_id")
val playlistCreatorName: String val playlistCreatorId: Int
) { ) {
@PrimaryKey(autoGenerate = true) @PrimaryKey(autoGenerate = true)
@ColumnInfo(name = "song_key") @ColumnInfo(name = "song_key")

View file

@ -6,8 +6,8 @@ import androidx.core.os.bundleOf
import androidx.fragment.app.DialogFragment import androidx.fragment.app.DialogFragment
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import code.name.monkey.retromusic.R import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.db.PlaylistDatabase
import code.name.monkey.retromusic.db.PlaylistEntity import code.name.monkey.retromusic.db.PlaylistEntity
import code.name.monkey.retromusic.db.RoomPlaylistRepository
import code.name.monkey.retromusic.db.SongEntity import code.name.monkey.retromusic.db.SongEntity
import code.name.monkey.retromusic.extensions.colorButtons import code.name.monkey.retromusic.extensions.colorButtons
import code.name.monkey.retromusic.extensions.extraNotNull import code.name.monkey.retromusic.extensions.extraNotNull
@ -37,15 +37,13 @@ class AddToRetroPlaylist : DialogFragment() {
return materialDialog(R.string.add_playlist_title) return materialDialog(R.string.add_playlist_title)
.setItems(playlistNames.toTypedArray()) { _, which -> .setItems(playlistNames.toTypedArray()) { _, which ->
val songs = RealSongRepository(requireContext()).songs() val songs = RealSongRepository(requireContext()).songs()
println(songs.size)
if (which == 0) { if (which == 0) {
CreateRetroPlaylist().show(requireActivity().supportFragmentManager, "Dialog") CreateRetroPlaylist().show(requireActivity().supportFragmentManager, "Dialog")
} else { } else {
lifecycleScope.launch(Dispatchers.IO) { lifecycleScope.launch(Dispatchers.IO) {
println(Thread.currentThread().name) val playlistRepository = get<RoomPlaylistRepository>()
val database: PlaylistDatabase = get()
val songEntities = songs.withPlaylistIds(playlistEntities[which - 1]) val songEntities = songs.withPlaylistIds(playlistEntities[which - 1])
database.playlistDao().insertSongs(songEntities) playlistRepository.insertSongs(songEntities)
} }
} }
dismiss() dismiss()
@ -56,7 +54,7 @@ class AddToRetroPlaylist : DialogFragment() {
private fun List<Song>.withPlaylistIds(playlistEntity: PlaylistEntity): List<SongEntity> { private fun List<Song>.withPlaylistIds(playlistEntity: PlaylistEntity): List<SongEntity> {
val songEntities = map { val songEntities = map {
SongEntity(it.id, playlistEntity.playlistName) SongEntity(it.id, playlistEntity.playListId)
} }
println(songEntities.size) println(songEntities.size)
return songEntities return songEntities

View file

@ -7,8 +7,8 @@ import android.view.LayoutInflater
import androidx.fragment.app.DialogFragment import androidx.fragment.app.DialogFragment
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import code.name.monkey.retromusic.R import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.db.PlaylistDatabase
import code.name.monkey.retromusic.db.PlaylistEntity import code.name.monkey.retromusic.db.PlaylistEntity
import code.name.monkey.retromusic.db.RoomPlaylistRepository
import code.name.monkey.retromusic.extensions.colorButtons import code.name.monkey.retromusic.extensions.colorButtons
import code.name.monkey.retromusic.extensions.materialDialog import code.name.monkey.retromusic.extensions.materialDialog
import com.google.android.material.textfield.TextInputEditText import com.google.android.material.textfield.TextInputEditText
@ -29,9 +29,13 @@ class CreateRetroPlaylist : DialogFragment() {
) { _, _ -> ) { _, _ ->
val playlistName = playlistView.text.toString() val playlistName = playlistView.text.toString()
if (!TextUtils.isEmpty(playlistName)) { if (!TextUtils.isEmpty(playlistName)) {
val database: PlaylistDatabase = get() val playlistRepository: RoomPlaylistRepository = get()
lifecycleScope.launch { lifecycleScope.launch {
database.playlistDao().createPlaylist(PlaylistEntity(playlistName)) if (playlistRepository.checkPlaylistExists(playlistName).isEmpty()) {
playlistRepository.createPlaylist(PlaylistEntity(playlistName))
} else {
println("Playlist exists")
}
} }
} else { } else {
playlistContainer.error = "Playlist is can't be empty" playlistContainer.error = "Playlist is can't be empty"

View file

@ -4,6 +4,7 @@ import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import code.name.monkey.retromusic.db.PlaylistWithSongs
import code.name.monkey.retromusic.fragments.ReloadType.* import code.name.monkey.retromusic.fragments.ReloadType.*
import code.name.monkey.retromusic.interfaces.MusicServiceEventListener import code.name.monkey.retromusic.interfaces.MusicServiceEventListener
import code.name.monkey.retromusic.model.* import code.name.monkey.retromusic.model.*
@ -22,6 +23,7 @@ class LibraryViewModel(
private val songs = MutableLiveData<List<Song>>() private val songs = MutableLiveData<List<Song>>()
private val artists = MutableLiveData<List<Artist>>() private val artists = MutableLiveData<List<Artist>>()
private val playlists = MutableLiveData<List<Playlist>>() private val playlists = MutableLiveData<List<Playlist>>()
private val roomPlaylists = MutableLiveData<List<PlaylistWithSongs>>()
private val genres = MutableLiveData<List<Genre>>() private val genres = MutableLiveData<List<Genre>>()
private val home = MutableLiveData<List<Home>>() private val home = MutableLiveData<List<Home>>()
@ -31,6 +33,7 @@ class LibraryViewModel(
val songsLiveData: LiveData<List<Song>> = songs val songsLiveData: LiveData<List<Song>> = songs
val artistsLiveData: LiveData<List<Artist>> = artists val artistsLiveData: LiveData<List<Artist>> = artists
val playlisitsLiveData: LiveData<List<Playlist>> = playlists val playlisitsLiveData: LiveData<List<Playlist>> = playlists
val roomPlaylisitsLiveData: LiveData<List<PlaylistWithSongs>> = roomPlaylists
val genresLiveData: LiveData<List<Genre>> = genres val genresLiveData: LiveData<List<Genre>> = genres
init { init {
@ -44,7 +47,8 @@ class LibraryViewModel(
albums.value = loadAlbums.await() albums.value = loadAlbums.await()
artists.value = loadArtists.await() artists.value = loadArtists.await()
playlists.value = loadPlaylists.await() playlists.value = loadPlaylists.await()
genres.value = loadGenres.await() roomPlaylists.value = loadPlaylistsWithSongs.await()
//genres.value = loadGenres.await()
home.value = loadHome.await() home.value = loadHome.await()
} }
@ -68,6 +72,10 @@ class LibraryViewModel(
get() = viewModelScope.async(IO) { get() = viewModelScope.async(IO) {
realRepository.allPlaylists() realRepository.allPlaylists()
} }
private val loadPlaylistsWithSongs: Deferred<List<PlaylistWithSongs>>
get() = viewModelScope.async(IO) {
realRepository.playlistWithSongs()
}
private val loadGenres: Deferred<List<Genre>> private val loadGenres: Deferred<List<Genre>>
get() = viewModelScope.async(IO) { get() = viewModelScope.async(IO) {
@ -80,7 +88,7 @@ class LibraryViewModel(
Songs -> songs.value = loadSongs.await() Songs -> songs.value = loadSongs.await()
Albums -> albums.value = loadAlbums.await() Albums -> albums.value = loadAlbums.await()
Artists -> artists.value = loadArtists.await() Artists -> artists.value = loadArtists.await()
HomeSections -> songs.value = loadSongs.await() HomeSections -> home.value = loadHome.await()
} }
} }

View file

@ -10,7 +10,7 @@ import androidx.navigation.ui.NavigationUI
import code.name.monkey.appthemehelper.common.ATHToolbarActivity.getToolbarBackgroundColor import code.name.monkey.appthemehelper.common.ATHToolbarActivity.getToolbarBackgroundColor
import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper
import code.name.monkey.retromusic.R import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.db.PlaylistDatabase import code.name.monkey.retromusic.db.RoomPlaylistRepository
import code.name.monkey.retromusic.dialogs.AddToRetroPlaylist import code.name.monkey.retromusic.dialogs.AddToRetroPlaylist
import code.name.monkey.retromusic.extensions.findNavController import code.name.monkey.retromusic.extensions.findNavController
import code.name.monkey.retromusic.fragments.base.AbsMainActivityFragment import code.name.monkey.retromusic.fragments.base.AbsMainActivityFragment
@ -63,8 +63,8 @@ class LibraryFragment : AbsMainActivityFragment(R.layout.fragment_library) {
R.id.action_settings -> R.id.action_settings ->
//CreateRetroPlaylist().show(childFragmentManager, "Dialog") //CreateRetroPlaylist().show(childFragmentManager, "Dialog")
lifecycleScope.launch { lifecycleScope.launch {
val database = get<PlaylistDatabase>() val playlistRepository = get<RoomPlaylistRepository>()
AddToRetroPlaylist.getInstance(database.playlistDao().playlists()) AddToRetroPlaylist.getInstance(playlistRepository.playlists())
.show(childFragmentManager, "PlaylistDialog") .show(childFragmentManager, "PlaylistDialog")
} }

View file

@ -19,7 +19,7 @@ class PlaylistsFragment :
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
libraryViewModel.playlisitsLiveData.observe(viewLifecycleOwner, Observer { libraryViewModel.roomPlaylisitsLiveData.observe(viewLifecycleOwner, Observer {
if (it.isNotEmpty()) if (it.isNotEmpty())
adapter?.swapDataSet(it) adapter?.swapDataSet(it)
else else
@ -43,6 +43,7 @@ class PlaylistsFragment :
) )
} }
companion object { companion object {
fun newInstance(): PlaylistsFragment { fun newInstance(): PlaylistsFragment {
return PlaylistsFragment() return PlaylistsFragment()

View file

@ -16,6 +16,8 @@ package code.name.monkey.retromusic.repository
import android.content.Context import android.content.Context
import code.name.monkey.retromusic.* import code.name.monkey.retromusic.*
import code.name.monkey.retromusic.db.PlaylistWithSongs
import code.name.monkey.retromusic.db.RoomPlaylistRepository
import code.name.monkey.retromusic.model.* import code.name.monkey.retromusic.model.*
import code.name.monkey.retromusic.model.smartplaylist.NotPlayedPlaylist import code.name.monkey.retromusic.model.smartplaylist.NotPlayedPlaylist
import code.name.monkey.retromusic.network.LastFMService import code.name.monkey.retromusic.network.LastFMService
@ -82,6 +84,10 @@ interface Repository {
suspend fun homeSectionsFlow(): Flow<Result<List<Home>>> suspend fun homeSectionsFlow(): Flow<Result<List<Home>>>
suspend fun playlist(playlistId: Int): Playlist
suspend fun playlistWithSongs(): List<PlaylistWithSongs>
fun songsFlow(): Flow<Result<List<Song>>> fun songsFlow(): Flow<Result<List<Song>>>
fun albumsFlow(): Flow<Result<List<Album>>> fun albumsFlow(): Flow<Result<List<Album>>>
@ -92,7 +98,6 @@ interface Repository {
fun genresFlow(): Flow<Result<List<Genre>>> fun genresFlow(): Flow<Result<List<Genre>>>
suspend fun playlist(playlistId: Int): Playlist
} }
class RealRepository( class RealRepository(
@ -105,7 +110,8 @@ class RealRepository(
private val lastAddedRepository: LastAddedRepository, private val lastAddedRepository: LastAddedRepository,
private val playlistRepository: PlaylistRepository, private val playlistRepository: PlaylistRepository,
private val searchRepository: RealSearchRepository, private val searchRepository: RealSearchRepository,
private val playedTracksRepository: TopPlayedRepository private val playedTracksRepository: TopPlayedRepository,
private val roomPlaylistRepository: RoomPlaylistRepository
) : Repository { ) : Repository {
override suspend fun allAlbums(): List<Album> = albumRepository.albums() override suspend fun allAlbums(): List<Album> = albumRepository.albums()
@ -214,6 +220,9 @@ class RealRepository(
override suspend fun playlist(playlistId: Int) = override suspend fun playlist(playlistId: Int) =
playlistRepository.playlist(playlistId) playlistRepository.playlist(playlistId)
override suspend fun playlistWithSongs(): List<PlaylistWithSongs> =
roomPlaylistRepository.playlistWithSongs()
override suspend fun suggestionsHome(): Home { override suspend fun suggestionsHome(): Home {
val songs = val songs =
NotPlayedPlaylist().songs().shuffled().takeIf { NotPlayedPlaylist().songs().shuffled().takeIf {

View file

@ -13,6 +13,7 @@ import android.widget.Toast
import androidx.core.content.FileProvider import androidx.core.content.FileProvider
import androidx.fragment.app.FragmentActivity import androidx.fragment.app.FragmentActivity
import code.name.monkey.retromusic.R import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.db.SongEntity
import code.name.monkey.retromusic.helper.MusicPlayerRemote.removeFromQueue import code.name.monkey.retromusic.helper.MusicPlayerRemote.removeFromQueue
import code.name.monkey.retromusic.model.Artist import code.name.monkey.retromusic.model.Artist
import code.name.monkey.retromusic.model.Playlist import code.name.monkey.retromusic.model.Playlist
@ -189,6 +190,13 @@ object MusicUtil : KoinComponent {
) )
} }
fun playlistInfoString(
context: Context,
songs: List<SongEntity>
): String {
return getSongCountString(context, songs.size)
}
fun getReadableDurationString(songDurationMillis: Long): String? { fun getReadableDurationString(songDurationMillis: Long): String? {
var minutes = songDurationMillis / 1000 / 60 var minutes = songDurationMillis / 1000 / 60
val seconds = songDurationMillis / 1000 % 60 val seconds = songDurationMillis / 1000 % 60