mirror of https://github.com/iSoron/uhabits.git
parent
1cdbc53dc5
commit
13826f4934
@ -1,114 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2016 Álinson Santos Xavier <isoron@gmail.com>
|
|
||||||
*
|
|
||||||
* This file is part of Loop Habit Tracker.
|
|
||||||
*
|
|
||||||
* Loop Habit Tracker is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by the
|
|
||||||
* Free Software Foundation, either version 3 of the License, or (at your
|
|
||||||
* option) any later version.
|
|
||||||
*
|
|
||||||
* Loop Habit Tracker is distributed in the hope that it will be useful, but
|
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
||||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
|
||||||
* more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License along
|
|
||||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
package org.isoron.uhabits.activities.habits.show.views
|
|
||||||
|
|
||||||
import android.content.Context
|
|
||||||
import android.util.AttributeSet
|
|
||||||
import android.view.LayoutInflater
|
|
||||||
import android.view.View
|
|
||||||
import android.widget.AdapterView
|
|
||||||
import android.widget.LinearLayout
|
|
||||||
import org.isoron.uhabits.core.models.Habit
|
|
||||||
import org.isoron.uhabits.core.models.PaletteColor
|
|
||||||
import org.isoron.uhabits.core.models.Score
|
|
||||||
import org.isoron.uhabits.core.utils.DateUtils
|
|
||||||
import org.isoron.uhabits.core.utils.DateUtils.TruncateField.DAY
|
|
||||||
import org.isoron.uhabits.core.utils.DateUtils.TruncateField.MONTH
|
|
||||||
import org.isoron.uhabits.core.utils.DateUtils.TruncateField.QUARTER
|
|
||||||
import org.isoron.uhabits.core.utils.DateUtils.TruncateField.WEEK_NUMBER
|
|
||||||
import org.isoron.uhabits.core.utils.DateUtils.TruncateField.YEAR
|
|
||||||
import org.isoron.uhabits.databinding.ShowHabitScoreBinding
|
|
||||||
import org.isoron.uhabits.utils.toThemedAndroidColor
|
|
||||||
|
|
||||||
data class ScoreCardViewModel(
|
|
||||||
val scores: List<Score>,
|
|
||||||
val bucketSize: Int,
|
|
||||||
val spinnerPosition: Int,
|
|
||||||
val color: PaletteColor,
|
|
||||||
)
|
|
||||||
|
|
||||||
class ScoreCard(context: Context, attrs: AttributeSet) : LinearLayout(context, attrs) {
|
|
||||||
private var binding = ShowHabitScoreBinding.inflate(LayoutInflater.from(context), this)
|
|
||||||
|
|
||||||
var onSpinnerPosition: (position: Int) -> Unit = {}
|
|
||||||
|
|
||||||
fun update(data: ScoreCardViewModel) {
|
|
||||||
val androidColor = data.color.toThemedAndroidColor(context)
|
|
||||||
binding.title.setTextColor(androidColor)
|
|
||||||
binding.spinner.setSelection(data.spinnerPosition)
|
|
||||||
binding.scoreView.setScores(data.scores)
|
|
||||||
binding.scoreView.reset()
|
|
||||||
binding.scoreView.setBucketSize(data.bucketSize)
|
|
||||||
binding.scoreView.setColor(androidColor)
|
|
||||||
|
|
||||||
binding.spinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
|
|
||||||
override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
|
|
||||||
onSpinnerPosition(position)
|
|
||||||
}
|
|
||||||
override fun onNothingSelected(parent: AdapterView<*>?) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class ScoreCardPresenter(
|
|
||||||
val habit: Habit,
|
|
||||||
val firstWeekday: Int,
|
|
||||||
) {
|
|
||||||
companion object {
|
|
||||||
val BUCKET_SIZES = intArrayOf(1, 7, 31, 92, 365)
|
|
||||||
fun getTruncateField(bucketSize: Int): DateUtils.TruncateField {
|
|
||||||
when (bucketSize) {
|
|
||||||
1 -> return DAY
|
|
||||||
7 -> return WEEK_NUMBER
|
|
||||||
31 -> return MONTH
|
|
||||||
92 -> return QUARTER
|
|
||||||
365 -> return YEAR
|
|
||||||
else -> return MONTH
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun present(spinnerPosition: Int): ScoreCardViewModel {
|
|
||||||
val bucketSize = BUCKET_SIZES[spinnerPosition]
|
|
||||||
val today = DateUtils.getTodayWithOffset()
|
|
||||||
val oldest = habit.computedEntries.getKnown().lastOrNull()?.timestamp ?: today
|
|
||||||
|
|
||||||
val field = getTruncateField(bucketSize)
|
|
||||||
val scores = habit.scores.getByInterval(oldest, today).groupBy {
|
|
||||||
DateUtils.truncate(field, it.timestamp, firstWeekday)
|
|
||||||
}.map { (timestamp, scores) ->
|
|
||||||
Score(
|
|
||||||
timestamp,
|
|
||||||
scores.map {
|
|
||||||
it.value
|
|
||||||
}.average()
|
|
||||||
)
|
|
||||||
}.sortedBy {
|
|
||||||
it.timestamp
|
|
||||||
}.reversed()
|
|
||||||
|
|
||||||
return ScoreCardViewModel(
|
|
||||||
color = habit.color,
|
|
||||||
scores = scores,
|
|
||||||
bucketSize = bucketSize,
|
|
||||||
spinnerPosition = spinnerPosition,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,59 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2016 Álinson Santos Xavier <isoron@gmail.com>
|
||||||
|
*
|
||||||
|
* This file is part of Loop Habit Tracker.
|
||||||
|
*
|
||||||
|
* Loop Habit Tracker is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by the
|
||||||
|
* Free Software Foundation, either version 3 of the License, or (at your
|
||||||
|
* option) any later version.
|
||||||
|
*
|
||||||
|
* Loop Habit Tracker is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
* more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package org.isoron.uhabits.activities.habits.show.views
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.util.AttributeSet
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.widget.AdapterView
|
||||||
|
import android.widget.LinearLayout
|
||||||
|
import org.isoron.uhabits.core.ui.screens.habits.show.views.ScoreCardViewModel
|
||||||
|
import org.isoron.uhabits.databinding.ShowHabitScoreBinding
|
||||||
|
import org.isoron.uhabits.utils.toThemedAndroidColor
|
||||||
|
|
||||||
|
class ScoreCardView(context: Context, attrs: AttributeSet) : LinearLayout(context, attrs) {
|
||||||
|
private var binding = ShowHabitScoreBinding.inflate(LayoutInflater.from(context), this)
|
||||||
|
|
||||||
|
var onSpinnerPosition: (position: Int) -> Unit = {}
|
||||||
|
|
||||||
|
fun update(data: ScoreCardViewModel) {
|
||||||
|
val androidColor = data.color.toThemedAndroidColor(context)
|
||||||
|
binding.title.setTextColor(androidColor)
|
||||||
|
binding.spinner.setSelection(data.spinnerPosition)
|
||||||
|
binding.scoreView.setScores(data.scores)
|
||||||
|
binding.scoreView.reset()
|
||||||
|
binding.scoreView.setBucketSize(data.bucketSize)
|
||||||
|
binding.scoreView.setColor(androidColor)
|
||||||
|
|
||||||
|
binding.spinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
|
||||||
|
override fun onItemSelected(
|
||||||
|
parent: AdapterView<*>?,
|
||||||
|
view: View?,
|
||||||
|
position: Int,
|
||||||
|
id: Long
|
||||||
|
) {
|
||||||
|
onSpinnerPosition(position)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onNothingSelected(parent: AdapterView<*>?) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,52 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2016 Álinson Santos Xavier <isoron@gmail.com>
|
||||||
|
*
|
||||||
|
* This file is part of Loop Habit Tracker.
|
||||||
|
*
|
||||||
|
* Loop Habit Tracker is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by the
|
||||||
|
* Free Software Foundation, either version 3 of the License, or (at your
|
||||||
|
* option) any later version.
|
||||||
|
*
|
||||||
|
* Loop Habit Tracker is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
* more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package org.isoron.uhabits.activities.habits.show.views
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.res.Resources
|
||||||
|
import android.util.AttributeSet
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.widget.LinearLayout
|
||||||
|
import org.isoron.uhabits.R
|
||||||
|
import org.isoron.uhabits.core.ui.screens.habits.show.views.TargetCardViewModel
|
||||||
|
import org.isoron.uhabits.databinding.ShowHabitTargetBinding
|
||||||
|
import org.isoron.uhabits.utils.toThemedAndroidColor
|
||||||
|
|
||||||
|
class TargetCardView(context: Context, attrs: AttributeSet) : LinearLayout(context, attrs) {
|
||||||
|
private val binding = ShowHabitTargetBinding.inflate(LayoutInflater.from(context), this)
|
||||||
|
fun update(data: TargetCardViewModel) {
|
||||||
|
val androidColor = data.color.toThemedAndroidColor(context)
|
||||||
|
binding.targetChart.setValues(data.values)
|
||||||
|
binding.targetChart.setTargets(data.targets)
|
||||||
|
binding.targetChart.setLabels(data.intervals.map { intervalToLabel(resources, it) })
|
||||||
|
binding.title.setTextColor(androidColor)
|
||||||
|
binding.targetChart.setColor(androidColor)
|
||||||
|
postInvalidate()
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun intervalToLabel(resources: Resources, interval: Int) = when (interval) {
|
||||||
|
1 -> resources.getString(R.string.today)
|
||||||
|
7 -> resources.getString(R.string.week)
|
||||||
|
30 -> resources.getString(R.string.month)
|
||||||
|
91 -> resources.getString(R.string.quarter)
|
||||||
|
else -> resources.getString(R.string.year)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,106 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2016-2020 Álinson Santos Xavier <isoron@gmail.com>
|
||||||
|
*
|
||||||
|
* This file is part of Loop Habit Tracker.
|
||||||
|
*
|
||||||
|
* Loop Habit Tracker is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by the
|
||||||
|
* Free Software Foundation, either version 3 of the License, or (at your
|
||||||
|
* option) any later version.
|
||||||
|
*
|
||||||
|
* Loop Habit Tracker is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
* more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.isoron.uhabits.core.ui.screens.habits.show
|
||||||
|
|
||||||
|
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.screens.habits.show.views.BarCardPresenter
|
||||||
|
import org.isoron.uhabits.core.ui.screens.habits.show.views.BarCardViewModel
|
||||||
|
import org.isoron.uhabits.core.ui.screens.habits.show.views.FrequencyCardPresenter
|
||||||
|
import org.isoron.uhabits.core.ui.screens.habits.show.views.FrequencyCardViewModel
|
||||||
|
import org.isoron.uhabits.core.ui.screens.habits.show.views.HistoryCardPresenter
|
||||||
|
import org.isoron.uhabits.core.ui.screens.habits.show.views.HistoryCardViewModel
|
||||||
|
import org.isoron.uhabits.core.ui.screens.habits.show.views.NotesCardPresenter
|
||||||
|
import org.isoron.uhabits.core.ui.screens.habits.show.views.NotesCardViewModel
|
||||||
|
import org.isoron.uhabits.core.ui.screens.habits.show.views.OverviewCardPresenter
|
||||||
|
import org.isoron.uhabits.core.ui.screens.habits.show.views.OverviewCardViewModel
|
||||||
|
import org.isoron.uhabits.core.ui.screens.habits.show.views.ScoreCardPresenter
|
||||||
|
import org.isoron.uhabits.core.ui.screens.habits.show.views.ScoreCardViewModel
|
||||||
|
import org.isoron.uhabits.core.ui.screens.habits.show.views.StreakCardViewModel
|
||||||
|
import org.isoron.uhabits.core.ui.screens.habits.show.views.StreakCartPresenter
|
||||||
|
import org.isoron.uhabits.core.ui.screens.habits.show.views.SubtitleCardPresenter
|
||||||
|
import org.isoron.uhabits.core.ui.screens.habits.show.views.SubtitleCardViewModel
|
||||||
|
import org.isoron.uhabits.core.ui.screens.habits.show.views.TargetCardPresenter
|
||||||
|
import org.isoron.uhabits.core.ui.screens.habits.show.views.TargetCardViewModel
|
||||||
|
|
||||||
|
data class ShowHabitViewModel(
|
||||||
|
val title: String = "",
|
||||||
|
val isNumerical: Boolean = false,
|
||||||
|
val color: PaletteColor = PaletteColor(1),
|
||||||
|
val subtitle: SubtitleCardViewModel,
|
||||||
|
val overview: OverviewCardViewModel,
|
||||||
|
val notes: NotesCardViewModel,
|
||||||
|
val target: TargetCardViewModel,
|
||||||
|
val streaks: StreakCardViewModel,
|
||||||
|
val scores: ScoreCardViewModel,
|
||||||
|
val frequency: FrequencyCardViewModel,
|
||||||
|
val history: HistoryCardViewModel,
|
||||||
|
val bar: BarCardViewModel,
|
||||||
|
)
|
||||||
|
|
||||||
|
class ShowHabitPresenter {
|
||||||
|
fun present(
|
||||||
|
habit: Habit,
|
||||||
|
preferences: Preferences,
|
||||||
|
): ShowHabitViewModel {
|
||||||
|
return ShowHabitViewModel(
|
||||||
|
title = habit.name,
|
||||||
|
color = habit.color,
|
||||||
|
isNumerical = habit.isNumerical,
|
||||||
|
subtitle = SubtitleCardPresenter().present(
|
||||||
|
habit = habit,
|
||||||
|
),
|
||||||
|
overview = OverviewCardPresenter().present(
|
||||||
|
habit = habit,
|
||||||
|
),
|
||||||
|
notes = NotesCardPresenter().present(
|
||||||
|
habit = habit,
|
||||||
|
),
|
||||||
|
target = TargetCardPresenter().present(
|
||||||
|
habit = habit,
|
||||||
|
firstWeekday = preferences.firstWeekday,
|
||||||
|
),
|
||||||
|
streaks = StreakCartPresenter().present(
|
||||||
|
habit = habit,
|
||||||
|
),
|
||||||
|
scores = ScoreCardPresenter().present(
|
||||||
|
spinnerPosition = preferences.scoreCardSpinnerPosition,
|
||||||
|
habit = habit,
|
||||||
|
firstWeekday = preferences.firstWeekday,
|
||||||
|
),
|
||||||
|
frequency = FrequencyCardPresenter().present(
|
||||||
|
habit = habit,
|
||||||
|
firstWeekday = preferences.firstWeekday,
|
||||||
|
),
|
||||||
|
history = HistoryCardPresenter().present(
|
||||||
|
habit = habit,
|
||||||
|
firstWeekday = preferences.firstWeekday,
|
||||||
|
isSkipEnabled = preferences.isSkipEnabled,
|
||||||
|
),
|
||||||
|
bar = BarCardPresenter().present(
|
||||||
|
habit = habit,
|
||||||
|
firstWeekday = preferences.firstWeekday,
|
||||||
|
boolSpinnerPosition = preferences.barCardBoolSpinnerPosition,
|
||||||
|
numericalSpinnerPosition = preferences.barCardNumericalSpinnerPosition,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,68 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2016-2020 Álinson Santos Xavier <isoron@gmail.com>
|
||||||
|
*
|
||||||
|
* This file is part of Loop Habit Tracker.
|
||||||
|
*
|
||||||
|
* Loop Habit Tracker is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by the
|
||||||
|
* Free Software Foundation, either version 3 of the License, or (at your
|
||||||
|
* option) any later version.
|
||||||
|
*
|
||||||
|
* Loop Habit Tracker is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
* more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.isoron.uhabits.core.ui.screens.habits.show.views
|
||||||
|
|
||||||
|
import org.isoron.uhabits.core.models.Entry
|
||||||
|
import org.isoron.uhabits.core.models.Habit
|
||||||
|
import org.isoron.uhabits.core.models.PaletteColor
|
||||||
|
import org.isoron.uhabits.core.models.groupedSum
|
||||||
|
import org.isoron.uhabits.core.utils.DateUtils
|
||||||
|
|
||||||
|
data class BarCardViewModel(
|
||||||
|
val boolSpinnerPosition: Int,
|
||||||
|
val bucketSize: Int,
|
||||||
|
val color: PaletteColor,
|
||||||
|
val entries: List<Entry>,
|
||||||
|
val isNumerical: Boolean,
|
||||||
|
val numericalSpinnerPosition: Int,
|
||||||
|
)
|
||||||
|
|
||||||
|
class BarCardPresenter {
|
||||||
|
val numericalBucketSizes = intArrayOf(1, 7, 31, 92, 365)
|
||||||
|
val boolBucketSizes = intArrayOf(7, 31, 92, 365)
|
||||||
|
|
||||||
|
fun present(
|
||||||
|
habit: Habit,
|
||||||
|
firstWeekday: Int,
|
||||||
|
numericalSpinnerPosition: Int,
|
||||||
|
boolSpinnerPosition: Int,
|
||||||
|
): BarCardViewModel {
|
||||||
|
val bucketSize = if (habit.isNumerical) {
|
||||||
|
numericalBucketSizes[numericalSpinnerPosition]
|
||||||
|
} else {
|
||||||
|
boolBucketSizes[boolSpinnerPosition]
|
||||||
|
}
|
||||||
|
val today = DateUtils.getToday()
|
||||||
|
val oldest = habit.computedEntries.getKnown().lastOrNull()?.timestamp ?: today
|
||||||
|
val entries = habit.computedEntries.getByInterval(oldest, today).groupedSum(
|
||||||
|
truncateField = ScoreCardPresenter.getTruncateField(bucketSize),
|
||||||
|
firstWeekday = firstWeekday,
|
||||||
|
isNumerical = habit.isNumerical,
|
||||||
|
)
|
||||||
|
return BarCardViewModel(
|
||||||
|
entries = entries,
|
||||||
|
bucketSize = bucketSize,
|
||||||
|
color = habit.color,
|
||||||
|
isNumerical = habit.isNumerical,
|
||||||
|
numericalSpinnerPosition = numericalSpinnerPosition,
|
||||||
|
boolSpinnerPosition = boolSpinnerPosition,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,44 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2016-2020 Álinson Santos Xavier <isoron@gmail.com>
|
||||||
|
*
|
||||||
|
* This file is part of Loop Habit Tracker.
|
||||||
|
*
|
||||||
|
* Loop Habit Tracker is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by the
|
||||||
|
* Free Software Foundation, either version 3 of the License, or (at your
|
||||||
|
* option) any later version.
|
||||||
|
*
|
||||||
|
* Loop Habit Tracker is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
* more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.isoron.uhabits.core.ui.screens.habits.show.views
|
||||||
|
|
||||||
|
import org.isoron.uhabits.core.models.Habit
|
||||||
|
import org.isoron.uhabits.core.models.PaletteColor
|
||||||
|
import org.isoron.uhabits.core.models.Timestamp
|
||||||
|
import java.util.HashMap
|
||||||
|
|
||||||
|
data class FrequencyCardViewModel(
|
||||||
|
val color: PaletteColor,
|
||||||
|
val firstWeekday: Int,
|
||||||
|
val frequency: HashMap<Timestamp, Array<Int>>,
|
||||||
|
)
|
||||||
|
|
||||||
|
class FrequencyCardPresenter {
|
||||||
|
fun present(
|
||||||
|
habit: Habit,
|
||||||
|
firstWeekday: Int,
|
||||||
|
) = FrequencyCardViewModel(
|
||||||
|
color = habit.color,
|
||||||
|
frequency = habit.originalEntries.computeWeekdayFrequency(
|
||||||
|
isNumerical = habit.isNumerical
|
||||||
|
),
|
||||||
|
firstWeekday = firstWeekday,
|
||||||
|
)
|
||||||
|
}
|
@ -0,0 +1,53 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2016-2020 Álinson Santos Xavier <isoron@gmail.com>
|
||||||
|
*
|
||||||
|
* This file is part of Loop Habit Tracker.
|
||||||
|
*
|
||||||
|
* Loop Habit Tracker is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by the
|
||||||
|
* Free Software Foundation, either version 3 of the License, or (at your
|
||||||
|
* option) any later version.
|
||||||
|
*
|
||||||
|
* Loop Habit Tracker is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
* more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.isoron.uhabits.core.ui.screens.habits.show.views
|
||||||
|
|
||||||
|
import org.isoron.uhabits.core.models.Habit
|
||||||
|
import org.isoron.uhabits.core.models.PaletteColor
|
||||||
|
import org.isoron.uhabits.core.utils.DateUtils
|
||||||
|
|
||||||
|
data class HistoryCardViewModel(
|
||||||
|
val color: PaletteColor,
|
||||||
|
val entries: IntArray,
|
||||||
|
val firstWeekday: Int,
|
||||||
|
val isNumerical: Boolean,
|
||||||
|
val isSkipEnabled: Boolean,
|
||||||
|
)
|
||||||
|
|
||||||
|
class HistoryCardPresenter {
|
||||||
|
fun present(
|
||||||
|
habit: Habit,
|
||||||
|
firstWeekday: Int,
|
||||||
|
isSkipEnabled: Boolean,
|
||||||
|
): HistoryCardViewModel {
|
||||||
|
val today = DateUtils.getTodayWithOffset()
|
||||||
|
val oldest = habit.computedEntries.getKnown().lastOrNull()?.timestamp ?: today
|
||||||
|
val entries =
|
||||||
|
habit.computedEntries.getByInterval(oldest, today).map { it.value }.toIntArray()
|
||||||
|
|
||||||
|
return HistoryCardViewModel(
|
||||||
|
entries = entries,
|
||||||
|
color = habit.color,
|
||||||
|
firstWeekday = firstWeekday,
|
||||||
|
isNumerical = habit.isNumerical,
|
||||||
|
isSkipEnabled = isSkipEnabled,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,32 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2016-2020 Álinson Santos Xavier <isoron@gmail.com>
|
||||||
|
*
|
||||||
|
* This file is part of Loop Habit Tracker.
|
||||||
|
*
|
||||||
|
* Loop Habit Tracker is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by the
|
||||||
|
* Free Software Foundation, either version 3 of the License, or (at your
|
||||||
|
* option) any later version.
|
||||||
|
*
|
||||||
|
* Loop Habit Tracker is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
* more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.isoron.uhabits.core.ui.screens.habits.show.views
|
||||||
|
|
||||||
|
import org.isoron.uhabits.core.models.Habit
|
||||||
|
|
||||||
|
data class NotesCardViewModel(
|
||||||
|
val description: String,
|
||||||
|
)
|
||||||
|
|
||||||
|
class NotesCardPresenter {
|
||||||
|
fun present(habit: Habit) = NotesCardViewModel(
|
||||||
|
description = habit.description,
|
||||||
|
)
|
||||||
|
}
|
@ -0,0 +1,56 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2016-2020 Álinson Santos Xavier <isoron@gmail.com>
|
||||||
|
*
|
||||||
|
* This file is part of Loop Habit Tracker.
|
||||||
|
*
|
||||||
|
* Loop Habit Tracker is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by the
|
||||||
|
* Free Software Foundation, either version 3 of the License, or (at your
|
||||||
|
* option) any later version.
|
||||||
|
*
|
||||||
|
* Loop Habit Tracker is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
* more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.isoron.uhabits.core.ui.screens.habits.show.views
|
||||||
|
|
||||||
|
import org.isoron.uhabits.core.models.Entry
|
||||||
|
import org.isoron.uhabits.core.models.Habit
|
||||||
|
import org.isoron.uhabits.core.models.PaletteColor
|
||||||
|
import org.isoron.uhabits.core.utils.DateUtils
|
||||||
|
|
||||||
|
data class OverviewCardViewModel(
|
||||||
|
val color: PaletteColor,
|
||||||
|
val scoreMonthDiff: Float,
|
||||||
|
val scoreYearDiff: Float,
|
||||||
|
val scoreToday: Float,
|
||||||
|
val totalCount: Long,
|
||||||
|
)
|
||||||
|
|
||||||
|
class OverviewCardPresenter {
|
||||||
|
fun present(habit: Habit): OverviewCardViewModel {
|
||||||
|
val today = DateUtils.getTodayWithOffset()
|
||||||
|
val lastMonth = today.minus(30)
|
||||||
|
val lastYear = today.minus(365)
|
||||||
|
val scores = habit.scores
|
||||||
|
val scoreToday = scores.get(today).value.toFloat()
|
||||||
|
val scoreLastMonth = scores.get(lastMonth).value.toFloat()
|
||||||
|
val scoreLastYear = scores.get(lastYear).value.toFloat()
|
||||||
|
val totalCount = habit.originalEntries.getKnown()
|
||||||
|
.filter { it.value == Entry.YES_MANUAL }
|
||||||
|
.count()
|
||||||
|
.toLong()
|
||||||
|
return OverviewCardViewModel(
|
||||||
|
color = habit.color,
|
||||||
|
scoreToday = scoreToday,
|
||||||
|
scoreMonthDiff = scoreToday - scoreLastMonth,
|
||||||
|
scoreYearDiff = scoreToday - scoreLastYear,
|
||||||
|
totalCount = totalCount,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,79 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2016-2020 Álinson Santos Xavier <isoron@gmail.com>
|
||||||
|
*
|
||||||
|
* This file is part of Loop Habit Tracker.
|
||||||
|
*
|
||||||
|
* Loop Habit Tracker is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by the
|
||||||
|
* Free Software Foundation, either version 3 of the License, or (at your
|
||||||
|
* option) any later version.
|
||||||
|
*
|
||||||
|
* Loop Habit Tracker is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
* more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.isoron.uhabits.core.ui.screens.habits.show.views
|
||||||
|
|
||||||
|
import org.isoron.uhabits.core.models.Habit
|
||||||
|
import org.isoron.uhabits.core.models.PaletteColor
|
||||||
|
import org.isoron.uhabits.core.models.Score
|
||||||
|
import org.isoron.uhabits.core.utils.DateUtils
|
||||||
|
|
||||||
|
data class ScoreCardViewModel(
|
||||||
|
val scores: List<Score>,
|
||||||
|
val bucketSize: Int,
|
||||||
|
val spinnerPosition: Int,
|
||||||
|
val color: PaletteColor,
|
||||||
|
)
|
||||||
|
|
||||||
|
class ScoreCardPresenter {
|
||||||
|
companion object {
|
||||||
|
val BUCKET_SIZES = intArrayOf(1, 7, 31, 92, 365)
|
||||||
|
fun getTruncateField(bucketSize: Int): DateUtils.TruncateField {
|
||||||
|
when (bucketSize) {
|
||||||
|
1 -> return DateUtils.TruncateField.DAY
|
||||||
|
7 -> return DateUtils.TruncateField.WEEK_NUMBER
|
||||||
|
31 -> return DateUtils.TruncateField.MONTH
|
||||||
|
92 -> return DateUtils.TruncateField.QUARTER
|
||||||
|
365 -> return DateUtils.TruncateField.YEAR
|
||||||
|
else -> return DateUtils.TruncateField.MONTH
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun present(
|
||||||
|
habit: Habit,
|
||||||
|
firstWeekday: Int,
|
||||||
|
spinnerPosition: Int,
|
||||||
|
): ScoreCardViewModel {
|
||||||
|
val bucketSize = BUCKET_SIZES[spinnerPosition]
|
||||||
|
val today = DateUtils.getTodayWithOffset()
|
||||||
|
val oldest = habit.computedEntries.getKnown().lastOrNull()?.timestamp ?: today
|
||||||
|
|
||||||
|
val field = getTruncateField(bucketSize)
|
||||||
|
val scores = habit.scores.getByInterval(oldest, today).groupBy {
|
||||||
|
DateUtils.truncate(field, it.timestamp, firstWeekday)
|
||||||
|
}.map { (timestamp, scores) ->
|
||||||
|
Score(
|
||||||
|
timestamp,
|
||||||
|
scores.map {
|
||||||
|
it.value
|
||||||
|
}.average()
|
||||||
|
)
|
||||||
|
}.sortedBy {
|
||||||
|
it.timestamp
|
||||||
|
}.reversed()
|
||||||
|
|
||||||
|
return ScoreCardViewModel(
|
||||||
|
color = habit.color,
|
||||||
|
scores = scores,
|
||||||
|
bucketSize = bucketSize,
|
||||||
|
spinnerPosition = spinnerPosition,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,38 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2016-2020 Álinson Santos Xavier <isoron@gmail.com>
|
||||||
|
*
|
||||||
|
* This file is part of Loop Habit Tracker.
|
||||||
|
*
|
||||||
|
* Loop Habit Tracker is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by the
|
||||||
|
* Free Software Foundation, either version 3 of the License, or (at your
|
||||||
|
* option) any later version.
|
||||||
|
*
|
||||||
|
* Loop Habit Tracker is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
* more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.isoron.uhabits.core.ui.screens.habits.show.views
|
||||||
|
|
||||||
|
import org.isoron.uhabits.core.models.Habit
|
||||||
|
import org.isoron.uhabits.core.models.PaletteColor
|
||||||
|
import org.isoron.uhabits.core.models.Streak
|
||||||
|
|
||||||
|
data class StreakCardViewModel(
|
||||||
|
val color: PaletteColor,
|
||||||
|
val bestStreaks: List<Streak>
|
||||||
|
)
|
||||||
|
|
||||||
|
class StreakCartPresenter {
|
||||||
|
fun present(habit: Habit): StreakCardViewModel {
|
||||||
|
return StreakCardViewModel(
|
||||||
|
color = habit.color,
|
||||||
|
bestStreaks = habit.streaks.getBest(10),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,49 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2016-2020 Álinson Santos Xavier <isoron@gmail.com>
|
||||||
|
*
|
||||||
|
* This file is part of Loop Habit Tracker.
|
||||||
|
*
|
||||||
|
* Loop Habit Tracker is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by the
|
||||||
|
* Free Software Foundation, either version 3 of the License, or (at your
|
||||||
|
* option) any later version.
|
||||||
|
*
|
||||||
|
* Loop Habit Tracker is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
* more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.isoron.uhabits.core.ui.screens.habits.show.views
|
||||||
|
|
||||||
|
import org.isoron.uhabits.core.models.Frequency
|
||||||
|
import org.isoron.uhabits.core.models.Habit
|
||||||
|
import org.isoron.uhabits.core.models.PaletteColor
|
||||||
|
import org.isoron.uhabits.core.models.Reminder
|
||||||
|
|
||||||
|
data class SubtitleCardViewModel(
|
||||||
|
val color: PaletteColor,
|
||||||
|
val frequency: Frequency,
|
||||||
|
val isNumerical: Boolean,
|
||||||
|
val question: String,
|
||||||
|
val reminder: Reminder?,
|
||||||
|
val targetValue: Double,
|
||||||
|
val unit: String,
|
||||||
|
)
|
||||||
|
|
||||||
|
class SubtitleCardPresenter {
|
||||||
|
fun present(
|
||||||
|
habit: Habit,
|
||||||
|
): SubtitleCardViewModel = SubtitleCardViewModel(
|
||||||
|
color = habit.color,
|
||||||
|
frequency = habit.frequency,
|
||||||
|
isNumerical = habit.isNumerical,
|
||||||
|
question = habit.question,
|
||||||
|
reminder = habit.reminder,
|
||||||
|
targetValue = habit.targetValue,
|
||||||
|
unit = habit.unit,
|
||||||
|
)
|
||||||
|
}
|
Loading…
Reference in new issue