Improve AddPiHoleFragment with enter button handling

This commit is contained in:
William Brawner 2020-04-19 11:58:14 -07:00
parent eb260dec4c
commit 738d2cc81d
4 changed files with 100 additions and 94 deletions

View file

@ -15,8 +15,6 @@ import androidx.navigation.fragment.findNavController
import kotlinx.android.synthetic.main.fragment_add_pi_hole.* import kotlinx.android.synthetic.main.fragment_add_pi_hole.*
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.cancel
import kotlinx.coroutines.launch
import org.koin.android.ext.android.inject import org.koin.android.ext.android.inject
import kotlin.coroutines.CoroutineContext import kotlin.coroutines.CoroutineContext
@ -40,39 +38,40 @@ class AddPiHoleFragment : Fragment(), CoroutineScope {
FragmentNavigatorExtras(piHelperLogo to "piHelperLogo") FragmentNavigatorExtras(piHelperLogo to "piHelperLogo")
) )
} }
connectButton.setOnClickListener { ipAddress.setOnEditorActionListener { _, _, _ ->
launch { connectButton.performClick()
val progressDialog = AlertDialog.Builder(it.context) }
.setTitle(R.string.connecting_to_pihole) connectButton.setSuspendingOnClickListener(this) {
.setNegativeButton(R.string.action_cancel) { _, _ -> val progressDialog = AlertDialog.Builder(it.context)
cancel() .setTitle(R.string.connecting_to_pihole)
} .setNegativeButton(R.string.action_cancel) { _, _ ->
.setView(FrameLayout(it.context).apply { cancel()
addView(ProgressBar(it.context).apply {
layoutParams = FrameLayout.LayoutParams(
FrameLayout.LayoutParams.WRAP_CONTENT,
FrameLayout.LayoutParams.WRAP_CONTENT,
Gravity.CENTER
)
})
})
.show()
if (viewModel.connectToIpAddress(ipAddress.text.toString())) {
navController.navigate(
R.id.action_addPiHoleFragment_to_retrieveApiKeyFragment,
null,
null,
FragmentNavigatorExtras(piHelperLogo to "piHelperLogo")
)
} else {
AlertDialog.Builder(view.context)
.setTitle(R.string.connection_failed_title)
.setMessage(R.string.connection_failed)
.setPositiveButton(android.R.string.ok) { _, _ -> }
.show()
} }
progressDialog.dismiss() .setView(FrameLayout(it.context).apply {
addView(ProgressBar(it.context).apply {
layoutParams = FrameLayout.LayoutParams(
FrameLayout.LayoutParams.WRAP_CONTENT,
FrameLayout.LayoutParams.WRAP_CONTENT,
Gravity.CENTER
)
})
})
.show()
if (viewModel.connectToIpAddress(ipAddress.text.toString())) {
navController.navigate(
R.id.action_addPiHoleFragment_to_retrieveApiKeyFragment,
null,
null,
FragmentNavigatorExtras(piHelperLogo to "piHelperLogo")
)
} else {
AlertDialog.Builder(view.context)
.setTitle(R.string.connection_failed_title)
.setMessage(R.string.connection_failed)
.setPositiveButton(android.R.string.ok) { _, _ -> }
.show()
} }
progressDialog.dismiss()
} }
} }

View file

@ -1,9 +1,24 @@
package com.wbrawner.pihelper package com.wbrawner.pihelper
import android.view.View
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Job
import kotlinx.coroutines.launch
import java.math.BigInteger import java.math.BigInteger
import java.security.MessageDigest import java.security.MessageDigest
fun String.hash(): String = BigInteger( fun String.hash(): String = BigInteger(
1, 1,
MessageDigest.getInstance("SHA-256").digest(this.toByteArray()) MessageDigest.getInstance("SHA-256").digest(this.toByteArray())
).toString(16).padStart(64, '0') ).toString(16).padStart(64, '0')
fun CoroutineScope.cancel() {
coroutineContext[Job]?.cancel()
}
fun View.setSuspendingOnClickListener(
coroutineScope: CoroutineScope,
clickListener: suspend (v: View) -> Unit
) = setOnClickListener { v ->
coroutineScope.launch { clickListener(v) }
}

View file

@ -89,44 +89,36 @@ class MainFragment : Fragment(), CoroutineScope {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
(activity as? AppCompatActivity)?.setSupportActionBar(toolbar) (activity as? AppCompatActivity)?.setSupportActionBar(toolbar)
showProgress(true) showProgress(true)
enableButton?.setOnClickListener { enableButton?.setSuspendingOnClickListener(this) {
launch { showProgress(true)
showProgress(true) try {
try { viewModel.enablePiHole()
viewModel.enablePiHole() } catch (ignored: Exception) {
} catch (ignored: Exception) { Log.e("Pi-Helper", "Failed to enable Pi-Hole", ignored)
Log.e("Pi-Helper", "Failed to enable Pi-Hole", ignored)
}
} }
} }
disable10SecondsButton?.setOnClickListener { disable10SecondsButton?.setSuspendingOnClickListener(this) {
launch { showProgress(true)
showProgress(true) try {
try { viewModel.disablePiHole(10)
viewModel.disablePiHole(10) } catch (ignored: Exception) {
} catch (ignored: Exception) { Log.e("Pi-Helper", "Failed to disable Pi-Hole", ignored)
Log.e("Pi-Helper", "Failed to disable Pi-Hole", ignored)
}
} }
} }
disable30SecondsButton?.setOnClickListener { disable30SecondsButton?.setSuspendingOnClickListener(this) {
launch { showProgress(true)
showProgress(true) try {
try { viewModel.disablePiHole(30)
viewModel.disablePiHole(30) } catch (ignored: Exception) {
} catch (ignored: Exception) { Log.e("Pi-Helper", "Failed to disable Pi-Hole", ignored)
Log.e("Pi-Helper", "Failed to disable Pi-Hole", ignored)
}
} }
} }
disable5MinutesButton?.setOnClickListener { disable5MinutesButton?.setSuspendingOnClickListener(this) {
launch { showProgress(true)
showProgress(true) try {
try { viewModel.disablePiHole(300)
viewModel.disablePiHole(300) } catch (ignored: Exception) {
} catch (ignored: Exception) { Log.e("Pi-Helper", "Failed to disable Pi-Hole", ignored)
Log.e("Pi-Helper", "Failed to disable Pi-Hole", ignored)
}
} }
} }
disableCustomTimeButton?.setOnClickListener { disableCustomTimeButton?.setOnClickListener {
@ -140,38 +132,34 @@ class MainFragment : Fragment(), CoroutineScope {
.create() .create()
.apply { .apply {
setOnShowListener { setOnShowListener {
getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener { getButton(AlertDialog.BUTTON_POSITIVE).setSuspendingOnClickListener(this@MainFragment) {
launch { try {
try { val rawTime = dialogView.findViewById<EditText>(R.id.time)
val rawTime = dialogView.findViewById<EditText>(R.id.time) .text
.text .toString()
.toString() .toLong()
.toLong() val checkedId =
val checkedId = dialogView.findViewById<RadioGroup>(R.id.timeUnit)
dialogView.findViewById<RadioGroup>(R.id.timeUnit) .checkedRadioButtonId
.checkedRadioButtonId val computedTime = if (checkedId == R.id.seconds) rawTime
val computedTime = if (checkedId == R.id.seconds) rawTime else rawTime * 60
else rawTime * 60 viewModel.disablePiHole(computedTime)
viewModel.disablePiHole(computedTime) dismiss()
dismiss() } catch (e: Exception) {
} catch (e: Exception) { dialogView.findViewById<EditText>(R.id.time)
dialogView.findViewById<EditText>(R.id.time) .error = "Failed to disable Pi-hole"
.error = "Failed to disable Pi-hole"
}
} }
} }
} }
} }
.show() .show()
} }
disablePermanentlyButton?.setOnClickListener { disablePermanentlyButton?.setSuspendingOnClickListener(this) {
launch { showProgress(true)
showProgress(true) try {
try { viewModel.disablePiHole()
viewModel.disablePiHole() } catch (ignored: Exception) {
} catch (ignored: Exception) { Log.e("Pi-Helper", "Failed to disable Pi-Hole", ignored)
Log.e("Pi-Helper", "Failed to disable Pi-Hole", ignored)
}
} }
} }
} }

View file

@ -50,11 +50,15 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:hint="@string/prompt_ip_address"> android:hint="@string/prompt_ip_address">
<!-- TODO: Figure out how to get this to work for inputting an IP address -->
<com.google.android.material.textfield.TextInputEditText <com.google.android.material.textfield.TextInputEditText
android:id="@+id/ipAddress" android:id="@+id/ipAddress"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" /> android:layout_height="wrap_content"
android:text="pi.hole"
android:inputType="text"
android:maxLines="1"
android:imeOptions="actionGo"
tools:ignore="HardcodedText" />
</com.google.android.material.textfield.TextInputLayout> </com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.button.MaterialButton <com.google.android.material.button.MaterialButton