From cb6843e08b1f531a6d87492592baa9bcac4a27b8 Mon Sep 17 00:00:00 2001 From: "Alinson S. Xavier" Date: Sat, 2 Jan 2021 00:45:16 -0600 Subject: [PATCH] Remove ShowHabitScreen and ShowHabitBehavior --- .../common/views/ScoreChartTest.java | 15 +- .../show/views/FrequencyCardViewTest.kt | 2 +- .../habits/show/views/HistoryCardViewTest.kt | 5 +- .../habits/show/views/NotesCardViewTest.kt | 6 +- .../habits/show/views/OverviewCardViewTest.kt | 6 +- .../habits/show/views/ScoreCardViewTest.kt | 4 +- .../habits/show/views/StreakCardViewTest.kt | 6 +- .../habits/show/views/SubtitleCardViewTest.kt | 6 +- .../uhabits/activities/HabitsDirFinder.kt | 4 +- .../common/dialogs/ConfirmDeleteDialog.java | 2 +- .../common/dialogs/HistoryEditorDialog.kt | 3 +- .../habits/show/ShowHabitActivity.kt | 119 +++++++++---- .../activities/habits/show/ShowHabitMenu.kt | 12 +- .../activities/habits/show/ShowHabitScreen.kt | 100 ----------- .../activities/habits/show/ShowHabitView.kt | 38 ++-- .../habits/show/views/BarCardView.kt | 58 +++--- .../habits/show/views/FrequencyCardView.kt | 10 +- .../habits/show/views/HistoryCardView.kt | 27 ++- .../habits/show/views/NotesCardView.kt | 8 +- .../habits/show/views/OverviewCardView.kt | 20 +-- .../habits/show/views/ScoreCardView.kt | 19 +- .../habits/show/views/StreakCardView.kt | 8 +- .../habits/show/views/SubtitleCardView.kt | 18 +- .../habits/show/views/TargetCardView.kt | 12 +- .../isoron/uhabits/widgets/HistoryWidget.kt | 3 +- .../org/isoron/uhabits/widgets/ScoreWidget.kt | 3 +- .../isoron/uhabits/widgets/TargetWidget.kt | 3 +- .../core/ui/screens/habits/show/ShowHabit.kt | 168 +++++++++++------- .../screens/habits/show/ShowHabitBehavior.kt | 109 ------------ ...uBehavior.kt => ShowHabitMenuPresenter.kt} | 6 +- .../ui/screens/habits/show/views/BarCard.kt | 85 +++++---- .../habits/show/views/FrequencyCard.kt | 24 +-- .../screens/habits/show/views/HistoryCard.kt | 126 +++++++++---- .../ui/screens/habits/show/views/NotesCard.kt | 10 +- .../screens/habits/show/views/OverviewCard.kt | 42 ++--- .../ui/screens/habits/show/views/ScoreCard.kt | 73 +++++--- .../screens/habits/show/views/StreakCart.kt | 14 +- .../screens/habits/show/views/SubtitleCard.kt | 26 +-- .../screens/habits/show/views/TargetCard.kt | 126 ++++++------- ...t.java => ShowHabitMenuPresenterTest.java} | 14 +- 40 files changed, 656 insertions(+), 684 deletions(-) delete mode 100644 android/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/show/ShowHabitScreen.kt delete mode 100644 android/uhabits-core/src/main/java/org/isoron/uhabits/core/ui/screens/habits/show/ShowHabitBehavior.kt rename android/uhabits-core/src/main/java/org/isoron/uhabits/core/ui/screens/habits/show/{ShowHabitMenuBehavior.kt => ShowHabitMenuPresenter.kt} (96%) rename android/uhabits-core/src/test/java/org/isoron/uhabits/core/ui/screens/habits/show/{ShowHabitMenuBehaviorTest.java => ShowHabitMenuPresenterTest.java} (80%) diff --git a/android/uhabits-android/src/androidTest/java/org/isoron/uhabits/activities/common/views/ScoreChartTest.java b/android/uhabits-android/src/androidTest/java/org/isoron/uhabits/activities/common/views/ScoreChartTest.java index 71ce5262f..b425f4640 100644 --- a/android/uhabits-android/src/androidTest/java/org/isoron/uhabits/activities/common/views/ScoreChartTest.java +++ b/android/uhabits-android/src/androidTest/java/org/isoron/uhabits/activities/common/views/ScoreChartTest.java @@ -39,8 +39,6 @@ public class ScoreChartTest extends BaseViewTest private ScoreChart view; - private ScoreCardPresenter presenter; - @Override @Before public void setUp() @@ -49,13 +47,12 @@ public class ScoreChartTest extends BaseViewTest fixtures.purgeHabits(habitList); habit = fixtures.createLongHabit(); - presenter = new ScoreCardPresenter(); - ScoreCardViewModel model = presenter.present(habit, prefs.getFirstWeekdayInt(), 0); + ScoreCardState state = ScoreCardPresenter.Companion.buildState(habit, prefs.getFirstWeekdayInt(), 0); view = new ScoreChart(targetContext); - view.setScores(model.getScores()); - view.setColor(PaletteUtilsKt.toFixedAndroidColor(model.getColor())); - view.setBucketSize(model.getBucketSize()); + view.setScores(state.getScores()); + view.setColor(PaletteUtilsKt.toFixedAndroidColor(state.getColor())); + view.setBucketSize(state.getBucketSize()); measureView(view, dpToPixels(300), dpToPixels(200)); } @@ -84,7 +81,7 @@ public class ScoreChartTest extends BaseViewTest @Test public void testRender_withMonthlyBucket() throws Throwable { - ScoreCardViewModel model = presenter.present(habit, prefs.getFirstWeekdayInt(), 2); + ScoreCardState model = ScoreCardPresenter.Companion.buildState(habit, prefs.getFirstWeekdayInt(), 2); view.setScores(model.getScores()); view.setBucketSize(model.getBucketSize()); view.invalidate(); @@ -102,7 +99,7 @@ public class ScoreChartTest extends BaseViewTest @Test public void testRender_withYearlyBucket() throws Throwable { - ScoreCardViewModel model = presenter.present(habit, prefs.getFirstWeekdayInt(), 4); + ScoreCardState model = ScoreCardPresenter.Companion.buildState(habit, prefs.getFirstWeekdayInt(), 4); view.setScores(model.getScores()); view.setBucketSize(model.getBucketSize()); view.invalidate(); diff --git a/android/uhabits-android/src/androidTest/java/org/isoron/uhabits/activities/habits/show/views/FrequencyCardViewTest.kt b/android/uhabits-android/src/androidTest/java/org/isoron/uhabits/activities/habits/show/views/FrequencyCardViewTest.kt index 18ce75c1f..f80876fba 100644 --- a/android/uhabits-android/src/androidTest/java/org/isoron/uhabits/activities/habits/show/views/FrequencyCardViewTest.kt +++ b/android/uhabits-android/src/androidTest/java/org/isoron/uhabits/activities/habits/show/views/FrequencyCardViewTest.kt @@ -43,7 +43,7 @@ class FrequencyCardViewTest : BaseViewTest() { .from(targetContext) .inflate(R.layout.show_habit, null) .findViewById(R.id.frequencyCard) as FrequencyCardView - view.update(FrequencyCardPresenter().present(habit = habit, firstWeekday = 0)) + view.setState(FrequencyCardPresenter.buildState(habit = habit, firstWeekday = 0)) measureView(view, 800f, 600f) } diff --git a/android/uhabits-android/src/androidTest/java/org/isoron/uhabits/activities/habits/show/views/HistoryCardViewTest.kt b/android/uhabits-android/src/androidTest/java/org/isoron/uhabits/activities/habits/show/views/HistoryCardViewTest.kt index f4db382fb..8428816fa 100644 --- a/android/uhabits-android/src/androidTest/java/org/isoron/uhabits/activities/habits/show/views/HistoryCardViewTest.kt +++ b/android/uhabits-android/src/androidTest/java/org/isoron/uhabits/activities/habits/show/views/HistoryCardViewTest.kt @@ -45,11 +45,10 @@ class HistoryCardViewTest : BaseViewTest() { .from(targetContext) .inflate(R.layout.show_habit, null) .findViewById(R.id.historyCard) as HistoryCardView - view.update( - HistoryCardPresenter().present( + view.setState( + HistoryCardPresenter.buildState( habit = habit, firstWeekday = SUNDAY, - isSkipEnabled = false, theme = LightTheme(), ) ) diff --git a/android/uhabits-android/src/androidTest/java/org/isoron/uhabits/activities/habits/show/views/NotesCardViewTest.kt b/android/uhabits-android/src/androidTest/java/org/isoron/uhabits/activities/habits/show/views/NotesCardViewTest.kt index f7e274ba6..32ec31019 100644 --- a/android/uhabits-android/src/androidTest/java/org/isoron/uhabits/activities/habits/show/views/NotesCardViewTest.kt +++ b/android/uhabits-android/src/androidTest/java/org/isoron/uhabits/activities/habits/show/views/NotesCardViewTest.kt @@ -25,7 +25,7 @@ import androidx.test.filters.MediumTest import org.hamcrest.Matchers.equalTo import org.isoron.uhabits.BaseViewTest import org.isoron.uhabits.R -import org.isoron.uhabits.core.ui.screens.habits.show.views.NotesCardViewModel +import org.isoron.uhabits.core.ui.screens.habits.show.views.NotesCardState import org.junit.Assert.assertThat import org.junit.Before import org.junit.Test @@ -44,7 +44,7 @@ class NotesCardViewTest : BaseViewTest() { .from(targetContext) .inflate(R.layout.show_habit, null) .findViewById(R.id.notesCard) - view.update(NotesCardViewModel(description = "This is a test description")) + view.setState(NotesCardState(description = "This is a test description")) measureView(view, 800f, 200f) } @@ -55,7 +55,7 @@ class NotesCardViewTest : BaseViewTest() { @Test fun testRenderEmptyDescription() { - view.update(NotesCardViewModel(description = "")) + view.setState(NotesCardState(description = "")) assertThat(view.visibility, equalTo(GONE)) } } diff --git a/android/uhabits-android/src/androidTest/java/org/isoron/uhabits/activities/habits/show/views/OverviewCardViewTest.kt b/android/uhabits-android/src/androidTest/java/org/isoron/uhabits/activities/habits/show/views/OverviewCardViewTest.kt index 3bf6edaa4..5b3b198c1 100644 --- a/android/uhabits-android/src/androidTest/java/org/isoron/uhabits/activities/habits/show/views/OverviewCardViewTest.kt +++ b/android/uhabits-android/src/androidTest/java/org/isoron/uhabits/activities/habits/show/views/OverviewCardViewTest.kt @@ -25,7 +25,7 @@ import androidx.test.filters.MediumTest import org.isoron.uhabits.BaseViewTest import org.isoron.uhabits.R import org.isoron.uhabits.core.models.PaletteColor -import org.isoron.uhabits.core.ui.screens.habits.show.views.OverviewCardViewModel +import org.isoron.uhabits.core.ui.screens.habits.show.views.OverviewCardState import org.junit.Before import org.junit.Test import org.junit.runner.RunWith @@ -43,8 +43,8 @@ class OverviewCardViewTest : BaseViewTest() { .from(targetContext) .inflate(R.layout.show_habit, null) .findViewById(R.id.overviewCard) as OverviewCardView - view.update( - OverviewCardViewModel( + view.setState( + OverviewCardState( scoreToday = 0.74f, scoreMonthDiff = 0.23f, scoreYearDiff = 0.74f, diff --git a/android/uhabits-android/src/androidTest/java/org/isoron/uhabits/activities/habits/show/views/ScoreCardViewTest.kt b/android/uhabits-android/src/androidTest/java/org/isoron/uhabits/activities/habits/show/views/ScoreCardViewTest.kt index 3c1981c53..82ad63e19 100644 --- a/android/uhabits-android/src/androidTest/java/org/isoron/uhabits/activities/habits/show/views/ScoreCardViewTest.kt +++ b/android/uhabits-android/src/androidTest/java/org/isoron/uhabits/activities/habits/show/views/ScoreCardViewTest.kt @@ -43,8 +43,8 @@ class ScoreCardViewTest : BaseViewTest() { .from(targetContext) .inflate(R.layout.show_habit, null) .findViewById(R.id.scoreCard) as ScoreCardView - view.update( - ScoreCardPresenter().present( + view.setState( + ScoreCardPresenter.buildState( habit = habit, firstWeekday = 0, spinnerPosition = 0, diff --git a/android/uhabits-android/src/androidTest/java/org/isoron/uhabits/activities/habits/show/views/StreakCardViewTest.kt b/android/uhabits-android/src/androidTest/java/org/isoron/uhabits/activities/habits/show/views/StreakCardViewTest.kt index 2968ccfab..2f41e960a 100644 --- a/android/uhabits-android/src/androidTest/java/org/isoron/uhabits/activities/habits/show/views/StreakCardViewTest.kt +++ b/android/uhabits-android/src/androidTest/java/org/isoron/uhabits/activities/habits/show/views/StreakCardViewTest.kt @@ -24,7 +24,7 @@ import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.MediumTest import org.isoron.uhabits.BaseViewTest import org.isoron.uhabits.R -import org.isoron.uhabits.core.ui.screens.habits.show.views.StreakCardViewModel +import org.isoron.uhabits.core.ui.screens.habits.show.views.StreakCardState import org.junit.Before import org.junit.Test import org.junit.runner.RunWith @@ -43,8 +43,8 @@ class StreakCardViewTest : BaseViewTest() { .from(targetContext) .inflate(R.layout.show_habit, null) .findViewById(R.id.streakCard) as StreakCardView - view.update( - StreakCardViewModel( + view.setState( + StreakCardState( bestStreaks = habit.streaks.getBest(10), color = habit.color, ) diff --git a/android/uhabits-android/src/androidTest/java/org/isoron/uhabits/activities/habits/show/views/SubtitleCardViewTest.kt b/android/uhabits-android/src/androidTest/java/org/isoron/uhabits/activities/habits/show/views/SubtitleCardViewTest.kt index 076e226c8..2e3f5c2d4 100644 --- a/android/uhabits-android/src/androidTest/java/org/isoron/uhabits/activities/habits/show/views/SubtitleCardViewTest.kt +++ b/android/uhabits-android/src/androidTest/java/org/isoron/uhabits/activities/habits/show/views/SubtitleCardViewTest.kt @@ -27,7 +27,7 @@ import org.isoron.uhabits.core.models.Frequency import org.isoron.uhabits.core.models.PaletteColor import org.isoron.uhabits.core.models.Reminder import org.isoron.uhabits.core.models.WeekdayList.EVERY_DAY -import org.isoron.uhabits.core.ui.screens.habits.show.views.SubtitleCardViewModel +import org.isoron.uhabits.core.ui.screens.habits.show.views.SubtitleCardState import org.junit.Before import org.junit.Test import org.junit.runner.RunWith @@ -45,8 +45,8 @@ class SubtitleCardViewTest : BaseViewTest() { .from(targetContext) .inflate(R.layout.show_habit, null) .findViewById(R.id.subtitleCard) - view.update( - SubtitleCardViewModel( + view.setState( + SubtitleCardState( color = PaletteColor(7), frequency = Frequency(3, 7), isNumerical = false, diff --git a/android/uhabits-android/src/main/java/org/isoron/uhabits/activities/HabitsDirFinder.kt b/android/uhabits-android/src/main/java/org/isoron/uhabits/activities/HabitsDirFinder.kt index dcc25d906..add675d3a 100644 --- a/android/uhabits-android/src/main/java/org/isoron/uhabits/activities/HabitsDirFinder.kt +++ b/android/uhabits-android/src/main/java/org/isoron/uhabits/activities/HabitsDirFinder.kt @@ -20,14 +20,14 @@ package org.isoron.uhabits.activities import org.isoron.uhabits.AndroidDirFinder import org.isoron.uhabits.core.ui.screens.habits.list.ListHabitsBehavior -import org.isoron.uhabits.core.ui.screens.habits.show.ShowHabitMenuBehavior +import org.isoron.uhabits.core.ui.screens.habits.show.ShowHabitMenuPresenter import java.io.File import javax.inject.Inject class HabitsDirFinder @Inject constructor( private val androidDirFinder: AndroidDirFinder -) : ShowHabitMenuBehavior.System, ListHabitsBehavior.DirFinder { +) : ShowHabitMenuPresenter.System, ListHabitsBehavior.DirFinder { override fun getCSVOutputDir(): File { return androidDirFinder.getFilesDir("CSV")!! diff --git a/android/uhabits-android/src/main/java/org/isoron/uhabits/activities/common/dialogs/ConfirmDeleteDialog.java b/android/uhabits-android/src/main/java/org/isoron/uhabits/activities/common/dialogs/ConfirmDeleteDialog.java index 5c0fbfe23..4b625e02f 100644 --- a/android/uhabits-android/src/main/java/org/isoron/uhabits/activities/common/dialogs/ConfirmDeleteDialog.java +++ b/android/uhabits-android/src/main/java/org/isoron/uhabits/activities/common/dialogs/ConfirmDeleteDialog.java @@ -37,7 +37,7 @@ import org.isoron.uhabits.inject.*; @AutoFactory(allowSubclasses = true) public class ConfirmDeleteDialog extends AlertDialog { - protected ConfirmDeleteDialog(@Provided @ActivityContext Context context, + public ConfirmDeleteDialog(@Provided @ActivityContext Context context, @NonNull OnConfirmedCallback callback, int quantity) { diff --git a/android/uhabits-android/src/main/java/org/isoron/uhabits/activities/common/dialogs/HistoryEditorDialog.kt b/android/uhabits-android/src/main/java/org/isoron/uhabits/activities/common/dialogs/HistoryEditorDialog.kt index 25af12e9b..178d8aa58 100644 --- a/android/uhabits-android/src/main/java/org/isoron/uhabits/activities/common/dialogs/HistoryEditorDialog.kt +++ b/android/uhabits-android/src/main/java/org/isoron/uhabits/activities/common/dialogs/HistoryEditorDialog.kt @@ -91,10 +91,9 @@ class HistoryEditorDialog : AppCompatDialogFragment(), CommandRunner.Listener { } private fun refreshData() { - val model = HistoryCardPresenter().present( + val model = HistoryCardPresenter.buildState( habit, preferences.firstWeekday, - preferences.isSkipEnabled, theme = LightTheme() ) chart?.series = model.series diff --git a/android/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/show/ShowHabitActivity.kt b/android/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/show/ShowHabitActivity.kt index 324e7bdbf..36547998a 100644 --- a/android/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/show/ShowHabitActivity.kt +++ b/android/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/show/ShowHabitActivity.kt @@ -20,6 +20,7 @@ package org.isoron.uhabits.activities.habits.show import android.content.ContentUris import android.os.Bundle +import android.view.HapticFeedbackConstants import android.view.Menu import android.view.MenuItem import androidx.appcompat.app.AppCompatActivity @@ -28,33 +29,39 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import org.isoron.uhabits.AndroidDirFinder import org.isoron.uhabits.HabitsApplication +import org.isoron.uhabits.R import org.isoron.uhabits.activities.AndroidThemeSwitcher import org.isoron.uhabits.activities.HabitsDirFinder -import org.isoron.uhabits.activities.common.dialogs.ConfirmDeleteDialogFactory +import org.isoron.uhabits.activities.common.dialogs.ConfirmDeleteDialog import org.isoron.uhabits.activities.common.dialogs.HistoryEditorDialog import org.isoron.uhabits.activities.common.dialogs.NumberPickerFactory import org.isoron.uhabits.core.commands.Command import org.isoron.uhabits.core.commands.CommandRunner import org.isoron.uhabits.core.models.Habit import org.isoron.uhabits.core.preferences.Preferences -import org.isoron.uhabits.core.ui.screens.habits.show.ShowHabitBehavior -import org.isoron.uhabits.core.ui.screens.habits.show.ShowHabitMenuBehavior +import org.isoron.uhabits.core.ui.callbacks.OnConfirmedCallback +import org.isoron.uhabits.core.ui.screens.habits.list.ListHabitsBehavior +import org.isoron.uhabits.core.ui.screens.habits.show.ShowHabitMenuPresenter import org.isoron.uhabits.core.ui.screens.habits.show.ShowHabitPresenter +import org.isoron.uhabits.core.ui.views.OnDateClickedListener import org.isoron.uhabits.intents.IntentFactory +import org.isoron.uhabits.utils.showMessage +import org.isoron.uhabits.utils.showSendFileScreen +import org.isoron.uhabits.widgets.WidgetUpdater class ShowHabitActivity : AppCompatActivity(), CommandRunner.Listener { - val presenter = ShowHabitPresenter() - private lateinit var commandRunner: CommandRunner private lateinit var menu: ShowHabitMenu private lateinit var view: ShowHabitView private lateinit var habit: Habit private lateinit var preferences: Preferences private lateinit var themeSwitcher: AndroidThemeSwitcher - private lateinit var behavior: ShowHabitBehavior + private lateinit var widgetUpdater: WidgetUpdater private val scope = CoroutineScope(Dispatchers.Main) + private lateinit var presenter: ShowHabitPresenter + private val screen = Screen() override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -64,21 +71,12 @@ class ShowHabitActivity : AppCompatActivity(), CommandRunner.Listener { habit = habitList.getById(ContentUris.parseId(intent.data!!))!! preferences = appComponent.preferences commandRunner = appComponent.commandRunner + widgetUpdater = appComponent.widgetUpdater + themeSwitcher = AndroidThemeSwitcher(this, preferences) themeSwitcher.apply() - view = ShowHabitView(this) - - val screen = ShowHabitScreen( - activity = this, - confirmDeleteDialogFactory = ConfirmDeleteDialogFactory { this }, - habit = habit, - intentFactory = IntentFactory(), - numberPickerFactory = NumberPickerFactory(this), - widgetUpdater = appComponent.widgetUpdater, - ) - - behavior = ShowHabitBehavior( + presenter = ShowHabitPresenter( commandRunner = commandRunner, habit = habit, habitList = habitList, @@ -86,7 +84,9 @@ class ShowHabitActivity : AppCompatActivity(), CommandRunner.Listener { screen = screen, ) - val menuBehavior = ShowHabitMenuBehavior( + view = ShowHabitView(this) + + val menuPresenter = ShowHabitMenuPresenter( commandRunner = commandRunner, habit = habit, habitList = habitList, @@ -97,15 +97,11 @@ class ShowHabitActivity : AppCompatActivity(), CommandRunner.Listener { menu = ShowHabitMenu( activity = this, - behavior = menuBehavior, + presenter = menuPresenter, preferences = preferences, ) - view.onScoreCardSpinnerPosition = behavior::onScoreCardSpinnerPosition - view.onBarCardBoolSpinnerPosition = behavior::onBarCardBoolSpinnerPosition - view.onBarCardNumericalSpinnerPosition = behavior::onBarCardNumericalSpinnerPosition - view.onClickEditHistoryButton = behavior::onClickEditHistory - + view.setListener(presenter) setContentView(view) } @@ -121,9 +117,9 @@ class ShowHabitActivity : AppCompatActivity(), CommandRunner.Listener { super.onResume() commandRunner.addListener(this) supportFragmentManager.findFragmentByTag("historyEditor")?.let { - (it as HistoryEditorDialog).setOnDateClickedListener(behavior) + (it as HistoryEditorDialog).setOnDateClickedListener(presenter.historyCardPresenter) } - refresh() + screen.refresh() } override fun onPause() { @@ -132,18 +128,69 @@ class ShowHabitActivity : AppCompatActivity(), CommandRunner.Listener { } override fun onCommandFinished(command: Command) { - refresh() + screen.refresh() } - fun refresh() { - scope.launch { - view.update( - presenter.present( - habit = habit, - preferences = preferences, - theme = themeSwitcher.currentTheme, + inner class Screen : ShowHabitMenuPresenter.Screen, ShowHabitPresenter.Screen { + override fun updateWidgets() { + widgetUpdater.updateWidgets() + } + + override fun refresh() { + scope.launch { + view.setState( + ShowHabitPresenter.buildState( + habit = habit, + preferences = preferences, + theme = themeSwitcher.currentTheme, + ) ) - ) + } + } + + override fun showHistoryEditorDialog(listener: OnDateClickedListener) { + val dialog = HistoryEditorDialog() + dialog.arguments = Bundle().apply { + putLong("habit", habit.id!!) + } + dialog.setOnDateClickedListener(listener) + dialog.show(supportFragmentManager, "historyEditor") + } + + override fun showFeedback() { + window.decorView.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY) + } + + override fun showNumberPicker( + value: Double, + unit: String, + callback: ListHabitsBehavior.NumberPickerCallback, + ) { + NumberPickerFactory(this@ShowHabitActivity).create(value, unit, callback).show() + } + + override fun showEditHabitScreen(habit: Habit) { + startActivity(IntentFactory().startEditActivity(this@ShowHabitActivity, habit)) + } + + override fun showMessage(m: ShowHabitMenuPresenter.Message?) { + when (m) { + ShowHabitMenuPresenter.Message.COULD_NOT_EXPORT -> { + showMessage(resources.getString(R.string.could_not_export)) + } + } + } + + override fun showSendFileScreen(filename: String) { + this@ShowHabitActivity.showSendFileScreen(filename) + } + + override fun showDeleteConfirmationScreen(callback: OnConfirmedCallback) { + ConfirmDeleteDialog(this@ShowHabitActivity, callback, 1).show() + } + + override fun close() { + this@ShowHabitActivity.finish() } } } diff --git a/android/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/show/ShowHabitMenu.kt b/android/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/show/ShowHabitMenu.kt index 57783fd6d..2d80fdc05 100644 --- a/android/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/show/ShowHabitMenu.kt +++ b/android/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/show/ShowHabitMenu.kt @@ -23,11 +23,11 @@ import android.view.Menu import android.view.MenuItem import org.isoron.uhabits.R import org.isoron.uhabits.core.preferences.Preferences -import org.isoron.uhabits.core.ui.screens.habits.show.ShowHabitMenuBehavior +import org.isoron.uhabits.core.ui.screens.habits.show.ShowHabitMenuPresenter class ShowHabitMenu( val activity: ShowHabitActivity, - val behavior: ShowHabitMenuBehavior, + val presenter: ShowHabitMenuPresenter, val preferences: Preferences, ) { fun onCreateOptionsMenu(menu: Menu): Boolean { @@ -41,19 +41,19 @@ class ShowHabitMenu( fun onOptionsItemSelected(item: MenuItem): Boolean { when (item.itemId) { R.id.action_edit_habit -> { - behavior.onEditHabit() + presenter.onEditHabit() return true } R.id.action_delete -> { - behavior.onDeleteHabit() + presenter.onDeleteHabit() return true } R.id.action_randomize -> { - behavior.onRandomize() + presenter.onRandomize() return true } R.id.export -> { - behavior.onExportCSV() + presenter.onExportCSV() return true } } diff --git a/android/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/show/ShowHabitScreen.kt b/android/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/show/ShowHabitScreen.kt deleted file mode 100644 index cc134ff43..000000000 --- a/android/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/show/ShowHabitScreen.kt +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright (C) 2016-2020 Álinson Santos Xavier - * - * 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 . - */ - -package org.isoron.uhabits.activities.habits.show - -import android.os.Bundle -import android.view.HapticFeedbackConstants -import org.isoron.uhabits.R -import org.isoron.uhabits.activities.common.dialogs.ConfirmDeleteDialogFactory -import org.isoron.uhabits.activities.common.dialogs.HistoryEditorDialog -import org.isoron.uhabits.activities.common.dialogs.NumberPickerFactory -import org.isoron.uhabits.core.models.Habit -import org.isoron.uhabits.core.ui.callbacks.OnConfirmedCallback -import org.isoron.uhabits.core.ui.screens.habits.list.ListHabitsBehavior -import org.isoron.uhabits.core.ui.screens.habits.show.ShowHabitBehavior -import org.isoron.uhabits.core.ui.screens.habits.show.ShowHabitMenuBehavior -import org.isoron.uhabits.core.ui.views.OnDateClickedListener -import org.isoron.uhabits.intents.IntentFactory -import org.isoron.uhabits.utils.showMessage -import org.isoron.uhabits.utils.showSendFileScreen -import org.isoron.uhabits.widgets.WidgetUpdater - -class ShowHabitScreen( - val activity: ShowHabitActivity, - val confirmDeleteDialogFactory: ConfirmDeleteDialogFactory, - val habit: Habit, - val intentFactory: IntentFactory, - val numberPickerFactory: NumberPickerFactory, - val widgetUpdater: WidgetUpdater, -) : ShowHabitBehavior.Screen, ShowHabitMenuBehavior.Screen { - - override fun showNumberPicker( - value: Double, - unit: String, - callback: ListHabitsBehavior.NumberPickerCallback, - ) { - numberPickerFactory.create(value, unit, callback).show() - } - - override fun updateWidgets() { - widgetUpdater.updateWidgets(habit.id) - } - - override fun refresh() { - activity.refresh() - } - - override fun showHistoryEditorDialog(listener: OnDateClickedListener) { - val dialog = HistoryEditorDialog() - dialog.arguments = Bundle().apply { - putLong("habit", habit.id!!) - } - dialog.setOnDateClickedListener(listener) - dialog.show(activity.supportFragmentManager, "historyEditor") - } - - override fun touchFeedback() { - activity.window.decorView.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY) - } - - override fun showEditHabitScreen(habit: Habit) { - activity.startActivity(intentFactory.startEditActivity(activity, habit)) - } - - override fun showMessage(m: ShowHabitMenuBehavior.Message?) { - when (m) { - ShowHabitMenuBehavior.Message.COULD_NOT_EXPORT -> { - activity.showMessage(activity.resources.getString(R.string.could_not_export)) - } - } - } - - override fun showSendFileScreen(filename: String) { - activity.showSendFileScreen(filename) - } - - override fun showDeleteConfirmationScreen(callback: OnConfirmedCallback) { - confirmDeleteDialogFactory.create(callback, 1).show() - } - - override fun close() { - activity.finish() - } -} diff --git a/android/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/show/ShowHabitView.kt b/android/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/show/ShowHabitView.kt index 3b84db82f..a8591c96e 100644 --- a/android/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/show/ShowHabitView.kt +++ b/android/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/show/ShowHabitView.kt @@ -22,37 +22,29 @@ package org.isoron.uhabits.activities.habits.show import android.content.Context import android.view.LayoutInflater import android.widget.FrameLayout -import org.isoron.uhabits.core.ui.screens.habits.show.ShowHabitViewModel +import org.isoron.uhabits.core.ui.screens.habits.show.ShowHabitPresenter +import org.isoron.uhabits.core.ui.screens.habits.show.ShowHabitState import org.isoron.uhabits.databinding.ShowHabitBinding import org.isoron.uhabits.utils.setupToolbar class ShowHabitView(context: Context) : FrameLayout(context) { private val binding = ShowHabitBinding.inflate(LayoutInflater.from(context)) - var onScoreCardSpinnerPosition: (position: Int) -> Unit = {} - var onClickEditHistoryButton: () -> Unit = {} - var onBarCardBoolSpinnerPosition: (position: Int) -> Unit = {} - var onBarCardNumericalSpinnerPosition: (position: Int) -> Unit = {} - init { addView(binding.root) - binding.scoreCard.onSpinnerPosition = { onScoreCardSpinnerPosition(it) } - binding.historyCard.onClickEditButton = { onClickEditHistoryButton() } - binding.barCard.onBoolSpinnerPosition = { onBarCardBoolSpinnerPosition(it) } - binding.barCard.onNumericalSpinnerPosition = { onBarCardNumericalSpinnerPosition(it) } } - fun update(data: ShowHabitViewModel) { + fun setState(data: ShowHabitState) { setupToolbar(binding.toolbar, title = data.title, color = data.color) - binding.subtitleCard.update(data.subtitle) - binding.overviewCard.update(data.overview) - binding.notesCard.update(data.notes) - binding.targetCard.update(data.target) - binding.streakCard.update(data.streaks) - binding.scoreCard.update(data.scores) - binding.frequencyCard.update(data.frequency) - binding.historyCard.update(data.history) - binding.barCard.update(data.bar) + binding.subtitleCard.setState(data.subtitle) + binding.overviewCard.setState(data.overview) + binding.notesCard.setState(data.notes) + binding.targetCard.setState(data.target) + binding.streakCard.setState(data.streaks) + binding.scoreCard.setState(data.scores) + binding.frequencyCard.setState(data.frequency) + binding.historyCard.setState(data.history) + binding.barCard.setState(data.bar) if (data.isNumerical) { binding.overviewCard.visibility = GONE binding.streakCard.visibility = GONE @@ -60,4 +52,10 @@ class ShowHabitView(context: Context) : FrameLayout(context) { binding.targetCard.visibility = GONE } } + + fun setListener(presenter: ShowHabitPresenter) { + binding.scoreCard.setListener(presenter.scoreCardPresenter) + binding.historyCard.setListener(presenter.historyCardPresenter) + binding.barCard.setListener(presenter.barCardPresenter) + } } diff --git a/android/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/show/views/BarCardView.kt b/android/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/show/views/BarCardView.kt index dfac3233b..48d40d309 100644 --- a/android/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/show/views/BarCardView.kt +++ b/android/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/show/views/BarCardView.kt @@ -25,7 +25,8 @@ import android.view.View import android.widget.AdapterView import android.widget.LinearLayout import org.isoron.platform.time.JavaLocalDateFormatter -import org.isoron.uhabits.core.ui.screens.habits.show.views.BarCardViewModel +import org.isoron.uhabits.core.ui.screens.habits.show.views.BarCardPresenter +import org.isoron.uhabits.core.ui.screens.habits.show.views.BarCardState import org.isoron.uhabits.core.ui.views.BarChart import org.isoron.uhabits.databinding.ShowHabitBarBinding import org.isoron.uhabits.utils.toThemedAndroidColor @@ -34,57 +35,56 @@ import java.util.Locale class BarCardView(context: Context, attrs: AttributeSet) : LinearLayout(context, attrs) { private var binding = ShowHabitBarBinding.inflate(LayoutInflater.from(context), this) - var onNumericalSpinnerPosition: (position: Int) -> Unit = {} - var onBoolSpinnerPosition: (position: Int) -> Unit = {} - fun update(data: BarCardViewModel) { - val androidColor = data.color.toThemedAndroidColor(context) - binding.chart.view = BarChart(data.theme, JavaLocalDateFormatter(Locale.US)).apply { - series = mutableListOf(data.entries.map { it.value / 1000.0 }) - colors = mutableListOf(theme.color(data.color.paletteIndex)) - axis = data.entries.map { it.timestamp.toLocalDate() } + fun setState(state: BarCardState) { + val androidColor = state.color.toThemedAndroidColor(context) + binding.chart.view = BarChart(state.theme, JavaLocalDateFormatter(Locale.US)).apply { + series = mutableListOf(state.entries.map { it.value / 1000.0 }) + colors = mutableListOf(theme.color(state.color.paletteIndex)) + axis = state.entries.map { it.timestamp.toLocalDate() } } binding.chart.resetDataOffset() binding.chart.postInvalidate() binding.title.setTextColor(androidColor) - if (data.isNumerical) { + if (state.isNumerical) { binding.boolSpinner.visibility = GONE } else { binding.numericalSpinner.visibility = GONE } binding.numericalSpinner.onItemSelectedListener = null - binding.numericalSpinner.setSelection(data.numericalSpinnerPosition) - binding.numericalSpinner.onItemSelectedListener = - object : AdapterView.OnItemSelectedListener { - override fun onItemSelected( - parent: AdapterView<*>?, - view: View?, - position: Int, - id: Long - ) { - onNumericalSpinnerPosition(position) - } - - override fun onNothingSelected(parent: AdapterView<*>?) { - } - } + binding.numericalSpinner.setSelection(state.numericalSpinnerPosition) + binding.boolSpinner.setSelection(state.boolSpinnerPosition) + } - binding.boolSpinner.onItemSelectedListener = null - binding.boolSpinner.setSelection(data.boolSpinnerPosition) + fun setListener(presenter: BarCardPresenter) { binding.boolSpinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener { override fun onItemSelected( parent: AdapterView<*>?, view: View?, position: Int, - id: Long + id: Long, ) { - onBoolSpinnerPosition(position) + presenter.onBoolSpinnerPosition(position) } override fun onNothingSelected(parent: AdapterView<*>?) { } } + binding.numericalSpinner.onItemSelectedListener = + object : AdapterView.OnItemSelectedListener { + override fun onItemSelected( + parent: AdapterView<*>?, + view: View?, + position: Int, + id: Long, + ) { + presenter.onNumericalSpinnerPosition(position) + } + + override fun onNothingSelected(parent: AdapterView<*>?) { + } + } } } diff --git a/android/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/show/views/FrequencyCardView.kt b/android/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/show/views/FrequencyCardView.kt index 1e2568f10..abb4b22e1 100644 --- a/android/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/show/views/FrequencyCardView.kt +++ b/android/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/show/views/FrequencyCardView.kt @@ -22,7 +22,7 @@ import android.content.Context import android.util.AttributeSet import android.view.LayoutInflater import android.widget.LinearLayout -import org.isoron.uhabits.core.ui.screens.habits.show.views.FrequencyCardViewModel +import org.isoron.uhabits.core.ui.screens.habits.show.views.FrequencyCardState import org.isoron.uhabits.databinding.ShowHabitFrequencyBinding import org.isoron.uhabits.utils.toThemedAndroidColor @@ -30,10 +30,10 @@ class FrequencyCardView(context: Context, attrs: AttributeSet) : LinearLayout(co private var binding = ShowHabitFrequencyBinding.inflate(LayoutInflater.from(context), this) - fun update(data: FrequencyCardViewModel) { - val androidColor = data.color.toThemedAndroidColor(context) - binding.frequencyChart.setFrequency(data.frequency) - binding.frequencyChart.setFirstWeekday(data.firstWeekday) + fun setState(state: FrequencyCardState) { + val androidColor = state.color.toThemedAndroidColor(context) + binding.frequencyChart.setFrequency(state.frequency) + binding.frequencyChart.setFirstWeekday(state.firstWeekday) binding.title.setTextColor(androidColor) binding.frequencyChart.setColor(androidColor) } diff --git a/android/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/show/views/HistoryCardView.kt b/android/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/show/views/HistoryCardView.kt index 3f151049e..834f78d49 100644 --- a/android/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/show/views/HistoryCardView.kt +++ b/android/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/show/views/HistoryCardView.kt @@ -23,7 +23,8 @@ import android.util.AttributeSet import android.view.LayoutInflater import android.widget.LinearLayout import org.isoron.platform.time.JavaLocalDateFormatter -import org.isoron.uhabits.core.ui.screens.habits.show.views.HistoryCardViewModel +import org.isoron.uhabits.core.ui.screens.habits.show.views.HistoryCardPresenter +import org.isoron.uhabits.core.ui.screens.habits.show.views.HistoryCardState import org.isoron.uhabits.core.ui.views.HistoryChart import org.isoron.uhabits.databinding.ShowHabitHistoryBinding import org.isoron.uhabits.utils.toThemedAndroidColor @@ -33,23 +34,21 @@ class HistoryCardView(context: Context, attrs: AttributeSet) : LinearLayout(cont private var binding = ShowHabitHistoryBinding.inflate(LayoutInflater.from(context), this) - var onClickEditButton: () -> Unit = {} - - init { - binding.edit.setOnClickListener { onClickEditButton() } - } - - fun update(data: HistoryCardViewModel) { - val androidColor = data.color.toThemedAndroidColor(context) + fun setState(state: HistoryCardState) { + val androidColor = state.color.toThemedAndroidColor(context) binding.title.setTextColor(androidColor) binding.chart.view = HistoryChart( - today = data.today, - paletteColor = data.color, - theme = data.theme, + today = state.today, + paletteColor = state.color, + theme = state.theme, dateFormatter = JavaLocalDateFormatter(Locale.getDefault()), - series = data.series, - firstWeekday = data.firstWeekday, + series = state.series, + firstWeekday = state.firstWeekday, ) binding.chart.postInvalidate() } + + fun setListener(presenter: HistoryCardPresenter) { + binding.edit.setOnClickListener { presenter.onClickEditButton() } + } } diff --git a/android/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/show/views/NotesCardView.kt b/android/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/show/views/NotesCardView.kt index 788f92c75..6bd3b62bc 100644 --- a/android/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/show/views/NotesCardView.kt +++ b/android/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/show/views/NotesCardView.kt @@ -23,17 +23,17 @@ import android.content.Context import android.util.AttributeSet import android.view.LayoutInflater import android.widget.LinearLayout -import org.isoron.uhabits.core.ui.screens.habits.show.views.NotesCardViewModel +import org.isoron.uhabits.core.ui.screens.habits.show.views.NotesCardState import org.isoron.uhabits.databinding.ShowHabitNotesBinding class NotesCardView(context: Context, attrs: AttributeSet) : LinearLayout(context, attrs) { private val binding = ShowHabitNotesBinding.inflate(LayoutInflater.from(context), this) - fun update(data: NotesCardViewModel) { - if (data.description.isEmpty()) { + fun setState(state: NotesCardState) { + if (state.description.isEmpty()) { visibility = GONE } else { visibility = VISIBLE - binding.habitNotes.text = data.description + binding.habitNotes.text = state.description } invalidate() } diff --git a/android/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/show/views/OverviewCardView.kt b/android/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/show/views/OverviewCardView.kt index d57fe84ed..99b95c956 100644 --- a/android/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/show/views/OverviewCardView.kt +++ b/android/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/show/views/OverviewCardView.kt @@ -23,7 +23,7 @@ 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.OverviewCardViewModel +import org.isoron.uhabits.core.ui.screens.habits.show.views.OverviewCardState import org.isoron.uhabits.databinding.ShowHabitOverviewBinding import org.isoron.uhabits.utils.StyledResources import org.isoron.uhabits.utils.toThemedAndroidColor @@ -40,21 +40,21 @@ class OverviewCardView(context: Context, attrs: AttributeSet) : LinearLayout(con ) } - fun update(data: OverviewCardViewModel) { - val androidColor = data.color.toThemedAndroidColor(context) + fun setState(state: OverviewCardState) { + val androidColor = state.color.toThemedAndroidColor(context) val res = StyledResources(context) val inactiveColor = res.getColor(R.attr.mediumContrastTextColor) - binding.monthDiffLabel.setTextColor(if (data.scoreMonthDiff >= 0) androidColor else inactiveColor) - binding.monthDiffLabel.text = formatPercentageDiff(data.scoreMonthDiff) + binding.monthDiffLabel.setTextColor(if (state.scoreMonthDiff >= 0) androidColor else inactiveColor) + binding.monthDiffLabel.text = formatPercentageDiff(state.scoreMonthDiff) binding.scoreLabel.setTextColor(androidColor) - binding.scoreLabel.text = String.format("%.0f%%", data.scoreToday * 100) + binding.scoreLabel.text = String.format("%.0f%%", state.scoreToday * 100) binding.scoreRing.color = androidColor - binding.scoreRing.percentage = data.scoreToday + binding.scoreRing.percentage = state.scoreToday binding.title.setTextColor(androidColor) binding.totalCountLabel.setTextColor(androidColor) - binding.totalCountLabel.text = data.totalCount.toString() - binding.yearDiffLabel.setTextColor(if (data.scoreYearDiff >= 0) androidColor else inactiveColor) - binding.yearDiffLabel.text = formatPercentageDiff(data.scoreYearDiff) + binding.totalCountLabel.text = state.totalCount.toString() + binding.yearDiffLabel.setTextColor(if (state.scoreYearDiff >= 0) androidColor else inactiveColor) + binding.yearDiffLabel.text = formatPercentageDiff(state.scoreYearDiff) postInvalidate() } } diff --git a/android/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/show/views/ScoreCardView.kt b/android/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/show/views/ScoreCardView.kt index 0bc74b1d7..b71d5e27b 100644 --- a/android/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/show/views/ScoreCardView.kt +++ b/android/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/show/views/ScoreCardView.kt @@ -24,24 +24,25 @@ 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.core.ui.screens.habits.show.views.ScoreCardPresenter +import org.isoron.uhabits.core.ui.screens.habits.show.views.ScoreCardState 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) + fun setState(state: ScoreCardState) { + val androidColor = state.color.toThemedAndroidColor(context) binding.title.setTextColor(androidColor) - binding.spinner.setSelection(data.spinnerPosition) - binding.scoreView.setScores(data.scores) + binding.spinner.setSelection(state.spinnerPosition) + binding.scoreView.setScores(state.scores) binding.scoreView.reset() - binding.scoreView.setBucketSize(data.bucketSize) + binding.scoreView.setBucketSize(state.bucketSize) binding.scoreView.setColor(androidColor) + } + fun setListener(presenter: ScoreCardPresenter) { binding.spinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener { override fun onItemSelected( parent: AdapterView<*>?, @@ -49,7 +50,7 @@ class ScoreCardView(context: Context, attrs: AttributeSet) : LinearLayout(contex position: Int, id: Long ) { - onSpinnerPosition(position) + presenter.onSpinnerPosition(position) } override fun onNothingSelected(parent: AdapterView<*>?) { diff --git a/android/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/show/views/StreakCardView.kt b/android/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/show/views/StreakCardView.kt index baa18f0fa..ff96ee674 100644 --- a/android/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/show/views/StreakCardView.kt +++ b/android/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/show/views/StreakCardView.kt @@ -22,17 +22,17 @@ import android.content.Context import android.util.AttributeSet import android.view.LayoutInflater import android.widget.LinearLayout -import org.isoron.uhabits.core.ui.screens.habits.show.views.StreakCardViewModel +import org.isoron.uhabits.core.ui.screens.habits.show.views.StreakCardState import org.isoron.uhabits.databinding.ShowHabitStreakBinding import org.isoron.uhabits.utils.toThemedAndroidColor class StreakCardView(context: Context, attrs: AttributeSet) : LinearLayout(context, attrs) { private val binding = ShowHabitStreakBinding.inflate(LayoutInflater.from(context), this) - fun update(data: StreakCardViewModel) { - val color = data.color.toThemedAndroidColor(context) + fun setState(state: StreakCardState) { + val color = state.color.toThemedAndroidColor(context) binding.title.setTextColor(color) binding.streakChart.setColor(color) - binding.streakChart.setStreaks(data.bestStreaks) + binding.streakChart.setStreaks(state.bestStreaks) postInvalidate() } } diff --git a/android/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/show/views/SubtitleCardView.kt b/android/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/show/views/SubtitleCardView.kt index 2cc143fa0..5af86bb41 100644 --- a/android/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/show/views/SubtitleCardView.kt +++ b/android/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/show/views/SubtitleCardView.kt @@ -28,7 +28,7 @@ import android.widget.LinearLayout import org.isoron.uhabits.R import org.isoron.uhabits.activities.habits.list.views.toShortString import org.isoron.uhabits.core.models.Frequency -import org.isoron.uhabits.core.ui.screens.habits.show.views.SubtitleCardViewModel +import org.isoron.uhabits.core.ui.screens.habits.show.views.SubtitleCardState import org.isoron.uhabits.databinding.ShowHabitSubtitleBinding import org.isoron.uhabits.utils.InterfaceUtils import org.isoron.uhabits.utils.formatTime @@ -47,27 +47,27 @@ class SubtitleCardView(context: Context, attrs: AttributeSet) : LinearLayout(con } @SuppressLint("SetTextI18n") - fun update(data: SubtitleCardViewModel) { - val color = data.color.toThemedAndroidColor(context) - val reminder = data.reminder - binding.frequencyLabel.text = data.frequency.format(resources) + fun setState(state: SubtitleCardState) { + val color = state.color.toThemedAndroidColor(context) + val reminder = state.reminder + binding.frequencyLabel.text = state.frequency.format(resources) binding.questionLabel.setTextColor(color) - binding.questionLabel.text = data.question + binding.questionLabel.text = state.question binding.reminderLabel.text = if (reminder != null) { formatTime(context, reminder.hour, reminder.minute) } else { resources.getString(R.string.reminder_off) } - binding.targetText.text = "${data.targetValue.toShortString()} ${data.unit}" + binding.targetText.text = "${state.targetValue.toShortString()} ${state.unit}" binding.questionLabel.visibility = View.VISIBLE binding.targetIcon.visibility = View.VISIBLE binding.targetText.visibility = View.VISIBLE - if (!data.isNumerical) { + if (!state.isNumerical) { binding.targetIcon.visibility = View.GONE binding.targetText.visibility = View.GONE } - if (data.question.isEmpty()) { + if (state.question.isEmpty()) { binding.questionLabel.visibility = View.GONE } diff --git a/android/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/show/views/TargetCardView.kt b/android/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/show/views/TargetCardView.kt index 2dd02022b..fdf5fae83 100644 --- a/android/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/show/views/TargetCardView.kt +++ b/android/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/show/views/TargetCardView.kt @@ -24,17 +24,17 @@ 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.core.ui.screens.habits.show.views.TargetCardState 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) }) + fun setState(state: TargetCardState) { + val androidColor = state.color.toThemedAndroidColor(context) + binding.targetChart.setValues(state.values) + binding.targetChart.setTargets(state.targets) + binding.targetChart.setLabels(state.intervals.map { intervalToLabel(resources, it) }) binding.title.setTextColor(androidColor) binding.targetChart.setColor(androidColor) postInvalidate() diff --git a/android/uhabits-android/src/main/java/org/isoron/uhabits/widgets/HistoryWidget.kt b/android/uhabits-android/src/main/java/org/isoron/uhabits/widgets/HistoryWidget.kt index 0216d7c5d..22d099090 100644 --- a/android/uhabits-android/src/main/java/org/isoron/uhabits/widgets/HistoryWidget.kt +++ b/android/uhabits-android/src/main/java/org/isoron/uhabits/widgets/HistoryWidget.kt @@ -46,9 +46,8 @@ class HistoryWidget( val widgetView = view as GraphWidgetView widgetView.setBackgroundAlpha(preferedBackgroundAlpha) if (preferedBackgroundAlpha >= 255) widgetView.setShadowAlpha(0x4f) - val model = HistoryCardPresenter().present( + val model = HistoryCardPresenter.buildState( habit = habit, - isSkipEnabled = prefs.isSkipEnabled, firstWeekday = prefs.firstWeekday, theme = WidgetTheme(), ) diff --git a/android/uhabits-android/src/main/java/org/isoron/uhabits/widgets/ScoreWidget.kt b/android/uhabits-android/src/main/java/org/isoron/uhabits/widgets/ScoreWidget.kt index 2a66ad8ad..a86d1d9d1 100644 --- a/android/uhabits-android/src/main/java/org/isoron/uhabits/widgets/ScoreWidget.kt +++ b/android/uhabits-android/src/main/java/org/isoron/uhabits/widgets/ScoreWidget.kt @@ -37,8 +37,7 @@ class ScoreWidget( pendingIntentFactory.showHabit(habit) override fun refreshData(view: View) { - val presenter = ScoreCardPresenter() - val viewModel = presenter.present( + val viewModel = ScoreCardPresenter.buildState( habit = habit, firstWeekday = prefs.firstWeekdayInt, spinnerPosition = prefs.scoreCardSpinnerPosition diff --git a/android/uhabits-android/src/main/java/org/isoron/uhabits/widgets/TargetWidget.kt b/android/uhabits-android/src/main/java/org/isoron/uhabits/widgets/TargetWidget.kt index bbda50005..c13ef4d10 100644 --- a/android/uhabits-android/src/main/java/org/isoron/uhabits/widgets/TargetWidget.kt +++ b/android/uhabits-android/src/main/java/org/isoron/uhabits/widgets/TargetWidget.kt @@ -45,8 +45,7 @@ class TargetWidget( widgetView.setBackgroundAlpha(preferedBackgroundAlpha) if (preferedBackgroundAlpha >= 255) widgetView.setShadowAlpha(0x4f) val chart = (widgetView.dataView as TargetChart) - val presenter = TargetCardPresenter() - val data = presenter.present(habit, prefs.firstWeekdayInt) + val data = TargetCardPresenter.buildState(habit, prefs.firstWeekdayInt) chart.setColor(data.color.toThemedAndroidColor(context)) chart.setTargets(data.targets) chart.setLabels(data.intervals.map { intervalToLabel(context.resources, it) }) diff --git a/android/uhabits-core/src/main/java/org/isoron/uhabits/core/ui/screens/habits/show/ShowHabit.kt b/android/uhabits-core/src/main/java/org/isoron/uhabits/core/ui/screens/habits/show/ShowHabit.kt index de0c1c37e..4156021af 100644 --- a/android/uhabits-core/src/main/java/org/isoron/uhabits/core/ui/screens/habits/show/ShowHabit.kt +++ b/android/uhabits-core/src/main/java/org/isoron/uhabits/core/ui/screens/habits/show/ShowHabit.kt @@ -19,92 +19,124 @@ package org.isoron.uhabits.core.ui.screens.habits.show +import org.isoron.uhabits.core.commands.CommandRunner import org.isoron.uhabits.core.models.Habit +import org.isoron.uhabits.core.models.HabitList 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.BarCardState 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.FrequencyCardState 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.HistoryCardState 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.NotesCardState 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.OverviewCardState 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.ScoreCardState +import org.isoron.uhabits.core.ui.screens.habits.show.views.StreakCardState 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.SubtitleCardState import org.isoron.uhabits.core.ui.screens.habits.show.views.TargetCardPresenter -import org.isoron.uhabits.core.ui.screens.habits.show.views.TargetCardViewModel +import org.isoron.uhabits.core.ui.screens.habits.show.views.TargetCardState import org.isoron.uhabits.core.ui.views.Theme -data class ShowHabitViewModel( +data class ShowHabitState( 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, + val subtitle: SubtitleCardState, + val overview: OverviewCardState, + val notes: NotesCardState, + val target: TargetCardState, + val streaks: StreakCardState, + val scores: ScoreCardState, + val frequency: FrequencyCardState, + val history: HistoryCardState, + val bar: BarCardState, ) -class ShowHabitPresenter { - fun present( - habit: Habit, - preferences: Preferences, - theme: Theme, - ): 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.firstWeekdayInt, - ), - streaks = StreakCartPresenter().present( - habit = habit, - ), - scores = ScoreCardPresenter().present( - spinnerPosition = preferences.scoreCardSpinnerPosition, - habit = habit, - firstWeekday = preferences.firstWeekdayInt, - ), - frequency = FrequencyCardPresenter().present( - habit = habit, - firstWeekday = preferences.firstWeekdayInt, - ), - history = HistoryCardPresenter().present( - habit = habit, - firstWeekday = preferences.firstWeekday, - isSkipEnabled = preferences.isSkipEnabled, - theme = theme, - ), - bar = BarCardPresenter().present( - habit = habit, - firstWeekday = preferences.firstWeekdayInt, - boolSpinnerPosition = preferences.barCardBoolSpinnerPosition, - numericalSpinnerPosition = preferences.barCardNumericalSpinnerPosition, - theme = theme, - ), - ) +class ShowHabitPresenter( + val habit: Habit, + val habitList: HabitList, + val preferences: Preferences, + val screen: Screen, + val commandRunner: CommandRunner, +) { + val historyCardPresenter = HistoryCardPresenter( + commandRunner = commandRunner, + habit = habit, + habitList = habitList, + preferences = preferences, + screen = screen, + ) + + val barCardPresenter = BarCardPresenter( + preferences = preferences, + screen = screen, + ) + + val scoreCardPresenter = ScoreCardPresenter( + preferences = preferences, + screen = screen, + ) + + companion object { + fun buildState( + habit: Habit, + preferences: Preferences, + theme: Theme, + ): ShowHabitState { + return ShowHabitState( + title = habit.name, + color = habit.color, + isNumerical = habit.isNumerical, + subtitle = SubtitleCardPresenter.buildState( + habit = habit, + ), + overview = OverviewCardPresenter.buildState( + habit = habit, + ), + notes = NotesCardPresenter.buildState( + habit = habit, + ), + target = TargetCardPresenter.buildState( + habit = habit, + firstWeekday = preferences.firstWeekdayInt, + ), + streaks = StreakCartPresenter.buildState( + habit = habit, + ), + scores = ScoreCardPresenter.buildState( + spinnerPosition = preferences.scoreCardSpinnerPosition, + habit = habit, + firstWeekday = preferences.firstWeekdayInt, + ), + frequency = FrequencyCardPresenter.buildState( + habit = habit, + firstWeekday = preferences.firstWeekdayInt, + ), + history = HistoryCardPresenter.buildState( + habit = habit, + firstWeekday = preferences.firstWeekday, + theme = theme, + ), + bar = BarCardPresenter.buildState( + habit = habit, + firstWeekday = preferences.firstWeekdayInt, + boolSpinnerPosition = preferences.barCardBoolSpinnerPosition, + numericalSpinnerPosition = preferences.barCardNumericalSpinnerPosition, + theme = theme, + ), + ) + } } + + interface Screen : + BarCardPresenter.Screen, + ScoreCardPresenter.Screen, + HistoryCardPresenter.Screen } diff --git a/android/uhabits-core/src/main/java/org/isoron/uhabits/core/ui/screens/habits/show/ShowHabitBehavior.kt b/android/uhabits-core/src/main/java/org/isoron/uhabits/core/ui/screens/habits/show/ShowHabitBehavior.kt deleted file mode 100644 index 420c40553..000000000 --- a/android/uhabits-core/src/main/java/org/isoron/uhabits/core/ui/screens/habits/show/ShowHabitBehavior.kt +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright (C) 2017 Álinson Santos Xavier - * - * 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 . - */ -package org.isoron.uhabits.core.ui.screens.habits.show - -import org.isoron.platform.time.LocalDate -import org.isoron.uhabits.core.commands.CommandRunner -import org.isoron.uhabits.core.commands.CreateRepetitionCommand -import org.isoron.uhabits.core.models.Entry -import org.isoron.uhabits.core.models.Habit -import org.isoron.uhabits.core.models.HabitList -import org.isoron.uhabits.core.preferences.Preferences -import org.isoron.uhabits.core.ui.screens.habits.list.ListHabitsBehavior -import org.isoron.uhabits.core.ui.views.OnDateClickedListener -import kotlin.math.roundToInt - -class ShowHabitBehavior( - private val habitList: HabitList, - private val commandRunner: CommandRunner, - private val habit: Habit, - private val screen: Screen, - private val preferences: Preferences, -) : OnDateClickedListener { - - fun onScoreCardSpinnerPosition(position: Int) { - preferences.scoreCardSpinnerPosition = position - screen.updateWidgets() - screen.refresh() - } - - fun onBarCardBoolSpinnerPosition(position: Int) { - preferences.barCardBoolSpinnerPosition = position - screen.updateWidgets() - screen.refresh() - } - - fun onBarCardNumericalSpinnerPosition(position: Int) { - preferences.barCardNumericalSpinnerPosition = position - screen.refresh() - screen.updateWidgets() - } - - fun onClickEditHistory() { - screen.showHistoryEditorDialog(this) - } - - override fun onDateClicked(date: LocalDate) { - val timestamp = date.timestamp - screen.touchFeedback() - if (habit.isNumerical) { - val entries = habit.computedEntries - val oldValue = entries.get(timestamp).value - screen.showNumberPicker(oldValue / 1000.0, habit.unit) { newValue: Double -> - val thousands = (newValue * 1000).roundToInt() - commandRunner.run( - CreateRepetitionCommand( - habitList, - habit, - timestamp, - thousands, - ), - ) - } - } else { - val currentValue = habit.computedEntries.get(timestamp).value - val nextValue = if (preferences.isSkipEnabled) { - Entry.nextToggleValueWithSkip(currentValue) - } else { - Entry.nextToggleValueWithoutSkip(currentValue) - } - commandRunner.run( - CreateRepetitionCommand( - habitList, - habit, - timestamp, - nextValue, - ), - ) - } - } - - interface Screen { - fun showNumberPicker( - value: Double, - unit: String, - callback: ListHabitsBehavior.NumberPickerCallback, - ) - - fun updateWidgets() - fun refresh() - fun showHistoryEditorDialog(listener: OnDateClickedListener) - fun touchFeedback() - } -} diff --git a/android/uhabits-core/src/main/java/org/isoron/uhabits/core/ui/screens/habits/show/ShowHabitMenuBehavior.kt b/android/uhabits-core/src/main/java/org/isoron/uhabits/core/ui/screens/habits/show/ShowHabitMenuPresenter.kt similarity index 96% rename from android/uhabits-core/src/main/java/org/isoron/uhabits/core/ui/screens/habits/show/ShowHabitMenuBehavior.kt rename to android/uhabits-core/src/main/java/org/isoron/uhabits/core/ui/screens/habits/show/ShowHabitMenuPresenter.kt index 0bb43f797..2668df77b 100644 --- a/android/uhabits-core/src/main/java/org/isoron/uhabits/core/ui/screens/habits/show/ShowHabitMenuBehavior.kt +++ b/android/uhabits-core/src/main/java/org/isoron/uhabits/core/ui/screens/habits/show/ShowHabitMenuPresenter.kt @@ -30,7 +30,7 @@ import org.isoron.uhabits.core.utils.DateUtils import java.io.File import java.util.Random -class ShowHabitMenuBehavior( +class ShowHabitMenuPresenter( private val commandRunner: CommandRunner, private val habit: Habit, private val habitList: HabitList, @@ -85,9 +85,7 @@ class ShowHabitMenuBehavior( fun showEditHabitScreen(habit: Habit) fun showMessage(m: Message?) fun showSendFileScreen(filename: String) - fun showDeleteConfirmationScreen( - callback: OnConfirmedCallback - ) + fun showDeleteConfirmationScreen(callback: OnConfirmedCallback) fun close() fun refresh() } diff --git a/android/uhabits-core/src/main/java/org/isoron/uhabits/core/ui/screens/habits/show/views/BarCard.kt b/android/uhabits-core/src/main/java/org/isoron/uhabits/core/ui/screens/habits/show/views/BarCard.kt index 1abad408d..ddf945b2f 100644 --- a/android/uhabits-core/src/main/java/org/isoron/uhabits/core/ui/screens/habits/show/views/BarCard.kt +++ b/android/uhabits-core/src/main/java/org/isoron/uhabits/core/ui/screens/habits/show/views/BarCard.kt @@ -23,10 +23,11 @@ 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.preferences.Preferences import org.isoron.uhabits.core.ui.views.Theme import org.isoron.uhabits.core.utils.DateUtils -data class BarCardViewModel( +data class BarCardState( val theme: Theme, val boolSpinnerPosition: Int, val bucketSize: Int, @@ -36,37 +37,59 @@ data class BarCardViewModel( val numericalSpinnerPosition: Int, ) -class BarCardPresenter { - val numericalBucketSizes = intArrayOf(1, 7, 31, 92, 365) - val boolBucketSizes = intArrayOf(7, 31, 92, 365) +class BarCardPresenter( + val preferences: Preferences, + val screen: Screen, +) { + companion object { + 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, - theme: Theme, - ): BarCardViewModel { - val bucketSize = if (habit.isNumerical) { - numericalBucketSizes[numericalSpinnerPosition] - } else { - boolBucketSizes[boolSpinnerPosition] + fun buildState( + habit: Habit, + firstWeekday: Int, + numericalSpinnerPosition: Int, + boolSpinnerPosition: Int, + theme: Theme, + ): BarCardState { + 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 BarCardState( + theme = theme, + entries = entries, + bucketSize = bucketSize, + color = habit.color, + isNumerical = habit.isNumerical, + numericalSpinnerPosition = numericalSpinnerPosition, + boolSpinnerPosition = 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( - theme = theme, - entries = entries, - bucketSize = bucketSize, - color = habit.color, - isNumerical = habit.isNumerical, - numericalSpinnerPosition = numericalSpinnerPosition, - boolSpinnerPosition = boolSpinnerPosition, - ) + } + + fun onNumericalSpinnerPosition(position: Int) { + preferences.barCardNumericalSpinnerPosition = position + screen.updateWidgets() + screen.refresh() + } + + fun onBoolSpinnerPosition(position: Int) { + preferences.barCardBoolSpinnerPosition = position + screen.updateWidgets() + screen.refresh() + } + + interface Screen { + fun updateWidgets() + fun refresh() } } diff --git a/android/uhabits-core/src/main/java/org/isoron/uhabits/core/ui/screens/habits/show/views/FrequencyCard.kt b/android/uhabits-core/src/main/java/org/isoron/uhabits/core/ui/screens/habits/show/views/FrequencyCard.kt index 85e319a24..667819c19 100644 --- a/android/uhabits-core/src/main/java/org/isoron/uhabits/core/ui/screens/habits/show/views/FrequencyCard.kt +++ b/android/uhabits-core/src/main/java/org/isoron/uhabits/core/ui/screens/habits/show/views/FrequencyCard.kt @@ -24,21 +24,23 @@ import org.isoron.uhabits.core.models.PaletteColor import org.isoron.uhabits.core.models.Timestamp import java.util.HashMap -data class FrequencyCardViewModel( +data class FrequencyCardState( val color: PaletteColor, val firstWeekday: Int, val frequency: HashMap>, ) class FrequencyCardPresenter { - fun present( - habit: Habit, - firstWeekday: Int, - ) = FrequencyCardViewModel( - color = habit.color, - frequency = habit.originalEntries.computeWeekdayFrequency( - isNumerical = habit.isNumerical - ), - firstWeekday = firstWeekday, - ) + companion object { + fun buildState( + habit: Habit, + firstWeekday: Int, + ) = FrequencyCardState( + color = habit.color, + frequency = habit.originalEntries.computeWeekdayFrequency( + isNumerical = habit.isNumerical + ), + firstWeekday = firstWeekday, + ) + } } diff --git a/android/uhabits-core/src/main/java/org/isoron/uhabits/core/ui/screens/habits/show/views/HistoryCard.kt b/android/uhabits-core/src/main/java/org/isoron/uhabits/core/ui/screens/habits/show/views/HistoryCard.kt index 6f7b8d6b0..6efe24e51 100644 --- a/android/uhabits-core/src/main/java/org/isoron/uhabits/core/ui/screens/habits/show/views/HistoryCard.kt +++ b/android/uhabits-core/src/main/java/org/isoron/uhabits/core/ui/screens/habits/show/views/HistoryCard.kt @@ -21,18 +21,25 @@ package org.isoron.uhabits.core.ui.screens.habits.show.views import org.isoron.platform.time.DayOfWeek import org.isoron.platform.time.LocalDate +import org.isoron.uhabits.core.commands.CommandRunner +import org.isoron.uhabits.core.commands.CreateRepetitionCommand import org.isoron.uhabits.core.models.Entry import org.isoron.uhabits.core.models.Entry.Companion.SKIP import org.isoron.uhabits.core.models.Entry.Companion.YES_AUTO import org.isoron.uhabits.core.models.Entry.Companion.YES_MANUAL import org.isoron.uhabits.core.models.Habit +import org.isoron.uhabits.core.models.HabitList import org.isoron.uhabits.core.models.PaletteColor +import org.isoron.uhabits.core.preferences.Preferences +import org.isoron.uhabits.core.ui.screens.habits.list.ListHabitsBehavior import org.isoron.uhabits.core.ui.views.HistoryChart +import org.isoron.uhabits.core.ui.views.OnDateClickedListener import org.isoron.uhabits.core.ui.views.Theme import org.isoron.uhabits.core.utils.DateUtils import kotlin.math.max +import kotlin.math.roundToInt -data class HistoryCardViewModel( +data class HistoryCardState( val color: PaletteColor, val firstWeekday: DayOfWeek, val series: List, @@ -40,42 +47,99 @@ data class HistoryCardViewModel( val today: LocalDate, ) -class HistoryCardPresenter { - fun present( - habit: Habit, - firstWeekday: DayOfWeek, - isSkipEnabled: Boolean, - theme: Theme, - ): HistoryCardViewModel { - val today = DateUtils.getTodayWithOffset() - val oldest = habit.computedEntries.getKnown().lastOrNull()?.timestamp ?: today - val entries = habit.computedEntries.getByInterval(oldest, today) - val series = if (habit.isNumerical) { - entries.map { - Entry(it.timestamp, max(0, it.value)) - }.map { - when (it.value) { - 0 -> HistoryChart.Square.OFF - else -> HistoryChart.Square.ON - } +class HistoryCardPresenter( + val commandRunner: CommandRunner, + val habit: Habit, + val habitList: HabitList, + val preferences: Preferences, + val screen: Screen, +) : OnDateClickedListener { + + override fun onDateClicked(date: LocalDate) { + val timestamp = date.timestamp + screen.showFeedback() + if (habit.isNumerical) { + val entries = habit.computedEntries + val oldValue = entries.get(timestamp).value + screen.showNumberPicker(oldValue / 1000.0, habit.unit) { newValue: Double -> + val thousands = (newValue * 1000).roundToInt() + commandRunner.run( + CreateRepetitionCommand( + habitList, + habit, + timestamp, + thousands, + ), + ) } } else { - entries.map { - when (it.value) { - YES_MANUAL -> HistoryChart.Square.ON - YES_AUTO -> HistoryChart.Square.DIMMED - SKIP -> HistoryChart.Square.HATCHED - else -> HistoryChart.Square.OFF + val currentValue = habit.computedEntries.get(timestamp).value + val nextValue = if (preferences.isSkipEnabled) { + Entry.nextToggleValueWithSkip(currentValue) + } else { + Entry.nextToggleValueWithoutSkip(currentValue) + } + commandRunner.run( + CreateRepetitionCommand( + habitList, + habit, + timestamp, + nextValue, + ), + ) + } + } + + fun onClickEditButton() { + screen.showHistoryEditorDialog(this) + } + + companion object { + fun buildState( + habit: Habit, + firstWeekday: DayOfWeek, + theme: Theme, + ): HistoryCardState { + val today = DateUtils.getTodayWithOffset() + val oldest = habit.computedEntries.getKnown().lastOrNull()?.timestamp ?: today + val entries = habit.computedEntries.getByInterval(oldest, today) + val series = if (habit.isNumerical) { + entries.map { + Entry(it.timestamp, max(0, it.value)) + }.map { + when (it.value) { + 0 -> HistoryChart.Square.OFF + else -> HistoryChart.Square.ON + } + } + } else { + entries.map { + when (it.value) { + YES_MANUAL -> HistoryChart.Square.ON + YES_AUTO -> HistoryChart.Square.DIMMED + SKIP -> HistoryChart.Square.HATCHED + else -> HistoryChart.Square.OFF + } } } + + return HistoryCardState( + color = habit.color, + firstWeekday = firstWeekday, + today = today.toLocalDate(), + theme = theme, + series = series, + ) } + } - return HistoryCardViewModel( - color = habit.color, - firstWeekday = firstWeekday, - today = today.toLocalDate(), - theme = theme, - series = series, + interface Screen { + fun showHistoryEditorDialog(listener: OnDateClickedListener) + fun showFeedback() + fun showNumberPicker( + value: Double, + unit: String, + callback: ListHabitsBehavior.NumberPickerCallback, ) } } diff --git a/android/uhabits-core/src/main/java/org/isoron/uhabits/core/ui/screens/habits/show/views/NotesCard.kt b/android/uhabits-core/src/main/java/org/isoron/uhabits/core/ui/screens/habits/show/views/NotesCard.kt index b210f7ec7..8d2a25836 100644 --- a/android/uhabits-core/src/main/java/org/isoron/uhabits/core/ui/screens/habits/show/views/NotesCard.kt +++ b/android/uhabits-core/src/main/java/org/isoron/uhabits/core/ui/screens/habits/show/views/NotesCard.kt @@ -21,12 +21,14 @@ package org.isoron.uhabits.core.ui.screens.habits.show.views import org.isoron.uhabits.core.models.Habit -data class NotesCardViewModel( +data class NotesCardState( val description: String, ) class NotesCardPresenter { - fun present(habit: Habit) = NotesCardViewModel( - description = habit.description, - ) + companion object { + fun buildState(habit: Habit) = NotesCardState( + description = habit.description, + ) + } } diff --git a/android/uhabits-core/src/main/java/org/isoron/uhabits/core/ui/screens/habits/show/views/OverviewCard.kt b/android/uhabits-core/src/main/java/org/isoron/uhabits/core/ui/screens/habits/show/views/OverviewCard.kt index d37c520c4..9469132cf 100644 --- a/android/uhabits-core/src/main/java/org/isoron/uhabits/core/ui/screens/habits/show/views/OverviewCard.kt +++ b/android/uhabits-core/src/main/java/org/isoron/uhabits/core/ui/screens/habits/show/views/OverviewCard.kt @@ -24,7 +24,7 @@ import org.isoron.uhabits.core.models.Habit import org.isoron.uhabits.core.models.PaletteColor import org.isoron.uhabits.core.utils.DateUtils -data class OverviewCardViewModel( +data class OverviewCardState( val color: PaletteColor, val scoreMonthDiff: Float, val scoreYearDiff: Float, @@ -33,24 +33,26 @@ data class OverviewCardViewModel( ) 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, - ) + companion object { + fun buildState(habit: Habit): OverviewCardState { + 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 OverviewCardState( + color = habit.color, + scoreToday = scoreToday, + scoreMonthDiff = scoreToday - scoreLastMonth, + scoreYearDiff = scoreToday - scoreLastYear, + totalCount = totalCount, + ) + } } } diff --git a/android/uhabits-core/src/main/java/org/isoron/uhabits/core/ui/screens/habits/show/views/ScoreCard.kt b/android/uhabits-core/src/main/java/org/isoron/uhabits/core/ui/screens/habits/show/views/ScoreCard.kt index 5813e7c28..8267b45de 100644 --- a/android/uhabits-core/src/main/java/org/isoron/uhabits/core/ui/screens/habits/show/views/ScoreCard.kt +++ b/android/uhabits-core/src/main/java/org/isoron/uhabits/core/ui/screens/habits/show/views/ScoreCard.kt @@ -22,16 +22,20 @@ 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.preferences.Preferences import org.isoron.uhabits.core.utils.DateUtils -data class ScoreCardViewModel( +data class ScoreCardState( val scores: List, val bucketSize: Int, val spinnerPosition: Int, val color: PaletteColor, ) -class ScoreCardPresenter { +class ScoreCardPresenter( + val preferences: Preferences, + val screen: Screen, +) { companion object { val BUCKET_SIZES = intArrayOf(1, 7, 31, 92, 365) fun getTruncateField(bucketSize: Int): DateUtils.TruncateField { @@ -44,36 +48,47 @@ class ScoreCardPresenter { 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 + fun buildState( + habit: Habit, + firstWeekday: Int, + spinnerPosition: Int, + ): ScoreCardState { + 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() - 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() + return ScoreCardState( + color = habit.color, + scores = scores, + bucketSize = bucketSize, + spinnerPosition = spinnerPosition, ) - }.sortedBy { - it.timestamp - }.reversed() + } + } + + fun onSpinnerPosition(position: Int) { + preferences.scoreCardSpinnerPosition = position + screen.updateWidgets() + screen.refresh() + } - return ScoreCardViewModel( - color = habit.color, - scores = scores, - bucketSize = bucketSize, - spinnerPosition = spinnerPosition, - ) + interface Screen { + fun updateWidgets() + fun refresh() } } diff --git a/android/uhabits-core/src/main/java/org/isoron/uhabits/core/ui/screens/habits/show/views/StreakCart.kt b/android/uhabits-core/src/main/java/org/isoron/uhabits/core/ui/screens/habits/show/views/StreakCart.kt index 381da43ee..ca897e3c5 100644 --- a/android/uhabits-core/src/main/java/org/isoron/uhabits/core/ui/screens/habits/show/views/StreakCart.kt +++ b/android/uhabits-core/src/main/java/org/isoron/uhabits/core/ui/screens/habits/show/views/StreakCart.kt @@ -23,16 +23,18 @@ import org.isoron.uhabits.core.models.Habit import org.isoron.uhabits.core.models.PaletteColor import org.isoron.uhabits.core.models.Streak -data class StreakCardViewModel( +data class StreakCardState( val color: PaletteColor, val bestStreaks: List ) class StreakCartPresenter { - fun present(habit: Habit): StreakCardViewModel { - return StreakCardViewModel( - color = habit.color, - bestStreaks = habit.streaks.getBest(10), - ) + companion object { + fun buildState(habit: Habit): StreakCardState { + return StreakCardState( + color = habit.color, + bestStreaks = habit.streaks.getBest(10), + ) + } } } diff --git a/android/uhabits-core/src/main/java/org/isoron/uhabits/core/ui/screens/habits/show/views/SubtitleCard.kt b/android/uhabits-core/src/main/java/org/isoron/uhabits/core/ui/screens/habits/show/views/SubtitleCard.kt index f39d78fae..8c71711d2 100644 --- a/android/uhabits-core/src/main/java/org/isoron/uhabits/core/ui/screens/habits/show/views/SubtitleCard.kt +++ b/android/uhabits-core/src/main/java/org/isoron/uhabits/core/ui/screens/habits/show/views/SubtitleCard.kt @@ -24,7 +24,7 @@ import org.isoron.uhabits.core.models.Habit import org.isoron.uhabits.core.models.PaletteColor import org.isoron.uhabits.core.models.Reminder -data class SubtitleCardViewModel( +data class SubtitleCardState( val color: PaletteColor, val frequency: Frequency, val isNumerical: Boolean, @@ -35,15 +35,17 @@ data class SubtitleCardViewModel( ) 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, - ) + companion object { + fun buildState( + habit: Habit, + ): SubtitleCardState = SubtitleCardState( + color = habit.color, + frequency = habit.frequency, + isNumerical = habit.isNumerical, + question = habit.question, + reminder = habit.reminder, + targetValue = habit.targetValue, + unit = habit.unit, + ) + } } diff --git a/android/uhabits-core/src/main/java/org/isoron/uhabits/core/ui/screens/habits/show/views/TargetCard.kt b/android/uhabits-core/src/main/java/org/isoron/uhabits/core/ui/screens/habits/show/views/TargetCard.kt index 6e6ac81c1..49dce8c63 100644 --- a/android/uhabits-core/src/main/java/org/isoron/uhabits/core/ui/screens/habits/show/views/TargetCard.kt +++ b/android/uhabits-core/src/main/java/org/isoron/uhabits/core/ui/screens/habits/show/views/TargetCard.kt @@ -26,7 +26,7 @@ import org.isoron.uhabits.core.utils.DateUtils import java.util.ArrayList import java.util.Calendar -data class TargetCardViewModel( +data class TargetCardState( val color: PaletteColor, val values: List = listOf(), val targets: List = listOf(), @@ -34,77 +34,79 @@ data class TargetCardViewModel( ) class TargetCardPresenter { - fun present( - habit: Habit, - firstWeekday: Int, - ): TargetCardViewModel { - val today = DateUtils.getTodayWithOffset() - val oldest = habit.computedEntries.getKnown().lastOrNull()?.timestamp ?: today - val entries = habit.computedEntries.getByInterval(oldest, today) + companion object { + fun buildState( + habit: Habit, + firstWeekday: Int, + ): TargetCardState { + val today = DateUtils.getTodayWithOffset() + val oldest = habit.computedEntries.getKnown().lastOrNull()?.timestamp ?: today + val entries = habit.computedEntries.getByInterval(oldest, today) - val valueToday = entries.groupedSum( - truncateField = DateUtils.TruncateField.DAY, - isNumerical = habit.isNumerical - ).firstOrNull()?.value ?: 0 + val valueToday = entries.groupedSum( + truncateField = DateUtils.TruncateField.DAY, + isNumerical = habit.isNumerical + ).firstOrNull()?.value ?: 0 - val valueThisWeek = entries.groupedSum( - truncateField = DateUtils.TruncateField.WEEK_NUMBER, - firstWeekday = firstWeekday, - isNumerical = habit.isNumerical - ).firstOrNull()?.value ?: 0 + val valueThisWeek = entries.groupedSum( + truncateField = DateUtils.TruncateField.WEEK_NUMBER, + firstWeekday = firstWeekday, + isNumerical = habit.isNumerical + ).firstOrNull()?.value ?: 0 - val valueThisMonth = entries.groupedSum( - truncateField = DateUtils.TruncateField.MONTH, - isNumerical = habit.isNumerical - ).firstOrNull()?.value ?: 0 + val valueThisMonth = entries.groupedSum( + truncateField = DateUtils.TruncateField.MONTH, + isNumerical = habit.isNumerical + ).firstOrNull()?.value ?: 0 - val valueThisQuarter = entries.groupedSum( - truncateField = DateUtils.TruncateField.QUARTER, - isNumerical = habit.isNumerical - ).firstOrNull()?.value ?: 0 + val valueThisQuarter = entries.groupedSum( + truncateField = DateUtils.TruncateField.QUARTER, + isNumerical = habit.isNumerical + ).firstOrNull()?.value ?: 0 - val valueThisYear = entries.groupedSum( - truncateField = DateUtils.TruncateField.YEAR, - isNumerical = habit.isNumerical - ).firstOrNull()?.value ?: 0 + val valueThisYear = entries.groupedSum( + truncateField = DateUtils.TruncateField.YEAR, + isNumerical = habit.isNumerical + ).firstOrNull()?.value ?: 0 - val cal = DateUtils.getStartOfTodayCalendarWithOffset() - val daysInMonth = cal.getActualMaximum(Calendar.DAY_OF_MONTH) - val daysInQuarter = 91 - val daysInYear = cal.getActualMaximum(Calendar.DAY_OF_YEAR) + 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.targetValue / habit.frequency.denominator - val targetThisWeek = targetToday * 7 - val targetThisMonth = targetToday * daysInMonth - val targetThisQuarter = targetToday * daysInQuarter - val targetThisYear = targetToday * daysInYear + val targetToday = habit.targetValue / habit.frequency.denominator + val targetThisWeek = targetToday * 7 + val targetThisMonth = targetToday * daysInMonth + val targetThisQuarter = targetToday * daysInQuarter + val targetThisYear = targetToday * daysInYear - val values = ArrayList() - if (habit.frequency.denominator <= 1) values.add(valueToday / 1e3) - if (habit.frequency.denominator <= 7) values.add(valueThisWeek / 1e3) - values.add(valueThisMonth / 1e3) - values.add(valueThisQuarter / 1e3) - values.add(valueThisYear / 1e3) + val values = ArrayList() + if (habit.frequency.denominator <= 1) values.add(valueToday / 1e3) + if (habit.frequency.denominator <= 7) values.add(valueThisWeek / 1e3) + values.add(valueThisMonth / 1e3) + values.add(valueThisQuarter / 1e3) + values.add(valueThisYear / 1e3) - val targets = ArrayList() - 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 targets = ArrayList() + 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 intervals = ArrayList() - if (habit.frequency.denominator <= 1) intervals.add(1) - if (habit.frequency.denominator <= 7) intervals.add(7) - intervals.add(30) - intervals.add(91) - intervals.add(365) + val intervals = ArrayList() + if (habit.frequency.denominator <= 1) intervals.add(1) + if (habit.frequency.denominator <= 7) intervals.add(7) + intervals.add(30) + intervals.add(91) + intervals.add(365) - return TargetCardViewModel( - color = habit.color, - values = values, - targets = targets, - intervals = intervals, - ) + return TargetCardState( + color = habit.color, + values = values, + targets = targets, + intervals = intervals, + ) + } } } diff --git a/android/uhabits-core/src/test/java/org/isoron/uhabits/core/ui/screens/habits/show/ShowHabitMenuBehaviorTest.java b/android/uhabits-core/src/test/java/org/isoron/uhabits/core/ui/screens/habits/show/ShowHabitMenuPresenterTest.java similarity index 80% rename from android/uhabits-core/src/test/java/org/isoron/uhabits/core/ui/screens/habits/show/ShowHabitMenuBehaviorTest.java rename to android/uhabits-core/src/test/java/org/isoron/uhabits/core/ui/screens/habits/show/ShowHabitMenuPresenterTest.java index efb48e927..404016084 100644 --- a/android/uhabits-core/src/test/java/org/isoron/uhabits/core/ui/screens/habits/show/ShowHabitMenuBehaviorTest.java +++ b/android/uhabits-core/src/test/java/org/isoron/uhabits/core/ui/screens/habits/show/ShowHabitMenuPresenterTest.java @@ -31,25 +31,25 @@ import static org.hamcrest.CoreMatchers.equalTo; import static org.junit.Assert.assertThat; import static org.mockito.Mockito.*; -public class ShowHabitMenuBehaviorTest extends BaseUnitTest +public class ShowHabitMenuPresenterTest extends BaseUnitTest { - private ShowHabitMenuBehavior.System system; + private ShowHabitMenuPresenter.System system; - private ShowHabitMenuBehavior.Screen screen; + private ShowHabitMenuPresenter.Screen screen; private Habit habit; - private ShowHabitMenuBehavior menu; + private ShowHabitMenuPresenter menu; @Override public void setUp() throws Exception { super.setUp(); - system = mock(ShowHabitMenuBehavior.System.class); - screen = mock(ShowHabitMenuBehavior.Screen.class); + system = mock(ShowHabitMenuPresenter.System.class); + screen = mock(ShowHabitMenuPresenter.Screen.class); habit = fixtures.createShortHabit(); - menu = new ShowHabitMenuBehavior(commandRunner, habit, habitList, screen, system, taskRunner); + menu = new ShowHabitMenuPresenter(commandRunner, habit, habitList, screen, system, taskRunner); } @Test