refactor: use Bundle for DialogFragment arguments

- ColorPickerDialog
- DeletePlaylistDialog
- RenamePlaylistDialog
This commit is contained in:
Ansh Tyagi 2023-09-05 18:11:42 +05:30 committed by Bnyro
parent 1044fcd153
commit f260c48f0a
8 changed files with 117 additions and 65 deletions

View File

@ -17,6 +17,7 @@ object IntentData {
const val minimizeByDefault = "minimizeByDefault" const val minimizeByDefault = "minimizeByDefault"
const val query = "query" const val query = "query"
const val playlistDescription = "playlistDescription" const val playlistDescription = "playlistDescription"
const val playlistName = "playlistName"
const val shareObjectType = "shareObjectType" const val shareObjectType = "shareObjectType"
const val shareData = "shareData" const val shareData = "shareData"
const val currentPosition = "currentPosition" const val currentPosition = "currentPosition"
@ -27,4 +28,5 @@ object IntentData {
const val playlistTask = "playlistTask" const val playlistTask = "playlistTask"
const val loginTask = "loginTask" const val loginTask = "loginTask"
const val logoutTask = "logoutTask" const val logoutTask = "logoutTask"
const val color = "color"
} }

View File

@ -3,8 +3,6 @@ package com.github.libretube.extensions
import android.os.Build import android.os.Build
import android.os.Bundle import android.os.Bundle
import android.os.Parcelable import android.os.Parcelable
import androidx.annotation.OptIn
import androidx.core.os.BuildCompat
import androidx.core.os.BundleCompat import androidx.core.os.BundleCompat
import java.io.Serializable import java.io.Serializable
@ -12,9 +10,8 @@ inline fun <reified T : Parcelable> Bundle.parcelable(key: String?): T? {
return BundleCompat.getParcelable(this, key, T::class.java) return BundleCompat.getParcelable(this, key, T::class.java)
} }
@OptIn(BuildCompat.PrereleaseSdkCheck::class)
inline fun <reified T : Serializable> Bundle.serializable(key: String): T? { inline fun <reified T : Serializable> Bundle.serializable(key: String): T? {
return if (BuildCompat.isAtLeastU()) { return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
getSerializable(key, T::class.java) getSerializable(key, T::class.java)
} else { } else {
@Suppress("DEPRECATION") @Suppress("DEPRECATION")

View File

@ -5,6 +5,7 @@ import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import com.github.libretube.R import com.github.libretube.R
import com.github.libretube.api.obj.Playlists import com.github.libretube.api.obj.Playlists
import com.github.libretube.constants.IntentData
import com.github.libretube.databinding.PlaylistsRowBinding import com.github.libretube.databinding.PlaylistsRowBinding
import com.github.libretube.enums.PlaylistType import com.github.libretube.enums.PlaylistType
import com.github.libretube.helpers.ImageHelper import com.github.libretube.helpers.ImageHelper
@ -51,25 +52,42 @@ class PlaylistsAdapter(
NavigationHelper.navigatePlaylist(root.context, playlist.id, playlistType) NavigationHelper.navigatePlaylist(root.context, playlist.id, playlistType)
} }
val fragmentManager = (root.context as BaseActivity).supportFragmentManager
fragmentManager.setFragmentResultListener(
IntentData.requestKey,
(root.context as BaseActivity)
) { _, resultBundle ->
val newPlaylistDescription =
resultBundle.getString(IntentData.playlistDescription)
val newPlaylistName =
resultBundle.getString(IntentData.playlistName)
val isPlaylistToBeDeleted =
resultBundle.getBoolean(IntentData.playlistTask)
newPlaylistDescription?.let {
playlistDescription.text = it
playlist.shortDescription = it
}
newPlaylistName?.let {
playlistTitle.text = it
playlist.name = it
}
if (isPlaylistToBeDeleted) {
// try to refresh the playlists in the library on deletion success
onDelete(position, root.context as BaseActivity)
}
}
root.setOnLongClickListener { root.setOnLongClickListener {
val playlistOptionsDialog = PlaylistOptionsBottomSheet( val playlistOptionsDialog = PlaylistOptionsBottomSheet(
playlistId = playlist.id!!, playlistId = playlist.id!!,
playlistName = playlist.name!!, playlistName = playlist.name!!,
playlistType = playlistType, playlistType = playlistType
onDelete = {
onDelete(position, root.context as BaseActivity)
},
onRename = {
playlistTitle.text = it
playlist.name = it
},
onChangeDescription = {
playlistDescription.text = it
playlist.shortDescription = it
}
) )
playlistOptionsDialog.show( playlistOptionsDialog.show(
(root.context as BaseActivity).supportFragmentManager, fragmentManager,
PlaylistOptionsBottomSheet::class.java.name PlaylistOptionsBottomSheet::class.java.name
) )
true true

View File

@ -1,32 +1,36 @@
package com.github.libretube.ui.dialogs package com.github.libretube.ui.dialogs
import android.app.Dialog import android.app.Dialog
import android.content.Context
import android.graphics.Color import android.graphics.Color
import android.os.Bundle import android.os.Bundle
import android.text.Editable import android.text.Editable
import android.text.TextWatcher import android.text.TextWatcher
import android.widget.SeekBar import android.widget.SeekBar
import android.widget.Toast import android.widget.Toast
import androidx.core.os.bundleOf
import androidx.fragment.app.DialogFragment import androidx.fragment.app.DialogFragment
import androidx.fragment.app.setFragmentResult
import com.github.libretube.R import com.github.libretube.R
import com.github.libretube.constants.IntentData
import com.github.libretube.databinding.DialogColorPickerBinding import com.github.libretube.databinding.DialogColorPickerBinding
import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.android.material.dialog.MaterialAlertDialogBuilder
class ColorPickerDialog( class ColorPickerDialog : DialogFragment(), SeekBar.OnSeekBarChangeListener {
private val context: Context, private var initialColor: Int? = null
private val initialColor: Int,
private val onColorSelectedListener: OnColorSelectedListener
) : DialogFragment(), SeekBar.OnSeekBarChangeListener {
private var _binding: DialogColorPickerBinding? = null private var _binding: DialogColorPickerBinding? = null
private val binding get() = _binding!! private val binding get() = _binding!!
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
initialColor = arguments?.getInt(IntentData.color)!!
}
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
_binding = DialogColorPickerBinding.inflate(layoutInflater) _binding = DialogColorPickerBinding.inflate(layoutInflater)
// Set initial color // Set initial color
setColor(initialColor) setColor(initialColor!!)
binding.alphaSeekBar.setOnSeekBarChangeListener(this) binding.alphaSeekBar.setOnSeekBarChangeListener(this)
binding.redSeekBar.setOnSeekBarChangeListener(this) binding.redSeekBar.setOnSeekBarChangeListener(this)
@ -74,7 +78,11 @@ class ColorPickerDialog(
return MaterialAlertDialogBuilder(requireContext()) return MaterialAlertDialogBuilder(requireContext())
.setView(binding.root) .setView(binding.root)
.setPositiveButton(R.string.okay) { _, _ -> .setPositiveButton(R.string.okay) { _, _ ->
onColorSelectedListener.onColorSelected(getColor()) val color = getColor()
setFragmentResult(
IntentData.requestKey,
bundleOf(IntentData.color to color)
)
} }
.setNegativeButton(R.string.cancel, null) .setNegativeButton(R.string.cancel, null)
.show() .show()
@ -134,8 +142,4 @@ class ColorPickerDialog(
private fun colorToString(color: Int): String { private fun colorToString(color: Int): String {
return String.format("#%08X", color) return String.format("#%08X", color)
} }
fun interface OnColorSelectedListener {
fun onColorSelected(color: Int)
}
} }

View File

@ -2,10 +2,14 @@ package com.github.libretube.ui.dialogs
import android.app.Dialog import android.app.Dialog
import android.os.Bundle import android.os.Bundle
import androidx.core.os.bundleOf
import androidx.fragment.app.DialogFragment import androidx.fragment.app.DialogFragment
import androidx.fragment.app.setFragmentResult
import com.github.libretube.R import com.github.libretube.R
import com.github.libretube.api.PlaylistsHelper import com.github.libretube.api.PlaylistsHelper
import com.github.libretube.constants.IntentData
import com.github.libretube.enums.PlaylistType import com.github.libretube.enums.PlaylistType
import com.github.libretube.extensions.serializable
import com.github.libretube.extensions.toastFromMainDispatcher import com.github.libretube.extensions.toastFromMainDispatcher
import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.android.material.dialog.MaterialAlertDialogBuilder
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
@ -13,11 +17,16 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
class DeletePlaylistDialog( class DeletePlaylistDialog : DialogFragment() {
private val playlistId: String, private lateinit var playlistId: String
private val playlistType: PlaylistType, private lateinit var playlistType: PlaylistType
private val onSuccess: () -> Unit override fun onCreate(savedInstanceState: Bundle?) {
) : DialogFragment() { super.onCreate(savedInstanceState)
arguments?.let {
playlistId = it.getString(IntentData.playlistId)!!
playlistType = it.serializable(IntentData.playlistType)!!
}
}
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
return MaterialAlertDialogBuilder(requireContext()) return MaterialAlertDialogBuilder(requireContext())
.setTitle(R.string.deletePlaylist) .setTitle(R.string.deletePlaylist)
@ -30,9 +39,10 @@ class DeletePlaylistDialog(
if (success) R.string.success else R.string.fail if (success) R.string.success else R.string.fail
) )
withContext(Dispatchers.Main) { withContext(Dispatchers.Main) {
runCatching { setFragmentResult(
onSuccess.invoke() IntentData.requestKey,
} bundleOf(IntentData.playlistTask to true)
)
} }
} }
} }

View File

@ -6,10 +6,13 @@ import android.os.Bundle
import android.text.InputType import android.text.InputType
import android.util.Log import android.util.Log
import android.widget.Toast import android.widget.Toast
import androidx.core.os.bundleOf
import androidx.fragment.app.DialogFragment import androidx.fragment.app.DialogFragment
import androidx.fragment.app.setFragmentResult
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import com.github.libretube.R import com.github.libretube.R
import com.github.libretube.api.PlaylistsHelper import com.github.libretube.api.PlaylistsHelper
import com.github.libretube.constants.IntentData
import com.github.libretube.databinding.DialogTextPreferenceBinding import com.github.libretube.databinding.DialogTextPreferenceBinding
import com.github.libretube.extensions.TAG import com.github.libretube.extensions.TAG
import com.github.libretube.extensions.toastFromMainDispatcher import com.github.libretube.extensions.toastFromMainDispatcher
@ -18,11 +21,17 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
class RenamePlaylistDialog( class RenamePlaylistDialog : DialogFragment() {
private val playlistId: String, private lateinit var playlistId: String
private val currentPlaylistName: String, private lateinit var currentPlaylistName: String
private val onSuccess: (String) -> Unit
) : DialogFragment() { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
arguments?.let {
playlistId = it.getString(IntentData.playlistId)!!
currentPlaylistName = it.getString(IntentData.playlistName)!!
}
}
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
val binding = DialogTextPreferenceBinding.inflate(layoutInflater) val binding = DialogTextPreferenceBinding.inflate(layoutInflater)
binding.input.inputType = InputType.TYPE_CLASS_TEXT binding.input.inputType = InputType.TYPE_CLASS_TEXT
@ -62,7 +71,10 @@ class RenamePlaylistDialog(
} }
if (success) { if (success) {
appContext.toastFromMainDispatcher(R.string.success) appContext.toastFromMainDispatcher(R.string.success)
onSuccess.invoke(newPlaylistName) setFragmentResult(
IntentData.requestKey,
bundleOf(IntentData.playlistName to newPlaylistName)
)
} else { } else {
appContext.toastFromMainDispatcher(R.string.server_error) appContext.toastFromMainDispatcher(R.string.server_error)
} }

View File

@ -102,15 +102,23 @@ class PlaylistOptionsBottomSheet(
} }
getString(R.string.deletePlaylist) -> { getString(R.string.deletePlaylist) -> {
DeletePlaylistDialog(playlistId, playlistType) { val bundle = bundleOf(
// try to refresh the playlists in the library on deletion success IntentData.playlistId to playlistId,
onDelete() IntentData.playlistType to playlistType
}.show(parentFragmentManager, null) )
val newDeletePlaylistDialog = DeletePlaylistDialog()
newDeletePlaylistDialog.arguments = bundle
newDeletePlaylistDialog.show(parentFragmentManager, null)
} }
getString(R.string.renamePlaylist) -> { getString(R.string.renamePlaylist) -> {
RenamePlaylistDialog(playlistId, playlistName, onRename) val bundle = bundleOf(
.show(parentFragmentManager, null) IntentData.playlistId to playlistId,
IntentData.playlistName to playlistName
)
val newRenamePlaylistDialog = RenamePlaylistDialog()
newRenamePlaylistDialog.arguments = bundle
newRenamePlaylistDialog.show(parentFragmentManager, null)
} }
getString(R.string.change_playlist_description) -> { getString(R.string.change_playlist_description) -> {
@ -118,17 +126,9 @@ class PlaylistOptionsBottomSheet(
IntentData.playlistId to playlistId, IntentData.playlistId to playlistId,
IntentData.playlistDescription to "" IntentData.playlistDescription to ""
) )
val newShareDialog = PlaylistDescriptionDialog() val newPlaylistDescriptionDialog = PlaylistDescriptionDialog()
newShareDialog.arguments = bundle newPlaylistDescriptionDialog.arguments = bundle
newShareDialog.show(parentFragmentManager, null) newPlaylistDescriptionDialog.show(parentFragmentManager, null)
parentFragmentManager.setFragmentResultListener(
IntentData.requestKey,
this
) { _, resultBundle ->
val newDescription =
resultBundle.getString(IntentData.playlistDescription)!!
onChangeDescription.invoke(newDescription)
}
} }
else -> { else -> {

View File

@ -7,9 +7,11 @@ import android.util.AttributeSet
import android.view.View import android.view.View
import android.widget.TextView import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.core.os.bundleOf
import androidx.preference.Preference import androidx.preference.Preference
import androidx.preference.PreferenceViewHolder import androidx.preference.PreferenceViewHolder
import com.github.libretube.R import com.github.libretube.R
import com.github.libretube.constants.IntentData
import com.github.libretube.ui.dialogs.ColorPickerDialog import com.github.libretube.ui.dialogs.ColorPickerDialog
class ColorPreference(context: Context, attrs: AttributeSet) : Preference(context, attrs) { class ColorPreference(context: Context, attrs: AttributeSet) : Preference(context, attrs) {
@ -60,11 +62,18 @@ class ColorPreference(context: Context, attrs: AttributeSet) : Preference(contex
private fun showColorPickerDialog() { private fun showColorPickerDialog() {
(if (currentColor is Int) currentColor else Color.BLACK)?.let { (if (currentColor is Int) currentColor else Color.BLACK)?.let {
val dialog = ColorPickerDialog(context, it) { color -> setColor(color) } val bundle = bundleOf(IntentData.color to it)
dialog.show( val dialog = ColorPickerDialog()
(context as AppCompatActivity).supportFragmentManager, val fragmentManager = (context as AppCompatActivity).supportFragmentManager
this::class.java.name fragmentManager.setFragmentResultListener(
) IntentData.requestKey,
context as AppCompatActivity
) { _, resultBundle ->
val newColor = resultBundle.getInt(IntentData.color)
setColor(newColor)
}
dialog.arguments = bundle
dialog.show(fragmentManager, this::class.java.name)
} }
} }