mirror of
https://github.com/iSoron/uhabits.git
synced 2025-12-06 09:08:52 -06:00
Handling multiple dialogs correctly
This commit is contained in:
@@ -20,6 +20,7 @@
|
|||||||
package org.isoron.uhabits
|
package org.isoron.uhabits
|
||||||
|
|
||||||
import android.app.Application
|
import android.app.Application
|
||||||
|
import android.app.Dialog
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import org.isoron.uhabits.core.database.UnsupportedDatabaseVersionException
|
import org.isoron.uhabits.core.database.UnsupportedDatabaseVersionException
|
||||||
import org.isoron.uhabits.core.reminders.ReminderScheduler
|
import org.isoron.uhabits.core.reminders.ReminderScheduler
|
||||||
@@ -118,5 +119,11 @@ class HabitsApplication : Application() {
|
|||||||
false
|
false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var currentDialog: Dialog? = null
|
||||||
|
fun clearCurrentDialog() {
|
||||||
|
currentDialog?.dismiss()
|
||||||
|
currentDialog = null
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ import android.view.LayoutInflater
|
|||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.View.GONE
|
import android.view.View.GONE
|
||||||
import android.view.View.VISIBLE
|
import android.view.View.VISIBLE
|
||||||
|
import org.isoron.uhabits.HabitsApplication
|
||||||
import org.isoron.uhabits.R
|
import org.isoron.uhabits.R
|
||||||
import org.isoron.uhabits.core.models.Entry.Companion.NO
|
import org.isoron.uhabits.core.models.Entry.Companion.NO
|
||||||
import org.isoron.uhabits.core.models.Entry.Companion.SKIP
|
import org.isoron.uhabits.core.models.Entry.Companion.SKIP
|
||||||
@@ -98,6 +99,7 @@ class CheckmarkPopup(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun show() {
|
fun show() {
|
||||||
|
HabitsApplication.clearCurrentDialog()
|
||||||
dialog = Dialog(context, android.R.style.Theme_NoTitleBar)
|
dialog = Dialog(context, android.R.style.Theme_NoTitleBar)
|
||||||
dialog.setContentView(view.root)
|
dialog.setContentView(view.root)
|
||||||
dialog.window?.apply {
|
dialog.window?.apply {
|
||||||
@@ -117,11 +119,13 @@ class CheckmarkPopup(
|
|||||||
view.unknownBtn.setOnClickListener { onClick(UNKNOWN) }
|
view.unknownBtn.setOnClickListener { onClick(UNKNOWN) }
|
||||||
dialog.setCanceledOnTouchOutside(true)
|
dialog.setCanceledOnTouchOutside(true)
|
||||||
dialog.dimBehind()
|
dialog.dimBehind()
|
||||||
|
HabitsApplication.currentDialog = dialog
|
||||||
dialog.show()
|
dialog.show()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun save() {
|
fun save() {
|
||||||
onToggle(value, view.notes.text.toString().trim())
|
onToggle(value, view.notes.text.toString().trim())
|
||||||
|
HabitsApplication.currentDialog = null
|
||||||
dialog.dismiss()
|
dialog.dismiss()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,7 +18,11 @@
|
|||||||
*/
|
*/
|
||||||
package org.isoron.uhabits.activities.common.dialogs
|
package org.isoron.uhabits.activities.common.dialogs
|
||||||
|
|
||||||
|
import android.app.Dialog
|
||||||
|
import android.content.DialogInterface
|
||||||
|
import android.os.Bundle
|
||||||
import com.android.colorpicker.ColorPickerDialog
|
import com.android.colorpicker.ColorPickerDialog
|
||||||
|
import org.isoron.uhabits.HabitsApplication
|
||||||
import org.isoron.uhabits.core.ui.callbacks.OnColorPickedCallback
|
import org.isoron.uhabits.core.ui.callbacks.OnColorPickedCallback
|
||||||
import org.isoron.uhabits.utils.toPaletteColor
|
import org.isoron.uhabits.utils.toPaletteColor
|
||||||
|
|
||||||
@@ -28,8 +32,22 @@ import org.isoron.uhabits.utils.toPaletteColor
|
|||||||
class ColorPickerDialog : ColorPickerDialog() {
|
class ColorPickerDialog : ColorPickerDialog() {
|
||||||
fun setListener(callback: OnColorPickedCallback) {
|
fun setListener(callback: OnColorPickedCallback) {
|
||||||
super.setOnColorSelectedListener { c: Int ->
|
super.setOnColorSelectedListener { c: Int ->
|
||||||
val pc = c.toPaletteColor(context!!)
|
val pc = c.toPaletteColor(requireContext())
|
||||||
callback.onColorPicked(pc)
|
callback.onColorPicked(pc)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
|
||||||
|
HabitsApplication.clearCurrentDialog()
|
||||||
|
HabitsApplication.currentDialog = this.dialog
|
||||||
|
return super.onCreateDialog(savedInstanceState)
|
||||||
|
}
|
||||||
|
override fun onColorSelected(color: Int) {
|
||||||
|
super.onColorSelected(color)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onDismiss(dialog: DialogInterface) {
|
||||||
|
HabitsApplication.currentDialog = null
|
||||||
|
super.onDismiss(dialog)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ package org.isoron.uhabits.activities.common.dialogs
|
|||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.DialogInterface
|
import android.content.DialogInterface
|
||||||
import androidx.appcompat.app.AlertDialog
|
import androidx.appcompat.app.AlertDialog
|
||||||
|
import org.isoron.uhabits.HabitsApplication
|
||||||
import org.isoron.uhabits.R
|
import org.isoron.uhabits.R
|
||||||
import org.isoron.uhabits.core.ui.callbacks.OnConfirmedCallback
|
import org.isoron.uhabits.core.ui.callbacks.OnConfirmedCallback
|
||||||
import org.isoron.uhabits.inject.ActivityContext
|
import org.isoron.uhabits.inject.ActivityContext
|
||||||
@@ -34,6 +35,7 @@ class ConfirmDeleteDialog(
|
|||||||
quantity: Int
|
quantity: Int
|
||||||
) : AlertDialog(context) {
|
) : AlertDialog(context) {
|
||||||
init {
|
init {
|
||||||
|
HabitsApplication.clearCurrentDialog()
|
||||||
val res = context.resources
|
val res = context.resources
|
||||||
setTitle(res.getQuantityString(R.plurals.delete_habits_title, quantity))
|
setTitle(res.getQuantityString(R.plurals.delete_habits_title, quantity))
|
||||||
setMessage(res.getQuantityString(R.plurals.delete_habits_message, quantity))
|
setMessage(res.getQuantityString(R.plurals.delete_habits_message, quantity))
|
||||||
@@ -45,5 +47,12 @@ class ConfirmDeleteDialog(
|
|||||||
BUTTON_NEGATIVE,
|
BUTTON_NEGATIVE,
|
||||||
res.getString(R.string.no)
|
res.getString(R.string.no)
|
||||||
) { dialog: DialogInterface?, which: Int -> }
|
) { dialog: DialogInterface?, which: Int -> }
|
||||||
|
|
||||||
|
HabitsApplication.currentDialog = this
|
||||||
|
|
||||||
|
this.setOnDismissListener{
|
||||||
|
HabitsApplication.currentDialog = null
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,6 +20,7 @@
|
|||||||
package org.isoron.uhabits.activities.common.dialogs
|
package org.isoron.uhabits.activities.common.dialogs
|
||||||
|
|
||||||
import android.app.Dialog
|
import android.app.Dialog
|
||||||
|
import android.content.DialogInterface
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
@@ -30,6 +31,7 @@ import android.widget.TextView
|
|||||||
import androidx.appcompat.app.AlertDialog
|
import androidx.appcompat.app.AlertDialog
|
||||||
import androidx.appcompat.app.AppCompatDialogFragment
|
import androidx.appcompat.app.AppCompatDialogFragment
|
||||||
import kotlinx.android.synthetic.main.frequency_picker_dialog.view.*
|
import kotlinx.android.synthetic.main.frequency_picker_dialog.view.*
|
||||||
|
import org.isoron.uhabits.HabitsApplication
|
||||||
import org.isoron.uhabits.R
|
import org.isoron.uhabits.R
|
||||||
|
|
||||||
class FrequencyPickerDialog(
|
class FrequencyPickerDialog(
|
||||||
@@ -43,6 +45,7 @@ class FrequencyPickerDialog(
|
|||||||
constructor() : this(1, 1)
|
constructor() : this(1, 1)
|
||||||
|
|
||||||
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
|
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
|
||||||
|
HabitsApplication.clearCurrentDialog()
|
||||||
val inflater = LayoutInflater.from(requireActivity())
|
val inflater = LayoutInflater.from(requireActivity())
|
||||||
contentView = inflater.inflate(R.layout.frequency_picker_dialog, null)
|
contentView = inflater.inflate(R.layout.frequency_picker_dialog, null)
|
||||||
|
|
||||||
@@ -111,10 +114,17 @@ class FrequencyPickerDialog(
|
|||||||
if (hasFocus) check(contentView.xTimesPerYDaysRadioButton)
|
if (hasFocus) check(contentView.xTimesPerYDaysRadioButton)
|
||||||
}
|
}
|
||||||
|
|
||||||
return AlertDialog.Builder(requireActivity())
|
val dialog = AlertDialog.Builder(requireActivity())
|
||||||
.setView(contentView)
|
.setView(contentView)
|
||||||
.setPositiveButton(R.string.save) { _, _ -> onSaveClicked() }
|
.setPositiveButton(R.string.save) { _, _ -> onSaveClicked() }
|
||||||
.create()
|
.create()
|
||||||
|
HabitsApplication.currentDialog = dialog
|
||||||
|
return dialog
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onDismiss(dialog: DialogInterface) {
|
||||||
|
super.onDismiss(dialog)
|
||||||
|
HabitsApplication.currentDialog = null
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun addBeforeAfterText(
|
private fun addBeforeAfterText(
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
package org.isoron.uhabits.activities.common.dialogs
|
package org.isoron.uhabits.activities.common.dialogs
|
||||||
|
|
||||||
import android.app.Dialog
|
import android.app.Dialog
|
||||||
|
import android.content.DialogInterface
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import androidx.appcompat.app.AppCompatDialogFragment
|
import androidx.appcompat.app.AppCompatDialogFragment
|
||||||
import org.isoron.platform.gui.AndroidDataView
|
import org.isoron.platform.gui.AndroidDataView
|
||||||
@@ -35,6 +36,7 @@ import org.isoron.uhabits.core.ui.views.HistoryChart
|
|||||||
import org.isoron.uhabits.core.ui.views.LightTheme
|
import org.isoron.uhabits.core.ui.views.LightTheme
|
||||||
import org.isoron.uhabits.core.ui.views.OnDateClickedListener
|
import org.isoron.uhabits.core.ui.views.OnDateClickedListener
|
||||||
import org.isoron.uhabits.core.utils.DateUtils
|
import org.isoron.uhabits.core.utils.DateUtils
|
||||||
|
import org.isoron.uhabits.inject.HabitsApplicationComponent
|
||||||
import java.util.Locale
|
import java.util.Locale
|
||||||
import kotlin.math.min
|
import kotlin.math.min
|
||||||
|
|
||||||
@@ -49,12 +51,13 @@ class HistoryEditorDialog : AppCompatDialogFragment(), CommandRunner.Listener {
|
|||||||
private var onDateClickedListener: OnDateClickedListener? = null
|
private var onDateClickedListener: OnDateClickedListener? = null
|
||||||
|
|
||||||
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
|
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
|
||||||
val component = (activity!!.application as HabitsApplication).component
|
clearCurrentDialog()
|
||||||
|
val component = (requireActivity().application as HabitsApplication).component
|
||||||
commandRunner = component.commandRunner
|
commandRunner = component.commandRunner
|
||||||
habit = component.habitList.getById(arguments!!.getLong("habit"))!!
|
habit = component.habitList.getById(requireArguments().getLong("habit"))!!
|
||||||
preferences = component.preferences
|
preferences = component.preferences
|
||||||
|
|
||||||
val themeSwitcher = AndroidThemeSwitcher(activity!!, preferences)
|
val themeSwitcher = AndroidThemeSwitcher(requireActivity(), preferences)
|
||||||
themeSwitcher.apply()
|
themeSwitcher.apply()
|
||||||
|
|
||||||
chart = HistoryChart(
|
chart = HistoryChart(
|
||||||
@@ -69,15 +72,23 @@ class HistoryEditorDialog : AppCompatDialogFragment(), CommandRunner.Listener {
|
|||||||
onDateClickedListener = onDateClickedListener ?: object : OnDateClickedListener {},
|
onDateClickedListener = onDateClickedListener ?: object : OnDateClickedListener {},
|
||||||
padding = 10.0,
|
padding = 10.0,
|
||||||
)
|
)
|
||||||
dataView = AndroidDataView(context!!, null)
|
dataView = AndroidDataView(requireContext(), null)
|
||||||
dataView.view = chart!!
|
dataView.view = chart!!
|
||||||
|
|
||||||
return Dialog(context!!).apply {
|
val dialog = Dialog(requireContext()).apply {
|
||||||
val metrics = resources.displayMetrics
|
val metrics = resources.displayMetrics
|
||||||
val maxHeight = resources.getDimensionPixelSize(R.dimen.history_editor_max_height)
|
val maxHeight = resources.getDimensionPixelSize(R.dimen.history_editor_max_height)
|
||||||
setContentView(dataView)
|
setContentView(dataView)
|
||||||
window!!.setLayout(metrics.widthPixels, min(metrics.heightPixels, maxHeight))
|
window!!.setLayout(metrics.widthPixels, min(metrics.heightPixels, maxHeight))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
currentDialog = dialog
|
||||||
|
return dialog
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onDismiss(dialog: DialogInterface) {
|
||||||
|
super.onDismiss(dialog)
|
||||||
|
currentDialog = null
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onResume() {
|
override fun onResume() {
|
||||||
@@ -111,4 +122,14 @@ class HistoryEditorDialog : AppCompatDialogFragment(), CommandRunner.Listener {
|
|||||||
override fun onCommandFinished(command: Command) {
|
override fun onCommandFinished(command: Command) {
|
||||||
refreshData()
|
refreshData()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
// HistoryEditorDialog handles multiple dialogs on its own,
|
||||||
|
// because sometimes we want it to be shown under another dialog (e.g. NumberPopup)
|
||||||
|
var currentDialog: Dialog? = null
|
||||||
|
fun clearCurrentDialog() {
|
||||||
|
currentDialog?.dismiss()
|
||||||
|
currentDialog = null
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ import android.view.MotionEvent.ACTION_DOWN
|
|||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.View.GONE
|
import android.view.View.GONE
|
||||||
import android.view.View.VISIBLE
|
import android.view.View.VISIBLE
|
||||||
|
import org.isoron.uhabits.HabitsApplication
|
||||||
import org.isoron.uhabits.core.models.Entry
|
import org.isoron.uhabits.core.models.Entry
|
||||||
import org.isoron.uhabits.core.preferences.Preferences
|
import org.isoron.uhabits.core.preferences.Preferences
|
||||||
import org.isoron.uhabits.databinding.CheckmarkPopupBinding
|
import org.isoron.uhabits.databinding.CheckmarkPopupBinding
|
||||||
@@ -73,7 +74,7 @@ class NumberPopup(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun show() {
|
fun show() {
|
||||||
clearCurrentDialog()
|
HabitsApplication.clearCurrentDialog()
|
||||||
dialog = Dialog(context, android.R.style.Theme_NoTitleBar)
|
dialog = Dialog(context, android.R.style.Theme_NoTitleBar)
|
||||||
dialog.setContentView(view.root)
|
dialog.setContentView(view.root)
|
||||||
dialog.window?.apply {
|
dialog.window?.apply {
|
||||||
@@ -85,7 +86,7 @@ class NumberPopup(
|
|||||||
}
|
}
|
||||||
dialog.setOnDismissListener {
|
dialog.setOnDismissListener {
|
||||||
onDismiss()
|
onDismiss()
|
||||||
currentDialog = null
|
HabitsApplication.currentDialog = null
|
||||||
}
|
}
|
||||||
|
|
||||||
view.value.setOnKeyListener { _, keyCode, event ->
|
view.value.setOnKeyListener { _, keyCode, event ->
|
||||||
@@ -105,7 +106,7 @@ class NumberPopup(
|
|||||||
view.value.requestFocusWithKeyboard()
|
view.value.requestFocusWithKeyboard()
|
||||||
dialog.setCanceledOnTouchOutside(true)
|
dialog.setCanceledOnTouchOutside(true)
|
||||||
dialog.dimBehind()
|
dialog.dimBehind()
|
||||||
currentDialog = dialog
|
HabitsApplication.currentDialog = dialog
|
||||||
dialog.show()
|
dialog.show()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -115,14 +116,4 @@ class NumberPopup(
|
|||||||
onToggle(value, notes)
|
onToggle(value, notes)
|
||||||
dialog.dismiss()
|
dialog.dismiss()
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
|
||||||
// Used to make sure that 2 popups aren't shown on top of each other
|
|
||||||
// If dialog that's already shown is detected, it's dismissed before the next one is opened.
|
|
||||||
private var currentDialog: Dialog? = null
|
|
||||||
fun clearCurrentDialog() {
|
|
||||||
currentDialog?.dismiss()
|
|
||||||
currentDialog = null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ import android.content.DialogInterface.OnMultiChoiceClickListener
|
|||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import androidx.appcompat.app.AlertDialog
|
import androidx.appcompat.app.AlertDialog
|
||||||
import androidx.appcompat.app.AppCompatDialogFragment
|
import androidx.appcompat.app.AppCompatDialogFragment
|
||||||
|
import org.isoron.uhabits.HabitsApplication
|
||||||
import org.isoron.uhabits.R
|
import org.isoron.uhabits.R
|
||||||
import org.isoron.uhabits.core.models.WeekdayList
|
import org.isoron.uhabits.core.models.WeekdayList
|
||||||
import org.isoron.uhabits.core.utils.DateUtils
|
import org.isoron.uhabits.core.utils.DateUtils
|
||||||
@@ -59,8 +60,9 @@ class WeekdayPickerDialog :
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
|
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
|
||||||
|
HabitsApplication.clearCurrentDialog()
|
||||||
val builder = AlertDialog.Builder(
|
val builder = AlertDialog.Builder(
|
||||||
activity!!
|
requireActivity()
|
||||||
)
|
)
|
||||||
builder
|
builder
|
||||||
.setTitle(R.string.select_weekdays)
|
.setTitle(R.string.select_weekdays)
|
||||||
@@ -73,7 +75,15 @@ class WeekdayPickerDialog :
|
|||||||
.setNegativeButton(
|
.setNegativeButton(
|
||||||
android.R.string.cancel
|
android.R.string.cancel
|
||||||
) { _: DialogInterface?, _: Int -> dismiss() }
|
) { _: DialogInterface?, _: Int -> dismiss() }
|
||||||
return builder.create()
|
|
||||||
|
val dialog = builder.create()
|
||||||
|
HabitsApplication.currentDialog = dialog
|
||||||
|
return dialog
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onDismiss(dialog: DialogInterface) {
|
||||||
|
super.onDismiss(dialog)
|
||||||
|
HabitsApplication.currentDialog = null
|
||||||
}
|
}
|
||||||
|
|
||||||
fun setListener(listener: OnWeekdaysPickedListener?) {
|
fun setListener(listener: OnWeekdaysPickedListener?) {
|
||||||
|
|||||||
Reference in New Issue
Block a user