Changes Playlist to PlaylistEntity

main
Hemanth S 2020-08-20 15:22:38 +05:30
parent b5e07a31d8
commit a93dcb0285
14 changed files with 115 additions and 89 deletions

View File

@ -1,6 +1,7 @@
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.PlaylistWithSongs
import code.name.monkey.retromusic.db.RealRoomPlaylistRepository import code.name.monkey.retromusic.db.RealRoomPlaylistRepository
import code.name.monkey.retromusic.db.RoomPlaylistRepository import code.name.monkey.retromusic.db.RoomPlaylistRepository
import code.name.monkey.retromusic.fragments.LibraryViewModel 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.playlists.PlaylistDetailsViewModel
import code.name.monkey.retromusic.fragments.search.SearchViewModel import code.name.monkey.retromusic.fragments.search.SearchViewModel
import code.name.monkey.retromusic.model.Genre 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.network.networkModule
import code.name.monkey.retromusic.repository.* import code.name.monkey.retromusic.repository.*
import org.koin.android.ext.koin.androidContext import org.koin.android.ext.koin.androidContext
@ -100,7 +100,7 @@ private val viewModules = module {
) )
} }
viewModel { (playlist: Playlist) -> viewModel { (playlist: PlaylistWithSongs) ->
PlaylistDetailsViewModel( PlaylistDetailsViewModel(
get(), get(),
playlist playlist

View File

@ -10,7 +10,6 @@ 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.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
@ -26,7 +25,6 @@ import code.name.monkey.retromusic.util.AppRater.appLaunched
import code.name.monkey.retromusic.util.PreferenceUtil import code.name.monkey.retromusic.util.PreferenceUtil
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import org.koin.android.ext.android.get
import org.koin.android.ext.android.inject import org.koin.android.ext.android.inject
import java.util.* import java.util.*
@ -57,11 +55,6 @@ class MainActivity : AbsSlidingMusicPanelActivity(), OnSharedPreferenceChangeLis
appLaunched(this) appLaunched(this)
addMusicServiceEventListener(libraryViewModel) addMusicServiceEventListener(libraryViewModel)
updateTabs() updateTabs()
val playlistRepository = get<RoomPlaylistRepository>()
lifecycleScope.launch {
println("Size:${playlistRepository.playlistWithSongs()}")
}
} }
override fun onSupportNavigateUp(): Boolean = override fun onSupportNavigateUp(): Boolean =

View File

@ -9,7 +9,7 @@ interface PlaylistDao {
suspend fun checkPlaylistExists(name: String): List<PlaylistEntity> suspend fun checkPlaylistExists(name: String): List<PlaylistEntity>
@Insert @Insert
suspend fun createPlaylist(playlistEntity: PlaylistEntity) suspend fun createPlaylist(playlistEntity: PlaylistEntity): Long
@Query("SELECT * FROM PlaylistEntity") @Query("SELECT * FROM PlaylistEntity")
suspend fun playlists(): List<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") @Query("SELECT * FROM SongEntity WHERE playlist_creator_id = :playlistName AND song_id = :songId")
suspend fun checkSongExistsWithPlaylistName(playlistName: String, songId: Int): List<SongEntity> 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>
} }

View File

@ -1,12 +1,16 @@
package code.name.monkey.retromusic.db package code.name.monkey.retromusic.db
import android.os.Parcelable
import androidx.room.Embedded import androidx.room.Embedded
import androidx.room.Relation import androidx.room.Relation
import kotlinx.android.parcel.Parcelize
@Parcelize
data class PlaylistWithSongs( data class PlaylistWithSongs(
@Embedded val playlistEntity: PlaylistEntity, @Embedded val playlistEntity: PlaylistEntity,
@Relation( @Relation(
parentColumn = "playlist_id", parentColumn = "playlist_id",
entityColumn = "playlist_creator_id" entityColumn = "playlist_creator_id"
) val songs: List<SongEntity>
) )
val songs: List<SongEntity>
):Parcelable

View File

@ -4,16 +4,17 @@ import androidx.annotation.WorkerThread
interface RoomPlaylistRepository { interface RoomPlaylistRepository {
suspend fun createPlaylist(playlistEntity: PlaylistEntity) suspend fun createPlaylist(playlistEntity: PlaylistEntity): Long
suspend fun checkPlaylistExists(playlistName: String): List<PlaylistEntity> suspend fun checkPlaylistExists(playlistName: String): List<PlaylistEntity>
suspend fun playlists(): List<PlaylistEntity> suspend fun playlists(): List<PlaylistEntity>
suspend fun playlistWithSongs(): List<PlaylistWithSongs> suspend fun playlistWithSongs(): List<PlaylistWithSongs>
suspend fun insertSongs(songs: List<SongEntity>) suspend fun insertSongs(songs: List<SongEntity>)
suspend fun getSongs(playlistEntity: PlaylistEntity): List<SongEntity>
} }
class RealRoomPlaylistRepository(private val playlistDao: PlaylistDao) : RoomPlaylistRepository { class RealRoomPlaylistRepository(private val playlistDao: PlaylistDao) : RoomPlaylistRepository {
@WorkerThread @WorkerThread
override suspend fun createPlaylist(playlistEntity: PlaylistEntity) = override suspend fun createPlaylist(playlistEntity: PlaylistEntity): Long =
playlistDao.createPlaylist(playlistEntity) playlistDao.createPlaylist(playlistEntity)
@WorkerThread @WorkerThread
@ -37,4 +38,8 @@ class RealRoomPlaylistRepository(private val playlistDao: PlaylistDao) : RoomPla
tempList.removeAll(existingSongs)*/ tempList.removeAll(existingSongs)*/
playlistDao.insertSongs(songs) playlistDao.insertSongs(songs)
} }
override suspend fun getSongs(playlistEntity: PlaylistEntity): List<SongEntity> {
return playlistDao.getSongs(playlistEntity.playListId)
}
} }

View File

@ -1,16 +1,19 @@
package code.name.monkey.retromusic.db package code.name.monkey.retromusic.db
import android.os.Parcelable
import androidx.room.ColumnInfo import androidx.room.ColumnInfo
import androidx.room.Entity import androidx.room.Entity
import androidx.room.PrimaryKey import androidx.room.PrimaryKey
import kotlinx.android.parcel.Parcelize
@Parcelize
@Entity @Entity
class SongEntity( class SongEntity(
@ColumnInfo(name = "song_id") @ColumnInfo(name = "song_id")
val songId: Int, val songId: Int,
@ColumnInfo(name = "playlist_creator_id") @ColumnInfo(name = "playlist_creator_id")
val playlistCreatorId: Int val playlistCreatorId: Int
) { ) : Parcelable {
@PrimaryKey(autoGenerate = true) @PrimaryKey(autoGenerate = true)
@ColumnInfo(name = "song_key") @ColumnInfo(name = "song_key")
var songPrimaryKey: Long = 0 var songPrimaryKey: Long = 0

View File

@ -11,13 +11,18 @@ import code.name.monkey.retromusic.db.PlaylistEntity
import code.name.monkey.retromusic.db.RoomPlaylistRepository 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 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.TextInputEditText
import com.google.android.material.textfield.TextInputLayout import com.google.android.material.textfield.TextInputLayout
import kotlinx.android.synthetic.main.dialog_playlist.view.* import kotlinx.android.synthetic.main.dialog_playlist.view.*
import kotlinx.coroutines.launch 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() { class CreateRetroPlaylist : DialogFragment() {
private val playlistRepository by inject<RoomPlaylistRepository>()
private val libraryViewModel by sharedViewModel<LibraryViewModel>()
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
val view = LayoutInflater.from(requireActivity()).inflate(R.layout.dialog_playlist, null) val view = LayoutInflater.from(requireActivity()).inflate(R.layout.dialog_playlist, null)
val playlistView: TextInputEditText = view.actionNewPlaylist val playlistView: TextInputEditText = view.actionNewPlaylist
@ -29,13 +34,16 @@ class CreateRetroPlaylist : DialogFragment() {
) { _, _ -> ) { _, _ ->
val playlistName = playlistView.text.toString() val playlistName = playlistView.text.toString()
if (!TextUtils.isEmpty(playlistName)) { if (!TextUtils.isEmpty(playlistName)) {
val playlistRepository: RoomPlaylistRepository = get()
lifecycleScope.launch { lifecycleScope.launch {
if (playlistRepository.checkPlaylistExists(playlistName).isEmpty()) { if (playlistRepository.checkPlaylistExists(playlistName).isEmpty()) {
val id: Long =
playlistRepository.createPlaylist(PlaylistEntity(playlistName)) playlistRepository.createPlaylist(PlaylistEntity(playlistName))
println(id)
libraryViewModel.forceReload(ReloadType.Playlists)
} else { } else {
println("Playlist exists") println("Playlist exists")
} }
} }
} else { } else {
playlistContainer.error = "Playlist is can't be empty" playlistContainer.error = "Playlist is can't be empty"

View File

@ -89,6 +89,8 @@ class LibraryViewModel(
Albums -> albums.value = loadAlbums.await() Albums -> albums.value = loadAlbums.await()
Artists -> artists.value = loadArtists.await() Artists -> artists.value = loadArtists.await()
HomeSections -> home.value = loadHome.await() HomeSections -> home.value = loadHome.await()
Playlists -> roomPlaylists.value = loadPlaylistsWithSongs.await()
Genres -> genres.value = loadGenres.await()
} }
} }
@ -136,5 +138,7 @@ enum class ReloadType {
Songs, Songs,
Albums, Albums,
Artists, Artists,
HomeSections HomeSections,
Playlists,
Genres,
} }

View File

@ -12,11 +12,9 @@ import androidx.recyclerview.widget.RecyclerView
import code.name.monkey.retromusic.R import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.adapter.song.OrderablePlaylistSongAdapter import code.name.monkey.retromusic.adapter.song.OrderablePlaylistSongAdapter
import code.name.monkey.retromusic.adapter.song.SongAdapter 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.extensions.dipToPix
import code.name.monkey.retromusic.fragments.base.AbsMainActivityFragment 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.model.Song
import code.name.monkey.retromusic.util.PlaylistsUtil import code.name.monkey.retromusic.util.PlaylistsUtil
import com.h6ah4i.android.widget.advrecyclerview.animator.RefactoredDefaultItemAnimator import com.h6ah4i.android.widget.advrecyclerview.animator.RefactoredDefaultItemAnimator
@ -32,7 +30,7 @@ class PlaylistDetailsFragment : AbsMainActivityFragment(R.layout.fragment_playli
parametersOf(arguments.extraPlaylist) parametersOf(arguments.extraPlaylist)
} }
private lateinit var playlist: Playlist private lateinit var playlist: PlaylistWithSongs
private lateinit var adapter: SongAdapter private lateinit var adapter: SongAdapter
private var wrappedAdapter: RecyclerView.Adapter<*>? = null private var wrappedAdapter: RecyclerView.Adapter<*>? = null
@ -46,25 +44,21 @@ class PlaylistDetailsFragment : AbsMainActivityFragment(R.layout.fragment_playli
mainActivity.hideBottomBarVisibility(false) mainActivity.hideBottomBarVisibility(false)
playlist = arguments.extraPlaylist playlist = arguments.extraPlaylist
toolbar.title = playlist.playlistEntity.playlistName
setUpRecyclerView() setUpRecyclerView()
viewModel.getSongs().observe(viewLifecycleOwner, Observer { viewModel.getSongs().observe(viewLifecycleOwner, Observer {
songs(it) songs(it)
}) })
viewModel.getPlaylist().observe(viewLifecycleOwner, Observer {
playlist = it
toolbar.title = it.name
})
} }
private fun setUpRecyclerView() { private fun setUpRecyclerView() {
recyclerView.layoutManager = LinearLayoutManager(requireContext()) recyclerView.layoutManager = LinearLayoutManager(requireContext())
if (playlist is AbsCustomPlaylist) { /*if (playlist is AbsCustomPlaylist) {
adapter = SongAdapter(requireActivity(), ArrayList(), R.layout.item_list, null) adapter = SongAdapter(requireActivity(), ArrayList(), R.layout.item_list, null)
recyclerView.adapter = adapter recyclerView.adapter = adapter
} else { } else {*/
recyclerViewDragDropManager = RecyclerViewDragDropManager() recyclerViewDragDropManager = RecyclerViewDragDropManager()
val animator = RefactoredDefaultItemAnimator() val animator = RefactoredDefaultItemAnimator()
adapter = OrderablePlaylistSongAdapter(requireActivity(), adapter = OrderablePlaylistSongAdapter(requireActivity(),
@ -75,7 +69,7 @@ class PlaylistDetailsFragment : AbsMainActivityFragment(R.layout.fragment_playli
override fun onMoveItem(fromPosition: Int, toPosition: Int) { override fun onMoveItem(fromPosition: Int, toPosition: Int) {
if (PlaylistsUtil.moveItem( if (PlaylistsUtil.moveItem(
requireContext(), requireContext(),
playlist.id, playlist.playlistEntity.playListId,
fromPosition, fromPosition,
toPosition toPosition
) )
@ -92,7 +86,7 @@ class PlaylistDetailsFragment : AbsMainActivityFragment(R.layout.fragment_playli
recyclerView.itemAnimator = animator recyclerView.itemAnimator = animator
recyclerViewDragDropManager?.attachRecyclerView(recyclerView) recyclerViewDragDropManager?.attachRecyclerView(recyclerView)
}
adapter.registerAdapterDataObserver(object : RecyclerView.AdapterDataObserver() { adapter.registerAdapterDataObserver(object : RecyclerView.AdapterDataObserver() {
override fun onChanged() { override fun onChanged() {
super.onChanged() super.onChanged()
@ -103,14 +97,14 @@ class PlaylistDetailsFragment : AbsMainActivityFragment(R.layout.fragment_playli
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) { override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
super.onCreateOptionsMenu(menu, inflater) super.onCreateOptionsMenu(menu, inflater)
val menuRes = if (playlist is AbsCustomPlaylist) val menuRes =/* if (playlist is AbsCustomPlaylist)
R.menu.menu_smart_playlist_detail R.menu.menu_smart_playlist_detail
else R.menu.menu_playlist_detail else*/ R.menu.menu_playlist_detail
inflater.inflate(menuRes, menu) inflater.inflate(menuRes, menu)
} }
override fun onOptionsItemSelected(item: MenuItem): Boolean { override fun onOptionsItemSelected(item: MenuItem): Boolean {
return PlaylistMenuHelper.handleMenuClick(requireActivity(), playlist, item) return true//PlaylistMenuHelper.handleMenuClick(requireActivity(), playlist, item)
} }
private fun checkForPadding() { private fun checkForPadding() {
@ -160,11 +154,11 @@ class PlaylistDetailsFragment : AbsMainActivityFragment(R.layout.fragment_playli
} }
fun songs(songs: List<Song>) { fun songs(songs: List<Song>) {
progressIndicator.hide()
if (songs.isNotEmpty()) { if (songs.isNotEmpty()) {
adapter.swapDataSet(songs) adapter.swapDataSet(songs)
} else { } else {
showEmptyView() showEmptyView()
} }
} }
} }

View File

@ -4,27 +4,26 @@ 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.App import code.name.monkey.retromusic.db.PlaylistWithSongs
import code.name.monkey.retromusic.interfaces.MusicServiceEventListener 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.model.Song
import code.name.monkey.retromusic.repository.RealRepository 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.Dispatchers.Main
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
class PlaylistDetailsViewModel( class PlaylistDetailsViewModel(
private val realRepository: RealRepository, private val realRepository: RealRepository,
private var playlist: Playlist private var playlist: PlaylistWithSongs
) : ViewModel(), MusicServiceEventListener { ) : ViewModel(), MusicServiceEventListener {
private val _playListSongs = MutableLiveData<List<Song>>() private val _playListSongs = MutableLiveData<List<Song>>()
private val _playlist = MutableLiveData<Playlist>().apply { private val _playlist = MutableLiveData<PlaylistWithSongs>().apply {
postValue(playlist) postValue(playlist)
} }
fun getPlaylist(): LiveData<Playlist> = _playlist fun getPlaylist(): LiveData<PlaylistWithSongs> = _playlist
fun getSongs(): LiveData<List<Song>> = _playListSongs fun getSongs(): LiveData<List<Song>> = _playListSongs
@ -32,13 +31,13 @@ class PlaylistDetailsViewModel(
loadPlaylistSongs(playlist) loadPlaylistSongs(playlist)
} }
private fun loadPlaylistSongs(playlist: Playlist) = viewModelScope.launch { private fun loadPlaylistSongs(playlist: PlaylistWithSongs) = viewModelScope.launch(Dispatchers.IO) {
val songs = realRepository.getPlaylistSongs(playlist) val songs: List<Song> = realRepository.playlistSongs(playlist)
withContext(Main) { _playListSongs.postValue(songs) } withContext(Main) { _playListSongs.postValue(songs) }
} }
override fun onMediaStoreChanged() { override fun onMediaStoreChanged() {
if (playlist !is AbsCustomPlaylist) { /*if (playlist !is AbsCustomPlaylist) {
// Playlist deleted // Playlist deleted
if (!PlaylistsUtil.doesPlaylistExist(App.getContext(), playlist.id)) { if (!PlaylistsUtil.doesPlaylistExist(App.getContext(), playlist.id)) {
//TODO Finish the page //TODO Finish the page
@ -54,7 +53,7 @@ class PlaylistDetailsViewModel(
} }
} }
} }
loadPlaylistSongs(playlist) loadPlaylistSongs(playlist)*/
} }
override fun onServiceConnected() {} override fun onServiceConnected() {}

View File

@ -88,6 +88,8 @@ interface Repository {
suspend fun playlistWithSongs(): List<PlaylistWithSongs> suspend fun playlistWithSongs(): List<PlaylistWithSongs>
suspend fun playlistSongs(playlistWithSongs: PlaylistWithSongs): List<Song>
fun songsFlow(): Flow<Result<List<Song>>> fun songsFlow(): Flow<Result<List<Song>>>
fun albumsFlow(): Flow<Result<List<Album>>> fun albumsFlow(): Flow<Result<List<Album>>>
@ -223,6 +225,12 @@ class RealRepository(
override suspend fun playlistWithSongs(): List<PlaylistWithSongs> = override suspend fun playlistWithSongs(): List<PlaylistWithSongs> =
roomPlaylistRepository.playlistWithSongs() roomPlaylistRepository.playlistWithSongs()
override suspend fun playlistSongs(playlistWithSongs: PlaylistWithSongs ): List<Song> {
return playlistWithSongs.songs.map {
songRepository.song(it.songId)
}
}
override suspend fun suggestionsHome(): Home { override suspend fun suggestionsHome(): Home {
val songs = val songs =
NotPlayedPlaylist().songs().shuffled().takeIf { NotPlayedPlaylist().songs().shuffled().takeIf {
@ -263,7 +271,7 @@ class RealRepository(
playlistRepository.favoritePlaylist(context.getString(R.string.favorites)).take(5) playlistRepository.favoritePlaylist(context.getString(R.string.favorites)).take(5)
val songs = if (playlists.isNotEmpty()) val songs = if (playlists.isNotEmpty())
PlaylistSongsLoader.getPlaylistSongList(context, playlists[0]) PlaylistSongsLoader.getPlaylistSongList(context, playlists[0])
else emptyList<Song>() else emptyList()
return Home(songs, FAVOURITES) return Home(songs, FAVOURITES)
} }

View File

@ -151,7 +151,7 @@ class RealSongRepository(private val context: Context) : SongRepository {
} }
selectionFinal = selectionFinal =
selectionFinal + " AND " + MediaStore.Audio.Media.DURATION + ">= " + (PreferenceUtil.filterLength * 1000) selectionFinal + " AND " + MediaStore.Audio.Media.DURATION + ">= " + (PreferenceUtil.filterLength * 1000)
try {
return context.contentResolver.query( return context.contentResolver.query(
MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
baseProjection, baseProjection,
@ -159,9 +159,6 @@ class RealSongRepository(private val context: Context) : SongRepository {
selectionValuesFinal, selectionValuesFinal,
sortOrder sortOrder
) )
} catch (e: SecurityException) {
return null
}
} }
private fun generateBlacklistSelection( private fun generateBlacklistSelection(

View File

@ -70,4 +70,12 @@
android:textColor="?android:attr/textColorSecondary" android:textColor="?android:attr/textColorSecondary"
tools:visibility="visible" /> tools:visibility="visible" />
</LinearLayout> </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> </androidx.coordinatorlayout.widget.CoordinatorLayout>

View File

@ -26,7 +26,7 @@
tools:layout="@layout/fragment_playlist_detail"> tools:layout="@layout/fragment_playlist_detail">
<argument <argument
android:name="extra_playlist" android:name="extra_playlist"
app:argType="code.name.monkey.retromusic.model.Playlist" /> app:argType="code.name.monkey.retromusic.db.PlaylistWithSongs" />
</fragment> </fragment>
<fragment <fragment