diff --git a/app/src/main/java/code/name/monkey/retromusic/db/SongExtension.kt b/app/src/main/java/code/name/monkey/retromusic/db/SongExtension.kt index 617e3a71..d5f009e0 100644 --- a/app/src/main/java/code/name/monkey/retromusic/db/SongExtension.kt +++ b/app/src/main/java/code/name/monkey/retromusic/db/SongExtension.kt @@ -86,4 +86,10 @@ fun Song.toPlayCount(): PlayCountEntity { System.currentTimeMillis(), 1 ) -} \ No newline at end of file +} + +fun List.toSongsEntity(playlistEntity: PlaylistEntity): List { + return map { + it.toSongEntity(playlistEntity.playListId) + } +} diff --git a/app/src/main/java/code/name/monkey/retromusic/dialogs/AddToPlaylistDialog.kt b/app/src/main/java/code/name/monkey/retromusic/dialogs/AddToPlaylistDialog.kt index 4faa019a..53acaa25 100644 --- a/app/src/main/java/code/name/monkey/retromusic/dialogs/AddToPlaylistDialog.kt +++ b/app/src/main/java/code/name/monkey/retromusic/dialogs/AddToPlaylistDialog.kt @@ -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() companion object { fun create(playlistEntities: List, song: Song): AddToPlaylistDialog { - val list = mutableListOf() + val list: MutableList = mutableListOf() list.add(song) return create(playlistEntities, list) } @@ -41,12 +42,13 @@ class AddToPlaylistDialog : BottomSheetDialogFragment() { } override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { - val playlistEntities = extraNotNull>(EXTRA_PLAYLISTS).value - val songs = extraNotNull>(EXTRA_SONG).value - val playlistNames = mutableListOf() + val playlistEntities: List = + extraNotNull>(EXTRA_PLAYLISTS).value + val songs: List = extraNotNull>(EXTRA_SONG).value + val playlistNames: MutableList = 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 = + songs.toSongsEntity(playlistEntities[which - 1]) libraryViewModel.insertSongs(songEntities) libraryViewModel.forceReload(Playlists) } @@ -64,10 +67,4 @@ class AddToPlaylistDialog : BottomSheetDialogFragment() { } .create().colorButtons() } -} - -private fun List.toSongEntity(playlistEntity: PlaylistEntity): List { - return map { - it.toSongEntity(playlistEntity.playListId) - } -} +} \ No newline at end of file diff --git a/app/src/main/java/code/name/monkey/retromusic/dialogs/SavePlaylistDialog.kt b/app/src/main/java/code/name/monkey/retromusic/dialogs/SavePlaylistDialog.kt index b392f61b..dd92a9a2 100644 --- a/app/src/main/java/code/name/monkey/retromusic/dialogs/SavePlaylistDialog.kt +++ b/app/src/main/java/code/name/monkey/retromusic/dialogs/SavePlaylistDialog.kt @@ -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(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() + } } \ No newline at end of file diff --git a/app/src/main/java/code/name/monkey/retromusic/helper/M3UWriter.kt b/app/src/main/java/code/name/monkey/retromusic/helper/M3UWriter.kt index daf0102a..35e87d80 100644 --- a/app/src/main/java/code/name/monkey/retromusic/helper/M3UWriter.kt +++ b/app/src/main/java/code/name/monkey/retromusic/helper/M3UWriter.kt @@ -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 = 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 + } } \ No newline at end of file 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 1640fe4e..971193e0 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 @@ -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 { - return if (playlist is AbsCustomPlaylist) { - playlist.songs() - } else { - playlist.getSongs() - } - } - - private class SavePlaylistAsyncTask(context: Context) : - WeakContextAsyncTask(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() - } - } - } } diff --git a/app/src/main/java/code/name/monkey/retromusic/util/PlaylistsUtil.java b/app/src/main/java/code/name/monkey/retromusic/util/PlaylistsUtil.java index c7b32229..cc2dad88 100644 --- a/app/src/main/java/code/name/monkey/retromusic/util/PlaylistsUtil.java +++ b/app/src/main/java/code/name/monkey/retromusic/util/PlaylistsUtil.java @@ -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 + "=?", diff --git a/app/src/main/res/layout/loading.xml b/app/src/main/res/layout/loading.xml index 54c6d3c1..6ae87157 100644 --- a/app/src/main/res/layout/loading.xml +++ b/app/src/main/res/layout/loading.xml @@ -20,7 +20,7 @@ android:padding="14dp">