Added a notes field and implemented dialog for numeric habits

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

@ -47,6 +47,7 @@ class NumberPickerFactory
fun create( fun create(
value: Double, value: Double,
unit: String, unit: String,
notes: String,
callback: ListHabitsBehavior.NumberPickerCallback callback: ListHabitsBehavior.NumberPickerCallback
): AlertDialog { ): AlertDialog {
val inflater = LayoutInflater.from(context) val inflater = LayoutInflater.from(context)
@ -54,6 +55,7 @@ class NumberPickerFactory
val picker = view.findViewById<NumberPicker>(R.id.picker) val picker = view.findViewById<NumberPicker>(R.id.picker)
val picker2 = view.findViewById<NumberPicker>(R.id.picker2) val picker2 = view.findViewById<NumberPicker>(R.id.picker2)
val etNotes = view.findViewById<EditText>(R.id.etNotes)
val watcherFilter: InputFilter = SeparatorWatcherInputFilter(picker2) val watcherFilter: InputFilter = SeparatorWatcherInputFilter(picker2)
val numberPickerInputText = getNumberPickerInputText(picker) val numberPickerInputText = getNumberPickerInputText(picker)
@ -77,13 +79,18 @@ class NumberPickerFactory
picker2.setFormatter { v -> String.format("%02d", v) } picker2.setFormatter { v -> String.format("%02d", v) }
picker2.value = intValue % 100 picker2.value = intValue % 100
etNotes.setText(notes)
val dialog = AlertDialog.Builder(context) val dialog = AlertDialog.Builder(context)
.setView(view) .setView(view)
.setTitle(R.string.change_value) .setTitle(R.string.change_value)
.setPositiveButton(android.R.string.ok) { _, _ -> .setPositiveButton(R.string.save) { _, _ ->
picker.clearFocus() picker.clearFocus()
val v = picker.value + 0.01 * picker2.value val v = picker.value + 0.01 * picker2.value
callback.onNumberPicked(v) val note = etNotes.text.toString()
callback.onNumberPicked(v, note)
}
.setNegativeButton(R.string.cancel) { _, _ ->
callback.onNumberPickerDismissed()
} }
.setOnDismissListener { .setOnDismissListener {
callback.onNumberPickerDismissed() callback.onNumberPickerDismissed()

@ -225,9 +225,10 @@ class ListHabitsScreen
override fun showNumberPicker( override fun showNumberPicker(
value: Double, value: Double,
unit: String, unit: String,
notes: String,
callback: ListHabitsBehavior.NumberPickerCallback callback: ListHabitsBehavior.NumberPickerCallback
) { ) {
numberPickerFactory.create(value, unit, callback).show() numberPickerFactory.create(value, unit, notes, callback).show()
} }
private fun getExecuteString(command: Command): String? { private fun getExecuteString(command: Command): String? {

@ -71,6 +71,12 @@ class CheckmarkButtonView(
invalidate() invalidate()
} }
var hasNotes = false
set(value) {
field = value
invalidate()
}
var onToggle: (Int) -> Unit = {} var onToggle: (Int) -> Unit = {}
private var drawer = Drawer() private var drawer = Drawer()

@ -54,6 +54,12 @@ class CheckmarkPanelView(
setupButtons() setupButtons()
} }
var notes = BooleanArray(0)
set(values) {
field = values
setupButtons()
}
var onToggle: (Timestamp, Int) -> Unit = { _, _ -> } var onToggle: (Timestamp, Int) -> Unit = { _, _ -> }
set(value) { set(value) {
field = value field = value
@ -72,6 +78,10 @@ class CheckmarkPanelView(
index + dataOffset < values.size -> values[index + dataOffset] index + dataOffset < values.size -> values[index + dataOffset]
else -> UNKNOWN else -> UNKNOWN
} }
button.hasNotes = when {
index + dataOffset < notes.size -> notes[index + dataOffset]
else -> false
}
button.color = color button.color = color
button.onToggle = { value -> onToggle(timestamp, value) } button.onToggle = { value -> onToggle(timestamp, value) }
} }

@ -124,8 +124,9 @@ class HabitCardListAdapter @Inject constructor(
val habit = cache.getHabitByPosition(position) val habit = cache.getHabitByPosition(position)
val score = cache.getScore(habit!!.id!!) val score = cache.getScore(habit!!.id!!)
val checkmarks = cache.getCheckmarks(habit.id!!) val checkmarks = cache.getCheckmarks(habit.id!!)
val notesIndicators = cache.getNoteIndicators(habit.id!!)
val selected = selected.contains(habit) val selected = selected.contains(habit)
listView!!.bindCardView(holder, habit, score, checkmarks, selected) listView!!.bindCardView(holder, habit, score, checkmarks, notesIndicators, selected)
} }
override fun onViewAttachedToWindow(holder: HabitCardViewHolder) { override fun onViewAttachedToWindow(holder: HabitCardViewHolder) {

@ -87,6 +87,7 @@ class HabitCardListView(
habit: Habit, habit: Habit,
score: Double, score: Double,
checkmarks: IntArray, checkmarks: IntArray,
notesIndicators: BooleanArray,
selected: Boolean selected: Boolean
): View { ): View {
val cardView = holder.itemView as HabitCardView val cardView = holder.itemView as HabitCardView
@ -98,6 +99,7 @@ class HabitCardListView(
cardView.score = score cardView.score = score
cardView.unit = habit.unit cardView.unit = habit.unit
cardView.threshold = habit.targetValue / habit.frequency.denominator cardView.threshold = habit.targetValue / habit.frequency.denominator
cardView.notes = notesIndicators
val detector = GestureDetector(context, CardViewGestureDetector(holder)) val detector = GestureDetector(context, CardViewGestureDetector(holder))
cardView.setOnTouchListener { _, ev -> cardView.setOnTouchListener { _, ev ->

@ -115,6 +115,13 @@ class HabitCardView(
numberPanel.threshold = value numberPanel.threshold = value
} }
var notes
get() = numberPanel.notes
set(values) {
checkmarkPanel.notes = values
numberPanel.notes = values
}
var checkmarkPanel: CheckmarkPanelView var checkmarkPanel: CheckmarkPanelView
private var numberPanel: NumberPanelView private var numberPanel: NumberPanelView
private var innerFrame: LinearLayout private var innerFrame: LinearLayout
@ -143,7 +150,7 @@ 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, "") }
} }
} }

@ -101,6 +101,11 @@ class NumberButtonView(
field = value field = value
invalidate() invalidate()
} }
var hasNotes = false
set(value) {
field = value
invalidate()
}
var onEdit: () -> Unit = {} var onEdit: () -> Unit = {}
private var drawer: Drawer = Drawer(context) private var drawer: Drawer = Drawer(context)
@ -111,8 +116,7 @@ class NumberButtonView(
} }
override fun onClick(v: View) { override fun onClick(v: View) {
if (preferences.isShortToggleEnabled) onEdit() onEdit()
else showMessage(resources.getString(R.string.long_press_to_edit))
} }
override fun onLongClick(v: View): Boolean { override fun onLongClick(v: View): Boolean {
@ -153,6 +157,8 @@ class NumberButtonView(
textAlign = Paint.Align.CENTER textAlign = Paint.Align.CENTER
} }
private val pNotesIndicator: Paint = Paint()
init { init {
em = pNumber.measureText("m") em = pNumber.measureText("m")
lowContrast = sres.getColor(R.attr.contrast40) lowContrast = sres.getColor(R.attr.contrast40)
@ -200,6 +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
if (units.isBlank()) { if (units.isBlank()) {
rect.set(0f, 0f, width.toFloat(), height.toFloat()) rect.set(0f, 0f, width.toFloat(), height.toFloat())
@ -211,6 +218,11 @@ class NumberButtonView(
rect.offset(0f, 1.3f * em) rect.offset(0f, 1.3f * em)
canvas.drawText(units, rect.centerX(), rect.centerY(), pUnit) canvas.drawText(units, rect.centerX(), rect.centerY(), pUnit)
} }
if (hasNotes) {
val cy = 0.8f * em
canvas.drawCircle(width.toFloat() - cy, cy, 8f, pNotesIndicator)
}
} }
} }
} }

@ -72,6 +72,12 @@ class NumberPanelView(
setupButtons() setupButtons()
} }
var notes = BooleanArray(0)
set(values) {
field = values
setupButtons()
}
var onEdit: (Timestamp) -> Unit = {} var onEdit: (Timestamp) -> Unit = {}
set(value) { set(value) {
field = value field = value
@ -90,6 +96,10 @@ class NumberPanelView(
index + dataOffset < values.size -> values[index + dataOffset] index + dataOffset < values.size -> values[index + dataOffset]
else -> 0.0 else -> 0.0
} }
button.hasNotes = when {
index + dataOffset < notes.size -> notes[index + dataOffset]
else -> false
}
button.color = color button.color = color
button.targetType = targetType button.targetType = targetType
button.threshold = threshold button.threshold = threshold

@ -164,9 +164,10 @@ class ShowHabitActivity : AppCompatActivity(), CommandRunner.Listener {
override fun showNumberPicker( override fun showNumberPicker(
value: Double, value: Double,
unit: String, unit: String,
notes: String,
callback: ListHabitsBehavior.NumberPickerCallback, callback: ListHabitsBehavior.NumberPickerCallback,
) { ) {
NumberPickerFactory(this@ShowHabitActivity).create(value, unit, callback).show() NumberPickerFactory(this@ShowHabitActivity).create(value, unit, notes, callback).show()
} }
override fun showEditHabitScreen(habit: Habit) { override fun showEditHabitScreen(habit: Habit) {

@ -60,8 +60,8 @@ class NumericalCheckmarkWidgetActivity : Activity(), ListHabitsBehavior.NumberPi
SystemUtils.unlockScreen(this) SystemUtils.unlockScreen(this)
} }
override fun onNumberPicked(newValue: Double) { override fun onNumberPicked(newValue: Double, notes: String) {
behavior.setValue(data.habit, data.timestamp, (newValue * 1000).toInt()) behavior.setValue(data.habit, data.timestamp, (newValue * 1000).toInt(), notes)
widgetUpdater.updateWidgets() widgetUpdater.updateWidgets()
finish() finish()
} }
@ -79,6 +79,7 @@ class NumericalCheckmarkWidgetActivity : Activity(), ListHabitsBehavior.NumberPi
numberPickerFactory.create( numberPickerFactory.create(
entry.value / 1000.0, entry.value / 1000.0,
data.habit.unit, data.habit.unit,
entry.notes,
this this
).show() ).show()
} }

@ -19,33 +19,64 @@
--> -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal" android:orientation="vertical"
android:gravity="center"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content"> android:layout_height="wrap_content">
<NumberPicker <LinearLayout
android:id="@+id/picker" android:orientation="horizontal"
android:layout_gravity="center" android:gravity="center"
android:layout_width="wrap_content" android:layout_width="match_parent"
android:layout_height="wrap_content"/> android:layout_height="match_parent">
<TextView <NumberPicker
android:id="@+id/tvSeparator" android:id="@+id/picker"
android:layout_width="wrap_content" android:layout_gravity="center"
android:layout_height="wrap_content" android:layout_width="wrap_content"
/> android:layout_height="wrap_content"/>
<TextView
android:id="@+id/tvSeparator"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
<NumberPicker
android:id="@+id/picker2"
android:layout_gravity="center"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
<TextView
android:id="@+id/tvUnit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<NumberPicker </LinearLayout>
android:id="@+id/picker2"
android:layout_gravity="center" <LinearLayout
android:layout_width="wrap_content" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
/> android:orientation="vertical"
android:padding="30dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="@style/TextAppearance.AppCompat.Title"
android:paddingBottom="10dp"
android:text="@string/notes"/>
<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"/>
<TextView </LinearLayout>
android:id="@+id/tvUnit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout> </LinearLayout>

@ -55,6 +55,7 @@
<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>

@ -20,4 +20,4 @@ package org.isoron.uhabits.core
const val DATABASE_FILENAME = "uhabits.db" const val DATABASE_FILENAME = "uhabits.db"
const val DATABASE_VERSION = 24 const val DATABASE_VERSION = 25

@ -28,10 +28,11 @@ data class CreateRepetitionCommand(
val habit: Habit, val habit: Habit,
val timestamp: Timestamp, val timestamp: Timestamp,
val value: Int, val value: Int,
val notes: String,
) : Command { ) : Command {
override fun run() { override fun run() {
val entries = habit.originalEntries val entries = habit.originalEntries
entries.add(Entry(timestamp, value)) entries.add(Entry(timestamp, value, notes))
habit.recompute() habit.recompute()
habitList.resort() habitList.resort()
} }

@ -77,7 +77,8 @@ class HabitBullCSVImporter
logger.info("Creating habit: $name") logger.info("Creating habit: $name")
} }
if (parseInt(cols[4]) == 1) { if (parseInt(cols[4]) == 1) {
h.originalEntries.add(Entry(timestamp, Entry.YES_MANUAL)) val notes = cols[5] ?: ""
h.originalEntries.add(Entry(timestamp, Entry.YES_MANUAL, notes))
} }
} }
} }

@ -101,8 +101,8 @@ class LoopDBImporter
for (r in entryRecords) { for (r in entryRecords) {
val t = Timestamp(r.timestamp!!) val t = Timestamp(r.timestamp!!)
val (_, value) = habit!!.originalEntries.get(t) val (_, value, notes) = habit!!.originalEntries.get(t)
if (value != r.value) CreateRepetitionCommand(habitList, habit, t, r.value!!).run() if (value != r.value || notes != r.notes) CreateRepetitionCommand(habitList, habit, t, r.value!!, r.notes!!).run()
} }
runner.notifyListeners(command) runner.notifyListeners(command)

@ -21,6 +21,7 @@ package org.isoron.uhabits.core.models
data class Entry( data class Entry(
val timestamp: Timestamp, val timestamp: Timestamp,
val value: Int, val value: Int,
val notes: String = "",
) { ) {
companion object { companion object {
/** /**

@ -41,12 +41,16 @@ class EntryRecord {
@field:Column @field:Column
var id: Long? = null var id: Long? = null
@field:Column
var notes: String? = null
fun copyFrom(entry: Entry) { fun copyFrom(entry: Entry) {
timestamp = entry.timestamp.unixTime timestamp = entry.timestamp.unixTime
value = entry.value value = entry.value
notes = entry.notes
} }
fun toEntry(): Entry { fun toEntry(): Entry {
return Entry(Timestamp(timestamp!!), value!!) return Entry(Timestamp(timestamp!!), value!!, notes!!)
} }
} }

@ -78,6 +78,11 @@ class HabitCardListCache @Inject constructor(
return data.checkmarks[habitId]!! return data.checkmarks[habitId]!!
} }
@Synchronized
fun getNoteIndicators(habitId: Long): BooleanArray {
return data.notesIndicators[habitId]!!
}
@Synchronized @Synchronized
fun hasNoHabit(): Boolean { fun hasNoHabit(): Boolean {
return allHabits.isEmpty return allHabits.isEmpty
@ -163,6 +168,7 @@ class HabitCardListCache @Inject constructor(
data.habits.removeAt(position) data.habits.removeAt(position)
data.idToHabit.remove(id) data.idToHabit.remove(id)
data.checkmarks.remove(id) data.checkmarks.remove(id)
data.notesIndicators.remove(id)
data.scores.remove(id) data.scores.remove(id)
listener.onItemRemoved(position) listener.onItemRemoved(position)
} }
@ -207,6 +213,7 @@ class HabitCardListCache @Inject constructor(
val habits: MutableList<Habit> val habits: MutableList<Habit>
val checkmarks: HashMap<Long?, IntArray> val checkmarks: HashMap<Long?, IntArray>
val scores: HashMap<Long?, Double> val scores: HashMap<Long?, Double>
val notesIndicators: HashMap<Long?, BooleanArray>
@Synchronized @Synchronized
fun copyCheckmarksFrom(oldData: CacheData) { fun copyCheckmarksFrom(oldData: CacheData) {
@ -217,6 +224,15 @@ class HabitCardListCache @Inject constructor(
} }
} }
@Synchronized
fun copyNoteIndicatorsFrom(oldData: CacheData) {
val empty = BooleanArray(checkmarkCount)
for (id in idToHabit.keys) {
if (oldData.notesIndicators.containsKey(id)) notesIndicators[id] =
oldData.notesIndicators[id]!! else notesIndicators[id] = empty
}
}
@Synchronized @Synchronized
fun copyScoresFrom(oldData: CacheData) { fun copyScoresFrom(oldData: CacheData) {
for (id in idToHabit.keys) { for (id in idToHabit.keys) {
@ -241,6 +257,7 @@ class HabitCardListCache @Inject constructor(
habits = LinkedList() habits = LinkedList()
checkmarks = HashMap() checkmarks = HashMap()
scores = HashMap() scores = HashMap()
notesIndicators = HashMap()
} }
} }
@ -271,6 +288,7 @@ class HabitCardListCache @Inject constructor(
newData.fetchHabits() newData.fetchHabits()
newData.copyScoresFrom(data) newData.copyScoresFrom(data)
newData.copyCheckmarksFrom(data) newData.copyCheckmarksFrom(data)
newData.copyNoteIndicatorsFrom(data)
val today = getTodayWithOffset() val today = getTodayWithOffset()
val dateFrom = today.minus(checkmarkCount - 1) val dateFrom = today.minus(checkmarkCount - 1)
if (runner != null) runner!!.publishProgress(this, -1) if (runner != null) runner!!.publishProgress(this, -1)
@ -280,10 +298,14 @@ class HabitCardListCache @Inject constructor(
if (targetId != null && targetId != habit.id) continue if (targetId != null && targetId != habit.id) continue
newData.scores[habit.id] = habit.scores[today].value newData.scores[habit.id] = habit.scores[today].value
val list: MutableList<Int> = ArrayList() val list: MutableList<Int> = ArrayList()
for ((_, value) in habit.computedEntries.getByInterval(dateFrom, today)) val notesList: MutableList<Boolean> = ArrayList()
for ((_, value, note) in habit.computedEntries.getByInterval(dateFrom, today)) {
list.add(value) list.add(value)
if (note.isNotEmpty()) notesList.add(true) else notesList.add(false)
}
val entries = list.toTypedArray() val entries = list.toTypedArray()
newData.checkmarks[habit.id] = ArrayUtils.toPrimitive(entries) newData.checkmarks[habit.id] = ArrayUtils.toPrimitive(entries)
newData.notesIndicators[habit.id] = notesList.toBooleanArray()
runner!!.publishProgress(this, position) runner!!.publishProgress(this, position)
} }
} }
@ -311,6 +333,7 @@ class HabitCardListCache @Inject constructor(
data.idToHabit[id] = habit data.idToHabit[id] = habit
data.scores[id] = newData.scores[id]!! data.scores[id] = newData.scores[id]!!
data.checkmarks[id] = newData.checkmarks[id]!! data.checkmarks[id] = newData.checkmarks[id]!!
data.notesIndicators[id] = newData.notesIndicators[id]!!
listener.onItemInserted(position) listener.onItemInserted(position)
} }
@ -338,14 +361,18 @@ class HabitCardListCache @Inject constructor(
private fun performUpdate(id: Long, position: Int) { private fun performUpdate(id: Long, position: Int) {
val oldScore = data.scores[id]!! val oldScore = data.scores[id]!!
val oldCheckmarks = data.checkmarks[id] val oldCheckmarks = data.checkmarks[id]
val oldNoteIndicators = data.notesIndicators[id]
val newScore = newData.scores[id]!! val newScore = newData.scores[id]!!
val newCheckmarks = newData.checkmarks[id]!! val newCheckmarks = newData.checkmarks[id]!!
val newNoteIndicators = newData.notesIndicators[id]!!
var unchanged = true var unchanged = true
if (oldScore != newScore) unchanged = false if (oldScore != newScore) unchanged = false
if (!Arrays.equals(oldCheckmarks, newCheckmarks)) unchanged = false if (!Arrays.equals(oldCheckmarks, newCheckmarks)) unchanged = false
if (!Arrays.equals(oldNoteIndicators, newNoteIndicators)) unchanged = false
if (unchanged) return if (unchanged) return
data.scores[id] = newScore data.scores[id] = newScore
data.checkmarks[id] = newCheckmarks data.checkmarks[id] = newCheckmarks
data.notesIndicators[id] = newNoteIndicators
listener.onItemChanged(position) listener.onItemChanged(position)
} }

@ -47,14 +47,16 @@ open class ListHabitsBehavior @Inject constructor(
} }
fun onEdit(habit: Habit, timestamp: Timestamp?) { fun onEdit(habit: Habit, timestamp: Timestamp?) {
val entries = habit.computedEntries val entries = habit.computedEntries.get(timestamp!!)
val oldValue = entries.get(timestamp!!).value.toDouble() val oldValue = entries.value.toDouble()
val notes = entries.notes
screen.showNumberPicker( screen.showNumberPicker(
oldValue / 1000, oldValue / 1000,
habit.unit habit.unit,
) { newValue: Double -> notes
) { newValue: Double, newNotes:String, ->
val value = (newValue * 1000).roundToInt() val value = (newValue * 1000).roundToInt()
commandRunner.run(CreateRepetitionCommand(habitList, habit, timestamp, value)) commandRunner.run(CreateRepetitionCommand(habitList, habit, timestamp, value, newNotes))
} }
} }
@ -104,9 +106,9 @@ open class ListHabitsBehavior @Inject constructor(
if (prefs.isFirstRun) onFirstRun() if (prefs.isFirstRun) onFirstRun()
} }
fun onToggle(habit: Habit, timestamp: Timestamp?, value: Int) { fun onToggle(habit: Habit, timestamp: Timestamp?, value: Int, notes: String) {
commandRunner.run( commandRunner.run(
CreateRepetitionCommand(habitList, habit, timestamp!!, value) CreateRepetitionCommand(habitList, habit, timestamp!!, value, notes)
) )
} }
@ -131,7 +133,7 @@ open class ListHabitsBehavior @Inject constructor(
} }
fun interface NumberPickerCallback { fun interface NumberPickerCallback {
fun onNumberPicked(newValue: Double) fun onNumberPicked(newValue: Double, notes: String)
fun onNumberPickerDismissed() {} fun onNumberPickerDismissed() {}
} }
@ -142,6 +144,7 @@ open class ListHabitsBehavior @Inject constructor(
fun showNumberPicker( fun showNumberPicker(
value: Double, value: Double,
unit: String, unit: String,
notes: String,
callback: NumberPickerCallback callback: NumberPickerCallback
) )

@ -64,7 +64,8 @@ class HistoryCardPresenter(
if (habit.isNumerical) { if (habit.isNumerical) {
val entries = habit.computedEntries val entries = habit.computedEntries
val oldValue = entries.get(timestamp).value val oldValue = entries.get(timestamp).value
screen.showNumberPicker(oldValue / 1000.0, habit.unit) { newValue: Double -> val notes = entries.get(timestamp).notes
screen.showNumberPicker(oldValue / 1000.0, habit.unit, notes) { newValue: Double, newNotes: String ->
val thousands = (newValue * 1000).roundToInt() val thousands = (newValue * 1000).roundToInt()
commandRunner.run( commandRunner.run(
CreateRepetitionCommand( CreateRepetitionCommand(
@ -72,11 +73,14 @@ class HistoryCardPresenter(
habit, habit,
timestamp, timestamp,
thousands, thousands,
newNotes,
), ),
) )
} }
} else { } else {
val currentValue = habit.computedEntries.get(timestamp).value val entry = habit.computedEntries.get(timestamp)
val currentValue = entry.value
val notes = entry.notes
val nextValue = Entry.nextToggleValue( val nextValue = Entry.nextToggleValue(
value = currentValue, value = currentValue,
isSkipEnabled = preferences.isSkipEnabled, isSkipEnabled = preferences.isSkipEnabled,
@ -88,6 +92,7 @@ class HistoryCardPresenter(
habit, habit,
timestamp, timestamp,
nextValue, nextValue,
notes,
), ),
) )
} }
@ -154,6 +159,7 @@ class HistoryCardPresenter(
fun showNumberPicker( fun showNumberPicker(
value: Double, value: Double,
unit: String, unit: String,
notes: String,
callback: ListHabitsBehavior.NumberPickerCallback, callback: ListHabitsBehavior.NumberPickerCallback,
) )
} }

@ -46,31 +46,37 @@ class WidgetBehavior @Inject constructor(
} }
fun onToggleRepetition(habit: Habit, timestamp: Timestamp) { fun onToggleRepetition(habit: Habit, timestamp: Timestamp) {
val currentValue = habit.originalEntries.get(timestamp).value val entry = habit.computedEntries.get(timestamp)
val currentValue = entry.value
val notes = entry.notes
val newValue = nextToggleValue( val newValue = nextToggleValue(
value = currentValue, value = currentValue,
isSkipEnabled = preferences.isSkipEnabled, isSkipEnabled = preferences.isSkipEnabled,
areQuestionMarksEnabled = preferences.areQuestionMarksEnabled areQuestionMarksEnabled = preferences.areQuestionMarksEnabled
) )
setValue(habit, timestamp, newValue) setValue(habit, timestamp, newValue, notes)
notificationTray.cancel(habit) notificationTray.cancel(habit)
} }
fun onIncrement(habit: Habit, timestamp: Timestamp, amount: Int) { fun onIncrement(habit: Habit, timestamp: Timestamp, amount: Int) {
val currentValue = habit.computedEntries.get(timestamp).value val entry = habit.computedEntries.get(timestamp)
setValue(habit, timestamp, currentValue + amount) val currentValue = entry.value
val notes = entry.notes
setValue(habit, timestamp, currentValue + amount, notes)
notificationTray.cancel(habit) notificationTray.cancel(habit)
} }
fun onDecrement(habit: Habit, timestamp: Timestamp, amount: Int) { fun onDecrement(habit: Habit, timestamp: Timestamp, amount: Int) {
val currentValue = habit.computedEntries.get(timestamp).value val entry = habit.computedEntries.get(timestamp)
setValue(habit, timestamp, currentValue - amount) val currentValue = entry.value
val notes = entry.notes
setValue(habit, timestamp, currentValue - amount, notes)
notificationTray.cancel(habit) notificationTray.cancel(habit)
} }
fun setValue(habit: Habit, timestamp: Timestamp?, newValue: Int) { fun setValue(habit: Habit, timestamp: Timestamp?, newValue: Int, notes: String = "") {
commandRunner.run( commandRunner.run(
CreateRepetitionCommand(habitList, habit, timestamp!!, newValue) CreateRepetitionCommand(habitList, habit, timestamp!!, newValue, notes)
) )
} }
} }

@ -0,0 +1 @@
alter table Repetitions add column notes text;

@ -38,7 +38,7 @@ class CreateRepetitionCommandTest : BaseUnitTest() {
habit = fixtures.createShortHabit() habit = fixtures.createShortHabit()
habitList.add(habit) habitList.add(habit)
today = getToday() today = getToday()
command = CreateRepetitionCommand(habitList, habit, today, 100) command = CreateRepetitionCommand(habitList, habit, today, 100, "")
} }
@Test @Test

@ -79,8 +79,8 @@ class ListHabitsBehaviorTest : BaseUnitTest() {
@Test @Test
fun testOnEdit() { fun testOnEdit() {
behavior.onEdit(habit2, getToday()) behavior.onEdit(habit2, getToday())
verify(screen).showNumberPicker(eq(0.1), eq("miles"), picker.capture()) verify(screen).showNumberPicker(eq(0.1), eq("miles"), "", picker.capture())
picker.lastValue.onNumberPicked(100.0) picker.lastValue.onNumberPicked(100.0, "")
val today = getTodayWithOffset() val today = getTodayWithOffset()
assertThat(habit2.computedEntries.get(today).value, equalTo(100000)) assertThat(habit2.computedEntries.get(today).value, equalTo(100000))
} }
@ -160,7 +160,7 @@ class ListHabitsBehaviorTest : BaseUnitTest() {
@Test @Test
fun testOnToggle() { fun testOnToggle() {
assertTrue(habit1.isCompletedToday()) assertTrue(habit1.isCompletedToday())
behavior.onToggle(habit1, getToday(), Entry.NO) behavior.onToggle(habit1, getToday(), Entry.NO, "")
assertFalse(habit1.isCompletedToday()) assertFalse(habit1.isCompletedToday())
} }
} }

Loading…
Cancel
Save