ui: refactor AppListDialogFragment's selection communication

Signed-off-by: Harsh Shandilya <me@msfjarvis.dev>
This commit is contained in:
Harsh Shandilya 2020-09-17 17:52:12 +05:30 committed by Jason A. Donenfeld
parent 59935a12b9
commit e99ccf9013
2 changed files with 31 additions and 33 deletions

View File

@ -10,9 +10,10 @@ import android.os.Bundle
import android.widget.Button import android.widget.Button
import android.widget.Toast import android.widget.Toast
import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AlertDialog
import androidx.core.os.bundleOf
import androidx.databinding.Observable import androidx.databinding.Observable
import androidx.fragment.app.DialogFragment import androidx.fragment.app.DialogFragment
import androidx.fragment.app.Fragment import androidx.fragment.app.setFragmentResult
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import com.google.android.material.tabs.TabLayout import com.google.android.material.tabs.TabLayout
import com.wireguard.android.BR import com.wireguard.android.BR
@ -21,7 +22,6 @@ import com.wireguard.android.databinding.AppListDialogFragmentBinding
import com.wireguard.android.databinding.ObservableKeyedArrayList import com.wireguard.android.databinding.ObservableKeyedArrayList
import com.wireguard.android.model.ApplicationData import com.wireguard.android.model.ApplicationData
import com.wireguard.android.util.ErrorMessages import com.wireguard.android.util.ErrorMessages
import com.wireguard.android.util.requireTargetFragment
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
@ -73,7 +73,6 @@ class AppListDialogFragment : DialogFragment() {
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
require(requireTargetFragment() is AppSelectionListener) { "${requireTargetFragment()} must implement AppSelectionListener" }
currentlySelectedApps = (arguments?.getStringArrayList(KEY_SELECTED_APPS) ?: emptyList()) currentlySelectedApps = (arguments?.getStringArrayList(KEY_SELECTED_APPS) ?: emptyList())
initiallyExcluded = arguments?.getBoolean(KEY_IS_EXCLUDED) ?: true initiallyExcluded = arguments?.getBoolean(KEY_IS_EXCLUDED) ?: true
} }
@ -130,23 +129,22 @@ class AppListDialogFragment : DialogFragment() {
selectedApps.add(data.packageName) selectedApps.add(data.packageName)
} }
} }
(requireTargetFragment() as AppSelectionListener).onSelectedAppsSelected(selectedApps, tabs?.selectedTabPosition == 0) setFragmentResult(REQUEST_SELECTION, bundleOf(
KEY_SELECTED_APPS to selectedApps.toTypedArray(),
KEY_IS_EXCLUDED to (tabs?.selectedTabPosition == 0)
))
dismiss() dismiss()
} }
interface AppSelectionListener {
fun onSelectedAppsSelected(selectedApps: List<String>, isExcluded: Boolean)
}
companion object { companion object {
private const val KEY_SELECTED_APPS = "selected_apps" const val KEY_SELECTED_APPS = "selected_apps"
private const val KEY_IS_EXCLUDED = "is_excluded" const val KEY_IS_EXCLUDED = "is_excluded"
fun <T> newInstance(selectedApps: ArrayList<String?>?, isExcluded: Boolean, target: T): AppListDialogFragment where T : Fragment?, T : AppSelectionListener? { const val REQUEST_SELECTION = "request_selection"
fun newInstance(selectedApps: ArrayList<String?>?, isExcluded: Boolean): AppListDialogFragment {
val extras = Bundle() val extras = Bundle()
extras.putStringArrayList(KEY_SELECTED_APPS, selectedApps) extras.putStringArrayList(KEY_SELECTED_APPS, selectedApps)
extras.putBoolean(KEY_IS_EXCLUDED, isExcluded) extras.putBoolean(KEY_IS_EXCLUDED, isExcluded)
val fragment = AppListDialogFragment() val fragment = AppListDialogFragment()
fragment.setTargetFragment(target, 0)
fragment.arguments = extras fragment.arguments = extras
return fragment return fragment
} }

View File

@ -24,7 +24,6 @@ import com.wireguard.android.Application
import com.wireguard.android.R import com.wireguard.android.R
import com.wireguard.android.backend.Tunnel import com.wireguard.android.backend.Tunnel
import com.wireguard.android.databinding.TunnelEditorFragmentBinding import com.wireguard.android.databinding.TunnelEditorFragmentBinding
import com.wireguard.android.fragment.AppListDialogFragment.AppSelectionListener
import com.wireguard.android.model.ObservableTunnel import com.wireguard.android.model.ObservableTunnel
import com.wireguard.android.util.AdminKnobs import com.wireguard.android.util.AdminKnobs
import com.wireguard.android.util.BiometricAuthenticator import com.wireguard.android.util.BiometricAuthenticator
@ -38,7 +37,7 @@ import kotlinx.coroutines.launch
/** /**
* Fragment for editing a WireGuard configuration. * Fragment for editing a WireGuard configuration.
*/ */
class TunnelEditorFragment : BaseFragment(), AppSelectionListener { class TunnelEditorFragment : BaseFragment() {
private var haveShownKeys = false private var haveShownKeys = false
private var binding: TunnelEditorFragmentBinding? = null private var binding: TunnelEditorFragmentBinding? = null
private var tunnel: ObservableTunnel? = null private var tunnel: ObservableTunnel? = null
@ -91,23 +90,6 @@ class TunnelEditorFragment : BaseFragment(), AppSelectionListener {
super.onDestroyView() super.onDestroyView()
} }
override fun onSelectedAppsSelected(selectedApps: List<String>, isExcluded: Boolean) {
requireNotNull(binding) { "Tried to set excluded/included apps while no view was loaded" }
if (isExcluded) {
binding!!.config!!.`interface`.includedApplications.clear()
binding!!.config!!.`interface`.excludedApplications.apply {
clear()
addAll(selectedApps)
}
} else {
binding!!.config!!.`interface`.excludedApplications.clear()
binding!!.config!!.`interface`.includedApplications.apply {
clear()
addAll(selectedApps)
}
}
}
private fun onFinished() { private fun onFinished() {
// Hide the keyboard; it rarely goes away on its own. // Hide the keyboard; it rarely goes away on its own.
val activity = activity ?: return val activity = activity ?: return
@ -183,8 +165,26 @@ class TunnelEditorFragment : BaseFragment(), AppSelectionListener {
if (selectedApps.isNotEmpty()) if (selectedApps.isNotEmpty())
isExcluded = false isExcluded = false
} }
val fragment = AppListDialogFragment.newInstance(selectedApps, isExcluded, this) val fragment = AppListDialogFragment.newInstance(selectedApps, isExcluded)
fragment.show(parentFragmentManager, null) childFragmentManager.setFragmentResultListener(AppListDialogFragment.REQUEST_SELECTION, viewLifecycleOwner) { _, bundle ->
requireNotNull(binding) { "Tried to set excluded/included apps while no view was loaded" }
val newSelections = requireNotNull(bundle.getStringArray(AppListDialogFragment.KEY_SELECTED_APPS))
val excluded = requireNotNull(bundle.getBoolean(AppListDialogFragment.KEY_IS_EXCLUDED))
if (excluded) {
binding!!.config!!.`interface`.includedApplications.clear()
binding!!.config!!.`interface`.excludedApplications.apply {
clear()
addAll(newSelections)
}
} else {
binding!!.config!!.`interface`.excludedApplications.clear()
binding!!.config!!.`interface`.includedApplications.apply {
clear()
addAll(newSelections)
}
}
}
fragment.show(childFragmentManager, null)
} }
} }