Playlist Add, Delete, Add Songs

This commit is contained in:
Hemanth S 2020-08-21 01:32:40 +05:30
parent 6aa9b08ff2
commit f3988ae1d1
51 changed files with 551 additions and 137 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 43 KiB

After

Width:  |  Height:  |  Size: 98 KiB

View file

@ -55,9 +55,11 @@ object Constants {
}
const val EXTRA_GENRE = "extra_genre"
const val EXTRA_PLAYLIST = "extra_playlist"
const val EXTRA_PLAYLIST_ID = "extra_playlist_id"
const val EXTRA_ALBUM_ID = "extra_album_id"
const val EXTRA_ARTIST_ID = "extra_artist_id"
const val EXTRA_SONG = "extra_songs"
const val EXTRA_PLAYLISTS = "extra_playlists"
const val LIBRARY_CATEGORIES = "library_categories"
const val EXTRA_SONG_INFO = "extra_song_info"
const val DESATURATED_COLOR = "desaturated_color"

View file

@ -24,6 +24,7 @@ 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.show
import code.name.monkey.retromusic.helper.menu.PlaylistMenuHelper
import code.name.monkey.retromusic.helper.menu.SongsMenuHelper
import code.name.monkey.retromusic.interfaces.CabHolder
import code.name.monkey.retromusic.model.Playlist
@ -45,7 +46,6 @@ class PlaylistAdapter(
R.menu.menu_playlists_selection
) {
init {
setHasStableIds(true)
}
@ -130,14 +130,14 @@ class PlaylistAdapter(
private fun getSongList(playlists: List<PlaylistWithSongs>): List<Song> {
val songs = ArrayList<Song>()
/* for (playlist in playlists) {
songs.addAll(playlist.songs)
if (playlist is AbsCustomPlaylist) {
songs.addAll(playlist.songs())
} else {
songs.addAll(PlaylistSongsLoader.getPlaylistSongList(activity, playlist.id))
}
}*/
/* for (playlist in playlists) {
songs.addAll(playlist.songs)
if (playlist is AbsCustomPlaylist) {
songs.addAll(playlist.songs())
} else {
songs.addAll(PlaylistSongsLoader.getPlaylistSongList(activity, playlist.id))
}
}*/
return songs
}
@ -165,7 +165,7 @@ class PlaylistAdapter(
val popupMenu = PopupMenu(activity, view)
popupMenu.inflate(R.menu.menu_item_playlist)
popupMenu.setOnMenuItemClickListener { item ->
return@setOnMenuItemClickListener true //PlaylistMenuHelper.handleMenuClick(activity, dataSet[layoutPosition], item)
PlaylistMenuHelper.handleMenuClick(activity, dataSet[layoutPosition], item)
}
popupMenu.show()
}
@ -219,7 +219,5 @@ class PlaylistAdapter(
companion object {
val TAG: String = PlaylistAdapter::class.java.simpleName
private const val SMART_PLAYLIST = 0
private const val DEFAULT_PLAYLIST = 1
}
}

View file

@ -6,6 +6,7 @@ import androidx.fragment.app.FragmentActivity
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.R.menu
import code.name.monkey.retromusic.dialogs.RemoveFromPlaylistDialog
import code.name.monkey.retromusic.dialogs.RemoveSongFromPlaylistDialog
import code.name.monkey.retromusic.interfaces.CabHolder
import code.name.monkey.retromusic.model.PlaylistSong
import code.name.monkey.retromusic.model.Song
@ -16,6 +17,7 @@ import com.h6ah4i.android.widget.advrecyclerview.draggable.ItemDraggableRange
import com.h6ah4i.android.widget.advrecyclerview.draggable.annotation.DraggableItemStateFlags
class OrderablePlaylistSongAdapter(
private val playlistId: Int,
activity: FragmentActivity,
dataSet: ArrayList<Song>,
itemLayoutRes: Int,
@ -118,7 +120,7 @@ class OrderablePlaylistSongAdapter(
override fun onSongMenuItemClick(item: MenuItem): Boolean {
when (item.itemId) {
R.id.action_remove_from_playlist -> {
RemoveFromPlaylistDialog.create(song as PlaylistSong)
RemoveSongFromPlaylistDialog.create( song.toSongEntity(playlistId))
.show(activity.supportFragmentManager, "REMOVE_FROM_PLAYLIST")
return true
}

View file

@ -4,16 +4,21 @@ import androidx.room.*
@Dao
interface PlaylistDao {
@Insert
suspend fun createPlaylist(playlistEntity: PlaylistEntity): Long
@Query("UPDATE PlaylistEntity SET playlist_name = :name WHERE playlist_id = :playlistId")
suspend fun renamePlaylistEntity(playlistId: Int, name: String)
@Query("SELECT * FROM PlaylistEntity WHERE playlist_name = :name")
suspend fun checkPlaylistExists(name: String): List<PlaylistEntity>
@Insert
suspend fun createPlaylist(playlistEntity: PlaylistEntity): Long
@Query("SELECT * FROM PlaylistEntity")
suspend fun playlists(): List<PlaylistEntity>
@Query("DELETE FROM SongEntity WHERE playlist_creator_id = :playlistId")
suspend fun deleteSongsFromPlaylist(playlistId: Int)
@Transaction
@Query("SELECT * FROM PlaylistEntity")
suspend fun playlistsWithSong(): List<PlaylistWithSongs>
@ -24,9 +29,16 @@ interface PlaylistDao {
@Query("SELECT * FROM SongEntity WHERE playlist_creator_id = :playlistName AND id = :songId")
suspend fun checkSongExistsWithPlaylistName(playlistName: String, songId: Int): List<SongEntity>
@Query("SELECT * FROM SongEntity WHERE playlist_creator_id = :playlistId ORDER BY title")
@Query("SELECT * FROM SongEntity WHERE playlist_creator_id = :playlistId")
suspend fun getSongs(playlistId: Int): List<SongEntity>
@Delete
suspend fun deletePlaylistEntity(playlistWithSongs: PlaylistWithSongs)
suspend fun deletePlaylistEntity(playlistEntity: PlaylistEntity)
@Delete
suspend fun deletePlaylistEntities(playlistEntities: List<PlaylistEntity>)
@Delete
suspend fun removeSongsFromPlaylist(songs: List<SongEntity>)
}

View file

@ -13,4 +13,5 @@ data class PlaylistWithSongs(
entityColumn = "playlist_creator_id"
)
val songs: List<SongEntity>
):Parcelable
):Parcelable

View file

@ -54,4 +54,10 @@ class SongEntity(
albumArtist
)
}
}
fun List<SongEntity>.toSongs(): List<Song> {
return map {
it.toSong()
}
}

View file

@ -5,30 +5,46 @@ import android.os.Bundle
import androidx.core.os.bundleOf
import androidx.fragment.app.DialogFragment
import androidx.lifecycle.lifecycleScope
import code.name.monkey.retromusic.EXTRA_PLAYLISTS
import code.name.monkey.retromusic.EXTRA_SONG
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.db.PlaylistEntity
import code.name.monkey.retromusic.repository.RoomPlaylistRepository
import code.name.monkey.retromusic.db.SongEntity
import code.name.monkey.retromusic.extensions.colorButtons
import code.name.monkey.retromusic.extensions.extraNotNull
import code.name.monkey.retromusic.extensions.materialDialog
import code.name.monkey.retromusic.fragments.LibraryViewModel
import code.name.monkey.retromusic.fragments.ReloadType
import code.name.monkey.retromusic.model.Song
import code.name.monkey.retromusic.repository.RealSongRepository
import code.name.monkey.retromusic.repository.RealRepository
import kotlinx.coroutines.Dispatchers
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 AddToRetroPlaylist : DialogFragment() {
private val repository by inject<RealRepository>()
private val libraryViewModel by sharedViewModel<LibraryViewModel>()
companion object {
fun getInstance(playlistName: List<PlaylistEntity>): AddToRetroPlaylist {
fun create(playlistEntities: List<PlaylistEntity>, song: Song): AddToRetroPlaylist {
val list = mutableListOf<Song>()
list.add(song)
return create(playlistEntities, list)
}
fun create(playlistEntities: List<PlaylistEntity>, songs: List<Song>): AddToRetroPlaylist {
return AddToRetroPlaylist().apply {
arguments = bundleOf("playlist_names" to playlistName)
arguments = bundleOf(
EXTRA_SONG to songs,
EXTRA_PLAYLISTS to playlistEntities
)
}
}
}
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
val playlistEntities = extraNotNull<List<PlaylistEntity>>("playlist_names").value
val playlistEntities = extraNotNull<List<PlaylistEntity>>(EXTRA_PLAYLISTS).value
val playlistNames = mutableListOf<String>()
playlistNames.add(requireContext().resources.getString(R.string.action_new_playlist))
for (p in playlistEntities) {
@ -36,14 +52,14 @@ class AddToRetroPlaylist : DialogFragment() {
}
return materialDialog(R.string.add_playlist_title)
.setItems(playlistNames.toTypedArray()) { _, which ->
val songs = RealSongRepository(requireContext()).songs()
val songs = extraNotNull<List<Song>>(EXTRA_SONG).value
if (which == 0) {
CreateRetroPlaylist().show(requireActivity().supportFragmentManager, "Dialog")
} else {
lifecycleScope.launch(Dispatchers.IO) {
val playlistRepository = get<RoomPlaylistRepository>()
val songEntities = songs.withPlaylistIds(playlistEntities[which - 1])
playlistRepository.insertSongs(songEntities)
repository.insertSongs(songEntities)
libraryViewModel.forceReload(ReloadType.Playlists)
}
}
dismiss()

View file

@ -4,24 +4,26 @@ import android.app.Dialog
import android.os.Bundle
import android.text.TextUtils
import android.view.LayoutInflater
import android.widget.Toast
import androidx.fragment.app.DialogFragment
import androidx.lifecycle.lifecycleScope
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.db.PlaylistEntity
import code.name.monkey.retromusic.repository.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 code.name.monkey.retromusic.fragments.ReloadType.Playlists
import code.name.monkey.retromusic.repository.RealRepository
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.Dispatchers
import kotlinx.coroutines.launch
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 repository by inject<RealRepository>()
private val libraryViewModel by sharedViewModel<LibraryViewModel>()
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
val view = LayoutInflater.from(requireActivity()).inflate(R.layout.dialog_playlist, null)
@ -34,14 +36,13 @@ class CreateRetroPlaylist : DialogFragment() {
) { _, _ ->
val playlistName = playlistView.text.toString()
if (!TextUtils.isEmpty(playlistName)) {
lifecycleScope.launch {
if (playlistRepository.checkPlaylistExists(playlistName).isEmpty()) {
val id: Long =
playlistRepository.createPlaylist(PlaylistEntity(playlistName))
println(id)
libraryViewModel.forceReload(ReloadType.Playlists)
lifecycleScope.launch(Dispatchers.IO) {
if (repository.checkPlaylistExists(playlistName).isEmpty()) {
repository.createPlaylist(PlaylistEntity(playlistName))
libraryViewModel.forceReload(Playlists)
} else {
println("Playlist exists")
Toast.makeText(requireContext(), "Playlist exists", Toast.LENGTH_SHORT)
.show()
}
}

View file

@ -0,0 +1,76 @@
package code.name.monkey.retromusic.dialogs
import android.app.Dialog
import android.os.Bundle
import androidx.core.os.bundleOf
import androidx.core.text.HtmlCompat
import androidx.fragment.app.DialogFragment
import androidx.lifecycle.lifecycleScope
import code.name.monkey.retromusic.EXTRA_PLAYLIST
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.db.PlaylistEntity
import code.name.monkey.retromusic.extensions.colorButtons
import code.name.monkey.retromusic.extensions.extraNotNull
import code.name.monkey.retromusic.extensions.materialDialog
import code.name.monkey.retromusic.fragments.LibraryViewModel
import code.name.monkey.retromusic.fragments.ReloadType
import code.name.monkey.retromusic.repository.Repository
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import org.koin.android.ext.android.inject
import org.koin.androidx.viewmodel.ext.android.sharedViewModel
class DeleteRetroPlaylist : DialogFragment() {
private val repository by inject<Repository>()
private val libraryViewModel by sharedViewModel<LibraryViewModel>()
companion object {
fun create(playlist: PlaylistEntity): DeleteRetroPlaylist {
val list = mutableListOf<PlaylistEntity>()
list.add(playlist)
return create(list)
}
fun create(playlists: List<PlaylistEntity>): DeleteRetroPlaylist {
return DeleteRetroPlaylist().apply {
arguments = bundleOf(EXTRA_PLAYLIST to playlists)
}
}
}
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
val playlists = extraNotNull<List<PlaylistEntity>>(EXTRA_PLAYLIST).value
val title: Int
val message: CharSequence
//noinspection ConstantConditions
if (playlists.size > 1) {
title = R.string.delete_playlists_title
message = HtmlCompat.fromHtml(
String.format(getString(R.string.delete_x_playlists), playlists.size),
HtmlCompat.FROM_HTML_MODE_LEGACY
)
} else {
title = R.string.delete_playlist_title
message = HtmlCompat.fromHtml(
String.format(getString(R.string.delete_playlist_x), playlists[0].playlistName),
HtmlCompat.FROM_HTML_MODE_LEGACY
)
}
return materialDialog(title)
.setTitle(title)
.setMessage(message)
.setNegativeButton(android.R.string.cancel, null)
.setPositiveButton(R.string.action_delete) { _, _ ->
lifecycleScope.launch(Dispatchers.IO) {
repository.deleteSongsFromPlaylist(playlists)
repository.deleteRoomPlaylist(playlists)
libraryViewModel.forceReload(ReloadType.Playlists)
}
}
.create()
.colorButtons()
}
}

View file

@ -0,0 +1,79 @@
package code.name.monkey.retromusic.dialogs
import android.app.Dialog
import android.os.Bundle
import androidx.core.os.bundleOf
import androidx.core.text.HtmlCompat
import androidx.fragment.app.DialogFragment
import androidx.lifecycle.lifecycleScope
import code.name.monkey.retromusic.EXTRA_SONG
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.db.SongEntity
import code.name.monkey.retromusic.extensions.colorButtons
import code.name.monkey.retromusic.extensions.extraNotNull
import code.name.monkey.retromusic.extensions.materialDialog
import code.name.monkey.retromusic.fragments.LibraryViewModel
import code.name.monkey.retromusic.repository.Repository
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import org.koin.android.ext.android.inject
import org.koin.androidx.viewmodel.ext.android.sharedViewModel
class RemoveSongFromPlaylistDialog : DialogFragment() {
private val repository by inject<Repository>()
private val libraryViewModel by sharedViewModel<LibraryViewModel>()
companion object {
fun create(song: SongEntity): RemoveSongFromPlaylistDialog {
val list = mutableListOf<SongEntity>()
list.add(song)
return create(list)
}
fun create(songs: List<SongEntity>): RemoveSongFromPlaylistDialog {
return RemoveSongFromPlaylistDialog().apply {
arguments = bundleOf(
EXTRA_SONG to songs
)
}
}
}
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
val songs = extraNotNull<List<SongEntity>>(EXTRA_SONG).value
val pair = if (songs.size > 1) {
Pair(
R.string.remove_songs_from_playlist_title,
HtmlCompat.fromHtml(
String.format(getString(R.string.remove_x_songs_from_playlist), songs.size),
HtmlCompat.FROM_HTML_MODE_LEGACY
)
)
} else {
Pair(
R.string.remove_song_from_playlist_title,
HtmlCompat.fromHtml(
String.format(
getString(R.string.remove_song_x_from_playlist),
songs[0].title
),
HtmlCompat.FROM_HTML_MODE_LEGACY
)
)
}
return materialDialog(pair.first)
.setMessage(pair.second)
.setPositiveButton(R.string.remove_action) { _, _ ->
lifecycleScope.launch(Dispatchers.IO) {
repository.removeSongFromPlaylist(songs)
}
/* PlaylistsUtil.removeFromPlaylist(
requireContext(),
songs as MutableList<PlaylistSong>
)*/
}
.setNegativeButton(android.R.string.cancel, null)
.create()
.colorButtons()
}
}

View file

@ -0,0 +1,64 @@
package code.name.monkey.retromusic.dialogs
import android.app.Dialog
import android.os.Bundle
import android.view.LayoutInflater
import androidx.core.os.bundleOf
import androidx.fragment.app.DialogFragment
import androidx.lifecycle.lifecycleScope
import code.name.monkey.retromusic.EXTRA_PLAYLIST_ID
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.db.PlaylistEntity
import code.name.monkey.retromusic.extensions.accentColor
import code.name.monkey.retromusic.extensions.colorButtons
import code.name.monkey.retromusic.extensions.extraNotNull
import code.name.monkey.retromusic.extensions.materialDialog
import code.name.monkey.retromusic.fragments.LibraryViewModel
import code.name.monkey.retromusic.fragments.ReloadType
import code.name.monkey.retromusic.repository.Repository
import com.google.android.material.textfield.TextInputEditText
import com.google.android.material.textfield.TextInputLayout
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import org.koin.android.ext.android.inject
import org.koin.androidx.viewmodel.ext.android.sharedViewModel
class RenameRetroPlaylistDialog : DialogFragment() {
private val repository by inject<Repository>()
private val libraryViewModel by sharedViewModel<LibraryViewModel>()
companion object {
fun create(playlistEntity: PlaylistEntity): RenameRetroPlaylistDialog {
return RenameRetroPlaylistDialog().apply {
arguments = bundleOf(
EXTRA_PLAYLIST_ID to playlistEntity
)
}
}
}
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
val playlistEntity = extraNotNull<PlaylistEntity>(EXTRA_PLAYLIST_ID).value
val layout = LayoutInflater.from(requireContext()).inflate(R.layout.dialog_playlist, null)
val inputEditText: TextInputEditText = layout.findViewById(R.id.actionNewPlaylist)
val nameContainer: TextInputLayout = layout.findViewById(R.id.actionNewPlaylistContainer)
nameContainer.accentColor()
inputEditText.setText(playlistEntity.playlistName)
return materialDialog(R.string.rename_playlist_title)
.setView(layout)
.setNegativeButton(android.R.string.cancel, null)
.setPositiveButton(R.string.action_rename) { _, _ ->
val name = inputEditText.text.toString()
if (name.isNotEmpty()) {
lifecycleScope.launch(Dispatchers.IO) {
repository.renameRoomPlaylist(playlistEntity.playListId, name)
libraryViewModel.forceReload(ReloadType.Playlists)
}
} else {
nameContainer.error = "Playlist name should'nt be empty"
}
}
.create()
.colorButtons()
}
}

View file

@ -34,6 +34,7 @@ class DetailListFragment : AbsMainActivityFragment(R.layout.fragment_playlist_de
super.onActivityCreated(savedInstanceState)
mainActivity.setSupportActionBar(toolbar)
mainActivity.hideBottomBarVisibility(false)
progressIndicator.hide()
when (args.type) {
TOP_ARTISTS -> {
loadArtists(R.string.top_artists, TOP_ARTISTS)

View file

@ -33,7 +33,7 @@ class LibraryViewModel(
val songsLiveData: LiveData<List<Song>> = songs
val artistsLiveData: LiveData<List<Artist>> = artists
val playlisitsLiveData: LiveData<List<Playlist>> = playlists
val roomPlaylisitsLiveData: LiveData<List<PlaylistWithSongs>> = roomPlaylists
val roomPlaylistsLiveData: LiveData<List<PlaylistWithSongs>> = roomPlaylists
val genresLiveData: LiveData<List<Genre>> = genres
init {
@ -43,13 +43,13 @@ class LibraryViewModel(
}
private fun loadLibraryContent() = viewModelScope.launch {
home.value = loadHome.await()
songs.value = loadSongs.await()
albums.value = loadAlbums.await()
artists.value = loadArtists.await()
playlists.value = loadPlaylists.await()
roomPlaylists.value = loadPlaylistsWithSongs.await()
//genres.value = loadGenres.await()
home.value = loadHome.await()
}
private val loadHome: Deferred<List<Home>>
@ -84,6 +84,7 @@ class LibraryViewModel(
fun forceReload(reloadType: ReloadType) = viewModelScope.launch {
println(reloadType)
when (reloadType) {
Songs -> songs.value = loadSongs.await()
Albums -> albums.value = loadAlbums.await()

View file

@ -7,6 +7,7 @@ import android.view.*
import androidx.appcompat.app.AppCompatActivity
import androidx.core.os.bundleOf
import androidx.lifecycle.Observer
import androidx.lifecycle.lifecycleScope
import androidx.navigation.findNavController
import androidx.navigation.fragment.findNavController
import androidx.navigation.fragment.navArgs
@ -22,7 +23,7 @@ import code.name.monkey.retromusic.activities.tageditor.AbsTagEditorActivity
import code.name.monkey.retromusic.activities.tageditor.AlbumTagEditorActivity
import code.name.monkey.retromusic.adapter.album.HorizontalAlbumAdapter
import code.name.monkey.retromusic.adapter.song.SimpleSongAdapter
import code.name.monkey.retromusic.dialogs.AddToPlaylistDialog
import code.name.monkey.retromusic.dialogs.AddToRetroPlaylist
import code.name.monkey.retromusic.dialogs.DeleteSongsDialog
import code.name.monkey.retromusic.extensions.applyColor
import code.name.monkey.retromusic.extensions.show
@ -35,6 +36,7 @@ import code.name.monkey.retromusic.helper.SortOrder
import code.name.monkey.retromusic.model.Album
import code.name.monkey.retromusic.model.Artist
import code.name.monkey.retromusic.network.model.LastFmAlbum
import code.name.monkey.retromusic.repository.RealRepository
import code.name.monkey.retromusic.util.MusicUtil
import code.name.monkey.retromusic.util.PreferenceUtil
import code.name.monkey.retromusic.util.RetroUtil
@ -42,6 +44,10 @@ import code.name.monkey.retromusic.util.color.MediaNotificationProcessor
import com.bumptech.glide.Glide
import kotlinx.android.synthetic.main.fragment_album_content.*
import kotlinx.android.synthetic.main.fragment_album_details.*
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.koin.android.ext.android.get
import org.koin.androidx.viewmodel.ext.android.viewModel
import org.koin.core.parameter.parametersOf
import java.util.*
@ -275,7 +281,13 @@ class AlbumDetailsFragment : AbsMainActivityFragment(R.layout.fragment_album_det
return true
}
R.id.action_add_to_playlist -> {
AddToPlaylistDialog.create(songs).show(childFragmentManager, "ADD_PLAYLIST")
lifecycleScope.launch(Dispatchers.IO) {
val playlists = get<RealRepository>().roomPlaylists()
withContext(Dispatchers.Main) {
AddToRetroPlaylist.create(playlists, songs)
.show(childFragmentManager, "ADD_PLAYLIST")
}
}
return true
}
R.id.action_delete_from_device -> {

View file

@ -10,6 +10,7 @@ import android.view.View
import androidx.core.os.bundleOf
import androidx.core.text.HtmlCompat
import androidx.lifecycle.Observer
import androidx.lifecycle.lifecycleScope
import androidx.navigation.fragment.FragmentNavigatorExtras
import androidx.navigation.fragment.findNavController
import androidx.navigation.fragment.navArgs
@ -19,7 +20,7 @@ import androidx.recyclerview.widget.LinearLayoutManager
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.adapter.album.HorizontalAlbumAdapter
import code.name.monkey.retromusic.adapter.song.SimpleSongAdapter
import code.name.monkey.retromusic.dialogs.AddToPlaylistDialog
import code.name.monkey.retromusic.dialogs.AddToRetroPlaylist
import code.name.monkey.retromusic.extensions.applyColor
import code.name.monkey.retromusic.extensions.show
import code.name.monkey.retromusic.extensions.showToast
@ -30,6 +31,7 @@ import code.name.monkey.retromusic.glide.RetroMusicColoredTarget
import code.name.monkey.retromusic.helper.MusicPlayerRemote
import code.name.monkey.retromusic.model.Artist
import code.name.monkey.retromusic.network.model.LastFmArtist
import code.name.monkey.retromusic.repository.RealRepository
import code.name.monkey.retromusic.util.CustomArtistImageUtil
import code.name.monkey.retromusic.util.MusicUtil
import code.name.monkey.retromusic.util.RetroUtil
@ -37,6 +39,10 @@ import code.name.monkey.retromusic.util.color.MediaNotificationProcessor
import com.bumptech.glide.Glide
import kotlinx.android.synthetic.main.fragment_artist_content.*
import kotlinx.android.synthetic.main.fragment_artist_details.*
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.koin.android.ext.android.get
import org.koin.androidx.viewmodel.ext.android.viewModel
import org.koin.core.parameter.parametersOf
import java.util.*
@ -216,7 +222,13 @@ class ArtistDetailsFragment : AbsMainActivityFragment(R.layout.fragment_artist_d
return true
}
R.id.action_add_to_playlist -> {
AddToPlaylistDialog.create(songs).show(childFragmentManager, "ADD_PLAYLIST")
lifecycleScope.launch(Dispatchers.IO) {
val playlists = get<RealRepository>().roomPlaylists()
withContext(Dispatchers.Main) {
AddToRetroPlaylist.create(playlists, songs)
.show(childFragmentManager, "ADD_PLAYLIST")
}
}
return true
}
R.id.action_set_artist_image -> {

View file

@ -15,6 +15,7 @@ import android.widget.Toast
import androidx.annotation.LayoutRes
import androidx.appcompat.widget.Toolbar
import androidx.core.os.bundleOf
import androidx.lifecycle.lifecycleScope
import androidx.navigation.findNavController
import code.name.monkey.retromusic.EXTRA_ALBUM_ID
import code.name.monkey.retromusic.EXTRA_ARTIST_ID
@ -29,8 +30,13 @@ import code.name.monkey.retromusic.helper.MusicPlayerRemote
import code.name.monkey.retromusic.interfaces.PaletteColorHolder
import code.name.monkey.retromusic.model.Song
import code.name.monkey.retromusic.model.lyrics.Lyrics
import code.name.monkey.retromusic.repository.RealRepository
import code.name.monkey.retromusic.util.*
import kotlinx.android.synthetic.main.shadow_statusbar_toolbar.*
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.koin.android.ext.android.get
import org.koin.androidx.viewmodel.ext.android.sharedViewModel
import java.io.FileNotFoundException
@ -64,7 +70,13 @@ abstract class AbsPlayerFragment(@LayoutRes layout: Int) : AbsMainActivityFragme
return true
}
R.id.action_add_to_playlist -> {
AddToPlaylistDialog.create(song).show(childFragmentManager, "ADD_PLAYLIST")
lifecycleScope.launch(Dispatchers.IO) {
val playlists = get<RealRepository>().roomPlaylists()
withContext(Dispatchers.Main) {
AddToRetroPlaylist.create(playlists, song)
.show(childFragmentManager, "ADD_PLAYLIST")
}
}
return true
}
R.id.action_clear_playing_queue -> {

View file

@ -4,20 +4,15 @@ import android.os.Bundle
import android.view.Menu
import android.view.MenuInflater
import android.view.MenuItem
import androidx.lifecycle.lifecycleScope
import androidx.navigation.fragment.findNavController
import androidx.navigation.ui.NavigationUI
import code.name.monkey.appthemehelper.common.ATHToolbarActivity.getToolbarBackgroundColor
import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.repository.RoomPlaylistRepository
import code.name.monkey.retromusic.dialogs.AddToRetroPlaylist
import code.name.monkey.retromusic.dialogs.CreateRetroPlaylist
import code.name.monkey.retromusic.extensions.findNavController
import code.name.monkey.retromusic.fragments.base.AbsMainActivityFragment
import com.google.android.material.appbar.AppBarLayout
import kotlinx.android.synthetic.main.fragment_library.*
import kotlinx.coroutines.launch
import org.koin.android.ext.android.get
class LibraryFragment : AbsMainActivityFragment(R.layout.fragment_library) {
@ -34,12 +29,29 @@ class LibraryFragment : AbsMainActivityFragment(R.layout.fragment_library) {
navOptions
)
}
addPlaylist.setOnClickListener {
CreateRetroPlaylist().show(childFragmentManager, "ShowCreatePlaylistDialog")
}
setupNavigationController()
}
private fun setupNavigationController() {
val navController = findNavController(R.id.fragment_container)
NavigationUI.setupWithNavController(mainActivity.getBottomNavigationView(), navController)
navController.addOnDestinationChangedListener { _, destination, _ ->
if (destination.id in arrayOf(
R.id.action_album,
R.id.action_artist,
R.id.action_home,
R.id.action_song,
R.id.action_genre
)
) {
addPlaylist.hide()
} else {
addPlaylist.show()
}
}
}
override fun onPrepareOptionsMenu(menu: Menu) {
@ -60,32 +72,12 @@ class LibraryFragment : AbsMainActivityFragment(R.layout.fragment_library) {
override fun onOptionsItemSelected(item: MenuItem): Boolean {
when (item.itemId) {
R.id.action_settings ->
//CreateRetroPlaylist().show(childFragmentManager, "Dialog")
lifecycleScope.launch {
val playlistRepository = get<RoomPlaylistRepository>()
AddToRetroPlaylist.getInstance(playlistRepository.playlists())
.show(childFragmentManager, "PlaylistDialog")
}
/*findNavController().navigate(
R.id.settingsActivity,
null,
navOptions
)*/
R.id.action_settings -> findNavController().navigate(
R.id.settingsActivity,
null,
navOptions
)
}
return super.onOptionsItemSelected(item)
}
fun addOnAppBarOffsetChangedListener(changedListener: AppBarLayout.OnOffsetChangedListener) {
appBarLayout.addOnOffsetChangedListener(changedListener)
}
fun removeOnAppBarOffsetChangedListener(changedListener: AppBarLayout.OnOffsetChangedListener) {
appBarLayout.removeOnOffsetChangedListener(changedListener)
}
fun getTotalAppBarScrollingRange(): Int {
return 0
}
}

View file

@ -15,6 +15,7 @@ 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.Song
import code.name.monkey.retromusic.util.PlaylistsUtil
import com.h6ah4i.android.widget.advrecyclerview.animator.RefactoredDefaultItemAnimator
@ -61,25 +62,28 @@ class PlaylistDetailsFragment : AbsMainActivityFragment(R.layout.fragment_playli
} else {*/
recyclerViewDragDropManager = RecyclerViewDragDropManager()
val animator = RefactoredDefaultItemAnimator()
adapter = OrderablePlaylistSongAdapter(requireActivity(),
ArrayList(),
R.layout.item_list,
null,
object : OrderablePlaylistSongAdapter.OnMoveItemListener {
override fun onMoveItem(fromPosition: Int, toPosition: Int) {
if (PlaylistsUtil.moveItem(
requireContext(),
playlist.playlistEntity.playListId,
fromPosition,
toPosition
)
) {
val song = adapter.dataSet.removeAt(fromPosition)
adapter.dataSet.add(toPosition, song)
adapter.notifyItemMoved(fromPosition, toPosition)
adapter =
OrderablePlaylistSongAdapter(
playlist.playlistEntity.playListId,
requireActivity(),
ArrayList(),
R.layout.item_list,
null,
object : OrderablePlaylistSongAdapter.OnMoveItemListener {
override fun onMoveItem(fromPosition: Int, toPosition: Int) {
if (PlaylistsUtil.moveItem(
requireContext(),
playlist.playlistEntity.playListId,
fromPosition,
toPosition
)
) {
val song = adapter.dataSet.removeAt(fromPosition)
adapter.dataSet.add(toPosition, song)
adapter.notifyItemMoved(fromPosition, toPosition)
}
}
}
})
})
wrappedAdapter = recyclerViewDragDropManager!!.createWrappedAdapter(adapter)
recyclerView.adapter = wrappedAdapter
@ -104,7 +108,7 @@ class PlaylistDetailsFragment : AbsMainActivityFragment(R.layout.fragment_playli
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
return true//PlaylistMenuHelper.handleMenuClick(requireActivity(), playlist, item)
return PlaylistMenuHelper.handleMenuClick(requireActivity(), playlist, item)
}
private fun checkForPadding() {

View file

@ -19,7 +19,7 @@ class PlaylistsFragment :
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
libraryViewModel.roomPlaylisitsLiveData.observe(viewLifecycleOwner, Observer {
libraryViewModel.roomPlaylistsLiveData.observe(viewLifecycleOwner, Observer {
if (it.isNotEmpty())
adapter?.swapDataSet(it)
else

View file

@ -19,12 +19,16 @@ import android.view.View
import androidx.preference.Preference
import code.name.monkey.appthemehelper.common.prefs.supportv7.ATEListPreference
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.fragments.LibraryViewModel
import code.name.monkey.retromusic.fragments.ReloadType.HomeSections
import org.koin.androidx.viewmodel.ext.android.sharedViewModel
/**
* @author Hemanth S (h4h13).
*/
class OtherSettingsFragment : AbsSettingsFragment() {
private val libraryViewModel by sharedViewModel<LibraryViewModel>()
override fun invalidateSettings() {
val languagePreference: ATEListPreference? = findPreference("language_name")
languagePreference?.setOnPreferenceChangeListener { _, _ ->
@ -42,6 +46,7 @@ class OtherSettingsFragment : AbsSettingsFragment() {
val preference: Preference? = findPreference("last_added_interval")
preference?.setOnPreferenceChangeListener { lastAdded, newValue ->
setSummary(lastAdded, newValue)
libraryViewModel.forceReload(HomeSections)
true
}
val languagePreference: Preference? = findPreference("language_name")

View file

@ -17,12 +17,18 @@ package code.name.monkey.retromusic.helper.menu
import android.view.MenuItem
import androidx.fragment.app.FragmentActivity
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.dialogs.AddToPlaylistDialog
import code.name.monkey.retromusic.dialogs.AddToRetroPlaylist
import code.name.monkey.retromusic.helper.MusicPlayerRemote
import code.name.monkey.retromusic.model.Genre
import code.name.monkey.retromusic.model.Song
import code.name.monkey.retromusic.repository.GenreRepository
import code.name.monkey.retromusic.repository.RealRepository
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.koin.core.KoinComponent
import org.koin.core.get
import org.koin.core.inject
object GenreMenuHelper : KoinComponent {
@ -38,8 +44,13 @@ object GenreMenuHelper : KoinComponent {
return true
}
R.id.action_add_to_playlist -> {
AddToPlaylistDialog.create(getGenreSongs(genre))
.show(activity.supportFragmentManager, "ADD_PLAYLIST")
CoroutineScope(Dispatchers.IO).launch {
val playlists = get<RealRepository>().roomPlaylists()
withContext(Dispatchers.Main) {
AddToRetroPlaylist.create(playlists, getGenreSongs(genre))
.show(activity.supportFragmentManager, "ADD_PLAYLIST")
}
}
return true
}
R.id.action_add_to_current_playing -> {

View file

@ -22,53 +22,67 @@ import android.widget.Toast
import androidx.fragment.app.FragmentActivity
import code.name.monkey.retromusic.App
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.dialogs.AddToPlaylistDialog
import code.name.monkey.retromusic.dialogs.DeletePlaylistDialog
import code.name.monkey.retromusic.dialogs.RenamePlaylistDialog
import code.name.monkey.retromusic.db.PlaylistWithSongs
import code.name.monkey.retromusic.db.toSongs
import code.name.monkey.retromusic.dialogs.AddToRetroPlaylist
import code.name.monkey.retromusic.dialogs.DeleteRetroPlaylist
import code.name.monkey.retromusic.dialogs.RenameRetroPlaylistDialog
import code.name.monkey.retromusic.helper.MusicPlayerRemote
import code.name.monkey.retromusic.misc.WeakContextAsyncTask
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.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.koin.core.KoinComponent
import org.koin.core.get
object PlaylistMenuHelper {
object PlaylistMenuHelper : KoinComponent {
fun handleMenuClick(
activity: FragmentActivity,
playlist: Playlist, item: MenuItem
playlistWithSongs: PlaylistWithSongs, item: MenuItem
): Boolean {
when (item.itemId) {
R.id.action_play -> {
MusicPlayerRemote.openQueue(getPlaylistSongs(activity, playlist), 9, true)
MusicPlayerRemote.openQueue(playlistWithSongs.songs.toSongs(), 0, true)
return true
}
R.id.action_play_next -> {
MusicPlayerRemote.playNext(getPlaylistSongs(activity, playlist))
MusicPlayerRemote.playNext(playlistWithSongs.songs.toSongs())
return true
}
R.id.action_add_to_playlist -> {
AddToPlaylistDialog.create(getPlaylistSongs(activity, playlist))
.show(activity.supportFragmentManager, "ADD_PLAYLIST")
CoroutineScope(Dispatchers.IO).launch {
val playlists = get<RealRepository>().roomPlaylists()
withContext(Dispatchers.Main) {
AddToRetroPlaylist.create(playlists, playlistWithSongs.songs.toSongs())
.show(activity.supportFragmentManager, "ADD_PLAYLIST")
}
}
return true
}
R.id.action_add_to_current_playing -> {
MusicPlayerRemote.enqueue(getPlaylistSongs(activity, playlist))
MusicPlayerRemote.enqueue(playlistWithSongs.songs.toSongs())
return true
}
R.id.action_rename_playlist -> {
RenamePlaylistDialog.create(playlist.id.toLong())
RenameRetroPlaylistDialog.create(playlistWithSongs.playlistEntity )
.show(activity.supportFragmentManager, "RENAME_PLAYLIST")
return true
}
R.id.action_delete_playlist -> {
DeletePlaylistDialog.create(playlist)
DeleteRetroPlaylist.create(playlistWithSongs.playlistEntity)
.show(activity.supportFragmentManager, "DELETE_PLAYLIST")
return true
}
R.id.action_save_playlist -> {
SavePlaylistAsyncTask(activity).execute(playlist)
//SavePlaylistAsyncTask(activity).execute(playlistWithSongs.songs.toSongs())
return true
}
}

View file

@ -26,16 +26,23 @@ import code.name.monkey.retromusic.EXTRA_ARTIST_ID
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.activities.tageditor.AbsTagEditorActivity
import code.name.monkey.retromusic.activities.tageditor.SongTagEditorActivity
import code.name.monkey.retromusic.dialogs.AddToPlaylistDialog
import code.name.monkey.retromusic.dialogs.AddToRetroPlaylist
import code.name.monkey.retromusic.dialogs.DeleteSongsDialog
import code.name.monkey.retromusic.dialogs.SongDetailDialog
import code.name.monkey.retromusic.helper.MusicPlayerRemote
import code.name.monkey.retromusic.interfaces.PaletteColorHolder
import code.name.monkey.retromusic.model.Song
import code.name.monkey.retromusic.repository.RealRepository
import code.name.monkey.retromusic.util.MusicUtil
import code.name.monkey.retromusic.util.RingtoneManager
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.koin.core.KoinComponent
import org.koin.core.get
object SongMenuHelper {
object SongMenuHelper : KoinComponent {
const val MENU_RES = R.menu.menu_item_song
fun handleMenuClick(activity: FragmentActivity, song: Song, menuItemId: Int): Boolean {
@ -63,8 +70,13 @@ object SongMenuHelper {
return true
}
R.id.action_add_to_playlist -> {
AddToPlaylistDialog.create(song)
.show(activity.supportFragmentManager, "ADD_PLAYLIST")
CoroutineScope(Dispatchers.IO).launch {
val playlists = get<RealRepository>().roomPlaylists()
withContext(Dispatchers.Main) {
AddToRetroPlaylist.create(playlists, song)
.show(activity.supportFragmentManager, "ADD_PLAYLIST")
}
}
return true
}
R.id.action_play_next -> {

View file

@ -16,13 +16,19 @@ package code.name.monkey.retromusic.helper.menu
import androidx.fragment.app.FragmentActivity
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.dialogs.AddToPlaylistDialog
import code.name.monkey.retromusic.dialogs.AddToRetroPlaylist
import code.name.monkey.retromusic.dialogs.DeleteSongsDialog
import code.name.monkey.retromusic.helper.MusicPlayerRemote
import code.name.monkey.retromusic.model.Song
import code.name.monkey.retromusic.repository.RealRepository
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.koin.core.KoinComponent
import org.koin.core.get
object SongsMenuHelper {
object SongsMenuHelper : KoinComponent {
fun handleMenuClick(
activity: FragmentActivity,
songs: List<Song>,
@ -38,8 +44,13 @@ object SongsMenuHelper {
return true
}
R.id.action_add_to_playlist -> {
AddToPlaylistDialog.create(songs)
.show(activity.supportFragmentManager, "ADD_PLAYLIST")
CoroutineScope(Dispatchers.IO).launch {
val playlists = get<RealRepository>().roomPlaylists()
withContext(Dispatchers.Main) {
AddToRetroPlaylist.create(playlists, songs)
.show(activity.supportFragmentManager, "ADD_PLAYLIST")
}
}
return true
}
R.id.action_delete_from_device -> {

View file

@ -16,7 +16,9 @@ package code.name.monkey.retromusic.repository
import android.content.Context
import code.name.monkey.retromusic.*
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.model.*
import code.name.monkey.retromusic.model.smartplaylist.NotPlayedPlaylist
import code.name.monkey.retromusic.network.LastFMService
@ -29,6 +31,17 @@ import kotlinx.coroutines.flow.flow
interface Repository {
fun songsFlow(): Flow<Result<List<Song>>>
fun albumsFlow(): Flow<Result<List<Album>>>
fun artistsFlow(): Flow<Result<List<Artist>>>
fun playlistsFlow(): Flow<Result<List<Playlist>>>
fun genresFlow(): Flow<Result<List<Genre>>>
suspend fun allAlbums(): List<Album>
suspend fun albumById(albumId: Int): Album
@ -89,16 +102,21 @@ interface Repository {
suspend fun playlistSongs(playlistWithSongs: PlaylistWithSongs): List<Song>
fun songsFlow(): Flow<Result<List<Song>>>
suspend fun insertSongs(songs: List<SongEntity>)
fun albumsFlow(): Flow<Result<List<Album>>>
suspend fun checkPlaylistExists(playlistName: String): List<PlaylistEntity>
fun artistsFlow(): Flow<Result<List<Artist>>>
suspend fun createPlaylist(playlistEntity: PlaylistEntity): Long
fun playlistsFlow(): Flow<Result<List<Playlist>>>
suspend fun roomPlaylists(): List<PlaylistEntity>
fun genresFlow(): Flow<Result<List<Genre>>>
suspend fun deleteRoomPlaylist(playlists: List<PlaylistEntity>)
suspend fun renameRoomPlaylist(playlistId: Int, name: String)
suspend fun removeSongFromPlaylist(songs: List<SongEntity>)
suspend fun deleteSongsFromPlaylist(playlists: List<PlaylistEntity>)
}
class RealRepository(
@ -206,7 +224,6 @@ class RealRepository(
)
for (section in sections) {
if (section.arrayList.isNotEmpty()) {
println("${section.homeSection} -> ${section.arrayList.size}")
homeSections.add(section)
}
}
@ -224,12 +241,35 @@ class RealRepository(
override suspend fun playlistWithSongs(): List<PlaylistWithSongs> =
roomPlaylistRepository.playlistWithSongs()
override suspend fun playlistSongs(playlistWithSongs: PlaylistWithSongs ): List<Song> {
override suspend fun playlistSongs(playlistWithSongs: PlaylistWithSongs): List<Song> {
return playlistWithSongs.songs.map {
it.toSong()
it.toSong()
}
}
override suspend fun insertSongs(songs: List<SongEntity>) =
roomPlaylistRepository.insertSongs(songs)
override suspend fun checkPlaylistExists(playlistName: String): List<PlaylistEntity> =
roomPlaylistRepository.checkPlaylistExists(playlistName)
override suspend fun createPlaylist(playlistEntity: PlaylistEntity): Long =
roomPlaylistRepository.createPlaylist(playlistEntity)
override suspend fun roomPlaylists(): List<PlaylistEntity> = roomPlaylistRepository.playlists()
override suspend fun deleteRoomPlaylist(playlists: List<PlaylistEntity>) =
roomPlaylistRepository.deletePlaylistEntities(playlists)
override suspend fun renameRoomPlaylist(playlistId: Int, name: String) =
roomPlaylistRepository.renamePlaylistEntity(playlistId, name)
override suspend fun removeSongFromPlaylist(songs: List<SongEntity>) =
roomPlaylistRepository.removeSongsFromPlaylist(songs)
override suspend fun deleteSongsFromPlaylist(playlists: List<PlaylistEntity>) =
roomPlaylistRepository.deleteSongsFromPlaylist(playlists)
override suspend fun suggestionsHome(): Home {
val songs =
NotPlayedPlaylist().songs().shuffled().takeIf {

View file

@ -14,9 +14,15 @@ interface RoomPlaylistRepository {
suspend fun playlistWithSongs(): List<PlaylistWithSongs>
suspend fun insertSongs(songs: List<SongEntity>)
suspend fun getSongs(playlistEntity: PlaylistEntity): List<SongEntity>
suspend fun deletePlaylistEntities(playlistEntities: List<PlaylistEntity>)
suspend fun renamePlaylistEntity(playlistId: Int, name: String)
suspend fun removeSongsFromPlaylist(songs: List<SongEntity>)
suspend fun deleteSongsFromPlaylist(playlists: List<PlaylistEntity>)
}
class RealRoomPlaylistRepository(private val playlistDao: PlaylistDao) : RoomPlaylistRepository {
class RealRoomPlaylistRepository(
private val playlistDao: PlaylistDao
) : RoomPlaylistRepository {
@WorkerThread
override suspend fun createPlaylist(playlistEntity: PlaylistEntity): Long =
playlistDao.createPlaylist(playlistEntity)
@ -46,4 +52,20 @@ class RealRoomPlaylistRepository(private val playlistDao: PlaylistDao) : RoomPla
override suspend fun getSongs(playlistEntity: PlaylistEntity): List<SongEntity> {
return playlistDao.getSongs(playlistEntity.playListId)
}
override suspend fun deletePlaylistEntities(playlistEntities: List<PlaylistEntity>) =
playlistDao.deletePlaylistEntities(playlistEntities)
override suspend fun renamePlaylistEntity(playlistId: Int, name: String) =
playlistDao.renamePlaylistEntity(playlistId, name)
override suspend fun removeSongsFromPlaylist(songs: List<SongEntity>) =
playlistDao.removeSongsFromPlaylist(songs)
override suspend fun deleteSongsFromPlaylist(playlists: List<PlaylistEntity>) {
playlists.forEach {
playlistDao.deleteSongsFromPlaylist(it.playListId)
}
}
}

View file

@ -19,7 +19,6 @@ import android.content.Context
import android.content.Intent
import android.content.SharedPreferences
import android.net.Uri
import android.widget.Toast
import code.name.monkey.retromusic.R
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.google.android.play.core.review.ReviewManagerFactory
@ -71,8 +70,7 @@ object AppRater {
val reviewInfo = request.result
manager.launchReviewFlow(context as Activity, reviewInfo).addOnCompleteListener {
if (it.isSuccessful) {
Toast.makeText(context, "Thanks for the feedback", Toast.LENGTH_SHORT)
.show()
//Toast.makeText(context, "Thanks for the feedback", Toast.LENGTH_SHORT).show()
}
}
}

View file

@ -32,8 +32,8 @@
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="@string/app_name"
android:textStyle="bold"
android:textAppearance="@style/TextViewHeadline6" />
android:textAppearance="@style/TextViewHeadline6"
android:textStyle="bold" />
</androidx.appcompat.widget.Toolbar>
<ViewStub
@ -43,6 +43,16 @@
</FrameLayout>
</com.google.android.material.appbar.AppBarLayout>
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_marginBottom="72dp"
android:layout_marginEnd="16dp"
android:id="@+id/addPlaylist"
android:src="@drawable/ic_playlist_add"
app:useCompatPadding="true" />
<androidx.fragment.app.FragmentContainerView
android:id="@+id/fragment_container"
android:name="androidx.navigation.fragment.NavHostFragment"

View file

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/ic_launcher_background"/>
<background android:drawable="@mipmap/ic_launcher_background"/>
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
</adaptive-icon>

View file

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/ic_launcher_background"/>
<background android:drawable="@mipmap/ic_launcher_background"/>
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
</adaptive-icon>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.7 KiB

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.5 KiB

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.6 KiB

After

Width:  |  Height:  |  Size: 8.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.3 KiB

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.7 KiB

After

Width:  |  Height:  |  Size: 9.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.2 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.3 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 24 KiB