6666* */
6767package io.matthewnelson.sampleapp.ui.fragments.settings.tor
6868
69+ import android.content.Context
6970import android.os.Bundle
7071import android.view.LayoutInflater
7172import android.view.View
7273import android.view.ViewGroup
7374import android.widget.Button
75+ import android.widget.CheckBox
7476import android.widget.LinearLayout
77+ import android.widget.TextView
7578import androidx.activity.OnBackPressedCallback
7679import androidx.constraintlayout.widget.ConstraintLayout
7780import androidx.core.view.marginTop
7881import androidx.fragment.app.Fragment
82+ import androidx.recyclerview.widget.LinearLayoutManager
83+ import androidx.recyclerview.widget.RecyclerView
7984import io.matthewnelson.sampleapp.R
80- import io.matthewnelson.topl_service.service.components.onionproxy.ServiceTorSettings
81-
85+ import io.matthewnelson.topl_core_base.BaseConsts.IsolationFlag
86+ import io.matthewnelson.topl_core_base.TorSettings
8287
8388class IsolationFlagsFragment (
8489 private val bottomMarginAdjust : Int ,
85- private val flagType : String ,
86- private val serviceTorSettings : ServiceTorSettings
90+ private val portType : String ,
91+ private val defaultTorSettings : TorSettings ,
92+ private val enabledIsolationFlags : MutableSet <@IsolationFlag String >
8793) : Fragment() {
8894
8995 companion object {
90- const val SOCKS_FLAGS = " SOCKS_FLAGS "
91- const val HTTP_FLAGS = " HTTP_FLAGS "
92- const val DNS_FLAGS = " DNS_FLAGS "
93- const val TRANS_FLAGS = " TRANS_FLAGS "
96+ const val SOCKS_FLAGS = " Socks Isolation Flags "
97+ const val HTTP_FLAGS = " HTTP Isolation Flags "
98+ const val DNS_FLAGS = " DNS Isolation Flags "
99+ const val TRANS_FLAGS = " Trans Isolation Flags "
94100 }
95101
96102 private val backPressHandler = BackPressHandler (true )
@@ -100,6 +106,9 @@ class IsolationFlagsFragment(
100106 private lateinit var layoutEnd: LinearLayout
101107 private lateinit var layoutStart: LinearLayout
102108 private lateinit var layoutConstraintInner: ConstraintLayout
109+ private lateinit var buttonReset: Button
110+ private lateinit var recyclerView: RecyclerView
111+ private lateinit var isolationFlagsAdapter: IsolationFlagsAdapter
103112
104113 override fun onCreateView (
105114 inflater : LayoutInflater ,
@@ -115,7 +124,9 @@ class IsolationFlagsFragment(
115124 override fun onViewCreated (view : View , savedInstanceState : Bundle ? ) {
116125 super .onViewCreated(view, savedInstanceState)
117126 findViews(view)
127+ setResetButtonText()
118128 setMargins()
129+ initRecyclerView(view.context)
119130 setClickListeners()
120131 enableParentViews(false )
121132 }
@@ -131,6 +142,23 @@ class IsolationFlagsFragment(
131142 layoutEnd = view.findViewById(R .id.isolation_flags_layout_end)
132143 layoutStart = view.findViewById(R .id.isolation_flags_layout_start)
133144 layoutConstraintInner = view.findViewById(R .id.isolation_flags_layout_constraint_inner)
145+ recyclerView = view.findViewById(R .id.recycler_view_isolation_flags)
146+ buttonReset = view.findViewById(R .id.isolation_flags_button_reset)
147+ }
148+
149+ private fun setResetButtonText () {
150+ when (portType) {
151+ // SOCKS_FLAGS is default string
152+ HTTP_FLAGS -> {
153+ buttonReset.text = getString(R .string.isolation_fragment_reset_http)
154+ }
155+ DNS_FLAGS -> {
156+ buttonReset.text = getString(R .string.isolation_fragment_reset_dns)
157+ }
158+ TRANS_FLAGS -> {
159+ buttonReset.text = getString(R .string.isolation_fragment_reset_trans)
160+ }
161+ }
134162 }
135163
136164 private fun setMargins () {
@@ -142,23 +170,38 @@ class IsolationFlagsFragment(
142170 }
143171 }
144172
173+ private fun initRecyclerView (context : Context ) {
174+ isolationFlagsAdapter = IsolationFlagsAdapter ()
175+ recyclerView.apply {
176+ setHasFixedSize(true )
177+ layoutManager = LinearLayoutManager (context)
178+ adapter = isolationFlagsAdapter
179+ }
180+ }
181+
145182 private fun setClickListeners () {
146183 layoutTop.setOnClickListener {
147- removeFragment(true )
184+ removeFragment()
148185 }
149186 layoutBottom.setOnClickListener {
150- removeFragment(true )
187+ removeFragment()
151188 }
152189 layoutEnd.setOnClickListener {
153- removeFragment(true )
190+ removeFragment()
154191 }
155192 layoutStart.setOnClickListener {
156- removeFragment(true )
193+ removeFragment()
194+ }
195+ buttonReset.setOnClickListener {
196+ isolationFlagsAdapter.resetToDefaults()
197+ isolationFlagsAdapter.notifyDataSetChanged()
157198 }
158199 }
159200
160- private fun removeFragment (saveData : Boolean ) {
161- // TODO: Save Data
201+ private fun removeFragment () {
202+ parentFragment?.let {
203+ (it as SettingsTorFragment ).setIsolationFlags(portType, enabledIsolationFlags.toList())
204+ }
162205 parentFragmentManager.beginTransaction().apply {
163206 remove(this @IsolationFlagsFragment)
164207 commit()
@@ -177,10 +220,77 @@ class IsolationFlagsFragment(
177220 }
178221
179222 private inner class BackPressHandler (enable : Boolean ): OnBackPressedCallback(enable) {
180-
181223 override fun handleOnBackPressed () {
182- removeFragment(false )
224+ removeFragment()
225+ }
226+ }
227+
228+ private inner class IsolationFlagsAdapter : RecyclerView .Adapter <IsolationFlagsAdapter .IsolationFlagHolder >() {
229+
230+ private val items = IsolationFlag .getAll()
231+
232+ fun resetToDefaults () {
233+ enabledIsolationFlags.clear()
234+ when (portType) {
235+ SOCKS_FLAGS -> {
236+ defaultTorSettings.socksPortIsolationFlags?.let {
237+ enabledIsolationFlags.addAll(it)
238+ }
239+ }
240+ HTTP_FLAGS -> {
241+ defaultTorSettings.httpTunnelPortIsolationFlags?.let {
242+ enabledIsolationFlags.addAll(it)
243+ }
244+ }
245+ DNS_FLAGS -> {
246+ defaultTorSettings.dnsPortIsolationFlags?.let {
247+ enabledIsolationFlags.addAll(it)
248+ }
249+ }
250+ TRANS_FLAGS -> {
251+ defaultTorSettings.transPortIsolationFlags?.let {
252+ enabledIsolationFlags.addAll(it)
253+ }
254+ }
255+ }
256+ }
257+
258+ inner class IsolationFlagHolder (view : View ): RecyclerView.ViewHolder(view)
259+
260+ override fun onCreateViewHolder (parent : ViewGroup , viewType : Int ): IsolationFlagHolder {
261+ val view = LayoutInflater .from(parent.context).inflate(R .layout.holder_isolation_flag, parent, false )
262+ return IsolationFlagHolder (view)
263+ }
264+
265+ override fun getItemCount (): Int {
266+ return items.size
183267 }
184268
269+ override fun onBindViewHolder (holder : IsolationFlagHolder , position : Int ) {
270+ val isolationFlag = items[position]
271+ val layout = holder.itemView.findViewById<ConstraintLayout >(R .id.holder_isolation_flag_layout_constraint)
272+ val textView = holder.itemView.findViewById<TextView >(R .id.holder_isolation_flag_text_view)
273+ val checkBox = holder.itemView.findViewById<CheckBox >(R .id.holder_isolation_flag_check_box)
274+
275+ textView.text = isolationFlag
276+ checkBox.isChecked = enabledIsolationFlags.contains(isolationFlag)
277+
278+ checkBox.setOnClickListener {
279+ clicked(isolationFlag, checkBox)
280+ }
281+ layout.setOnClickListener {
282+ clicked(isolationFlag, checkBox)
283+ }
284+ }
285+
286+ private fun clicked (@IsolationFlag isolationFlag : String , checkBox : CheckBox ) {
287+ if (enabledIsolationFlags.contains(isolationFlag)) {
288+ enabledIsolationFlags.remove(isolationFlag)
289+ checkBox.isChecked = false
290+ } else {
291+ enabledIsolationFlags.add(isolationFlag)
292+ checkBox.isChecked = true
293+ }
294+ }
185295 }
186296}
0 commit comments