Changes Playlist to PlaylistEntity
This commit is contained in:
parent
b5e07a31d8
commit
a93dcb0285
14 changed files with 115 additions and 89 deletions
|
@ -1,6 +1,7 @@
|
|||
package code.name.monkey.retromusic
|
||||
|
||||
import code.name.monkey.retromusic.db.PlaylistDatabase
|
||||
import code.name.monkey.retromusic.db.PlaylistWithSongs
|
||||
import code.name.monkey.retromusic.db.RealRoomPlaylistRepository
|
||||
import code.name.monkey.retromusic.db.RoomPlaylistRepository
|
||||
import code.name.monkey.retromusic.fragments.LibraryViewModel
|
||||
|
@ -10,7 +11,6 @@ import code.name.monkey.retromusic.fragments.genres.GenreDetailsViewModel
|
|||
import code.name.monkey.retromusic.fragments.playlists.PlaylistDetailsViewModel
|
||||
import code.name.monkey.retromusic.fragments.search.SearchViewModel
|
||||
import code.name.monkey.retromusic.model.Genre
|
||||
import code.name.monkey.retromusic.model.Playlist
|
||||
import code.name.monkey.retromusic.network.networkModule
|
||||
import code.name.monkey.retromusic.repository.*
|
||||
import org.koin.android.ext.koin.androidContext
|
||||
|
@ -100,7 +100,7 @@ private val viewModules = module {
|
|||
)
|
||||
}
|
||||
|
||||
viewModel { (playlist: Playlist) ->
|
||||
viewModel { (playlist: PlaylistWithSongs) ->
|
||||
PlaylistDetailsViewModel(
|
||||
get(),
|
||||
playlist
|
||||
|
|
|
@ -10,7 +10,6 @@ import android.view.View
|
|||
import androidx.lifecycle.lifecycleScope
|
||||
import code.name.monkey.retromusic.*
|
||||
import code.name.monkey.retromusic.activities.base.AbsSlidingMusicPanelActivity
|
||||
import code.name.monkey.retromusic.db.RoomPlaylistRepository
|
||||
import code.name.monkey.retromusic.extensions.findNavController
|
||||
import code.name.monkey.retromusic.fragments.LibraryViewModel
|
||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote.openAndShuffleQueue
|
||||
|
@ -26,7 +25,6 @@ import code.name.monkey.retromusic.util.AppRater.appLaunched
|
|||
import code.name.monkey.retromusic.util.PreferenceUtil
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import org.koin.android.ext.android.get
|
||||
import org.koin.android.ext.android.inject
|
||||
import java.util.*
|
||||
|
||||
|
@ -57,11 +55,6 @@ class MainActivity : AbsSlidingMusicPanelActivity(), OnSharedPreferenceChangeLis
|
|||
appLaunched(this)
|
||||
addMusicServiceEventListener(libraryViewModel)
|
||||
updateTabs()
|
||||
|
||||
val playlistRepository = get<RoomPlaylistRepository>()
|
||||
lifecycleScope.launch {
|
||||
println("Size:${playlistRepository.playlistWithSongs()}")
|
||||
}
|
||||
}
|
||||
|
||||
override fun onSupportNavigateUp(): Boolean =
|
||||
|
|
|
@ -9,7 +9,7 @@ interface PlaylistDao {
|
|||
suspend fun checkPlaylistExists(name: String): List<PlaylistEntity>
|
||||
|
||||
@Insert
|
||||
suspend fun createPlaylist(playlistEntity: PlaylistEntity)
|
||||
suspend fun createPlaylist(playlistEntity: PlaylistEntity): Long
|
||||
|
||||
@Query("SELECT * FROM PlaylistEntity")
|
||||
suspend fun playlists(): List<PlaylistEntity>
|
||||
|
@ -23,4 +23,7 @@ interface PlaylistDao {
|
|||
|
||||
@Query("SELECT * FROM SongEntity WHERE playlist_creator_id = :playlistName AND song_id = :songId")
|
||||
suspend fun checkSongExistsWithPlaylistName(playlistName: String, songId: Int): List<SongEntity>
|
||||
|
||||
@Query("SELECT * FROM SongEntity WHERE playlist_creator_id = :playlistId ORDER BY song_key")
|
||||
suspend fun getSongs(playlistId: Int): List<SongEntity>
|
||||
}
|
|
@ -1,12 +1,16 @@
|
|||
package code.name.monkey.retromusic.db
|
||||
|
||||
import android.os.Parcelable
|
||||
import androidx.room.Embedded
|
||||
import androidx.room.Relation
|
||||
import kotlinx.android.parcel.Parcelize
|
||||
|
||||
@Parcelize
|
||||
data class PlaylistWithSongs(
|
||||
@Embedded val playlistEntity: PlaylistEntity,
|
||||
@Relation(
|
||||
parentColumn = "playlist_id",
|
||||
entityColumn = "playlist_creator_id"
|
||||
) val songs: List<SongEntity>
|
||||
)
|
||||
val songs: List<SongEntity>
|
||||
):Parcelable
|
|
@ -4,16 +4,17 @@ import androidx.annotation.WorkerThread
|
|||
|
||||
|
||||
interface RoomPlaylistRepository {
|
||||
suspend fun createPlaylist(playlistEntity: PlaylistEntity)
|
||||
suspend fun createPlaylist(playlistEntity: PlaylistEntity): Long
|
||||
suspend fun checkPlaylistExists(playlistName: String): List<PlaylistEntity>
|
||||
suspend fun playlists(): List<PlaylistEntity>
|
||||
suspend fun playlistWithSongs(): List<PlaylistWithSongs>
|
||||
suspend fun insertSongs(songs: List<SongEntity>)
|
||||
suspend fun getSongs(playlistEntity: PlaylistEntity): List<SongEntity>
|
||||
}
|
||||
|
||||
class RealRoomPlaylistRepository(private val playlistDao: PlaylistDao) : RoomPlaylistRepository {
|
||||
@WorkerThread
|
||||
override suspend fun createPlaylist(playlistEntity: PlaylistEntity) =
|
||||
override suspend fun createPlaylist(playlistEntity: PlaylistEntity): Long =
|
||||
playlistDao.createPlaylist(playlistEntity)
|
||||
|
||||
@WorkerThread
|
||||
|
@ -37,4 +38,8 @@ class RealRoomPlaylistRepository(private val playlistDao: PlaylistDao) : RoomPla
|
|||
tempList.removeAll(existingSongs)*/
|
||||
playlistDao.insertSongs(songs)
|
||||
}
|
||||
|
||||
override suspend fun getSongs(playlistEntity: PlaylistEntity): List<SongEntity> {
|
||||
return playlistDao.getSongs(playlistEntity.playListId)
|
||||
}
|
||||
}
|
|
@ -1,16 +1,19 @@
|
|||
package code.name.monkey.retromusic.db
|
||||
|
||||
import android.os.Parcelable
|
||||
import androidx.room.ColumnInfo
|
||||
import androidx.room.Entity
|
||||
import androidx.room.PrimaryKey
|
||||
import kotlinx.android.parcel.Parcelize
|
||||
|
||||
@Parcelize
|
||||
@Entity
|
||||
class SongEntity(
|
||||
@ColumnInfo(name = "song_id")
|
||||
val songId: Int,
|
||||
@ColumnInfo(name = "playlist_creator_id")
|
||||
val playlistCreatorId: Int
|
||||
) {
|
||||
) : Parcelable {
|
||||
@PrimaryKey(autoGenerate = true)
|
||||
@ColumnInfo(name = "song_key")
|
||||
var songPrimaryKey: Long = 0
|
||||
|
|
|
@ -11,13 +11,18 @@ 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.materialDialog
|
||||
import code.name.monkey.retromusic.fragments.LibraryViewModel
|
||||
import code.name.monkey.retromusic.fragments.ReloadType
|
||||
import com.google.android.material.textfield.TextInputEditText
|
||||
import com.google.android.material.textfield.TextInputLayout
|
||||
import kotlinx.android.synthetic.main.dialog_playlist.view.*
|
||||
import kotlinx.coroutines.launch
|
||||
import org.koin.android.ext.android.get
|
||||
import org.koin.android.ext.android.inject
|
||||
import org.koin.androidx.viewmodel.ext.android.sharedViewModel
|
||||
|
||||
class CreateRetroPlaylist : DialogFragment() {
|
||||
private val playlistRepository by inject<RoomPlaylistRepository>()
|
||||
private val libraryViewModel by sharedViewModel<LibraryViewModel>()
|
||||
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
|
||||
val view = LayoutInflater.from(requireActivity()).inflate(R.layout.dialog_playlist, null)
|
||||
val playlistView: TextInputEditText = view.actionNewPlaylist
|
||||
|
@ -29,13 +34,16 @@ class CreateRetroPlaylist : DialogFragment() {
|
|||
) { _, _ ->
|
||||
val playlistName = playlistView.text.toString()
|
||||
if (!TextUtils.isEmpty(playlistName)) {
|
||||
val playlistRepository: RoomPlaylistRepository = get()
|
||||
lifecycleScope.launch {
|
||||
if (playlistRepository.checkPlaylistExists(playlistName).isEmpty()) {
|
||||
val id: Long =
|
||||
playlistRepository.createPlaylist(PlaylistEntity(playlistName))
|
||||
println(id)
|
||||
libraryViewModel.forceReload(ReloadType.Playlists)
|
||||
} else {
|
||||
println("Playlist exists")
|
||||
}
|
||||
|
||||
}
|
||||
} else {
|
||||
playlistContainer.error = "Playlist is can't be empty"
|
||||
|
|
|
@ -89,6 +89,8 @@ class LibraryViewModel(
|
|||
Albums -> albums.value = loadAlbums.await()
|
||||
Artists -> artists.value = loadArtists.await()
|
||||
HomeSections -> home.value = loadHome.await()
|
||||
Playlists -> roomPlaylists.value = loadPlaylistsWithSongs.await()
|
||||
Genres -> genres.value = loadGenres.await()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -136,5 +138,7 @@ enum class ReloadType {
|
|||
Songs,
|
||||
Albums,
|
||||
Artists,
|
||||
HomeSections
|
||||
HomeSections,
|
||||
Playlists,
|
||||
Genres,
|
||||
}
|
|
@ -12,11 +12,9 @@ import androidx.recyclerview.widget.RecyclerView
|
|||
import code.name.monkey.retromusic.R
|
||||
import code.name.monkey.retromusic.adapter.song.OrderablePlaylistSongAdapter
|
||||
import code.name.monkey.retromusic.adapter.song.SongAdapter
|
||||
import code.name.monkey.retromusic.db.PlaylistWithSongs
|
||||
import code.name.monkey.retromusic.extensions.dipToPix
|
||||
import code.name.monkey.retromusic.fragments.base.AbsMainActivityFragment
|
||||
import code.name.monkey.retromusic.helper.menu.PlaylistMenuHelper
|
||||
import code.name.monkey.retromusic.model.AbsCustomPlaylist
|
||||
import code.name.monkey.retromusic.model.Playlist
|
||||
import code.name.monkey.retromusic.model.Song
|
||||
import code.name.monkey.retromusic.util.PlaylistsUtil
|
||||
import com.h6ah4i.android.widget.advrecyclerview.animator.RefactoredDefaultItemAnimator
|
||||
|
@ -32,7 +30,7 @@ class PlaylistDetailsFragment : AbsMainActivityFragment(R.layout.fragment_playli
|
|||
parametersOf(arguments.extraPlaylist)
|
||||
}
|
||||
|
||||
private lateinit var playlist: Playlist
|
||||
private lateinit var playlist: PlaylistWithSongs
|
||||
private lateinit var adapter: SongAdapter
|
||||
|
||||
private var wrappedAdapter: RecyclerView.Adapter<*>? = null
|
||||
|
@ -46,25 +44,21 @@ class PlaylistDetailsFragment : AbsMainActivityFragment(R.layout.fragment_playli
|
|||
mainActivity.hideBottomBarVisibility(false)
|
||||
|
||||
playlist = arguments.extraPlaylist
|
||||
toolbar.title = playlist.playlistEntity.playlistName
|
||||
|
||||
setUpRecyclerView()
|
||||
|
||||
viewModel.getSongs().observe(viewLifecycleOwner, Observer {
|
||||
songs(it)
|
||||
})
|
||||
|
||||
viewModel.getPlaylist().observe(viewLifecycleOwner, Observer {
|
||||
playlist = it
|
||||
toolbar.title = it.name
|
||||
})
|
||||
}
|
||||
|
||||
private fun setUpRecyclerView() {
|
||||
recyclerView.layoutManager = LinearLayoutManager(requireContext())
|
||||
if (playlist is AbsCustomPlaylist) {
|
||||
/*if (playlist is AbsCustomPlaylist) {
|
||||
adapter = SongAdapter(requireActivity(), ArrayList(), R.layout.item_list, null)
|
||||
recyclerView.adapter = adapter
|
||||
} else {
|
||||
} else {*/
|
||||
recyclerViewDragDropManager = RecyclerViewDragDropManager()
|
||||
val animator = RefactoredDefaultItemAnimator()
|
||||
adapter = OrderablePlaylistSongAdapter(requireActivity(),
|
||||
|
@ -75,7 +69,7 @@ class PlaylistDetailsFragment : AbsMainActivityFragment(R.layout.fragment_playli
|
|||
override fun onMoveItem(fromPosition: Int, toPosition: Int) {
|
||||
if (PlaylistsUtil.moveItem(
|
||||
requireContext(),
|
||||
playlist.id,
|
||||
playlist.playlistEntity.playListId,
|
||||
fromPosition,
|
||||
toPosition
|
||||
)
|
||||
|
@ -92,7 +86,7 @@ class PlaylistDetailsFragment : AbsMainActivityFragment(R.layout.fragment_playli
|
|||
recyclerView.itemAnimator = animator
|
||||
|
||||
recyclerViewDragDropManager?.attachRecyclerView(recyclerView)
|
||||
}
|
||||
|
||||
adapter.registerAdapterDataObserver(object : RecyclerView.AdapterDataObserver() {
|
||||
override fun onChanged() {
|
||||
super.onChanged()
|
||||
|
@ -103,14 +97,14 @@ class PlaylistDetailsFragment : AbsMainActivityFragment(R.layout.fragment_playli
|
|||
|
||||
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
|
||||
super.onCreateOptionsMenu(menu, inflater)
|
||||
val menuRes = if (playlist is AbsCustomPlaylist)
|
||||
val menuRes =/* if (playlist is AbsCustomPlaylist)
|
||||
R.menu.menu_smart_playlist_detail
|
||||
else R.menu.menu_playlist_detail
|
||||
else*/ R.menu.menu_playlist_detail
|
||||
inflater.inflate(menuRes, menu)
|
||||
}
|
||||
|
||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||
return PlaylistMenuHelper.handleMenuClick(requireActivity(), playlist, item)
|
||||
return true//PlaylistMenuHelper.handleMenuClick(requireActivity(), playlist, item)
|
||||
}
|
||||
|
||||
private fun checkForPadding() {
|
||||
|
@ -160,11 +154,11 @@ class PlaylistDetailsFragment : AbsMainActivityFragment(R.layout.fragment_playli
|
|||
}
|
||||
|
||||
fun songs(songs: List<Song>) {
|
||||
progressIndicator.hide()
|
||||
if (songs.isNotEmpty()) {
|
||||
adapter.swapDataSet(songs)
|
||||
} else {
|
||||
showEmptyView()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -4,27 +4,26 @@ import androidx.lifecycle.LiveData
|
|||
import androidx.lifecycle.MutableLiveData
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import code.name.monkey.retromusic.App
|
||||
import code.name.monkey.retromusic.db.PlaylistWithSongs
|
||||
import code.name.monkey.retromusic.interfaces.MusicServiceEventListener
|
||||
import code.name.monkey.retromusic.model.AbsCustomPlaylist
|
||||
import code.name.monkey.retromusic.model.Playlist
|
||||
import code.name.monkey.retromusic.model.Song
|
||||
import code.name.monkey.retromusic.repository.RealRepository
|
||||
import code.name.monkey.retromusic.util.PlaylistsUtil
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Dispatchers.Main
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
|
||||
class PlaylistDetailsViewModel(
|
||||
private val realRepository: RealRepository,
|
||||
private var playlist: Playlist
|
||||
private var playlist: PlaylistWithSongs
|
||||
) : ViewModel(), MusicServiceEventListener {
|
||||
|
||||
private val _playListSongs = MutableLiveData<List<Song>>()
|
||||
private val _playlist = MutableLiveData<Playlist>().apply {
|
||||
private val _playlist = MutableLiveData<PlaylistWithSongs>().apply {
|
||||
postValue(playlist)
|
||||
}
|
||||
|
||||
fun getPlaylist(): LiveData<Playlist> = _playlist
|
||||
fun getPlaylist(): LiveData<PlaylistWithSongs> = _playlist
|
||||
|
||||
fun getSongs(): LiveData<List<Song>> = _playListSongs
|
||||
|
||||
|
@ -32,13 +31,13 @@ class PlaylistDetailsViewModel(
|
|||
loadPlaylistSongs(playlist)
|
||||
}
|
||||
|
||||
private fun loadPlaylistSongs(playlist: Playlist) = viewModelScope.launch {
|
||||
val songs = realRepository.getPlaylistSongs(playlist)
|
||||
private fun loadPlaylistSongs(playlist: PlaylistWithSongs) = viewModelScope.launch(Dispatchers.IO) {
|
||||
val songs: List<Song> = realRepository.playlistSongs(playlist)
|
||||
withContext(Main) { _playListSongs.postValue(songs) }
|
||||
}
|
||||
|
||||
override fun onMediaStoreChanged() {
|
||||
if (playlist !is AbsCustomPlaylist) {
|
||||
/*if (playlist !is AbsCustomPlaylist) {
|
||||
// Playlist deleted
|
||||
if (!PlaylistsUtil.doesPlaylistExist(App.getContext(), playlist.id)) {
|
||||
//TODO Finish the page
|
||||
|
@ -54,7 +53,7 @@ class PlaylistDetailsViewModel(
|
|||
}
|
||||
}
|
||||
}
|
||||
loadPlaylistSongs(playlist)
|
||||
loadPlaylistSongs(playlist)*/
|
||||
}
|
||||
|
||||
override fun onServiceConnected() {}
|
||||
|
|
|
@ -88,6 +88,8 @@ interface Repository {
|
|||
|
||||
suspend fun playlistWithSongs(): List<PlaylistWithSongs>
|
||||
|
||||
suspend fun playlistSongs(playlistWithSongs: PlaylistWithSongs): List<Song>
|
||||
|
||||
fun songsFlow(): Flow<Result<List<Song>>>
|
||||
|
||||
fun albumsFlow(): Flow<Result<List<Album>>>
|
||||
|
@ -223,6 +225,12 @@ class RealRepository(
|
|||
override suspend fun playlistWithSongs(): List<PlaylistWithSongs> =
|
||||
roomPlaylistRepository.playlistWithSongs()
|
||||
|
||||
override suspend fun playlistSongs(playlistWithSongs: PlaylistWithSongs ): List<Song> {
|
||||
return playlistWithSongs.songs.map {
|
||||
songRepository.song(it.songId)
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun suggestionsHome(): Home {
|
||||
val songs =
|
||||
NotPlayedPlaylist().songs().shuffled().takeIf {
|
||||
|
@ -263,7 +271,7 @@ class RealRepository(
|
|||
playlistRepository.favoritePlaylist(context.getString(R.string.favorites)).take(5)
|
||||
val songs = if (playlists.isNotEmpty())
|
||||
PlaylistSongsLoader.getPlaylistSongList(context, playlists[0])
|
||||
else emptyList<Song>()
|
||||
else emptyList()
|
||||
|
||||
return Home(songs, FAVOURITES)
|
||||
}
|
||||
|
|
|
@ -151,7 +151,7 @@ class RealSongRepository(private val context: Context) : SongRepository {
|
|||
}
|
||||
selectionFinal =
|
||||
selectionFinal + " AND " + MediaStore.Audio.Media.DURATION + ">= " + (PreferenceUtil.filterLength * 1000)
|
||||
try {
|
||||
|
||||
return context.contentResolver.query(
|
||||
MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
|
||||
baseProjection,
|
||||
|
@ -159,9 +159,6 @@ class RealSongRepository(private val context: Context) : SongRepository {
|
|||
selectionValuesFinal,
|
||||
sortOrder
|
||||
)
|
||||
} catch (e: SecurityException) {
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
private fun generateBlacklistSelection(
|
||||
|
|
|
@ -70,4 +70,12 @@
|
|||
android:textColor="?android:attr/textColorSecondary"
|
||||
tools:visibility="visible" />
|
||||
</LinearLayout>
|
||||
|
||||
<com.google.android.material.progressindicator.ProgressIndicator
|
||||
android:layout_width="100dp"
|
||||
android:id="@+id/progressIndicator"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:indeterminate="true"
|
||||
android:gravity="center" />
|
||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
|
@ -26,7 +26,7 @@
|
|||
tools:layout="@layout/fragment_playlist_detail">
|
||||
<argument
|
||||
android:name="extra_playlist"
|
||||
app:argType="code.name.monkey.retromusic.model.Playlist" />
|
||||
app:argType="code.name.monkey.retromusic.db.PlaylistWithSongs" />
|
||||
</fragment>
|
||||
|
||||
<fragment
|
||||
|
|
Loading…
Reference in a new issue