11package com.github.libretube.ui.dialogs
22
3- import android.annotation.SuppressLint
43import android.app.Dialog
54import android.content.DialogInterface
65import android.os.Bundle
76import android.util.Log
87import android.widget.Toast
98import androidx.core.os.bundleOf
109import androidx.fragment.app.DialogFragment
11- import androidx.fragment.app.activityViewModels
1210import androidx.fragment.app.setFragmentResult
13- import androidx.lifecycle.Lifecycle
14- import androidx.lifecycle.lifecycleScope
15- import androidx.lifecycle.repeatOnLifecycle
11+ import androidx.fragment.app.viewModels
1612import com.github.libretube.R
17- import com.github.libretube.api.PlaylistsHelper
18- import com.github.libretube.api.obj.Playlists
1913import com.github.libretube.api.obj.StreamItem
2014import com.github.libretube.constants.IntentData
2115import com.github.libretube.databinding.DialogAddToPlaylistBinding
22- import com.github.libretube.extensions.TAG
2316import com.github.libretube.extensions.parcelable
24- import com.github.libretube.extensions.toastFromMainDispatcher
2517import com.github.libretube.ui.models.PlaylistViewModel
26- import com.github.libretube.util.PlayingQueue
2718import com.google.android.material.dialog.MaterialAlertDialogBuilder
28- import kotlinx.coroutines.launch
2919
3020/* *
3121 * Dialog to insert new videos to a playlist
3222 * videoId: The id of the video to add. If non is provided, insert the whole playing queue
3323 */
3424class AddToPlaylistDialog : DialogFragment () {
35- private var videoInfo: StreamItem ? = null
36- private val viewModel: PlaylistViewModel by activityViewModels()
3725
38- var playlists = emptyList<Playlists >()
26+ private var videoInfo: StreamItem ? = null
27+ private val viewModel: PlaylistViewModel by viewModels { PlaylistViewModel .Factory }
3928
4029 override fun onCreate (savedInstanceState : Bundle ? ) {
4130 super .onCreate(savedInstanceState)
@@ -44,19 +33,39 @@ class AddToPlaylistDialog : DialogFragment() {
4433 }
4534
4635 override fun onCreateDialog (savedInstanceState : Bundle ? ): Dialog {
47- val binding = DialogAddToPlaylistBinding .inflate(layoutInflater)
48-
4936 childFragmentManager.setFragmentResultListener(
5037 CreatePlaylistDialog .CREATE_PLAYLIST_DIALOG_REQUEST_KEY ,
5138 this
5239 ) { _, resultBundle ->
5340 val addedToPlaylist = resultBundle.getBoolean(IntentData .playlistTask)
5441 if (addedToPlaylist) {
55- fetchPlaylists(binding )
42+ viewModel. fetchPlaylists()
5643 }
5744 }
5845
59- fetchPlaylists(binding)
46+ val binding = DialogAddToPlaylistBinding .inflate(layoutInflater)
47+ viewModel.uiState.observe(this ) { (lastSelectedPlaylistId, playlists, msg, saved) ->
48+ binding.playlistsSpinner.items = playlists.mapNotNull { it.name }
49+
50+ // select the last used playlist
51+ lastSelectedPlaylistId?.let { id ->
52+ binding.playlistsSpinner.selectedItemPosition = playlists
53+ .indexOfFirst { it.id == id }
54+ .takeIf { it >= 0 } ? : 0
55+ }
56+
57+ msg?.let {
58+ with (binding.root.context) {
59+ Toast .makeText(this , getString(it.resId, it.formatArgs), Toast .LENGTH_SHORT ).show()
60+ }
61+ viewModel.onMessageShown()
62+ }
63+
64+ saved?.let {
65+ dismiss()
66+ viewModel.onDismissed()
67+ }
68+ }
6069
6170 return MaterialAlertDialogBuilder (requireContext())
6271 .setTitle(R .string.addToPlaylist)
@@ -65,71 +74,17 @@ class AddToPlaylistDialog : DialogFragment() {
6574 .setView(binding.root)
6675 .show()
6776 .apply {
77+ // Click listeners without closing the dialog
6878 getButton(DialogInterface .BUTTON_NEGATIVE ).setOnClickListener {
6979 CreatePlaylistDialog ().show(childFragmentManager, null )
7080 }
7181 getButton(DialogInterface .BUTTON_POSITIVE ).setOnClickListener {
72- val playlistIndex = binding.playlistsSpinner.selectedItemPosition
73-
74- val playlist = playlists.getOrElse(playlistIndex) { return @setOnClickListener }
75- viewModel.lastSelectedPlaylistId = playlist.id!!
76-
77- dialog?.hide()
78- lifecycleScope.launch {
79- addToPlaylist(playlist.id, playlist.name!! )
80- dialog?.dismiss()
81- }
82+ val selectedItemPosition = binding.playlistsSpinner.selectedItemPosition
83+ viewModel.onAddToPlaylist(selectedItemPosition)
8284 }
8385 }
8486 }
8587
86- private fun fetchPlaylists (binding : DialogAddToPlaylistBinding ) {
87- lifecycleScope.launch {
88- repeatOnLifecycle(Lifecycle .State .CREATED ) {
89- playlists = try {
90- PlaylistsHelper .getPlaylists()
91- } catch (e: Exception ) {
92- Log .e(TAG (), e.toString())
93- Toast .makeText(context, R .string.unknown_error, Toast .LENGTH_SHORT ).show()
94- return @repeatOnLifecycle
95- }.filter { ! it.name.isNullOrEmpty() }
96-
97- binding.playlistsSpinner.items = playlists.map { it.name!! }
98-
99- if (playlists.isEmpty()) return @repeatOnLifecycle
100-
101- // select the last used playlist
102- viewModel.lastSelectedPlaylistId?.let { id ->
103- binding.playlistsSpinner.selectedItemPosition = playlists
104- .indexOfFirst { it.id == id }
105- .takeIf { it >= 0 } ? : 0
106- }
107- }
108- }
109- }
110-
111- @SuppressLint(" StringFormatInvalid" )
112- private suspend fun addToPlaylist (playlistId : String , playlistName : String ) {
113- val appContext = context?.applicationContext ? : return
114- val streams = videoInfo?.let { listOf (it) } ? : PlayingQueue .getStreams()
115-
116- val success = try {
117- if (streams.isEmpty()) throw IllegalArgumentException ()
118- PlaylistsHelper .addToPlaylist(playlistId, * streams.toTypedArray())
119- } catch (e: Exception ) {
120- Log .e(TAG (), e.toString())
121- appContext.toastFromMainDispatcher(R .string.unknown_error)
122- return
123- }
124- if (success) {
125- appContext.toastFromMainDispatcher(
126- appContext.getString(R .string.added_to_playlist, playlistName)
127- )
128- } else {
129- appContext.toastFromMainDispatcher(R .string.fail)
130- }
131- }
132-
13388 override fun onDismiss (dialog : DialogInterface ) {
13489 super .onDismiss(dialog)
13590
0 commit comments