Add save playlist 💾

This commit is contained in:
Hemanth S 2020-09-06 00:21:44 +05:30
parent 41e8aa8a03
commit 6e8ff6ab71
7 changed files with 105 additions and 60 deletions

View file

@ -87,3 +87,9 @@ fun Song.toPlayCount(): PlayCountEntity {
1
)
}
fun List<Song>.toSongsEntity(playlistEntity: PlaylistEntity): List<SongEntity> {
return map {
it.toSongEntity(playlistEntity.playListId)
}
}

View file

@ -3,29 +3,30 @@ package code.name.monkey.retromusic.dialogs
import android.app.Dialog
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.db.SongEntity
import code.name.monkey.retromusic.db.toSongsEntity
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.Playlists
import code.name.monkey.retromusic.model.Song
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import org.koin.androidx.viewmodel.ext.android.sharedViewModel
class AddToPlaylistDialog : BottomSheetDialogFragment() {
class AddToPlaylistDialog : DialogFragment() {
private val libraryViewModel by sharedViewModel<LibraryViewModel>()
companion object {
fun create(playlistEntities: List<PlaylistEntity>, song: Song): AddToPlaylistDialog {
val list = mutableListOf<Song>()
val list: MutableList<Song> = mutableListOf()
list.add(song)
return create(playlistEntities, list)
}
@ -41,12 +42,13 @@ class AddToPlaylistDialog : BottomSheetDialogFragment() {
}
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
val playlistEntities = extraNotNull<List<PlaylistEntity>>(EXTRA_PLAYLISTS).value
val songs = extraNotNull<List<Song>>(EXTRA_SONG).value
val playlistNames = mutableListOf<String>()
val playlistEntities: List<PlaylistEntity> =
extraNotNull<List<PlaylistEntity>>(EXTRA_PLAYLISTS).value
val songs: List<Song> = extraNotNull<List<Song>>(EXTRA_SONG).value
val playlistNames: MutableList<String> = mutableListOf()
playlistNames.add(requireContext().resources.getString(R.string.action_new_playlist))
for (p in playlistEntities) {
playlistNames.add(p.playlistName)
for (entity: PlaylistEntity in playlistEntities) {
playlistNames.add(entity.playlistName)
}
return materialDialog(R.string.add_playlist_title)
.setItems(playlistNames.toTypedArray()) { _, which ->
@ -55,7 +57,8 @@ class AddToPlaylistDialog : BottomSheetDialogFragment() {
.show(requireActivity().supportFragmentManager, "Dialog")
} else {
lifecycleScope.launch(Dispatchers.IO) {
val songEntities = songs.toSongEntity(playlistEntities[which - 1])
val songEntities: List<SongEntity> =
songs.toSongsEntity(playlistEntities[which - 1])
libraryViewModel.insertSongs(songEntities)
libraryViewModel.forceReload(Playlists)
}
@ -65,9 +68,3 @@ class AddToPlaylistDialog : BottomSheetDialogFragment() {
.create().colorButtons()
}
}
private fun List<Song>.toSongEntity(playlistEntity: PlaylistEntity): List<SongEntity> {
return map {
it.toSongEntity(playlistEntity.playListId)
}
}

View file

@ -1,4 +1,55 @@
package code.name.monkey.retromusic.dialogs
class SavePlaylistDialog {
import android.app.Dialog
import android.os.Bundle
import android.widget.Toast
import androidx.core.os.bundleOf
import androidx.fragment.app.DialogFragment
import androidx.lifecycle.lifecycleScope
import code.name.monkey.retromusic.App
import code.name.monkey.retromusic.EXTRA_PLAYLIST
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.db.PlaylistWithSongs
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.util.PlaylistsUtil
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
class SavePlaylistDialog : DialogFragment() {
companion object {
fun create(playlistWithSongs: PlaylistWithSongs): SavePlaylistDialog {
return SavePlaylistDialog().apply {
arguments = bundleOf(
EXTRA_PLAYLIST to playlistWithSongs
)
}
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
lifecycleScope.launch(Dispatchers.IO) {
val playlistWithSongs: PlaylistWithSongs =
extraNotNull<PlaylistWithSongs>(EXTRA_PLAYLIST).value
val file = PlaylistsUtil.savePlaylistWithSongs(requireContext(), playlistWithSongs)
withContext(Dispatchers.Main) {
Toast.makeText(
requireContext(),
String.format(App.getContext().getString(R.string.saved_playlist_to), file),
Toast.LENGTH_LONG
).show()
dismiss()
}
}
}
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
return materialDialog(R.string.save_playlist_title)
.setView(R.layout.loading)
.create().colorButtons()
}
}

View file

@ -13,7 +13,10 @@
*/
package code.name.monkey.retromusic.helper
import code.name.monkey.retromusic.db.PlaylistWithSongs
import code.name.monkey.retromusic.db.toSongs
import code.name.monkey.retromusic.model.Playlist
import code.name.monkey.retromusic.model.Song
import java.io.BufferedWriter
import java.io.File
import java.io.FileWriter
@ -42,4 +45,25 @@ object M3UWriter : M3UConstants {
}
return file
}
@JvmStatic
@Throws(IOException::class)
fun writeIO(dir: File, playlistWithSongs: PlaylistWithSongs): File {
if (!dir.exists()) dir.mkdirs()
val fileName = "${playlistWithSongs.playlistEntity.playlistName}.${M3UConstants.EXTENSION}"
val file = File(dir, fileName)
val songs: List<Song> = playlistWithSongs.songs.toSongs()
if (songs.isNotEmpty()) {
val bufferedWriter = BufferedWriter(FileWriter(file))
bufferedWriter.write(M3UConstants.HEADER)
songs.forEach {
bufferedWriter.newLine()
bufferedWriter.write(M3UConstants.ENTRY + it.duration + M3UConstants.DURATION_SEPARATOR + it.artistName + " - " + it.title)
bufferedWriter.newLine()
bufferedWriter.write(it.data)
}
bufferedWriter.close()
}
return file
}
}

View file

@ -15,24 +15,17 @@
package code.name.monkey.retromusic.helper.menu
import android.content.Context
import android.view.MenuItem
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.db.PlaylistWithSongs
import code.name.monkey.retromusic.db.toSongs
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.dialogs.SavePlaylistDialog
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
@ -81,42 +74,11 @@ object PlaylistMenuHelper : KoinComponent {
return true
}
R.id.action_save_playlist -> {
//SavePlaylistAsyncTask(activity).execute(playlistWithSongs.songs.toSongs())
Toast.makeText(activity, "Coming soon", Toast.LENGTH_SHORT).show()
SavePlaylistDialog.create(playlistWithSongs)
.show(activity.supportFragmentManager, "SavePlaylist")
return true
}
}
return false
}
private fun getPlaylistSongs(
playlist: Playlist
): List<Song> {
return if (playlist is AbsCustomPlaylist) {
playlist.songs()
} else {
playlist.getSongs()
}
}
private class SavePlaylistAsyncTask(context: Context) :
WeakContextAsyncTask<Playlist, String, String>(context) {
override fun doInBackground(vararg params: Playlist): String {
return String.format(
App.getContext().getString(
R.string
.saved_playlist_to
), PlaylistsUtil.savePlaylist(App.getContext(), params[0])
)
}
override fun onPostExecute(string: String) {
super.onPostExecute(string)
val context = context
if (context != null) {
Toast.makeText(context, string, Toast.LENGTH_LONG).show()
}
}
}
}

View file

@ -33,6 +33,7 @@ import java.util.ArrayList;
import java.util.List;
import code.name.monkey.retromusic.R;
import code.name.monkey.retromusic.db.PlaylistWithSongs;
import code.name.monkey.retromusic.helper.M3UWriter;
import code.name.monkey.retromusic.model.Playlist;
import code.name.monkey.retromusic.model.PlaylistSong;
@ -250,6 +251,10 @@ public class PlaylistsUtil {
return M3UWriter.write(new File(Environment.getExternalStorageDirectory(), "Playlists"), playlist);
}
public static File savePlaylistWithSongs(Context context, PlaylistWithSongs playlist) throws IOException {
return M3UWriter.writeIO(new File(Environment.getExternalStorageDirectory(), "Playlists"), playlist);
}
public static boolean doesPlaylistExist(@NonNull final Context context, final int playlistId) {
return playlistId != -1 && doesPlaylistExist(context,
MediaStore.Audio.Playlists._ID + "=?",

View file

@ -20,7 +20,7 @@
android:padding="14dp">
<ProgressBar
style="@style/Widget.AppCompat.ProgressBar.Horizontal"
style="@style/Widget.MaterialComponents.ProgressIndicator.Linear.Indeterminate"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:indeterminate="true" />