mirror of
https://github.com/iSoron/uhabits.git
synced 2025-12-06 01:08:50 -06:00
Create view-model and presenter for TargetCard; reduce boilerplate
This commit is contained in:
@@ -1,68 +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 androidx.test.filters.*;
|
||||
import androidx.test.runner.*;
|
||||
import android.view.*;
|
||||
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
|
||||
import org.isoron.uhabits.*;
|
||||
import org.isoron.uhabits.core.models.*;
|
||||
import org.junit.*;
|
||||
import org.junit.runner.*;
|
||||
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
@MediumTest
|
||||
public class SubtitleCardTest extends BaseViewTest
|
||||
{
|
||||
public static final String PATH = "habits/show/SubtitleCard/";
|
||||
|
||||
private SubtitleCard view;
|
||||
|
||||
private Habit habit;
|
||||
|
||||
@Before
|
||||
@Override
|
||||
public void setUp()
|
||||
{
|
||||
super.setUp();
|
||||
|
||||
habit = fixtures.createLongHabit();
|
||||
habit.setReminder(new Reminder(8, 30, WeekdayList.EVERY_DAY));
|
||||
|
||||
view = LayoutInflater
|
||||
.from(targetContext)
|
||||
.inflate(R.layout.show_habit, null)
|
||||
.findViewById(R.id.subtitleCard);
|
||||
|
||||
view.setHabit(habit);
|
||||
view.refreshData();
|
||||
|
||||
measureView(view, 800, 200);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRender() throws Exception
|
||||
{
|
||||
assertRenders(view, PATH + "render.png");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* 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.view.*
|
||||
import androidx.test.ext.junit.runners.*
|
||||
import androidx.test.filters.*
|
||||
import org.isoron.uhabits.*
|
||||
import org.isoron.uhabits.activities.habits.show.*
|
||||
import org.junit.*
|
||||
import org.junit.runner.*
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
@MediumTest
|
||||
class SubtitleCardTest : BaseViewTest() {
|
||||
val PATH = "habits/show/SubtitleCard/"
|
||||
private lateinit var view: SubtitleCard
|
||||
|
||||
@Before
|
||||
override fun setUp() {
|
||||
super.setUp()
|
||||
view = LayoutInflater
|
||||
.from(targetContext)
|
||||
.inflate(R.layout.show_habit, null)
|
||||
.findViewById(R.id.subtitleCard)
|
||||
view.onData(ShowHabitViewModel(
|
||||
question = "Did you meditate this morning?",
|
||||
reminderText = "8:30 AM",
|
||||
frequencyText = "3 times in 7 days",
|
||||
))
|
||||
measureView(view, 800f, 200f)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testRender() {
|
||||
assertRenders(view, PATH + "render.png")
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* 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.activities
|
||||
|
||||
import android.content.*
|
||||
import android.util.*
|
||||
import android.widget.*
|
||||
|
||||
abstract class DataView<T>(
|
||||
context: Context,
|
||||
attrs: AttributeSet,
|
||||
) : LinearLayout(context, attrs), Presenter.Listener<T> {
|
||||
|
||||
lateinit var presenter: Presenter<T>
|
||||
|
||||
override fun onAttachedToWindow() {
|
||||
super.onAttachedToWindow()
|
||||
presenter.addListener(this)
|
||||
presenter.requestData(this)
|
||||
}
|
||||
|
||||
override fun onDetachedFromWindow() {
|
||||
presenter.removeListener(this)
|
||||
super.onDetachedFromWindow()
|
||||
}
|
||||
|
||||
abstract override fun onData(data: T)
|
||||
}
|
||||
@@ -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.activities
|
||||
|
||||
import org.isoron.uhabits.core.commands.*
|
||||
|
||||
abstract class Presenter<M>(
|
||||
val commandRunner: CommandRunner,
|
||||
) : CommandRunner.Listener {
|
||||
|
||||
private val listeners = mutableListOf<Listener<M>>()
|
||||
private var data: M? = null
|
||||
|
||||
fun onResume() {
|
||||
commandRunner.addListener(this)
|
||||
data = refresh()
|
||||
notifyListeners()
|
||||
}
|
||||
|
||||
abstract fun refresh(): M
|
||||
|
||||
fun onPause() {
|
||||
commandRunner.removeListener(this)
|
||||
}
|
||||
|
||||
fun addListener(listener: Listener<M>) {
|
||||
listeners.add(listener)
|
||||
}
|
||||
|
||||
fun removeListener(listener: Listener<M>) {
|
||||
listeners.remove(listener)
|
||||
}
|
||||
|
||||
fun requestData(listener: Listener<M>) {
|
||||
if (data == null) data = refresh()
|
||||
listener.onData(data!!)
|
||||
}
|
||||
|
||||
override fun onCommandExecuted(command: Command?, refreshKey: Long?) {
|
||||
data = refresh()
|
||||
notifyListeners()
|
||||
}
|
||||
|
||||
private fun notifyListeners() {
|
||||
for (l in listeners) l.onData(data!!)
|
||||
}
|
||||
|
||||
interface Listener<T> {
|
||||
fun onData(data: T)
|
||||
}
|
||||
}
|
||||
@@ -23,6 +23,7 @@ import android.annotation.*
|
||||
import android.content.*
|
||||
import org.isoron.androidbase.activities.*
|
||||
import org.isoron.uhabits.*
|
||||
import org.isoron.uhabits.activities.*
|
||||
import org.isoron.uhabits.activities.habits.list.views.*
|
||||
import org.isoron.uhabits.core.commands.*
|
||||
import org.isoron.uhabits.core.models.*
|
||||
@@ -36,47 +37,14 @@ import javax.inject.*
|
||||
class ShowHabitPresenter
|
||||
@Inject constructor(
|
||||
val habit: Habit,
|
||||
val commandRunner: CommandRunner,
|
||||
val preferences: Preferences,
|
||||
commandRunner: CommandRunner,
|
||||
@ActivityContext val context: Context,
|
||||
) : CommandRunner.Listener {
|
||||
) : Presenter<ShowHabitViewModel>(commandRunner) {
|
||||
|
||||
private val listeners = mutableListOf<Listener>()
|
||||
private var data = ShowHabitViewModel()
|
||||
private val resources = context.resources
|
||||
|
||||
fun onResume() {
|
||||
commandRunner.addListener(this)
|
||||
refresh()
|
||||
notifyListeners()
|
||||
}
|
||||
|
||||
fun onPause() {
|
||||
commandRunner.removeListener(this)
|
||||
}
|
||||
|
||||
fun addListener(listener: Listener) {
|
||||
listeners.add(listener)
|
||||
}
|
||||
|
||||
fun removeListener(listener: Listener) {
|
||||
listeners.remove(listener)
|
||||
}
|
||||
|
||||
fun requestData(listener: Listener) {
|
||||
listener.onData(data)
|
||||
}
|
||||
|
||||
override fun onCommandExecuted(command: Command?, refreshKey: Long?) {
|
||||
refresh()
|
||||
notifyListeners()
|
||||
}
|
||||
|
||||
private fun notifyListeners() {
|
||||
for (l in listeners) l.onData(data)
|
||||
}
|
||||
|
||||
private fun refresh() {
|
||||
override fun refresh(): ShowHabitViewModel {
|
||||
val today = DateUtils.getTodayWithOffset()
|
||||
val lastMonth = today.minus(30)
|
||||
val lastYear = today.minus(365)
|
||||
@@ -92,46 +60,7 @@ class ShowHabitPresenter
|
||||
val scoreLastMonth = scores.getValue(lastMonth).toFloat()
|
||||
val scoreLastYear = scores.getValue(lastYear).toFloat()
|
||||
|
||||
val checkmarks = habit.checkmarks
|
||||
val valueToday = checkmarks.todayValue / 1e3
|
||||
val valueThisWeek = checkmarks.getThisWeekValue(preferences.firstWeekday) / 1e3
|
||||
val valueThisMonth = checkmarks.thisMonthValue / 1e3
|
||||
val valueThisQuarter = checkmarks.thisQuarterValue / 1e3
|
||||
val valueThisYear = checkmarks.thisYearValue / 1e3
|
||||
|
||||
val cal = DateUtils.getStartOfTodayCalendarWithOffset()
|
||||
val daysInMonth = cal.getActualMaximum(Calendar.DAY_OF_MONTH)
|
||||
val daysInQuarter = 91
|
||||
val daysInYear = cal.getActualMaximum(Calendar.DAY_OF_YEAR)
|
||||
|
||||
val targetToday = habit.getTargetValue() / habit.frequency.denominator
|
||||
val targetThisWeek = targetToday * 7
|
||||
val targetThisMonth = targetToday * daysInMonth
|
||||
val targetThisQuarter = targetToday * daysInQuarter
|
||||
val targetThisYear = targetToday * daysInYear
|
||||
|
||||
val targetCompleted = ArrayList<Double>()
|
||||
if (habit.frequency.denominator <= 1) targetCompleted.add(valueToday)
|
||||
if (habit.frequency.denominator <= 7) targetCompleted.add(valueThisWeek)
|
||||
targetCompleted.add(valueThisMonth)
|
||||
targetCompleted.add(valueThisQuarter)
|
||||
targetCompleted.add(valueThisYear)
|
||||
|
||||
val targetTotal = ArrayList<Double>()
|
||||
if (habit.frequency.denominator <= 1) targetTotal.add(targetToday)
|
||||
if (habit.frequency.denominator <= 7) targetTotal.add(targetThisWeek)
|
||||
targetTotal.add(targetThisMonth)
|
||||
targetTotal.add(targetThisQuarter)
|
||||
targetTotal.add(targetThisYear)
|
||||
|
||||
val targetLabels = ArrayList<String>()
|
||||
if (habit.frequency.denominator <= 1) targetLabels.add(resources.getString(R.string.today))
|
||||
if (habit.frequency.denominator <= 7) targetLabels.add(resources.getString(R.string.week))
|
||||
targetLabels.add(resources.getString(R.string.month))
|
||||
targetLabels.add(resources.getString(R.string.quarter))
|
||||
targetLabels.add(resources.getString(R.string.year))
|
||||
|
||||
data = ShowHabitViewModel(
|
||||
return ShowHabitViewModel(
|
||||
title = habit.name,
|
||||
description = habit.description,
|
||||
question = habit.question,
|
||||
@@ -144,9 +73,6 @@ class ShowHabitPresenter
|
||||
targetText = "${habit.targetValue.toShortString()} ${habit.unit}",
|
||||
frequencyText = habit.frequency.format(),
|
||||
reminderText = reminderText,
|
||||
targetCompleted = targetCompleted,
|
||||
targetTotal = targetTotal,
|
||||
targetLabels = targetLabels,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -184,8 +110,4 @@ class ShowHabitPresenter
|
||||
resources.getString(R.string.days),
|
||||
)
|
||||
}
|
||||
|
||||
interface Listener {
|
||||
fun onData(data: ShowHabitViewModel)
|
||||
}
|
||||
}
|
||||
@@ -23,6 +23,7 @@ import android.view.*
|
||||
import org.isoron.androidbase.activities.*
|
||||
import org.isoron.androidbase.utils.*
|
||||
import org.isoron.uhabits.*
|
||||
import org.isoron.uhabits.activities.*
|
||||
import org.isoron.uhabits.activities.habits.show.views.*
|
||||
import org.isoron.uhabits.core.models.*
|
||||
import org.isoron.uhabits.databinding.*
|
||||
@@ -35,7 +36,8 @@ class ShowHabitRootView
|
||||
@ActivityContext context: Context,
|
||||
private val habit: Habit,
|
||||
private val presenter: ShowHabitPresenter,
|
||||
) : BaseRootView(context), ShowHabitPresenter.Listener {
|
||||
targetCardPresenter: TargetCardPresenter,
|
||||
) : BaseRootView(context), Presenter.Listener<ShowHabitViewModel> {
|
||||
|
||||
private var controller: Controller = object : Controller {}
|
||||
private var binding = ShowHabitBinding.inflate(LayoutInflater.from(context))
|
||||
@@ -47,7 +49,7 @@ class ShowHabitRootView
|
||||
binding.overviewCard.presenter = presenter
|
||||
binding.notesCard.presenter = presenter
|
||||
binding.subtitleCard.presenter = presenter
|
||||
binding.targetCard.presenter = presenter
|
||||
binding.targetCard.presenter = targetCardPresenter
|
||||
|
||||
binding.scoreCard.habit = habit
|
||||
binding.historyCard.habit = habit
|
||||
|
||||
@@ -34,7 +34,4 @@ data class ShowHabitViewModel(
|
||||
val targetText: String = "",
|
||||
val frequencyText: String = "",
|
||||
val reminderText: String = "",
|
||||
val targetCompleted: List<Double> = listOf(),
|
||||
val targetTotal: List<Double> = listOf(),
|
||||
val targetLabels: List<String> = listOf(),
|
||||
)
|
||||
@@ -1,30 +1,34 @@
|
||||
/*
|
||||
* 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.activities.habits.show.views
|
||||
|
||||
import android.content.*
|
||||
import android.util.*
|
||||
import android.view.*
|
||||
import android.widget.*
|
||||
import org.isoron.uhabits.activities.*
|
||||
import org.isoron.uhabits.activities.habits.show.*
|
||||
import org.isoron.uhabits.databinding.*
|
||||
|
||||
class NotesCard(
|
||||
context: Context,
|
||||
attrs: AttributeSet
|
||||
) : LinearLayout(context, attrs), ShowHabitPresenter.Listener {
|
||||
class NotesCard(context: Context, attrs: AttributeSet) : DataView<ShowHabitViewModel>(context, attrs) {
|
||||
|
||||
private val binding = ShowHabitNotesBinding.inflate(LayoutInflater.from(context), this)
|
||||
lateinit var presenter: ShowHabitPresenter
|
||||
|
||||
override fun onAttachedToWindow() {
|
||||
super.onAttachedToWindow()
|
||||
presenter.addListener(this)
|
||||
presenter.requestData(this)
|
||||
}
|
||||
|
||||
override fun onDetachedFromWindow() {
|
||||
presenter.removeListener(this)
|
||||
super.onDetachedFromWindow()
|
||||
}
|
||||
|
||||
override fun onData(data: ShowHabitViewModel) {
|
||||
if (data.description.isEmpty()) {
|
||||
|
||||
@@ -21,48 +21,16 @@ package org.isoron.uhabits.activities.habits.show.views
|
||||
import android.content.*
|
||||
import android.util.*
|
||||
import android.view.*
|
||||
import android.widget.*
|
||||
import org.isoron.androidbase.utils.*
|
||||
import org.isoron.uhabits.*
|
||||
import org.isoron.uhabits.activities.*
|
||||
import org.isoron.uhabits.activities.habits.show.*
|
||||
import org.isoron.uhabits.databinding.*
|
||||
import org.isoron.uhabits.utils.*
|
||||
|
||||
class OverviewCard : LinearLayout, ShowHabitPresenter.Listener {
|
||||
class OverviewCard(context: Context, attrs: AttributeSet) : DataView<ShowHabitViewModel>(context, attrs) {
|
||||
|
||||
private val binding = ShowHabitOverviewBinding.inflate(LayoutInflater.from(context), this)
|
||||
lateinit var presenter: ShowHabitPresenter
|
||||
|
||||
constructor(context: Context) : super(context) {
|
||||
init()
|
||||
}
|
||||
|
||||
constructor(context: Context, attrs: AttributeSet) : super(context, attrs) {
|
||||
init()
|
||||
}
|
||||
|
||||
private fun init() {
|
||||
if (isInEditMode) initEditMode()
|
||||
}
|
||||
|
||||
override fun onAttachedToWindow() {
|
||||
super.onAttachedToWindow()
|
||||
presenter.addListener(this)
|
||||
presenter.requestData(this)
|
||||
}
|
||||
|
||||
override fun onDetachedFromWindow() {
|
||||
presenter.removeListener(this)
|
||||
super.onDetachedFromWindow()
|
||||
}
|
||||
|
||||
private fun initEditMode() {
|
||||
onData(ShowHabitViewModel(
|
||||
scoreToday = 0.6f,
|
||||
scoreMonthDiff = 0.42f,
|
||||
scoreYearDiff = 0.75f,
|
||||
))
|
||||
}
|
||||
|
||||
private fun formatPercentageDiff(percentageDiff: Float): String {
|
||||
return String.format("%s%.0f%%", if (percentageDiff >= 0) "+" else "\u2212",
|
||||
|
||||
@@ -21,44 +21,21 @@ package org.isoron.uhabits.activities.habits.show.views
|
||||
import android.content.*
|
||||
import android.util.*
|
||||
import android.view.*
|
||||
import android.widget.*
|
||||
import org.isoron.androidbase.utils.*
|
||||
import org.isoron.uhabits.activities.*
|
||||
import org.isoron.uhabits.activities.habits.show.*
|
||||
import org.isoron.uhabits.core.models.*
|
||||
import org.isoron.uhabits.databinding.*
|
||||
import org.isoron.uhabits.utils.*
|
||||
|
||||
class SubtitleCard(
|
||||
context: Context,
|
||||
attrs: AttributeSet,
|
||||
) : LinearLayout(context, attrs), ShowHabitPresenter.Listener {
|
||||
class SubtitleCard(context: Context, attrs: AttributeSet) : DataView<ShowHabitViewModel>(context, attrs) {
|
||||
|
||||
private val binding = ShowHabitSubtitleBinding.inflate(LayoutInflater.from(context), this)
|
||||
lateinit var presenter: ShowHabitPresenter
|
||||
|
||||
init {
|
||||
val fontAwesome = InterfaceUtils.getFontAwesome(context)
|
||||
binding.targetIcon.typeface = fontAwesome
|
||||
binding.frequencyIcon.typeface = fontAwesome
|
||||
binding.reminderIcon.typeface = fontAwesome
|
||||
if (isInEditMode) onData(ShowHabitViewModel(
|
||||
isNumerical = false,
|
||||
frequencyText = "Every day",
|
||||
question = "How many steps did you walk today?",
|
||||
color = PaletteColor(1),
|
||||
|
||||
))
|
||||
}
|
||||
|
||||
override fun onAttachedToWindow() {
|
||||
super.onAttachedToWindow()
|
||||
presenter.addListener(this)
|
||||
presenter.requestData(this)
|
||||
}
|
||||
|
||||
override fun onDetachedFromWindow() {
|
||||
presenter.removeListener(this)
|
||||
super.onDetachedFromWindow()
|
||||
}
|
||||
|
||||
override fun onData(data: ShowHabitViewModel) {
|
||||
|
||||
@@ -21,36 +21,95 @@ package org.isoron.uhabits.activities.habits.show.views
|
||||
import android.content.*
|
||||
import android.util.*
|
||||
import android.view.*
|
||||
import android.widget.*
|
||||
import org.isoron.uhabits.activities.habits.show.*
|
||||
import org.isoron.androidbase.activities.*
|
||||
import org.isoron.uhabits.*
|
||||
import org.isoron.uhabits.activities.*
|
||||
import org.isoron.uhabits.core.commands.*
|
||||
import org.isoron.uhabits.core.models.*
|
||||
import org.isoron.uhabits.core.preferences.*
|
||||
import org.isoron.uhabits.core.utils.*
|
||||
import org.isoron.uhabits.databinding.*
|
||||
import org.isoron.uhabits.utils.*
|
||||
import java.util.*
|
||||
import javax.inject.*
|
||||
|
||||
class TargetCard(
|
||||
context: Context,
|
||||
attrs: AttributeSet,
|
||||
) : LinearLayout(context, attrs), ShowHabitPresenter.Listener {
|
||||
data class TargetCardViewModel(
|
||||
val color: PaletteColor,
|
||||
val values: List<Double> = listOf(),
|
||||
val targets: List<Double> = listOf(),
|
||||
val labels: List<String> = listOf(),
|
||||
)
|
||||
|
||||
class TargetCardView(context: Context, attrs: AttributeSet) : DataView<TargetCardViewModel>(context, attrs) {
|
||||
|
||||
private val binding = ShowHabitTargetBinding.inflate(LayoutInflater.from(context), this)
|
||||
lateinit var presenter: ShowHabitPresenter
|
||||
|
||||
override fun onAttachedToWindow() {
|
||||
super.onAttachedToWindow()
|
||||
presenter.addListener(this)
|
||||
presenter.requestData(this)
|
||||
}
|
||||
|
||||
override fun onDetachedFromWindow() {
|
||||
presenter.removeListener(this)
|
||||
super.onDetachedFromWindow()
|
||||
}
|
||||
|
||||
override fun onData(data: ShowHabitViewModel) {
|
||||
override fun onData(data: TargetCardViewModel) {
|
||||
val androidColor = data.color.toThemedAndroidColor(context)
|
||||
binding.targetChart.setValues(data.targetCompleted)
|
||||
binding.targetChart.setTargets(data.targetTotal)
|
||||
binding.targetChart.setLabels(data.targetLabels)
|
||||
binding.targetChart.setValues(data.values)
|
||||
binding.targetChart.setTargets(data.targets)
|
||||
binding.targetChart.setLabels(data.labels)
|
||||
binding.title.setTextColor(androidColor)
|
||||
binding.targetChart.setColor(androidColor)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ActivityScope
|
||||
class TargetCardPresenter
|
||||
@Inject constructor(
|
||||
val habit: Habit,
|
||||
val preferences: Preferences,
|
||||
@ActivityContext val context: Context,
|
||||
commandRunner: CommandRunner,
|
||||
) : Presenter<TargetCardViewModel>(commandRunner) {
|
||||
|
||||
val resources = context.resources
|
||||
|
||||
override fun refresh(): TargetCardViewModel {
|
||||
val checkmarks = habit.checkmarks
|
||||
val valueToday = checkmarks.todayValue / 1e3
|
||||
val valueThisWeek = checkmarks.getThisWeekValue(preferences.firstWeekday) / 1e3
|
||||
val valueThisMonth = checkmarks.thisMonthValue / 1e3
|
||||
val valueThisQuarter = checkmarks.thisQuarterValue / 1e3
|
||||
val valueThisYear = checkmarks.thisYearValue / 1e3
|
||||
|
||||
val cal = DateUtils.getStartOfTodayCalendarWithOffset()
|
||||
val daysInMonth = cal.getActualMaximum(Calendar.DAY_OF_MONTH)
|
||||
val daysInQuarter = 91
|
||||
val daysInYear = cal.getActualMaximum(Calendar.DAY_OF_YEAR)
|
||||
|
||||
val targetToday = habit.getTargetValue() / habit.frequency.denominator
|
||||
val targetThisWeek = targetToday * 7
|
||||
val targetThisMonth = targetToday * daysInMonth
|
||||
val targetThisQuarter = targetToday * daysInQuarter
|
||||
val targetThisYear = targetToday * daysInYear
|
||||
|
||||
val values = ArrayList<Double>()
|
||||
if (habit.frequency.denominator <= 1) values.add(valueToday)
|
||||
if (habit.frequency.denominator <= 7) values.add(valueThisWeek)
|
||||
values.add(valueThisMonth)
|
||||
values.add(valueThisQuarter)
|
||||
values.add(valueThisYear)
|
||||
|
||||
val targets = ArrayList<Double>()
|
||||
if (habit.frequency.denominator <= 1) targets.add(targetToday)
|
||||
if (habit.frequency.denominator <= 7) targets.add(targetThisWeek)
|
||||
targets.add(targetThisMonth)
|
||||
targets.add(targetThisQuarter)
|
||||
targets.add(targetThisYear)
|
||||
|
||||
val labels = ArrayList<String>()
|
||||
if (habit.frequency.denominator <= 1) labels.add(resources.getString(R.string.today))
|
||||
if (habit.frequency.denominator <= 7) labels.add(resources.getString(R.string.week))
|
||||
labels.add(resources.getString(R.string.month))
|
||||
labels.add(resources.getString(R.string.quarter))
|
||||
labels.add(resources.getString(R.string.year))
|
||||
|
||||
return TargetCardViewModel(
|
||||
color = habit.color,
|
||||
values = values,
|
||||
labels = labels,
|
||||
targets = targets,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@ import android.widget.*;
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import org.isoron.uhabits.*;
|
||||
import org.isoron.uhabits.core.commands.*;
|
||||
import org.isoron.uhabits.core.preferences.*;
|
||||
import org.isoron.uhabits.intents.*;
|
||||
|
||||
@@ -49,6 +50,9 @@ public abstract class BaseWidget
|
||||
@NonNull
|
||||
private final Context context;
|
||||
|
||||
@NonNull
|
||||
protected final CommandRunner commandRunner;
|
||||
|
||||
@NonNull
|
||||
private WidgetDimensions dimensions;
|
||||
|
||||
@@ -62,6 +66,7 @@ public abstract class BaseWidget
|
||||
|
||||
widgetPrefs = app.getComponent().getWidgetPreferences();
|
||||
prefs = app.getComponent().getPreferences();
|
||||
commandRunner = app.getComponent().getCommandRunner();
|
||||
pendingIntentFactory = app.getComponent().getPendingIntentFactory();
|
||||
dimensions = new WidgetDimensions(getDefaultWidth(), getDefaultHeight(),
|
||||
getDefaultWidth(), getDefaultHeight());
|
||||
|
||||
@@ -26,6 +26,7 @@ import android.view.ViewGroup.LayoutParams.*
|
||||
import org.isoron.uhabits.activities.common.views.*
|
||||
import org.isoron.uhabits.activities.habits.show.views.*
|
||||
import org.isoron.uhabits.core.models.*
|
||||
import org.isoron.uhabits.utils.*
|
||||
import org.isoron.uhabits.widgets.views.*
|
||||
|
||||
class TargetWidget(
|
||||
@@ -38,15 +39,16 @@ class TargetWidget(
|
||||
pendingIntentFactory.showHabit(habit)
|
||||
|
||||
override fun refreshData(view: View) {
|
||||
// val widgetView = view as GraphWidgetView
|
||||
// widgetView.setBackgroundAlpha(preferedBackgroundAlpha)
|
||||
// if (preferedBackgroundAlpha >= 255) widgetView.setShadowAlpha(0x4f)
|
||||
// val chart = (widgetView.dataView as TargetChart)
|
||||
// with(TargetCard.RefreshTask(context, habit, prefs.firstWeekday, chart, null)) {
|
||||
// onPreExecute()
|
||||
// doInBackground()
|
||||
// onPostExecute()
|
||||
// }
|
||||
val widgetView = view as GraphWidgetView
|
||||
widgetView.setBackgroundAlpha(preferedBackgroundAlpha)
|
||||
if (preferedBackgroundAlpha >= 255) widgetView.setShadowAlpha(0x4f)
|
||||
val chart = (widgetView.dataView as TargetChart)
|
||||
val presenter = TargetCardPresenter(habit, prefs, context, commandRunner)
|
||||
val data = presenter.refresh()
|
||||
chart.setColor(data.color.toThemedAndroidColor(context))
|
||||
chart.setTargets(data.targets)
|
||||
chart.setLabels(data.labels)
|
||||
chart.setValues(data.values)
|
||||
}
|
||||
|
||||
override fun buildView(): View {
|
||||
|
||||
@@ -57,7 +57,7 @@
|
||||
style="@style/Card"
|
||||
android:paddingTop="12dp"/>
|
||||
|
||||
<org.isoron.uhabits.activities.habits.show.views.TargetCard
|
||||
<org.isoron.uhabits.activities.habits.show.views.TargetCardView
|
||||
android:id="@+id/targetCard"
|
||||
style="@style/Card"
|
||||
android:paddingTop="12dp"/>
|
||||
|
||||
Reference in New Issue
Block a user