Implement dialog for Yes/No Habits

pull/1103/head
Bindu 4 years ago
parent d38f83e961
commit d644170141

@ -0,0 +1,50 @@
package org.isoron.uhabits.activities.common.dialogs
import androidx.appcompat.app.AlertDialog
import android.content.Context
import android.view.LayoutInflater
import android.view.WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE
import android.widget.EditText
import org.isoron.uhabits.R
import org.isoron.uhabits.core.ui.screens.habits.list.ListHabitsBehavior
import org.isoron.uhabits.inject.ActivityContext
import javax.inject.Inject
class CheckmarkDialog
@Inject constructor(
@ActivityContext private val context: Context
) {
fun create(
notes: String,
callback: ListHabitsBehavior.CheckMarkDialogCallback
): AlertDialog {
val inflater = LayoutInflater.from(context)
val view = inflater.inflate(R.layout.checkmark_dialog, null)
val etNotes = view.findViewById<EditText>(R.id.etNotes)
etNotes.setText(notes)
val dialog = AlertDialog.Builder(context)
.setView(view)
.setTitle(R.string.edit_notes)
.setPositiveButton(R.string.save) { _, _ ->
val note = etNotes.text.toString()
callback.onNotesSaved(note)
}
.setNegativeButton(android.R.string.cancel) { _, _ ->
callback.onNotesDismissed()
}
.setOnDismissListener {
callback.onNotesDismissed()
}
.create()
dialog.setOnShowListener {
etNotes.requestFocus()
dialog.window?.setSoftInputMode(SOFT_INPUT_STATE_ALWAYS_VISIBLE)
}
return dialog
}
}

@ -89,7 +89,7 @@ class NumberPickerFactory
val note = etNotes.text.toString() val note = etNotes.text.toString()
callback.onNumberPicked(v, note) callback.onNumberPicked(v, note)
} }
.setNegativeButton(R.string.cancel) { _, _ -> .setNegativeButton(android.R.string.cancel) { _, _ ->
callback.onNumberPickerDismissed() callback.onNumberPickerDismissed()
} }
.setOnDismissListener { .setOnDismissListener {

@ -25,6 +25,7 @@ import android.content.Intent
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import dagger.Lazy import dagger.Lazy
import org.isoron.uhabits.R import org.isoron.uhabits.R
import org.isoron.uhabits.activities.common.dialogs.CheckmarkDialog
import org.isoron.uhabits.activities.common.dialogs.ColorPickerDialogFactory import org.isoron.uhabits.activities.common.dialogs.ColorPickerDialogFactory
import org.isoron.uhabits.activities.common.dialogs.ConfirmDeleteDialog import org.isoron.uhabits.activities.common.dialogs.ConfirmDeleteDialog
import org.isoron.uhabits.activities.common.dialogs.NumberPickerFactory import org.isoron.uhabits.activities.common.dialogs.NumberPickerFactory
@ -89,6 +90,7 @@ class ListHabitsScreen
private val importTaskFactory: ImportDataTaskFactory, private val importTaskFactory: ImportDataTaskFactory,
private val colorPickerFactory: ColorPickerDialogFactory, private val colorPickerFactory: ColorPickerDialogFactory,
private val numberPickerFactory: NumberPickerFactory, private val numberPickerFactory: NumberPickerFactory,
private val checkMarkDialog: CheckmarkDialog,
private val behavior: Lazy<ListHabitsBehavior> private val behavior: Lazy<ListHabitsBehavior>
) : CommandRunner.Listener, ) : CommandRunner.Listener,
ListHabitsBehavior.Screen, ListHabitsBehavior.Screen,
@ -231,6 +233,13 @@ class ListHabitsScreen
numberPickerFactory.create(value, unit, notes, callback).show() numberPickerFactory.create(value, unit, notes, callback).show()
} }
override fun showCheckmarkDialog(
notes: String,
callback: ListHabitsBehavior.CheckMarkDialogCallback
) {
checkMarkDialog.create(notes, callback).show()
}
private fun getExecuteString(command: Command): String? { private fun getExecuteString(command: Command): String? {
when (command) { when (command) {
is ArchiveHabitsCommand -> { is ArchiveHabitsCommand -> {

@ -39,7 +39,6 @@ import org.isoron.uhabits.core.preferences.Preferences
import org.isoron.uhabits.inject.ActivityContext import org.isoron.uhabits.inject.ActivityContext
import org.isoron.uhabits.utils.dim import org.isoron.uhabits.utils.dim
import org.isoron.uhabits.utils.getFontAwesome import org.isoron.uhabits.utils.getFontAwesome
import org.isoron.uhabits.utils.showMessage
import org.isoron.uhabits.utils.sres import org.isoron.uhabits.utils.sres
import org.isoron.uhabits.utils.toMeasureSpec import org.isoron.uhabits.utils.toMeasureSpec
import javax.inject.Inject import javax.inject.Inject
@ -78,6 +77,8 @@ class CheckmarkButtonView(
} }
var onToggle: (Int) -> Unit = {} var onToggle: (Int) -> Unit = {}
var onEdit: () -> Unit = {}
private var drawer = Drawer() private var drawer = Drawer()
init { init {
@ -99,7 +100,7 @@ class CheckmarkButtonView(
override fun onClick(v: View) { override fun onClick(v: View) {
if (preferences.isShortToggleEnabled) performToggle() if (preferences.isShortToggleEnabled) performToggle()
else showMessage(resources.getString(R.string.long_press_to_toggle)) else onEdit()
} }
override fun onLongClick(v: View): Boolean { override fun onLongClick(v: View): Boolean {
@ -133,6 +134,8 @@ class CheckmarkButtonView(
textAlign = Paint.Align.CENTER textAlign = Paint.Align.CENTER
} }
private val pNotesIndicator: Paint = Paint()
fun draw(canvas: Canvas) { fun draw(canvas: Canvas) {
paint.color = when (value) { paint.color = when (value) {
YES_MANUAL, YES_AUTO, SKIP -> color YES_MANUAL, YES_AUTO, SKIP -> color
@ -142,6 +145,7 @@ class CheckmarkButtonView(
} }
else -> lowContrastColor else -> lowContrastColor
} }
pNotesIndicator.color = color
val id = when (value) { val id = when (value) {
SKIP -> R.string.fa_skipped SKIP -> R.string.fa_skipped
NO -> R.string.fa_times NO -> R.string.fa_times
@ -176,6 +180,11 @@ class CheckmarkButtonView(
paint.style = Paint.Style.FILL paint.style = Paint.Style.FILL
canvas.drawText(label, rect.centerX(), rect.centerY(), paint) canvas.drawText(label, rect.centerX(), rect.centerY(), paint)
} }
if (hasNotes) {
val cy = 0.8f * em
canvas.drawCircle(width.toFloat() - cy, cy, 8f, pNotesIndicator)
}
} }
} }
} }

@ -66,6 +66,12 @@ class CheckmarkPanelView(
setupButtons() setupButtons()
} }
var onEdit: (Timestamp) -> Unit = {}
set(value) {
field = value
setupButtons()
}
override fun createButton(): CheckmarkButtonView = buttonFactory.create() override fun createButton(): CheckmarkButtonView = buttonFactory.create()
@Synchronized @Synchronized
@ -84,6 +90,7 @@ class CheckmarkPanelView(
} }
button.color = color button.color = color
button.onToggle = { value -> onToggle(timestamp, value) } button.onToggle = { value -> onToggle(timestamp, value) }
button.onEdit = { onEdit(timestamp) }
} }
} }
} }

@ -116,7 +116,7 @@ class HabitCardView(
} }
var notes var notes
get() = numberPanel.notes get() = checkmarkPanel.notes
set(values) { set(values) {
checkmarkPanel.notes = values checkmarkPanel.notes = values
numberPanel.notes = values numberPanel.notes = values
@ -150,7 +150,11 @@ class HabitCardView(
checkmarkPanel = checkmarkPanelFactory.create().apply { checkmarkPanel = checkmarkPanelFactory.create().apply {
onToggle = { timestamp, value -> onToggle = { timestamp, value ->
triggerRipple(timestamp) triggerRipple(timestamp)
habit?.let { behavior.onToggle(it, timestamp, value, "") } habit?.let { behavior.onToggle(it, timestamp, value) }
}
onEdit = { timestamp ->
triggerRipple(timestamp)
habit?.let { behavior.onEdit(it, timestamp) }
} }
} }

@ -206,7 +206,7 @@ class NumberButtonView(
pNumber.color = activeColor pNumber.color = activeColor
pNumber.typeface = typeface pNumber.typeface = typeface
pUnit.color = activeColor pUnit.color = activeColor
pNotesIndicator.color = activeColor pNotesIndicator.color = color
if (units.isBlank()) { if (units.isBlank()) {
rect.set(0f, 0f, width.toFloat(), height.toFloat()) rect.set(0f, 0f, width.toFloat(), height.toFloat())

@ -32,6 +32,7 @@ import org.isoron.uhabits.HabitsApplication
import org.isoron.uhabits.R import org.isoron.uhabits.R
import org.isoron.uhabits.activities.AndroidThemeSwitcher import org.isoron.uhabits.activities.AndroidThemeSwitcher
import org.isoron.uhabits.activities.HabitsDirFinder import org.isoron.uhabits.activities.HabitsDirFinder
import org.isoron.uhabits.activities.common.dialogs.CheckmarkDialog
import org.isoron.uhabits.activities.common.dialogs.ConfirmDeleteDialog import org.isoron.uhabits.activities.common.dialogs.ConfirmDeleteDialog
import org.isoron.uhabits.activities.common.dialogs.HistoryEditorDialog import org.isoron.uhabits.activities.common.dialogs.HistoryEditorDialog
import org.isoron.uhabits.activities.common.dialogs.NumberPickerFactory import org.isoron.uhabits.activities.common.dialogs.NumberPickerFactory
@ -170,6 +171,13 @@ class ShowHabitActivity : AppCompatActivity(), CommandRunner.Listener {
NumberPickerFactory(this@ShowHabitActivity).create(value, unit, notes, callback).show() NumberPickerFactory(this@ShowHabitActivity).create(value, unit, notes, callback).show()
} }
override fun showCheckmarkDialog(
notes: String,
callback: ListHabitsBehavior.CheckMarkDialogCallback
) {
CheckmarkDialog(this@ShowHabitActivity).create(notes, callback).show()
}
override fun showEditHabitScreen(habit: Habit) { override fun showEditHabitScreen(habit: Habit) {
startActivity(IntentFactory().startEditActivity(this@ShowHabitActivity, habit)) startActivity(IntentFactory().startEditActivity(this@ShowHabitActivity, habit))
} }

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:gravity="center"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="30dp">
<EditText
android:id="@+id/etNotes"
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"/>
</LinearLayout>

@ -55,7 +55,6 @@
<string name="clear">Clear</string> <string name="clear">Clear</string>
<string name="reminder">Reminder</string> <string name="reminder">Reminder</string>
<string name="save">Save</string> <string name="save">Save</string>
<string name="cancel">Cancel</string>
<string name="streaks">Streaks</string> <string name="streaks">Streaks</string>
<string name="no_habits_found">You have no active habits</string> <string name="no_habits_found">You have no active habits</string>
<string name="no_habits_left_to_do">You\'re all done for today!</string> <string name="no_habits_left_to_do">You\'re all done for today!</string>
@ -233,4 +232,5 @@
<string name="activity_not_found">No app was found to support this action</string> <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_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="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> </resources>

@ -22,6 +22,7 @@ import org.isoron.uhabits.core.commands.CommandRunner
import org.isoron.uhabits.core.commands.CreateRepetitionCommand import org.isoron.uhabits.core.commands.CreateRepetitionCommand
import org.isoron.uhabits.core.models.Habit import org.isoron.uhabits.core.models.Habit
import org.isoron.uhabits.core.models.HabitList import org.isoron.uhabits.core.models.HabitList
import org.isoron.uhabits.core.models.HabitType
import org.isoron.uhabits.core.models.Timestamp import org.isoron.uhabits.core.models.Timestamp
import org.isoron.uhabits.core.preferences.Preferences import org.isoron.uhabits.core.preferences.Preferences
import org.isoron.uhabits.core.tasks.ExportCSVTask import org.isoron.uhabits.core.tasks.ExportCSVTask
@ -48,8 +49,9 @@ open class ListHabitsBehavior @Inject constructor(
fun onEdit(habit: Habit, timestamp: Timestamp?) { fun onEdit(habit: Habit, timestamp: Timestamp?) {
val entries = habit.computedEntries.get(timestamp!!) val entries = habit.computedEntries.get(timestamp!!)
val oldValue = entries.value.toDouble()
val notes = entries.notes val notes = entries.notes
if (habit.type == HabitType.NUMERICAL) {
val oldValue = entries.value.toDouble()
screen.showNumberPicker( screen.showNumberPicker(
oldValue / 1000, oldValue / 1000,
habit.unit, habit.unit,
@ -58,6 +60,14 @@ open class ListHabitsBehavior @Inject constructor(
val value = (newValue * 1000).roundToInt() val value = (newValue * 1000).roundToInt()
commandRunner.run(CreateRepetitionCommand(habitList, habit, timestamp, value, newNotes)) commandRunner.run(CreateRepetitionCommand(habitList, habit, timestamp, value, newNotes))
} }
} else {
val value = entries.value
screen.showCheckmarkDialog(
notes
) { newNotes ->
commandRunner.run(CreateRepetitionCommand(habitList, habit, timestamp, value, newNotes))
}
}
} }
fun onExportCSV() { fun onExportCSV() {
@ -106,9 +116,10 @@ open class ListHabitsBehavior @Inject constructor(
if (prefs.isFirstRun) onFirstRun() if (prefs.isFirstRun) onFirstRun()
} }
fun onToggle(habit: Habit, timestamp: Timestamp?, value: Int, notes: String) { fun onToggle(habit: Habit, timestamp: Timestamp?, value: Int) {
val notes = habit.computedEntries.get(timestamp!!).notes
commandRunner.run( commandRunner.run(
CreateRepetitionCommand(habitList, habit, timestamp!!, value, notes) CreateRepetitionCommand(habitList, habit, timestamp, value, notes)
) )
} }
@ -137,6 +148,11 @@ open class ListHabitsBehavior @Inject constructor(
fun onNumberPickerDismissed() {} fun onNumberPickerDismissed() {}
} }
fun interface CheckMarkDialogCallback {
fun onNotesSaved(notes: String)
fun onNotesDismissed() {}
}
interface Screen { interface Screen {
fun showHabitScreen(h: Habit) fun showHabitScreen(h: Habit)
fun showIntroScreen() fun showIntroScreen()
@ -147,6 +163,10 @@ open class ListHabitsBehavior @Inject constructor(
notes: String, notes: String,
callback: NumberPickerCallback callback: NumberPickerCallback
) )
fun showCheckmarkDialog(
notes: String,
callback: CheckMarkDialogCallback
)
fun showSendBugReportToDeveloperScreen(log: String) fun showSendBugReportToDeveloperScreen(log: String)
fun showSendFileScreen(filename: String) fun showSendFileScreen(filename: String)

@ -162,5 +162,9 @@ class HistoryCardPresenter(
notes: String, notes: String,
callback: ListHabitsBehavior.NumberPickerCallback, callback: ListHabitsBehavior.NumberPickerCallback,
) )
fun showCheckmarkDialog(
notes: String,
callback: ListHabitsBehavior.CheckMarkDialogCallback,
)
} }
} }

Loading…
Cancel
Save