improve yes/no dialog design

pull/1103/head
Bindu 4 years ago
parent 71f400f587
commit 8036b10ee6

@ -1,36 +1,63 @@
package org.isoron.uhabits.activities.common.dialogs
import android.content.Context
import android.graphics.Color
import android.graphics.Typeface
import android.view.LayoutInflater
import android.view.View
import android.view.WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE
import android.widget.EditText
import android.widget.Button
import androidx.appcompat.app.AlertDialog
import org.isoron.uhabits.R
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.UNKNOWN
import org.isoron.uhabits.core.models.Entry.Companion.YES_AUTO
import org.isoron.uhabits.core.models.Entry.Companion.YES_MANUAL
import org.isoron.uhabits.core.models.PaletteColor
import org.isoron.uhabits.core.preferences.Preferences
import org.isoron.uhabits.core.ui.screens.habits.list.ListHabitsBehavior
import org.isoron.uhabits.databinding.CheckmarkDialogBinding
import org.isoron.uhabits.inject.ActivityContext
import org.isoron.uhabits.utils.InterfaceUtils
import org.isoron.uhabits.utils.StyledResources
import javax.inject.Inject
class CheckmarkDialog
@Inject constructor(
@ActivityContext private val context: Context
) {
@ActivityContext private val context: Context,
private val preferences: Preferences,
) : View.OnClickListener {
private lateinit var binding: CheckmarkDialogBinding
private lateinit var fontAwesome: Typeface
private val allButtons = mutableListOf<Button>()
private var selectedButton: Button? = null
fun create(
value: Int,
notes: String,
dateString: String,
paletteColor: PaletteColor,
callback: ListHabitsBehavior.CheckMarkDialogCallback
): AlertDialog {
val inflater = LayoutInflater.from(context)
val view = inflater.inflate(R.layout.checkmark_dialog, null)
binding = CheckmarkDialogBinding.inflate(LayoutInflater.from(context))
fontAwesome = InterfaceUtils.getFontAwesome(context)!!
val etNotes = view.findViewById<EditText>(R.id.etNotes)
binding.etNotes.setText(notes)
setUpButtons(value, Color.parseColor(paletteColor.toCsvColor()))
etNotes.setText(notes)
val dialog = AlertDialog.Builder(context)
.setView(view)
.setTitle(R.string.edit_notes)
.setView(binding.root)
.setTitle(dateString)
.setPositiveButton(R.string.save) { _, _ ->
val note = etNotes.text.toString()
callback.onNotesSaved(note)
val newValue = when (selectedButton?.id) {
R.id.yesBtn -> YES_MANUAL
R.id.noBtn -> NO
R.id.skippedBtn -> SKIP
else -> UNKNOWN
}
callback.onNotesSaved(newValue, binding.etNotes.text.toString())
}
.setNegativeButton(android.R.string.cancel) { _, _ ->
callback.onNotesDismissed()
@ -41,10 +68,52 @@ class CheckmarkDialog
.create()
dialog.setOnShowListener {
etNotes.requestFocus()
binding.etNotes.requestFocus()
dialog.window?.setSoftInputMode(SOFT_INPUT_STATE_ALWAYS_VISIBLE)
}
return dialog
}
private fun setUpButtons(value: Int, color: Int) {
val sres = StyledResources(context)
val mediumContrastColor = sres.getColor(R.attr.contrast60)
setButtonAttrs(binding.yesBtn, color)
setButtonAttrs(binding.noBtn, mediumContrastColor)
if (preferences.isSkipEnabled) {
setButtonAttrs(binding.skippedBtn, color)
if (value == SKIP) binding.skippedBtn.performClick()
}
if (preferences.areQuestionMarksEnabled) {
setButtonAttrs(binding.questionBtn, mediumContrastColor)
if (value == UNKNOWN) binding.questionBtn.performClick()
}
when (value) {
YES_MANUAL, YES_AUTO -> binding.yesBtn.performClick()
NO -> binding.noBtn.performClick()
}
}
private fun setButtonAttrs(button: Button, color: Int) {
button.apply {
visibility = View.VISIBLE
typeface = fontAwesome
setTextColor(color)
setOnClickListener(this@CheckmarkDialog)
}
allButtons.add(button)
}
override fun onClick(v: View?) {
allButtons.forEach {
if (v?.id == it.id) {
it.isSelected = true
selectedButton = it
} else it.isSelected = false
}
}
}

@ -235,10 +235,13 @@ class ListHabitsScreen
}
override fun showCheckmarkDialog(
value: Int,
notes: String,
dateString: String,
color: PaletteColor,
callback: ListHabitsBehavior.CheckMarkDialogCallback
) {
checkMarkDialog.create(notes, callback).show()
checkMarkDialog.create(value, notes, dateString, color, callback).show()
}
private fun getExecuteString(command: Command): String? {

@ -39,6 +39,7 @@ import org.isoron.uhabits.activities.common.dialogs.NumberPickerFactory
import org.isoron.uhabits.core.commands.Command
import org.isoron.uhabits.core.commands.CommandRunner
import org.isoron.uhabits.core.models.Habit
import org.isoron.uhabits.core.models.PaletteColor
import org.isoron.uhabits.core.preferences.Preferences
import org.isoron.uhabits.core.ui.callbacks.OnConfirmedCallback
import org.isoron.uhabits.core.ui.screens.habits.list.ListHabitsBehavior
@ -173,10 +174,14 @@ class ShowHabitActivity : AppCompatActivity(), CommandRunner.Listener {
}
override fun showCheckmarkDialog(
value: Int,
notes: String,
dateString: String,
preferences: Preferences,
color: PaletteColor,
callback: ListHabitsBehavior.CheckMarkDialogCallback
) {
CheckmarkDialog(this@ShowHabitActivity).create(notes, callback).show()
CheckmarkDialog(this@ShowHabitActivity, preferences).create(value, notes, dateString, color, callback).show()
}
override fun showEditHabitScreen(habit: Habit) {

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_selected="true">
<shape>
<solid android:color="?attr/contrast40" />
<corners android:radius="4dp"/>
<padding
android:bottom="0dp"
android:left="8dp"
android:right="8dp"
android:top="0dp" />
</shape>
</item>
</selector>

@ -4,15 +4,92 @@
android:gravity="center"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="30dp">
android:orientation="vertical"
android:paddingTop="12dp"
android:paddingStart="10dp"
android:paddingEnd="10dp">
<EditText
android:id="@+id/etNotes"
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textCapSentences|textMultiLine"
style="@style/TextAppearance.AppCompat.Body1"
android:scrollbars="vertical"
android:hint="@string/example_notes"/>
android:orientation="horizontal"
android:padding="8dp"
android:baselineAligned="false">
<FrameLayout
style="@style/FormOuterBox"
android:layout_width="0dp"
android:layout_weight="1">
<LinearLayout style="@style/DialogFormInnerBox">
<TextView
style="@style/DialogFormLabel"
android:text="@string/value" />
<LinearLayout
android:orientation="horizontal"
android:gravity="center_horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="8dp">
<Button
android:id="@+id/yesBtn"
android:text="@string/fa_check"
style="@style/CheckmarkDialogBtn"/>
<Button
android:id="@+id/skippedBtn"
android:text="@string/fa_skipped"
android:visibility="gone"
style="@style/CheckmarkDialogBtn"/>
<Button
android:id="@+id/noBtn"
android:text="@string/fa_times"
style="@style/CheckmarkDialogBtn"/>
<Button
android:id="@+id/questionBtn"
android:text="@string/fa_question"
android:visibility="gone"
style="@style/CheckmarkDialogBtn"/>
</LinearLayout>
</LinearLayout>
</FrameLayout>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="5dp"
android:baselineAligned="false">
<FrameLayout
style="@style/FormOuterBox"
android:layout_width="0dp"
android:layout_weight="1">
<LinearLayout style="@style/DialogFormInnerBox">
<TextView
style="@style/DialogFormLabel"
android:text="@string/notes" />
<EditText
android:id="@+id/etNotes"
android:inputType="textCapSentences|textMultiLine"
style="@style/FormInput"
android:scrollbars="vertical"
android:hint="@string/example_notes"/>
</LinearLayout>
</FrameLayout>
</LinearLayout>
</LinearLayout>

@ -232,5 +232,4 @@
<string name="activity_not_found">No app was found to support this action</string>
<string name="pref_midnight_delay_title">Extend day a few hours past midnight</string>
<string name="pref_midnight_delay_description">Wait until 3:00 AM to show a new day. Useful if you typically go to sleep after midnight. Requires app restart.</string>
<string name="edit_notes">Edit notes</string>
</resources>

@ -387,4 +387,16 @@
<item name="android:textSize">@dimen/smallTextSize</item>
</style>
<style name="CheckmarkDialogBtn">
<item name="android:layout_width">48dp</item>
<item name="android:layout_height">48dp</item>
<item name="android:layout_marginTop">8dp</item>
<item name="android:layout_marginBottom">8dp</item>
<item name="android:layout_marginEnd">12dp</item>
<item name="android:textSize">@dimen/regularTextSize</item>
<item name="backgroundTint">@null</item>
<item name="android:background">@drawable/bg_select_button</item>
<item name="selectable">true</item>
</style>
</resources>

@ -23,6 +23,7 @@ import org.isoron.uhabits.core.commands.CreateRepetitionCommand
import org.isoron.uhabits.core.models.Habit
import org.isoron.uhabits.core.models.HabitList
import org.isoron.uhabits.core.models.HabitType
import org.isoron.uhabits.core.models.PaletteColor
import org.isoron.uhabits.core.models.Timestamp
import org.isoron.uhabits.core.preferences.Preferences
import org.isoron.uhabits.core.tasks.ExportCSVTask
@ -62,9 +63,12 @@ open class ListHabitsBehavior @Inject constructor(
}
} else {
screen.showCheckmarkDialog(
entry.notes
) { newNotes ->
commandRunner.run(CreateRepetitionCommand(habitList, habit, timestamp, entry.value, newNotes))
entry.value,
entry.notes,
timestamp.toDialogDateString(),
habit.color,
) { newValue, newNotes ->
commandRunner.run(CreateRepetitionCommand(habitList, habit, timestamp, newValue, newNotes))
}
}
}
@ -148,7 +152,7 @@ open class ListHabitsBehavior @Inject constructor(
}
fun interface CheckMarkDialogCallback {
fun onNotesSaved(notes: String)
fun onNotesSaved(value: Int, notes: String)
fun onNotesDismissed() {}
}
@ -164,7 +168,10 @@ open class ListHabitsBehavior @Inject constructor(
callback: NumberPickerCallback
)
fun showCheckmarkDialog(
value: Int,
notes: String,
dateString: String,
color: PaletteColor,
callback: CheckMarkDialogCallback
)

@ -90,13 +90,19 @@ class HistoryCardPresenter(
showNumberPicker(timestamp)
} else {
val entry = habit.computedEntries.get(timestamp)
screen.showCheckmarkDialog(entry.notes) { newNotes ->
screen.showCheckmarkDialog(
entry.value,
entry.notes,
timestamp.toDialogDateString(),
preferences,
habit.color,
) { newValue, newNotes ->
commandRunner.run(
CreateRepetitionCommand(
habitList,
habit,
timestamp,
entry.value,
newValue,
newNotes,
),
)
@ -200,7 +206,11 @@ class HistoryCardPresenter(
callback: ListHabitsBehavior.NumberPickerCallback,
)
fun showCheckmarkDialog(
value: Int,
notes: String,
dateString: String,
preferences: Preferences,
color: PaletteColor,
callback: ListHabitsBehavior.CheckMarkDialogCallback,
)
}

Loading…
Cancel
Save