2021-10-28 05:04:14 +02:00
|
|
|
package io.heckel.ntfy.ui
|
2021-10-28 04:25:02 +02:00
|
|
|
|
|
|
|
import android.app.AlertDialog
|
|
|
|
import android.app.Dialog
|
2021-11-18 02:16:58 +01:00
|
|
|
import android.content.Context
|
2021-10-28 04:25:02 +02:00
|
|
|
import android.os.Bundle
|
|
|
|
import android.text.Editable
|
|
|
|
import android.text.TextWatcher
|
2021-11-18 02:16:58 +01:00
|
|
|
import android.util.Log
|
2021-10-28 04:25:02 +02:00
|
|
|
import android.view.View
|
2021-11-01 13:58:12 +01:00
|
|
|
import android.widget.Button
|
2021-10-28 04:25:02 +02:00
|
|
|
import android.widget.CheckBox
|
|
|
|
import androidx.fragment.app.DialogFragment
|
2021-11-01 13:58:12 +01:00
|
|
|
import androidx.lifecycle.lifecycleScope
|
2021-10-28 04:25:02 +02:00
|
|
|
import com.google.android.material.textfield.TextInputEditText
|
2021-10-28 05:04:14 +02:00
|
|
|
import io.heckel.ntfy.R
|
2021-11-18 02:16:58 +01:00
|
|
|
import io.heckel.ntfy.data.Database
|
|
|
|
import io.heckel.ntfy.data.Repository
|
2021-11-01 13:58:12 +01:00
|
|
|
import kotlinx.coroutines.Dispatchers
|
|
|
|
import kotlinx.coroutines.launch
|
2021-10-28 04:25:02 +02:00
|
|
|
|
2021-11-18 02:16:58 +01:00
|
|
|
class AddFragment : DialogFragment() {
|
|
|
|
private lateinit var repository: Repository
|
|
|
|
private lateinit var subscribeListener: SubscribeListener
|
|
|
|
|
2021-11-01 13:58:12 +01:00
|
|
|
private lateinit var topicNameText: TextInputEditText
|
|
|
|
private lateinit var baseUrlText: TextInputEditText
|
|
|
|
private lateinit var useAnotherServerCheckbox: CheckBox
|
2021-11-14 01:26:37 +01:00
|
|
|
private lateinit var useAnotherServerDescription: View
|
2021-11-15 13:57:35 +01:00
|
|
|
private lateinit var instantDeliveryBox: View
|
2021-11-14 01:26:37 +01:00
|
|
|
private lateinit var instantDeliveryCheckbox: CheckBox
|
|
|
|
private lateinit var instantDeliveryDescription: View
|
2021-11-01 13:58:12 +01:00
|
|
|
private lateinit var subscribeButton: Button
|
2021-10-28 04:25:02 +02:00
|
|
|
|
2021-11-18 02:16:58 +01:00
|
|
|
interface SubscribeListener {
|
|
|
|
fun onSubscribe(topic: String, baseUrl: String, instant: Boolean)
|
|
|
|
}
|
|
|
|
|
|
|
|
override fun onAttach(context: Context) {
|
|
|
|
super.onAttach(context)
|
|
|
|
subscribeListener = activity as SubscribeListener
|
|
|
|
}
|
|
|
|
|
2021-10-28 04:25:02 +02:00
|
|
|
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
|
2021-11-18 02:16:58 +01:00
|
|
|
if (activity == null) {
|
|
|
|
throw IllegalStateException("Activity cannot be null")
|
|
|
|
}
|
|
|
|
|
|
|
|
// Dependencies
|
|
|
|
val database = Database.getInstance(activity!!.applicationContext)
|
|
|
|
repository = Repository.getInstance(database.subscriptionDao(), database.notificationDao())
|
|
|
|
|
|
|
|
// Build root view
|
|
|
|
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)
|
|
|
|
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
|
|
|
|
useAnotherServerDescription = view.findViewById(R.id.add_dialog_use_another_server_description)
|
|
|
|
|
|
|
|
// Build dialog
|
|
|
|
val alert = AlertDialog.Builder(activity)
|
|
|
|
.setView(view)
|
|
|
|
.setPositiveButton(R.string.add_dialog_button_subscribe) { _, _ ->
|
|
|
|
val topic = topicNameText.text.toString()
|
|
|
|
val baseUrl = getBaseUrl()
|
|
|
|
val instant = if (useAnotherServerCheckbox.isChecked) true else instantDeliveryCheckbox.isChecked
|
|
|
|
subscribeListener.onSubscribe(topic, baseUrl, instant)
|
|
|
|
}
|
|
|
|
.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)
|
|
|
|
subscribeButton.isEnabled = false
|
|
|
|
|
|
|
|
val textWatcher = object : TextWatcher {
|
|
|
|
override fun afterTextChanged(s: Editable?) {
|
|
|
|
validateInput()
|
2021-10-28 04:25:02 +02:00
|
|
|
}
|
2021-11-18 02:16:58 +01:00
|
|
|
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
|
|
|
|
// Nothing
|
2021-10-28 04:25:02 +02:00
|
|
|
}
|
2021-11-18 02:16:58 +01:00
|
|
|
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
|
|
|
|
// Nothing
|
2021-10-28 04:25:02 +02:00
|
|
|
}
|
2021-11-18 02:16:58 +01:00
|
|
|
}
|
|
|
|
topicNameText.addTextChangedListener(textWatcher)
|
|
|
|
baseUrlText.addTextChangedListener(textWatcher)
|
|
|
|
instantDeliveryCheckbox.setOnCheckedChangeListener { _, isChecked ->
|
|
|
|
if (isChecked) instantDeliveryDescription.visibility = View.VISIBLE
|
|
|
|
else instantDeliveryDescription.visibility = View.GONE
|
|
|
|
}
|
|
|
|
useAnotherServerCheckbox.setOnCheckedChangeListener { _, isChecked ->
|
|
|
|
if (isChecked) {
|
|
|
|
useAnotherServerDescription.visibility = View.VISIBLE
|
|
|
|
baseUrlText.visibility = View.VISIBLE
|
|
|
|
instantDeliveryBox.visibility = View.GONE
|
|
|
|
instantDeliveryDescription.visibility = View.GONE
|
|
|
|
} else {
|
|
|
|
useAnotherServerDescription.visibility = View.GONE
|
|
|
|
baseUrlText.visibility = View.GONE
|
|
|
|
instantDeliveryBox.visibility = View.VISIBLE
|
|
|
|
if (instantDeliveryCheckbox.isChecked) instantDeliveryDescription.visibility = View.VISIBLE
|
2021-11-14 01:26:37 +01:00
|
|
|
else instantDeliveryDescription.visibility = View.GONE
|
|
|
|
}
|
2021-11-18 02:16:58 +01:00
|
|
|
validateInput()
|
2021-10-28 04:25:02 +02:00
|
|
|
}
|
2021-11-18 02:16:58 +01:00
|
|
|
}
|
2021-10-28 04:25:02 +02:00
|
|
|
|
2021-11-18 02:16:58 +01:00
|
|
|
return alert
|
2021-10-28 04:25:02 +02:00
|
|
|
}
|
2021-11-01 13:58:12 +01:00
|
|
|
|
|
|
|
private fun validateInput() = lifecycleScope.launch(Dispatchers.IO) {
|
|
|
|
val baseUrl = getBaseUrl()
|
|
|
|
val topic = topicNameText.text.toString()
|
2021-11-18 02:16:58 +01:00
|
|
|
val subscription = repository.getSubscription(baseUrl, topic)
|
2021-11-01 13:58:12 +01:00
|
|
|
|
|
|
|
activity?.let {
|
|
|
|
it.runOnUiThread {
|
|
|
|
if (subscription != null) {
|
|
|
|
subscribeButton.isEnabled = false
|
|
|
|
} else if (useAnotherServerCheckbox.isChecked) {
|
|
|
|
subscribeButton.isEnabled = topic.isNotBlank()
|
2021-11-08 03:02:27 +01:00
|
|
|
&& "[-_A-Za-z0-9]{1,64}".toRegex().matches(topic)
|
2021-11-01 13:58:12 +01:00
|
|
|
&& baseUrl.isNotBlank()
|
|
|
|
&& "^https?://.+".toRegex().matches(baseUrl)
|
|
|
|
} else {
|
|
|
|
subscribeButton.isEnabled = topic.isNotBlank()
|
2021-11-08 03:02:27 +01:00
|
|
|
&& "[-_A-Za-z0-9]{1,64}".toRegex().matches(topic)
|
2021-11-01 13:58:12 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private fun getBaseUrl(): String {
|
|
|
|
return if (useAnotherServerCheckbox.isChecked) {
|
|
|
|
baseUrlText.text.toString()
|
|
|
|
} else {
|
|
|
|
getString(R.string.app_base_url)
|
|
|
|
}
|
|
|
|
}
|
2021-11-17 21:30:57 +01:00
|
|
|
|
|
|
|
companion object {
|
2021-11-18 02:16:58 +01:00
|
|
|
const val TAG = "NtfyAffFragment"
|
2021-11-17 21:30:57 +01:00
|
|
|
}
|
2021-10-28 04:25:02 +02:00
|
|
|
}
|