diff --git a/app/src/main/ic_launcher-playstore.png b/app/src/main/ic_launcher-playstore.png index f9c45db6..94550783 100644 Binary files a/app/src/main/ic_launcher-playstore.png and b/app/src/main/ic_launcher-playstore.png differ diff --git a/app/src/main/java/code/name/monkey/retromusic/Constants.kt b/app/src/main/java/code/name/monkey/retromusic/Constants.kt index 0f037ba7..32e91aca 100644 --- a/app/src/main/java/code/name/monkey/retromusic/Constants.kt +++ b/app/src/main/java/code/name/monkey/retromusic/Constants.kt @@ -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" diff --git a/app/src/main/java/code/name/monkey/retromusic/adapter/playlist/PlaylistAdapter.kt b/app/src/main/java/code/name/monkey/retromusic/adapter/playlist/PlaylistAdapter.kt index a4fa0914..7f1af392 100755 --- a/app/src/main/java/code/name/monkey/retromusic/adapter/playlist/PlaylistAdapter.kt +++ b/app/src/main/java/code/name/monkey/retromusic/adapter/playlist/PlaylistAdapter.kt @@ -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): List { val songs = ArrayList() - /* 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 } } diff --git a/app/src/main/java/code/name/monkey/retromusic/adapter/song/OrderablePlaylistSongAdapter.kt b/app/src/main/java/code/name/monkey/retromusic/adapter/song/OrderablePlaylistSongAdapter.kt index 2b3ccc3c..77aa8eb6 100644 --- a/app/src/main/java/code/name/monkey/retromusic/adapter/song/OrderablePlaylistSongAdapter.kt +++ b/app/src/main/java/code/name/monkey/retromusic/adapter/song/OrderablePlaylistSongAdapter.kt @@ -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, 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 } diff --git a/app/src/main/java/code/name/monkey/retromusic/db/PlaylistDao.kt b/app/src/main/java/code/name/monkey/retromusic/db/PlaylistDao.kt index 53f3ee65..f2266037 100644 --- a/app/src/main/java/code/name/monkey/retromusic/db/PlaylistDao.kt +++ b/app/src/main/java/code/name/monkey/retromusic/db/PlaylistDao.kt @@ -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 - @Insert - suspend fun createPlaylist(playlistEntity: PlaylistEntity): Long - @Query("SELECT * FROM PlaylistEntity") suspend fun playlists(): List + @Query("DELETE FROM SongEntity WHERE playlist_creator_id = :playlistId") + suspend fun deleteSongsFromPlaylist(playlistId: Int) + @Transaction @Query("SELECT * FROM PlaylistEntity") suspend fun playlistsWithSong(): List @@ -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 - @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 @Delete - suspend fun deletePlaylistEntity(playlistWithSongs: PlaylistWithSongs) + suspend fun deletePlaylistEntity(playlistEntity: PlaylistEntity) + + @Delete + suspend fun deletePlaylistEntities(playlistEntities: List) + + @Delete + suspend fun removeSongsFromPlaylist(songs: List) + } \ No newline at end of file diff --git a/app/src/main/java/code/name/monkey/retromusic/db/PlaylistWithSongs.kt b/app/src/main/java/code/name/monkey/retromusic/db/PlaylistWithSongs.kt index 405c7944..c69a415a 100644 --- a/app/src/main/java/code/name/monkey/retromusic/db/PlaylistWithSongs.kt +++ b/app/src/main/java/code/name/monkey/retromusic/db/PlaylistWithSongs.kt @@ -13,4 +13,5 @@ data class PlaylistWithSongs( entityColumn = "playlist_creator_id" ) val songs: List -):Parcelable \ No newline at end of file +):Parcelable + diff --git a/app/src/main/java/code/name/monkey/retromusic/db/SongEntity.kt b/app/src/main/java/code/name/monkey/retromusic/db/SongEntity.kt index 6d8b2e9d..715c0231 100644 --- a/app/src/main/java/code/name/monkey/retromusic/db/SongEntity.kt +++ b/app/src/main/java/code/name/monkey/retromusic/db/SongEntity.kt @@ -54,4 +54,10 @@ class SongEntity( albumArtist ) } +} + +fun List.toSongs(): List { + return map { + it.toSong() + } } \ No newline at end of file diff --git a/app/src/main/java/code/name/monkey/retromusic/dialogs/AddToRetroPlaylist.kt b/app/src/main/java/code/name/monkey/retromusic/dialogs/AddToRetroPlaylist.kt index 28d351bc..55519007 100644 --- a/app/src/main/java/code/name/monkey/retromusic/dialogs/AddToRetroPlaylist.kt +++ b/app/src/main/java/code/name/monkey/retromusic/dialogs/AddToRetroPlaylist.kt @@ -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() + private val libraryViewModel by sharedViewModel() + companion object { - fun getInstance(playlistName: List): AddToRetroPlaylist { + fun create(playlistEntities: List, song: Song): AddToRetroPlaylist { + val list = mutableListOf() + list.add(song) + return create(playlistEntities, list) + } + + fun create(playlistEntities: List, songs: List): 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>("playlist_names").value + val playlistEntities = extraNotNull>(EXTRA_PLAYLISTS).value val playlistNames = mutableListOf() 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>(EXTRA_SONG).value if (which == 0) { CreateRetroPlaylist().show(requireActivity().supportFragmentManager, "Dialog") } else { lifecycleScope.launch(Dispatchers.IO) { - val playlistRepository = get() val songEntities = songs.withPlaylistIds(playlistEntities[which - 1]) - playlistRepository.insertSongs(songEntities) + repository.insertSongs(songEntities) + libraryViewModel.forceReload(ReloadType.Playlists) } } dismiss() diff --git a/app/src/main/java/code/name/monkey/retromusic/dialogs/CreateRetroPlaylist.kt b/app/src/main/java/code/name/monkey/retromusic/dialogs/CreateRetroPlaylist.kt index 1b6f9867..6d237ebb 100644 --- a/app/src/main/java/code/name/monkey/retromusic/dialogs/CreateRetroPlaylist.kt +++ b/app/src/main/java/code/name/monkey/retromusic/dialogs/CreateRetroPlaylist.kt @@ -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() + private val repository by inject() private val libraryViewModel by sharedViewModel() 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() } } diff --git a/app/src/main/java/code/name/monkey/retromusic/dialogs/DeleteRetroPlaylist.kt b/app/src/main/java/code/name/monkey/retromusic/dialogs/DeleteRetroPlaylist.kt new file mode 100644 index 00000000..3b024044 --- /dev/null +++ b/app/src/main/java/code/name/monkey/retromusic/dialogs/DeleteRetroPlaylist.kt @@ -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() + private val libraryViewModel by sharedViewModel() + + companion object { + + fun create(playlist: PlaylistEntity): DeleteRetroPlaylist { + val list = mutableListOf() + list.add(playlist) + return create(list) + } + + fun create(playlists: List): DeleteRetroPlaylist { + return DeleteRetroPlaylist().apply { + arguments = bundleOf(EXTRA_PLAYLIST to playlists) + } + } + } + + override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { + val playlists = extraNotNull>(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() + } + +} \ No newline at end of file diff --git a/app/src/main/java/code/name/monkey/retromusic/dialogs/RemoveSongFromPlaylistDialog.kt b/app/src/main/java/code/name/monkey/retromusic/dialogs/RemoveSongFromPlaylistDialog.kt new file mode 100644 index 00000000..7193a5b3 --- /dev/null +++ b/app/src/main/java/code/name/monkey/retromusic/dialogs/RemoveSongFromPlaylistDialog.kt @@ -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() + private val libraryViewModel by sharedViewModel() + + companion object { + fun create(song: SongEntity): RemoveSongFromPlaylistDialog { + val list = mutableListOf() + list.add(song) + return create(list) + } + + fun create(songs: List): RemoveSongFromPlaylistDialog { + return RemoveSongFromPlaylistDialog().apply { + arguments = bundleOf( + EXTRA_SONG to songs + ) + } + } + } + + override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { + val songs = extraNotNull>(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 + )*/ + } + .setNegativeButton(android.R.string.cancel, null) + .create() + .colorButtons() + } +} \ No newline at end of file diff --git a/app/src/main/java/code/name/monkey/retromusic/dialogs/RenameRetroPlaylistDialog.kt b/app/src/main/java/code/name/monkey/retromusic/dialogs/RenameRetroPlaylistDialog.kt new file mode 100644 index 00000000..a12da522 --- /dev/null +++ b/app/src/main/java/code/name/monkey/retromusic/dialogs/RenameRetroPlaylistDialog.kt @@ -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() + private val libraryViewModel by sharedViewModel() + + 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(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() + } +} \ No newline at end of file diff --git a/app/src/main/java/code/name/monkey/retromusic/fragments/DetailListFragment.kt b/app/src/main/java/code/name/monkey/retromusic/fragments/DetailListFragment.kt index 53273281..e4045edd 100644 --- a/app/src/main/java/code/name/monkey/retromusic/fragments/DetailListFragment.kt +++ b/app/src/main/java/code/name/monkey/retromusic/fragments/DetailListFragment.kt @@ -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) diff --git a/app/src/main/java/code/name/monkey/retromusic/fragments/LibraryViewModel.kt b/app/src/main/java/code/name/monkey/retromusic/fragments/LibraryViewModel.kt index 53952e5c..852ccc56 100644 --- a/app/src/main/java/code/name/monkey/retromusic/fragments/LibraryViewModel.kt +++ b/app/src/main/java/code/name/monkey/retromusic/fragments/LibraryViewModel.kt @@ -33,7 +33,7 @@ class LibraryViewModel( val songsLiveData: LiveData> = songs val artistsLiveData: LiveData> = artists val playlisitsLiveData: LiveData> = playlists - val roomPlaylisitsLiveData: LiveData> = roomPlaylists + val roomPlaylistsLiveData: LiveData> = roomPlaylists val genresLiveData: LiveData> = 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> @@ -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() diff --git a/app/src/main/java/code/name/monkey/retromusic/fragments/albums/AlbumDetailsFragment.kt b/app/src/main/java/code/name/monkey/retromusic/fragments/albums/AlbumDetailsFragment.kt index 9bc60bd5..526cd5c9 100644 --- a/app/src/main/java/code/name/monkey/retromusic/fragments/albums/AlbumDetailsFragment.kt +++ b/app/src/main/java/code/name/monkey/retromusic/fragments/albums/AlbumDetailsFragment.kt @@ -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().roomPlaylists() + withContext(Dispatchers.Main) { + AddToRetroPlaylist.create(playlists, songs) + .show(childFragmentManager, "ADD_PLAYLIST") + } + } return true } R.id.action_delete_from_device -> { diff --git a/app/src/main/java/code/name/monkey/retromusic/fragments/artists/ArtistDetailsFragment.kt b/app/src/main/java/code/name/monkey/retromusic/fragments/artists/ArtistDetailsFragment.kt index 8fc574eb..58d59d1d 100644 --- a/app/src/main/java/code/name/monkey/retromusic/fragments/artists/ArtistDetailsFragment.kt +++ b/app/src/main/java/code/name/monkey/retromusic/fragments/artists/ArtistDetailsFragment.kt @@ -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().roomPlaylists() + withContext(Dispatchers.Main) { + AddToRetroPlaylist.create(playlists, songs) + .show(childFragmentManager, "ADD_PLAYLIST") + } + } return true } R.id.action_set_artist_image -> { diff --git a/app/src/main/java/code/name/monkey/retromusic/fragments/base/AbsPlayerFragment.kt b/app/src/main/java/code/name/monkey/retromusic/fragments/base/AbsPlayerFragment.kt index f37423fe..ed4e7f91 100644 --- a/app/src/main/java/code/name/monkey/retromusic/fragments/base/AbsPlayerFragment.kt +++ b/app/src/main/java/code/name/monkey/retromusic/fragments/base/AbsPlayerFragment.kt @@ -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().roomPlaylists() + withContext(Dispatchers.Main) { + AddToRetroPlaylist.create(playlists, song) + .show(childFragmentManager, "ADD_PLAYLIST") + } + } return true } R.id.action_clear_playing_queue -> { diff --git a/app/src/main/java/code/name/monkey/retromusic/fragments/library/LibraryFragment.kt b/app/src/main/java/code/name/monkey/retromusic/fragments/library/LibraryFragment.kt index 2868a368..6a4b9f0d 100644 --- a/app/src/main/java/code/name/monkey/retromusic/fragments/library/LibraryFragment.kt +++ b/app/src/main/java/code/name/monkey/retromusic/fragments/library/LibraryFragment.kt @@ -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() - 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 - } } \ No newline at end of file diff --git a/app/src/main/java/code/name/monkey/retromusic/fragments/playlists/PlaylistDetailsFragment.kt b/app/src/main/java/code/name/monkey/retromusic/fragments/playlists/PlaylistDetailsFragment.kt index e8b65a1e..beaedd5a 100644 --- a/app/src/main/java/code/name/monkey/retromusic/fragments/playlists/PlaylistDetailsFragment.kt +++ b/app/src/main/java/code/name/monkey/retromusic/fragments/playlists/PlaylistDetailsFragment.kt @@ -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() { diff --git a/app/src/main/java/code/name/monkey/retromusic/fragments/playlists/PlaylistsFragment.kt b/app/src/main/java/code/name/monkey/retromusic/fragments/playlists/PlaylistsFragment.kt index 6659fca1..cd3a2f60 100644 --- a/app/src/main/java/code/name/monkey/retromusic/fragments/playlists/PlaylistsFragment.kt +++ b/app/src/main/java/code/name/monkey/retromusic/fragments/playlists/PlaylistsFragment.kt @@ -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 diff --git a/app/src/main/java/code/name/monkey/retromusic/fragments/settings/OtherSettingsFragment.kt b/app/src/main/java/code/name/monkey/retromusic/fragments/settings/OtherSettingsFragment.kt index 2338c6f7..c52d4adb 100644 --- a/app/src/main/java/code/name/monkey/retromusic/fragments/settings/OtherSettingsFragment.kt +++ b/app/src/main/java/code/name/monkey/retromusic/fragments/settings/OtherSettingsFragment.kt @@ -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() 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") diff --git a/app/src/main/java/code/name/monkey/retromusic/helper/menu/GenreMenuHelper.kt b/app/src/main/java/code/name/monkey/retromusic/helper/menu/GenreMenuHelper.kt index 08b9c3a2..df43e38d 100644 --- a/app/src/main/java/code/name/monkey/retromusic/helper/menu/GenreMenuHelper.kt +++ b/app/src/main/java/code/name/monkey/retromusic/helper/menu/GenreMenuHelper.kt @@ -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().roomPlaylists() + withContext(Dispatchers.Main) { + AddToRetroPlaylist.create(playlists, getGenreSongs(genre)) + .show(activity.supportFragmentManager, "ADD_PLAYLIST") + } + } return true } R.id.action_add_to_current_playing -> { diff --git a/app/src/main/java/code/name/monkey/retromusic/helper/menu/PlaylistMenuHelper.kt b/app/src/main/java/code/name/monkey/retromusic/helper/menu/PlaylistMenuHelper.kt index 37e5e3d1..9314e4ee 100644 --- a/app/src/main/java/code/name/monkey/retromusic/helper/menu/PlaylistMenuHelper.kt +++ b/app/src/main/java/code/name/monkey/retromusic/helper/menu/PlaylistMenuHelper.kt @@ -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().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 } } diff --git a/app/src/main/java/code/name/monkey/retromusic/helper/menu/SongMenuHelper.kt b/app/src/main/java/code/name/monkey/retromusic/helper/menu/SongMenuHelper.kt index 0fb27c98..115926de 100644 --- a/app/src/main/java/code/name/monkey/retromusic/helper/menu/SongMenuHelper.kt +++ b/app/src/main/java/code/name/monkey/retromusic/helper/menu/SongMenuHelper.kt @@ -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().roomPlaylists() + withContext(Dispatchers.Main) { + AddToRetroPlaylist.create(playlists, song) + .show(activity.supportFragmentManager, "ADD_PLAYLIST") + } + } return true } R.id.action_play_next -> { diff --git a/app/src/main/java/code/name/monkey/retromusic/helper/menu/SongsMenuHelper.kt b/app/src/main/java/code/name/monkey/retromusic/helper/menu/SongsMenuHelper.kt index 871619e1..058de45f 100644 --- a/app/src/main/java/code/name/monkey/retromusic/helper/menu/SongsMenuHelper.kt +++ b/app/src/main/java/code/name/monkey/retromusic/helper/menu/SongsMenuHelper.kt @@ -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, @@ -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().roomPlaylists() + withContext(Dispatchers.Main) { + AddToRetroPlaylist.create(playlists, songs) + .show(activity.supportFragmentManager, "ADD_PLAYLIST") + } + } return true } R.id.action_delete_from_device -> { diff --git a/app/src/main/java/code/name/monkey/retromusic/repository/Repository.kt b/app/src/main/java/code/name/monkey/retromusic/repository/Repository.kt index ab3a05fb..dab9e818 100644 --- a/app/src/main/java/code/name/monkey/retromusic/repository/Repository.kt +++ b/app/src/main/java/code/name/monkey/retromusic/repository/Repository.kt @@ -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>> + + fun albumsFlow(): Flow>> + + fun artistsFlow(): Flow>> + + fun playlistsFlow(): Flow>> + + fun genresFlow(): Flow>> + + suspend fun allAlbums(): List suspend fun albumById(albumId: Int): Album @@ -89,16 +102,21 @@ interface Repository { suspend fun playlistSongs(playlistWithSongs: PlaylistWithSongs): List - fun songsFlow(): Flow>> + suspend fun insertSongs(songs: List) - fun albumsFlow(): Flow>> + suspend fun checkPlaylistExists(playlistName: String): List - fun artistsFlow(): Flow>> + suspend fun createPlaylist(playlistEntity: PlaylistEntity): Long - fun playlistsFlow(): Flow>> + suspend fun roomPlaylists(): List - fun genresFlow(): Flow>> + suspend fun deleteRoomPlaylist(playlists: List) + suspend fun renameRoomPlaylist(playlistId: Int, name: String) + + suspend fun removeSongFromPlaylist(songs: List) + + suspend fun deleteSongsFromPlaylist(playlists: List) } 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 = roomPlaylistRepository.playlistWithSongs() - override suspend fun playlistSongs(playlistWithSongs: PlaylistWithSongs ): List { + override suspend fun playlistSongs(playlistWithSongs: PlaylistWithSongs): List { return playlistWithSongs.songs.map { - it.toSong() + it.toSong() } } + override suspend fun insertSongs(songs: List) = + roomPlaylistRepository.insertSongs(songs) + + override suspend fun checkPlaylistExists(playlistName: String): List = + roomPlaylistRepository.checkPlaylistExists(playlistName) + + override suspend fun createPlaylist(playlistEntity: PlaylistEntity): Long = + roomPlaylistRepository.createPlaylist(playlistEntity) + + override suspend fun roomPlaylists(): List = roomPlaylistRepository.playlists() + + override suspend fun deleteRoomPlaylist(playlists: List) = + roomPlaylistRepository.deletePlaylistEntities(playlists) + + override suspend fun renameRoomPlaylist(playlistId: Int, name: String) = + roomPlaylistRepository.renamePlaylistEntity(playlistId, name) + + override suspend fun removeSongFromPlaylist(songs: List) = + roomPlaylistRepository.removeSongsFromPlaylist(songs) + + override suspend fun deleteSongsFromPlaylist(playlists: List) = + roomPlaylistRepository.deleteSongsFromPlaylist(playlists) + override suspend fun suggestionsHome(): Home { val songs = NotPlayedPlaylist().songs().shuffled().takeIf { diff --git a/app/src/main/java/code/name/monkey/retromusic/repository/RoomPlaylistRepository.kt b/app/src/main/java/code/name/monkey/retromusic/repository/RoomPlaylistRepository.kt index d303a861..b7b8e009 100644 --- a/app/src/main/java/code/name/monkey/retromusic/repository/RoomPlaylistRepository.kt +++ b/app/src/main/java/code/name/monkey/retromusic/repository/RoomPlaylistRepository.kt @@ -14,9 +14,15 @@ interface RoomPlaylistRepository { suspend fun playlistWithSongs(): List suspend fun insertSongs(songs: List) suspend fun getSongs(playlistEntity: PlaylistEntity): List + suspend fun deletePlaylistEntities(playlistEntities: List) + suspend fun renamePlaylistEntity(playlistId: Int, name: String) + suspend fun removeSongsFromPlaylist(songs: List) + suspend fun deleteSongsFromPlaylist(playlists: List) } -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 { return playlistDao.getSongs(playlistEntity.playListId) } + + override suspend fun deletePlaylistEntities(playlistEntities: List) = + playlistDao.deletePlaylistEntities(playlistEntities) + + override suspend fun renamePlaylistEntity(playlistId: Int, name: String) = + playlistDao.renamePlaylistEntity(playlistId, name) + + override suspend fun removeSongsFromPlaylist(songs: List) = + playlistDao.removeSongsFromPlaylist(songs) + + override suspend fun deleteSongsFromPlaylist(playlists: List) { + playlists.forEach { + playlistDao.deleteSongsFromPlaylist(it.playListId) + } + } + } \ No newline at end of file diff --git a/app/src/main/java/code/name/monkey/retromusic/util/AppRater.kt b/app/src/main/java/code/name/monkey/retromusic/util/AppRater.kt index 6cbeb1fb..8b12c41e 100644 --- a/app/src/main/java/code/name/monkey/retromusic/util/AppRater.kt +++ b/app/src/main/java/code/name/monkey/retromusic/util/AppRater.kt @@ -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() } } } diff --git a/app/src/main/res/layout/fragment_library.xml b/app/src/main/res/layout/fragment_library.xml index bc0ec2a8..5d61e740 100644 --- a/app/src/main/res/layout/fragment_library.xml +++ b/app/src/main/res/layout/fragment_library.xml @@ -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" /> + + - + \ No newline at end of file diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml index 036d09bc..4ae7d123 100644 --- a/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml +++ b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml @@ -1,5 +1,5 @@ - + \ No newline at end of file diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher.png b/app/src/main/res/mipmap-hdpi/ic_launcher.png index ef3cfc0a..b5c2dab1 100644 Binary files a/app/src/main/res/mipmap-hdpi/ic_launcher.png and b/app/src/main/res/mipmap-hdpi/ic_launcher.png differ diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher_background.png b/app/src/main/res/mipmap-hdpi/ic_launcher_background.png new file mode 100644 index 00000000..94cbef3c Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/ic_launcher_background.png differ diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png b/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png index ba687419..a7a2521b 100644 Binary files a/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png and b/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png differ diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher_round.png b/app/src/main/res/mipmap-hdpi/ic_launcher_round.png index 6c46ac4c..e79f3cbb 100644 Binary files a/app/src/main/res/mipmap-hdpi/ic_launcher_round.png and b/app/src/main/res/mipmap-hdpi/ic_launcher_round.png differ diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher.png b/app/src/main/res/mipmap-mdpi/ic_launcher.png index 4e45638f..6dff6080 100644 Binary files a/app/src/main/res/mipmap-mdpi/ic_launcher.png and b/app/src/main/res/mipmap-mdpi/ic_launcher.png differ diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher_background.png b/app/src/main/res/mipmap-mdpi/ic_launcher_background.png new file mode 100644 index 00000000..41be5687 Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/ic_launcher_background.png differ diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png b/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png index 5fe585e3..1f9c1cef 100644 Binary files a/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png and b/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png differ diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher_round.png b/app/src/main/res/mipmap-mdpi/ic_launcher_round.png index 00668b42..989a7c13 100644 Binary files a/app/src/main/res/mipmap-mdpi/ic_launcher_round.png and b/app/src/main/res/mipmap-mdpi/ic_launcher_round.png differ diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/app/src/main/res/mipmap-xhdpi/ic_launcher.png index 23394228..2670ecb0 100644 Binary files a/app/src/main/res/mipmap-xhdpi/ic_launcher.png and b/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher_background.png b/app/src/main/res/mipmap-xhdpi/ic_launcher_background.png new file mode 100644 index 00000000..c775d1c8 Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/ic_launcher_background.png differ diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png b/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png index bcaf1a42..5b187906 100644 Binary files a/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png and b/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png differ diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png index c998e206..23ab4168 100644 Binary files a/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png and b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png differ diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/app/src/main/res/mipmap-xxhdpi/ic_launcher.png index 9142374e..959c0ceb 100644 Binary files a/app/src/main/res/mipmap-xxhdpi/ic_launcher.png and b/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher_background.png b/app/src/main/res/mipmap-xxhdpi/ic_launcher_background.png new file mode 100644 index 00000000..a42cd921 Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_launcher_background.png differ diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png b/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png index 451e815e..40e35c0a 100644 Binary files a/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png and b/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png differ diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png index 663d2450..c9740192 100644 Binary files a/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png and b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png differ diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png index e78b0afd..42e4cf59 100644 Binary files a/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png and b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_background.png b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_background.png new file mode 100644 index 00000000..0282220d Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_background.png differ diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png index 3f076e2d..055c6ed8 100644 Binary files a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png and b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png differ diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png index 8b5d5d8d..471bfebe 100644 Binary files a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png and b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png differ