ntfy-android/app/src/main/java/io/heckel/ntfy/ui/AddFragment.kt

129 lines
6 KiB
Kotlin
Raw Normal View History

2021-10-28 16:04:14 +13:00
package io.heckel.ntfy.ui
2021-10-28 15:25:02 +13:00
import android.app.AlertDialog
import android.app.Dialog
import android.os.Bundle
import android.text.Editable
import android.text.TextWatcher
import android.view.View
import android.widget.Button
2021-10-28 15:25:02 +13:00
import android.widget.CheckBox
import androidx.fragment.app.DialogFragment
import androidx.lifecycle.lifecycleScope
2021-10-28 15:25:02 +13:00
import com.google.android.material.textfield.TextInputEditText
2021-10-28 16:04:14 +13:00
import io.heckel.ntfy.R
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
2021-10-28 15:25:02 +13:00
2021-11-14 13:26:37 +13:00
class AddFragment(private val viewModel: SubscriptionsViewModel, private val onSubscribe: (topic: String, baseUrl: String, instant: Boolean) -> Unit) : DialogFragment() {
private lateinit var topicNameText: TextInputEditText
private lateinit var baseUrlText: TextInputEditText
private lateinit var useAnotherServerCheckbox: CheckBox
2021-11-14 13:26:37 +13:00
private lateinit var useAnotherServerDescription: View
private lateinit var instantDeliveryBox: View
2021-11-14 13:26:37 +13:00
private lateinit var instantDeliveryCheckbox: CheckBox
private lateinit var instantDeliveryDescription: View
private lateinit var subscribeButton: Button
2021-10-28 15:25:02 +13:00
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
return activity?.let {
// Build root view
2021-10-29 01:28:22 +13:00
val view = requireActivity().layoutInflater.inflate(R.layout.add_dialog_fragment, null)
topicNameText = view.findViewById(R.id.add_dialog_topic_text) as TextInputEditText
baseUrlText = view.findViewById(R.id.add_dialog_base_url_text) as TextInputEditText
instantDeliveryBox = view.findViewById(R.id.add_dialog_instant_delivery_box)
2021-11-14 13:26:37 +13:00
instantDeliveryCheckbox = view.findViewById(R.id.add_dialog_instant_delivery_checkbox) as CheckBox
instantDeliveryDescription = view.findViewById(R.id.add_dialog_instant_delivery_description)
useAnotherServerCheckbox = view.findViewById(R.id.add_dialog_use_another_server_checkbox) as CheckBox
2021-11-14 13:26:37 +13:00
useAnotherServerDescription = view.findViewById(R.id.add_dialog_use_another_server_description)
2021-10-30 14:13:58 +13:00
2021-10-28 15:25:02 +13:00
// Build dialog
val alert = AlertDialog.Builder(it)
.setView(view)
.setPositiveButton(R.string.add_dialog_button_subscribe) { _, _ ->
val topic = topicNameText.text.toString()
val baseUrl = getBaseUrl()
2021-11-14 13:26:37 +13:00
val instant = if (useAnotherServerCheckbox.isChecked) true else instantDeliveryCheckbox.isChecked
onSubscribe(topic, baseUrl, instant)
2021-10-28 15:25:02 +13:00
}
.setNegativeButton(R.string.add_dialog_button_cancel) { _, _ ->
dialog?.cancel()
}
.create()
// Add logic to disable "Subscribe" button on invalid input
alert.setOnShowListener {
val dialog = it as AlertDialog
subscribeButton = dialog.getButton(AlertDialog.BUTTON_POSITIVE)
2021-10-28 15:25:02 +13:00
subscribeButton.isEnabled = false
val textWatcher = object : TextWatcher {
override fun afterTextChanged(s: Editable?) {
validateInput()
2021-10-28 15:25:02 +13:00
}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
// Nothing
}
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
// Nothing
}
}
topicNameText.addTextChangedListener(textWatcher)
baseUrlText.addTextChangedListener(textWatcher)
2021-11-14 13:26:37 +13:00
instantDeliveryCheckbox.setOnCheckedChangeListener { _, isChecked ->
if (isChecked) instantDeliveryDescription.visibility = View.VISIBLE
else instantDeliveryDescription.visibility = View.GONE
}
2021-10-29 01:28:22 +13:00
useAnotherServerCheckbox.setOnCheckedChangeListener { _, isChecked ->
2021-11-14 13:26:37 +13:00
if (isChecked) {
useAnotherServerDescription.visibility = View.VISIBLE
baseUrlText.visibility = View.VISIBLE
instantDeliveryBox.visibility = View.GONE
2021-11-14 13:26:37 +13:00
instantDeliveryDescription.visibility = View.GONE
} else {
useAnotherServerDescription.visibility = View.GONE
baseUrlText.visibility = View.GONE
instantDeliveryBox.visibility = View.VISIBLE
2021-11-14 13:26:37 +13:00
if (instantDeliveryCheckbox.isChecked) instantDeliveryDescription.visibility = View.VISIBLE
else instantDeliveryDescription.visibility = View.GONE
}
validateInput()
}
2021-10-28 15:25:02 +13:00
}
alert
} ?: throw IllegalStateException("Activity cannot be null")
}
private fun validateInput() = lifecycleScope.launch(Dispatchers.IO) {
val baseUrl = getBaseUrl()
val topic = topicNameText.text.toString()
val subscription = viewModel.get(baseUrl, topic)
activity?.let {
it.runOnUiThread {
if (subscription != null) {
subscribeButton.isEnabled = false
} else if (useAnotherServerCheckbox.isChecked) {
subscribeButton.isEnabled = topic.isNotBlank()
2021-11-08 15:02:27 +13:00
&& "[-_A-Za-z0-9]{1,64}".toRegex().matches(topic)
&& baseUrl.isNotBlank()
&& "^https?://.+".toRegex().matches(baseUrl)
} else {
subscribeButton.isEnabled = topic.isNotBlank()
2021-11-08 15:02:27 +13:00
&& "[-_A-Za-z0-9]{1,64}".toRegex().matches(topic)
}
}
}
}
private fun getBaseUrl(): String {
return if (useAnotherServerCheckbox.isChecked) {
baseUrlText.text.toString()
} else {
getString(R.string.app_base_url)
}
}
2021-10-28 15:25:02 +13:00
}