Add Room for playlist
Added DAO Queries and Able insert songs to playlist
This commit is contained in:
parent
6ace96708b
commit
b5e07a31d8
16 changed files with 140 additions and 66 deletions
|
@ -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)
|
|
@ -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 =
|
||||||
|
|
|
@ -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()
|
||||||
}
|
}
|
||||||
|
|
|
@ -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>
|
||||||
}
|
}
|
|
@ -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() {
|
||||||
|
|
|
@ -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
|
||||||
|
}
|
|
@ -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>
|
||||||
)
|
)
|
|
@ -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)
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -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")
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue