mirror of
https://github.com/iSoron/uhabits.git
synced 2025-12-06 09:08:52 -06:00
Remove ShowHabitScreen and ShowHabitBehavior
This commit is contained in:
@@ -39,8 +39,6 @@ public class ScoreChartTest extends BaseViewTest
|
|||||||
|
|
||||||
private ScoreChart view;
|
private ScoreChart view;
|
||||||
|
|
||||||
private ScoreCardPresenter presenter;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Before
|
@Before
|
||||||
public void setUp()
|
public void setUp()
|
||||||
@@ -49,13 +47,12 @@ public class ScoreChartTest extends BaseViewTest
|
|||||||
|
|
||||||
fixtures.purgeHabits(habitList);
|
fixtures.purgeHabits(habitList);
|
||||||
habit = fixtures.createLongHabit();
|
habit = fixtures.createLongHabit();
|
||||||
presenter = new ScoreCardPresenter();
|
ScoreCardState state = ScoreCardPresenter.Companion.buildState(habit, prefs.getFirstWeekdayInt(), 0);
|
||||||
ScoreCardViewModel model = presenter.present(habit, prefs.getFirstWeekdayInt(), 0);
|
|
||||||
|
|
||||||
view = new ScoreChart(targetContext);
|
view = new ScoreChart(targetContext);
|
||||||
view.setScores(model.getScores());
|
view.setScores(state.getScores());
|
||||||
view.setColor(PaletteUtilsKt.toFixedAndroidColor(model.getColor()));
|
view.setColor(PaletteUtilsKt.toFixedAndroidColor(state.getColor()));
|
||||||
view.setBucketSize(model.getBucketSize());
|
view.setBucketSize(state.getBucketSize());
|
||||||
measureView(view, dpToPixels(300), dpToPixels(200));
|
measureView(view, dpToPixels(300), dpToPixels(200));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -84,7 +81,7 @@ public class ScoreChartTest extends BaseViewTest
|
|||||||
@Test
|
@Test
|
||||||
public void testRender_withMonthlyBucket() throws Throwable
|
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.setScores(model.getScores());
|
||||||
view.setBucketSize(model.getBucketSize());
|
view.setBucketSize(model.getBucketSize());
|
||||||
view.invalidate();
|
view.invalidate();
|
||||||
@@ -102,7 +99,7 @@ public class ScoreChartTest extends BaseViewTest
|
|||||||
@Test
|
@Test
|
||||||
public void testRender_withYearlyBucket() throws Throwable
|
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.setScores(model.getScores());
|
||||||
view.setBucketSize(model.getBucketSize());
|
view.setBucketSize(model.getBucketSize());
|
||||||
view.invalidate();
|
view.invalidate();
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ class FrequencyCardViewTest : BaseViewTest() {
|
|||||||
.from(targetContext)
|
.from(targetContext)
|
||||||
.inflate(R.layout.show_habit, null)
|
.inflate(R.layout.show_habit, null)
|
||||||
.findViewById<View>(R.id.frequencyCard) as FrequencyCardView
|
.findViewById<View>(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)
|
measureView(view, 800f, 600f)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -45,11 +45,10 @@ class HistoryCardViewTest : BaseViewTest() {
|
|||||||
.from(targetContext)
|
.from(targetContext)
|
||||||
.inflate(R.layout.show_habit, null)
|
.inflate(R.layout.show_habit, null)
|
||||||
.findViewById<View>(R.id.historyCard) as HistoryCardView
|
.findViewById<View>(R.id.historyCard) as HistoryCardView
|
||||||
view.update(
|
view.setState(
|
||||||
HistoryCardPresenter().present(
|
HistoryCardPresenter.buildState(
|
||||||
habit = habit,
|
habit = habit,
|
||||||
firstWeekday = SUNDAY,
|
firstWeekday = SUNDAY,
|
||||||
isSkipEnabled = false,
|
|
||||||
theme = LightTheme(),
|
theme = LightTheme(),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ import androidx.test.filters.MediumTest
|
|||||||
import org.hamcrest.Matchers.equalTo
|
import org.hamcrest.Matchers.equalTo
|
||||||
import org.isoron.uhabits.BaseViewTest
|
import org.isoron.uhabits.BaseViewTest
|
||||||
import org.isoron.uhabits.R
|
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.Assert.assertThat
|
||||||
import org.junit.Before
|
import org.junit.Before
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
@@ -44,7 +44,7 @@ class NotesCardViewTest : BaseViewTest() {
|
|||||||
.from(targetContext)
|
.from(targetContext)
|
||||||
.inflate(R.layout.show_habit, null)
|
.inflate(R.layout.show_habit, null)
|
||||||
.findViewById(R.id.notesCard)
|
.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)
|
measureView(view, 800f, 200f)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -55,7 +55,7 @@ class NotesCardViewTest : BaseViewTest() {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testRenderEmptyDescription() {
|
fun testRenderEmptyDescription() {
|
||||||
view.update(NotesCardViewModel(description = ""))
|
view.setState(NotesCardState(description = ""))
|
||||||
assertThat(view.visibility, equalTo(GONE))
|
assertThat(view.visibility, equalTo(GONE))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ import androidx.test.filters.MediumTest
|
|||||||
import org.isoron.uhabits.BaseViewTest
|
import org.isoron.uhabits.BaseViewTest
|
||||||
import org.isoron.uhabits.R
|
import org.isoron.uhabits.R
|
||||||
import org.isoron.uhabits.core.models.PaletteColor
|
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.Before
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import org.junit.runner.RunWith
|
import org.junit.runner.RunWith
|
||||||
@@ -43,8 +43,8 @@ class OverviewCardViewTest : BaseViewTest() {
|
|||||||
.from(targetContext)
|
.from(targetContext)
|
||||||
.inflate(R.layout.show_habit, null)
|
.inflate(R.layout.show_habit, null)
|
||||||
.findViewById<View>(R.id.overviewCard) as OverviewCardView
|
.findViewById<View>(R.id.overviewCard) as OverviewCardView
|
||||||
view.update(
|
view.setState(
|
||||||
OverviewCardViewModel(
|
OverviewCardState(
|
||||||
scoreToday = 0.74f,
|
scoreToday = 0.74f,
|
||||||
scoreMonthDiff = 0.23f,
|
scoreMonthDiff = 0.23f,
|
||||||
scoreYearDiff = 0.74f,
|
scoreYearDiff = 0.74f,
|
||||||
|
|||||||
@@ -43,8 +43,8 @@ class ScoreCardViewTest : BaseViewTest() {
|
|||||||
.from(targetContext)
|
.from(targetContext)
|
||||||
.inflate(R.layout.show_habit, null)
|
.inflate(R.layout.show_habit, null)
|
||||||
.findViewById<View>(R.id.scoreCard) as ScoreCardView
|
.findViewById<View>(R.id.scoreCard) as ScoreCardView
|
||||||
view.update(
|
view.setState(
|
||||||
ScoreCardPresenter().present(
|
ScoreCardPresenter.buildState(
|
||||||
habit = habit,
|
habit = habit,
|
||||||
firstWeekday = 0,
|
firstWeekday = 0,
|
||||||
spinnerPosition = 0,
|
spinnerPosition = 0,
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ import androidx.test.ext.junit.runners.AndroidJUnit4
|
|||||||
import androidx.test.filters.MediumTest
|
import androidx.test.filters.MediumTest
|
||||||
import org.isoron.uhabits.BaseViewTest
|
import org.isoron.uhabits.BaseViewTest
|
||||||
import org.isoron.uhabits.R
|
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.Before
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import org.junit.runner.RunWith
|
import org.junit.runner.RunWith
|
||||||
@@ -43,8 +43,8 @@ class StreakCardViewTest : BaseViewTest() {
|
|||||||
.from(targetContext)
|
.from(targetContext)
|
||||||
.inflate(R.layout.show_habit, null)
|
.inflate(R.layout.show_habit, null)
|
||||||
.findViewById<View>(R.id.streakCard) as StreakCardView
|
.findViewById<View>(R.id.streakCard) as StreakCardView
|
||||||
view.update(
|
view.setState(
|
||||||
StreakCardViewModel(
|
StreakCardState(
|
||||||
bestStreaks = habit.streaks.getBest(10),
|
bestStreaks = habit.streaks.getBest(10),
|
||||||
color = habit.color,
|
color = habit.color,
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ import org.isoron.uhabits.core.models.Frequency
|
|||||||
import org.isoron.uhabits.core.models.PaletteColor
|
import org.isoron.uhabits.core.models.PaletteColor
|
||||||
import org.isoron.uhabits.core.models.Reminder
|
import org.isoron.uhabits.core.models.Reminder
|
||||||
import org.isoron.uhabits.core.models.WeekdayList.EVERY_DAY
|
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.Before
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import org.junit.runner.RunWith
|
import org.junit.runner.RunWith
|
||||||
@@ -45,8 +45,8 @@ class SubtitleCardViewTest : BaseViewTest() {
|
|||||||
.from(targetContext)
|
.from(targetContext)
|
||||||
.inflate(R.layout.show_habit, null)
|
.inflate(R.layout.show_habit, null)
|
||||||
.findViewById(R.id.subtitleCard)
|
.findViewById(R.id.subtitleCard)
|
||||||
view.update(
|
view.setState(
|
||||||
SubtitleCardViewModel(
|
SubtitleCardState(
|
||||||
color = PaletteColor(7),
|
color = PaletteColor(7),
|
||||||
frequency = Frequency(3, 7),
|
frequency = Frequency(3, 7),
|
||||||
isNumerical = false,
|
isNumerical = false,
|
||||||
|
|||||||
@@ -20,14 +20,14 @@ package org.isoron.uhabits.activities
|
|||||||
|
|
||||||
import org.isoron.uhabits.AndroidDirFinder
|
import org.isoron.uhabits.AndroidDirFinder
|
||||||
import org.isoron.uhabits.core.ui.screens.habits.list.ListHabitsBehavior
|
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 java.io.File
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class HabitsDirFinder @Inject
|
class HabitsDirFinder @Inject
|
||||||
constructor(
|
constructor(
|
||||||
private val androidDirFinder: AndroidDirFinder
|
private val androidDirFinder: AndroidDirFinder
|
||||||
) : ShowHabitMenuBehavior.System, ListHabitsBehavior.DirFinder {
|
) : ShowHabitMenuPresenter.System, ListHabitsBehavior.DirFinder {
|
||||||
|
|
||||||
override fun getCSVOutputDir(): File {
|
override fun getCSVOutputDir(): File {
|
||||||
return androidDirFinder.getFilesDir("CSV")!!
|
return androidDirFinder.getFilesDir("CSV")!!
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ import org.isoron.uhabits.inject.*;
|
|||||||
@AutoFactory(allowSubclasses = true)
|
@AutoFactory(allowSubclasses = true)
|
||||||
public class ConfirmDeleteDialog extends AlertDialog
|
public class ConfirmDeleteDialog extends AlertDialog
|
||||||
{
|
{
|
||||||
protected ConfirmDeleteDialog(@Provided @ActivityContext Context context,
|
public ConfirmDeleteDialog(@Provided @ActivityContext Context context,
|
||||||
@NonNull OnConfirmedCallback callback,
|
@NonNull OnConfirmedCallback callback,
|
||||||
int quantity)
|
int quantity)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -91,10 +91,9 @@ class HistoryEditorDialog : AppCompatDialogFragment(), CommandRunner.Listener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun refreshData() {
|
private fun refreshData() {
|
||||||
val model = HistoryCardPresenter().present(
|
val model = HistoryCardPresenter.buildState(
|
||||||
habit,
|
habit,
|
||||||
preferences.firstWeekday,
|
preferences.firstWeekday,
|
||||||
preferences.isSkipEnabled,
|
|
||||||
theme = LightTheme()
|
theme = LightTheme()
|
||||||
)
|
)
|
||||||
chart?.series = model.series
|
chart?.series = model.series
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ package org.isoron.uhabits.activities.habits.show
|
|||||||
|
|
||||||
import android.content.ContentUris
|
import android.content.ContentUris
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
|
import android.view.HapticFeedbackConstants
|
||||||
import android.view.Menu
|
import android.view.Menu
|
||||||
import android.view.MenuItem
|
import android.view.MenuItem
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
@@ -28,33 +29,39 @@ import kotlinx.coroutines.Dispatchers
|
|||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import org.isoron.uhabits.AndroidDirFinder
|
import org.isoron.uhabits.AndroidDirFinder
|
||||||
import org.isoron.uhabits.HabitsApplication
|
import org.isoron.uhabits.HabitsApplication
|
||||||
|
import org.isoron.uhabits.R
|
||||||
import org.isoron.uhabits.activities.AndroidThemeSwitcher
|
import org.isoron.uhabits.activities.AndroidThemeSwitcher
|
||||||
import org.isoron.uhabits.activities.HabitsDirFinder
|
import org.isoron.uhabits.activities.HabitsDirFinder
|
||||||
import org.isoron.uhabits.activities.common.dialogs.ConfirmDeleteDialogFactory
|
import org.isoron.uhabits.activities.common.dialogs.ConfirmDeleteDialog
|
||||||
import org.isoron.uhabits.activities.common.dialogs.HistoryEditorDialog
|
import org.isoron.uhabits.activities.common.dialogs.HistoryEditorDialog
|
||||||
import org.isoron.uhabits.activities.common.dialogs.NumberPickerFactory
|
import org.isoron.uhabits.activities.common.dialogs.NumberPickerFactory
|
||||||
import org.isoron.uhabits.core.commands.Command
|
import org.isoron.uhabits.core.commands.Command
|
||||||
import org.isoron.uhabits.core.commands.CommandRunner
|
import org.isoron.uhabits.core.commands.CommandRunner
|
||||||
import org.isoron.uhabits.core.models.Habit
|
import org.isoron.uhabits.core.models.Habit
|
||||||
import org.isoron.uhabits.core.preferences.Preferences
|
import org.isoron.uhabits.core.preferences.Preferences
|
||||||
import org.isoron.uhabits.core.ui.screens.habits.show.ShowHabitBehavior
|
import org.isoron.uhabits.core.ui.callbacks.OnConfirmedCallback
|
||||||
import org.isoron.uhabits.core.ui.screens.habits.show.ShowHabitMenuBehavior
|
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.screens.habits.show.ShowHabitPresenter
|
||||||
|
import org.isoron.uhabits.core.ui.views.OnDateClickedListener
|
||||||
import org.isoron.uhabits.intents.IntentFactory
|
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 {
|
class ShowHabitActivity : AppCompatActivity(), CommandRunner.Listener {
|
||||||
|
|
||||||
val presenter = ShowHabitPresenter()
|
|
||||||
|
|
||||||
private lateinit var commandRunner: CommandRunner
|
private lateinit var commandRunner: CommandRunner
|
||||||
private lateinit var menu: ShowHabitMenu
|
private lateinit var menu: ShowHabitMenu
|
||||||
private lateinit var view: ShowHabitView
|
private lateinit var view: ShowHabitView
|
||||||
private lateinit var habit: Habit
|
private lateinit var habit: Habit
|
||||||
private lateinit var preferences: Preferences
|
private lateinit var preferences: Preferences
|
||||||
private lateinit var themeSwitcher: AndroidThemeSwitcher
|
private lateinit var themeSwitcher: AndroidThemeSwitcher
|
||||||
private lateinit var behavior: ShowHabitBehavior
|
private lateinit var widgetUpdater: WidgetUpdater
|
||||||
|
|
||||||
private val scope = CoroutineScope(Dispatchers.Main)
|
private val scope = CoroutineScope(Dispatchers.Main)
|
||||||
|
private lateinit var presenter: ShowHabitPresenter
|
||||||
|
private val screen = Screen()
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
@@ -64,21 +71,12 @@ class ShowHabitActivity : AppCompatActivity(), CommandRunner.Listener {
|
|||||||
habit = habitList.getById(ContentUris.parseId(intent.data!!))!!
|
habit = habitList.getById(ContentUris.parseId(intent.data!!))!!
|
||||||
preferences = appComponent.preferences
|
preferences = appComponent.preferences
|
||||||
commandRunner = appComponent.commandRunner
|
commandRunner = appComponent.commandRunner
|
||||||
|
widgetUpdater = appComponent.widgetUpdater
|
||||||
|
|
||||||
themeSwitcher = AndroidThemeSwitcher(this, preferences)
|
themeSwitcher = AndroidThemeSwitcher(this, preferences)
|
||||||
themeSwitcher.apply()
|
themeSwitcher.apply()
|
||||||
|
|
||||||
view = ShowHabitView(this)
|
presenter = ShowHabitPresenter(
|
||||||
|
|
||||||
val screen = ShowHabitScreen(
|
|
||||||
activity = this,
|
|
||||||
confirmDeleteDialogFactory = ConfirmDeleteDialogFactory { this },
|
|
||||||
habit = habit,
|
|
||||||
intentFactory = IntentFactory(),
|
|
||||||
numberPickerFactory = NumberPickerFactory(this),
|
|
||||||
widgetUpdater = appComponent.widgetUpdater,
|
|
||||||
)
|
|
||||||
|
|
||||||
behavior = ShowHabitBehavior(
|
|
||||||
commandRunner = commandRunner,
|
commandRunner = commandRunner,
|
||||||
habit = habit,
|
habit = habit,
|
||||||
habitList = habitList,
|
habitList = habitList,
|
||||||
@@ -86,7 +84,9 @@ class ShowHabitActivity : AppCompatActivity(), CommandRunner.Listener {
|
|||||||
screen = screen,
|
screen = screen,
|
||||||
)
|
)
|
||||||
|
|
||||||
val menuBehavior = ShowHabitMenuBehavior(
|
view = ShowHabitView(this)
|
||||||
|
|
||||||
|
val menuPresenter = ShowHabitMenuPresenter(
|
||||||
commandRunner = commandRunner,
|
commandRunner = commandRunner,
|
||||||
habit = habit,
|
habit = habit,
|
||||||
habitList = habitList,
|
habitList = habitList,
|
||||||
@@ -97,15 +97,11 @@ class ShowHabitActivity : AppCompatActivity(), CommandRunner.Listener {
|
|||||||
|
|
||||||
menu = ShowHabitMenu(
|
menu = ShowHabitMenu(
|
||||||
activity = this,
|
activity = this,
|
||||||
behavior = menuBehavior,
|
presenter = menuPresenter,
|
||||||
preferences = preferences,
|
preferences = preferences,
|
||||||
)
|
)
|
||||||
|
|
||||||
view.onScoreCardSpinnerPosition = behavior::onScoreCardSpinnerPosition
|
view.setListener(presenter)
|
||||||
view.onBarCardBoolSpinnerPosition = behavior::onBarCardBoolSpinnerPosition
|
|
||||||
view.onBarCardNumericalSpinnerPosition = behavior::onBarCardNumericalSpinnerPosition
|
|
||||||
view.onClickEditHistoryButton = behavior::onClickEditHistory
|
|
||||||
|
|
||||||
setContentView(view)
|
setContentView(view)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -121,9 +117,9 @@ class ShowHabitActivity : AppCompatActivity(), CommandRunner.Listener {
|
|||||||
super.onResume()
|
super.onResume()
|
||||||
commandRunner.addListener(this)
|
commandRunner.addListener(this)
|
||||||
supportFragmentManager.findFragmentByTag("historyEditor")?.let {
|
supportFragmentManager.findFragmentByTag("historyEditor")?.let {
|
||||||
(it as HistoryEditorDialog).setOnDateClickedListener(behavior)
|
(it as HistoryEditorDialog).setOnDateClickedListener(presenter.historyCardPresenter)
|
||||||
}
|
}
|
||||||
refresh()
|
screen.refresh()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onPause() {
|
override fun onPause() {
|
||||||
@@ -132,13 +128,18 @@ class ShowHabitActivity : AppCompatActivity(), CommandRunner.Listener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onCommandFinished(command: Command) {
|
override fun onCommandFinished(command: Command) {
|
||||||
refresh()
|
screen.refresh()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun refresh() {
|
inner class Screen : ShowHabitMenuPresenter.Screen, ShowHabitPresenter.Screen {
|
||||||
|
override fun updateWidgets() {
|
||||||
|
widgetUpdater.updateWidgets()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun refresh() {
|
||||||
scope.launch {
|
scope.launch {
|
||||||
view.update(
|
view.setState(
|
||||||
presenter.present(
|
ShowHabitPresenter.buildState(
|
||||||
habit = habit,
|
habit = habit,
|
||||||
preferences = preferences,
|
preferences = preferences,
|
||||||
theme = themeSwitcher.currentTheme,
|
theme = themeSwitcher.currentTheme,
|
||||||
@@ -146,4 +147,50 @@ class ShowHabitActivity : AppCompatActivity(), CommandRunner.Listener {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,11 +23,11 @@ import android.view.Menu
|
|||||||
import android.view.MenuItem
|
import android.view.MenuItem
|
||||||
import org.isoron.uhabits.R
|
import org.isoron.uhabits.R
|
||||||
import org.isoron.uhabits.core.preferences.Preferences
|
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(
|
class ShowHabitMenu(
|
||||||
val activity: ShowHabitActivity,
|
val activity: ShowHabitActivity,
|
||||||
val behavior: ShowHabitMenuBehavior,
|
val presenter: ShowHabitMenuPresenter,
|
||||||
val preferences: Preferences,
|
val preferences: Preferences,
|
||||||
) {
|
) {
|
||||||
fun onCreateOptionsMenu(menu: Menu): Boolean {
|
fun onCreateOptionsMenu(menu: Menu): Boolean {
|
||||||
@@ -41,19 +41,19 @@ class ShowHabitMenu(
|
|||||||
fun onOptionsItemSelected(item: MenuItem): Boolean {
|
fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||||
when (item.itemId) {
|
when (item.itemId) {
|
||||||
R.id.action_edit_habit -> {
|
R.id.action_edit_habit -> {
|
||||||
behavior.onEditHabit()
|
presenter.onEditHabit()
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
R.id.action_delete -> {
|
R.id.action_delete -> {
|
||||||
behavior.onDeleteHabit()
|
presenter.onDeleteHabit()
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
R.id.action_randomize -> {
|
R.id.action_randomize -> {
|
||||||
behavior.onRandomize()
|
presenter.onRandomize()
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
R.id.export -> {
|
R.id.export -> {
|
||||||
behavior.onExportCSV()
|
presenter.onExportCSV()
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,100 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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
|
|
||||||
|
|
||||||
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()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -22,37 +22,29 @@ package org.isoron.uhabits.activities.habits.show
|
|||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.widget.FrameLayout
|
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.databinding.ShowHabitBinding
|
||||||
import org.isoron.uhabits.utils.setupToolbar
|
import org.isoron.uhabits.utils.setupToolbar
|
||||||
|
|
||||||
class ShowHabitView(context: Context) : FrameLayout(context) {
|
class ShowHabitView(context: Context) : FrameLayout(context) {
|
||||||
private val binding = ShowHabitBinding.inflate(LayoutInflater.from(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 {
|
init {
|
||||||
addView(binding.root)
|
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)
|
setupToolbar(binding.toolbar, title = data.title, color = data.color)
|
||||||
binding.subtitleCard.update(data.subtitle)
|
binding.subtitleCard.setState(data.subtitle)
|
||||||
binding.overviewCard.update(data.overview)
|
binding.overviewCard.setState(data.overview)
|
||||||
binding.notesCard.update(data.notes)
|
binding.notesCard.setState(data.notes)
|
||||||
binding.targetCard.update(data.target)
|
binding.targetCard.setState(data.target)
|
||||||
binding.streakCard.update(data.streaks)
|
binding.streakCard.setState(data.streaks)
|
||||||
binding.scoreCard.update(data.scores)
|
binding.scoreCard.setState(data.scores)
|
||||||
binding.frequencyCard.update(data.frequency)
|
binding.frequencyCard.setState(data.frequency)
|
||||||
binding.historyCard.update(data.history)
|
binding.historyCard.setState(data.history)
|
||||||
binding.barCard.update(data.bar)
|
binding.barCard.setState(data.bar)
|
||||||
if (data.isNumerical) {
|
if (data.isNumerical) {
|
||||||
binding.overviewCard.visibility = GONE
|
binding.overviewCard.visibility = GONE
|
||||||
binding.streakCard.visibility = GONE
|
binding.streakCard.visibility = GONE
|
||||||
@@ -60,4 +52,10 @@ class ShowHabitView(context: Context) : FrameLayout(context) {
|
|||||||
binding.targetCard.visibility = GONE
|
binding.targetCard.visibility = GONE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun setListener(presenter: ShowHabitPresenter) {
|
||||||
|
binding.scoreCard.setListener(presenter.scoreCardPresenter)
|
||||||
|
binding.historyCard.setListener(presenter.historyCardPresenter)
|
||||||
|
binding.barCard.setListener(presenter.barCardPresenter)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,7 +25,8 @@ import android.view.View
|
|||||||
import android.widget.AdapterView
|
import android.widget.AdapterView
|
||||||
import android.widget.LinearLayout
|
import android.widget.LinearLayout
|
||||||
import org.isoron.platform.time.JavaLocalDateFormatter
|
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.core.ui.views.BarChart
|
||||||
import org.isoron.uhabits.databinding.ShowHabitBarBinding
|
import org.isoron.uhabits.databinding.ShowHabitBarBinding
|
||||||
import org.isoron.uhabits.utils.toThemedAndroidColor
|
import org.isoron.uhabits.utils.toThemedAndroidColor
|
||||||
@@ -34,53 +35,52 @@ import java.util.Locale
|
|||||||
class BarCardView(context: Context, attrs: AttributeSet) : LinearLayout(context, attrs) {
|
class BarCardView(context: Context, attrs: AttributeSet) : LinearLayout(context, attrs) {
|
||||||
|
|
||||||
private var binding = ShowHabitBarBinding.inflate(LayoutInflater.from(context), this)
|
private var binding = ShowHabitBarBinding.inflate(LayoutInflater.from(context), this)
|
||||||
var onNumericalSpinnerPosition: (position: Int) -> Unit = {}
|
|
||||||
var onBoolSpinnerPosition: (position: Int) -> Unit = {}
|
|
||||||
|
|
||||||
fun update(data: BarCardViewModel) {
|
fun setState(state: BarCardState) {
|
||||||
val androidColor = data.color.toThemedAndroidColor(context)
|
val androidColor = state.color.toThemedAndroidColor(context)
|
||||||
binding.chart.view = BarChart(data.theme, JavaLocalDateFormatter(Locale.US)).apply {
|
binding.chart.view = BarChart(state.theme, JavaLocalDateFormatter(Locale.US)).apply {
|
||||||
series = mutableListOf(data.entries.map { it.value / 1000.0 })
|
series = mutableListOf(state.entries.map { it.value / 1000.0 })
|
||||||
colors = mutableListOf(theme.color(data.color.paletteIndex))
|
colors = mutableListOf(theme.color(state.color.paletteIndex))
|
||||||
axis = data.entries.map { it.timestamp.toLocalDate() }
|
axis = state.entries.map { it.timestamp.toLocalDate() }
|
||||||
}
|
}
|
||||||
binding.chart.resetDataOffset()
|
binding.chart.resetDataOffset()
|
||||||
binding.chart.postInvalidate()
|
binding.chart.postInvalidate()
|
||||||
|
|
||||||
binding.title.setTextColor(androidColor)
|
binding.title.setTextColor(androidColor)
|
||||||
if (data.isNumerical) {
|
if (state.isNumerical) {
|
||||||
binding.boolSpinner.visibility = GONE
|
binding.boolSpinner.visibility = GONE
|
||||||
} else {
|
} else {
|
||||||
binding.numericalSpinner.visibility = GONE
|
binding.numericalSpinner.visibility = GONE
|
||||||
}
|
}
|
||||||
|
|
||||||
binding.numericalSpinner.onItemSelectedListener = null
|
binding.numericalSpinner.onItemSelectedListener = null
|
||||||
binding.numericalSpinner.setSelection(data.numericalSpinnerPosition)
|
binding.numericalSpinner.setSelection(state.numericalSpinnerPosition)
|
||||||
|
binding.boolSpinner.setSelection(state.boolSpinnerPosition)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun setListener(presenter: BarCardPresenter) {
|
||||||
|
binding.boolSpinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
|
||||||
|
override fun onItemSelected(
|
||||||
|
parent: AdapterView<*>?,
|
||||||
|
view: View?,
|
||||||
|
position: Int,
|
||||||
|
id: Long,
|
||||||
|
) {
|
||||||
|
presenter.onBoolSpinnerPosition(position)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onNothingSelected(parent: AdapterView<*>?) {
|
||||||
|
}
|
||||||
|
}
|
||||||
binding.numericalSpinner.onItemSelectedListener =
|
binding.numericalSpinner.onItemSelectedListener =
|
||||||
object : AdapterView.OnItemSelectedListener {
|
object : AdapterView.OnItemSelectedListener {
|
||||||
override fun onItemSelected(
|
override fun onItemSelected(
|
||||||
parent: AdapterView<*>?,
|
parent: AdapterView<*>?,
|
||||||
view: View?,
|
view: View?,
|
||||||
position: Int,
|
position: Int,
|
||||||
id: Long
|
id: Long,
|
||||||
) {
|
) {
|
||||||
onNumericalSpinnerPosition(position)
|
presenter.onNumericalSpinnerPosition(position)
|
||||||
}
|
|
||||||
|
|
||||||
override fun onNothingSelected(parent: AdapterView<*>?) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
binding.boolSpinner.onItemSelectedListener = null
|
|
||||||
binding.boolSpinner.setSelection(data.boolSpinnerPosition)
|
|
||||||
binding.boolSpinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
|
|
||||||
override fun onItemSelected(
|
|
||||||
parent: AdapterView<*>?,
|
|
||||||
view: View?,
|
|
||||||
position: Int,
|
|
||||||
id: Long
|
|
||||||
) {
|
|
||||||
onBoolSpinnerPosition(position)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onNothingSelected(parent: AdapterView<*>?) {
|
override fun onNothingSelected(parent: AdapterView<*>?) {
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ import android.content.Context
|
|||||||
import android.util.AttributeSet
|
import android.util.AttributeSet
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.widget.LinearLayout
|
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.databinding.ShowHabitFrequencyBinding
|
||||||
import org.isoron.uhabits.utils.toThemedAndroidColor
|
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)
|
private var binding = ShowHabitFrequencyBinding.inflate(LayoutInflater.from(context), this)
|
||||||
|
|
||||||
fun update(data: FrequencyCardViewModel) {
|
fun setState(state: FrequencyCardState) {
|
||||||
val androidColor = data.color.toThemedAndroidColor(context)
|
val androidColor = state.color.toThemedAndroidColor(context)
|
||||||
binding.frequencyChart.setFrequency(data.frequency)
|
binding.frequencyChart.setFrequency(state.frequency)
|
||||||
binding.frequencyChart.setFirstWeekday(data.firstWeekday)
|
binding.frequencyChart.setFirstWeekday(state.firstWeekday)
|
||||||
binding.title.setTextColor(androidColor)
|
binding.title.setTextColor(androidColor)
|
||||||
binding.frequencyChart.setColor(androidColor)
|
binding.frequencyChart.setColor(androidColor)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,7 +23,8 @@ import android.util.AttributeSet
|
|||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.widget.LinearLayout
|
import android.widget.LinearLayout
|
||||||
import org.isoron.platform.time.JavaLocalDateFormatter
|
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.core.ui.views.HistoryChart
|
||||||
import org.isoron.uhabits.databinding.ShowHabitHistoryBinding
|
import org.isoron.uhabits.databinding.ShowHabitHistoryBinding
|
||||||
import org.isoron.uhabits.utils.toThemedAndroidColor
|
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)
|
private var binding = ShowHabitHistoryBinding.inflate(LayoutInflater.from(context), this)
|
||||||
|
|
||||||
var onClickEditButton: () -> Unit = {}
|
fun setState(state: HistoryCardState) {
|
||||||
|
val androidColor = state.color.toThemedAndroidColor(context)
|
||||||
init {
|
|
||||||
binding.edit.setOnClickListener { onClickEditButton() }
|
|
||||||
}
|
|
||||||
|
|
||||||
fun update(data: HistoryCardViewModel) {
|
|
||||||
val androidColor = data.color.toThemedAndroidColor(context)
|
|
||||||
binding.title.setTextColor(androidColor)
|
binding.title.setTextColor(androidColor)
|
||||||
binding.chart.view = HistoryChart(
|
binding.chart.view = HistoryChart(
|
||||||
today = data.today,
|
today = state.today,
|
||||||
paletteColor = data.color,
|
paletteColor = state.color,
|
||||||
theme = data.theme,
|
theme = state.theme,
|
||||||
dateFormatter = JavaLocalDateFormatter(Locale.getDefault()),
|
dateFormatter = JavaLocalDateFormatter(Locale.getDefault()),
|
||||||
series = data.series,
|
series = state.series,
|
||||||
firstWeekday = data.firstWeekday,
|
firstWeekday = state.firstWeekday,
|
||||||
)
|
)
|
||||||
binding.chart.postInvalidate()
|
binding.chart.postInvalidate()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun setListener(presenter: HistoryCardPresenter) {
|
||||||
|
binding.edit.setOnClickListener { presenter.onClickEditButton() }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,17 +23,17 @@ import android.content.Context
|
|||||||
import android.util.AttributeSet
|
import android.util.AttributeSet
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.widget.LinearLayout
|
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
|
import org.isoron.uhabits.databinding.ShowHabitNotesBinding
|
||||||
|
|
||||||
class NotesCardView(context: Context, attrs: AttributeSet) : LinearLayout(context, attrs) {
|
class NotesCardView(context: Context, attrs: AttributeSet) : LinearLayout(context, attrs) {
|
||||||
private val binding = ShowHabitNotesBinding.inflate(LayoutInflater.from(context), this)
|
private val binding = ShowHabitNotesBinding.inflate(LayoutInflater.from(context), this)
|
||||||
fun update(data: NotesCardViewModel) {
|
fun setState(state: NotesCardState) {
|
||||||
if (data.description.isEmpty()) {
|
if (state.description.isEmpty()) {
|
||||||
visibility = GONE
|
visibility = GONE
|
||||||
} else {
|
} else {
|
||||||
visibility = VISIBLE
|
visibility = VISIBLE
|
||||||
binding.habitNotes.text = data.description
|
binding.habitNotes.text = state.description
|
||||||
}
|
}
|
||||||
invalidate()
|
invalidate()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ import android.util.AttributeSet
|
|||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.widget.LinearLayout
|
import android.widget.LinearLayout
|
||||||
import org.isoron.uhabits.R
|
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.databinding.ShowHabitOverviewBinding
|
||||||
import org.isoron.uhabits.utils.StyledResources
|
import org.isoron.uhabits.utils.StyledResources
|
||||||
import org.isoron.uhabits.utils.toThemedAndroidColor
|
import org.isoron.uhabits.utils.toThemedAndroidColor
|
||||||
@@ -40,21 +40,21 @@ class OverviewCardView(context: Context, attrs: AttributeSet) : LinearLayout(con
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun update(data: OverviewCardViewModel) {
|
fun setState(state: OverviewCardState) {
|
||||||
val androidColor = data.color.toThemedAndroidColor(context)
|
val androidColor = state.color.toThemedAndroidColor(context)
|
||||||
val res = StyledResources(context)
|
val res = StyledResources(context)
|
||||||
val inactiveColor = res.getColor(R.attr.mediumContrastTextColor)
|
val inactiveColor = res.getColor(R.attr.mediumContrastTextColor)
|
||||||
binding.monthDiffLabel.setTextColor(if (data.scoreMonthDiff >= 0) androidColor else inactiveColor)
|
binding.monthDiffLabel.setTextColor(if (state.scoreMonthDiff >= 0) androidColor else inactiveColor)
|
||||||
binding.monthDiffLabel.text = formatPercentageDiff(data.scoreMonthDiff)
|
binding.monthDiffLabel.text = formatPercentageDiff(state.scoreMonthDiff)
|
||||||
binding.scoreLabel.setTextColor(androidColor)
|
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.color = androidColor
|
||||||
binding.scoreRing.percentage = data.scoreToday
|
binding.scoreRing.percentage = state.scoreToday
|
||||||
binding.title.setTextColor(androidColor)
|
binding.title.setTextColor(androidColor)
|
||||||
binding.totalCountLabel.setTextColor(androidColor)
|
binding.totalCountLabel.setTextColor(androidColor)
|
||||||
binding.totalCountLabel.text = data.totalCount.toString()
|
binding.totalCountLabel.text = state.totalCount.toString()
|
||||||
binding.yearDiffLabel.setTextColor(if (data.scoreYearDiff >= 0) androidColor else inactiveColor)
|
binding.yearDiffLabel.setTextColor(if (state.scoreYearDiff >= 0) androidColor else inactiveColor)
|
||||||
binding.yearDiffLabel.text = formatPercentageDiff(data.scoreYearDiff)
|
binding.yearDiffLabel.text = formatPercentageDiff(state.scoreYearDiff)
|
||||||
postInvalidate()
|
postInvalidate()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,24 +24,25 @@ import android.view.LayoutInflater
|
|||||||
import android.view.View
|
import android.view.View
|
||||||
import android.widget.AdapterView
|
import android.widget.AdapterView
|
||||||
import android.widget.LinearLayout
|
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.databinding.ShowHabitScoreBinding
|
||||||
import org.isoron.uhabits.utils.toThemedAndroidColor
|
import org.isoron.uhabits.utils.toThemedAndroidColor
|
||||||
|
|
||||||
class ScoreCardView(context: Context, attrs: AttributeSet) : LinearLayout(context, attrs) {
|
class ScoreCardView(context: Context, attrs: AttributeSet) : LinearLayout(context, attrs) {
|
||||||
private var binding = ShowHabitScoreBinding.inflate(LayoutInflater.from(context), this)
|
private var binding = ShowHabitScoreBinding.inflate(LayoutInflater.from(context), this)
|
||||||
|
|
||||||
var onSpinnerPosition: (position: Int) -> Unit = {}
|
fun setState(state: ScoreCardState) {
|
||||||
|
val androidColor = state.color.toThemedAndroidColor(context)
|
||||||
fun update(data: ScoreCardViewModel) {
|
|
||||||
val androidColor = data.color.toThemedAndroidColor(context)
|
|
||||||
binding.title.setTextColor(androidColor)
|
binding.title.setTextColor(androidColor)
|
||||||
binding.spinner.setSelection(data.spinnerPosition)
|
binding.spinner.setSelection(state.spinnerPosition)
|
||||||
binding.scoreView.setScores(data.scores)
|
binding.scoreView.setScores(state.scores)
|
||||||
binding.scoreView.reset()
|
binding.scoreView.reset()
|
||||||
binding.scoreView.setBucketSize(data.bucketSize)
|
binding.scoreView.setBucketSize(state.bucketSize)
|
||||||
binding.scoreView.setColor(androidColor)
|
binding.scoreView.setColor(androidColor)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun setListener(presenter: ScoreCardPresenter) {
|
||||||
binding.spinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
|
binding.spinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
|
||||||
override fun onItemSelected(
|
override fun onItemSelected(
|
||||||
parent: AdapterView<*>?,
|
parent: AdapterView<*>?,
|
||||||
@@ -49,7 +50,7 @@ class ScoreCardView(context: Context, attrs: AttributeSet) : LinearLayout(contex
|
|||||||
position: Int,
|
position: Int,
|
||||||
id: Long
|
id: Long
|
||||||
) {
|
) {
|
||||||
onSpinnerPosition(position)
|
presenter.onSpinnerPosition(position)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onNothingSelected(parent: AdapterView<*>?) {
|
override fun onNothingSelected(parent: AdapterView<*>?) {
|
||||||
|
|||||||
@@ -22,17 +22,17 @@ import android.content.Context
|
|||||||
import android.util.AttributeSet
|
import android.util.AttributeSet
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.widget.LinearLayout
|
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.databinding.ShowHabitStreakBinding
|
||||||
import org.isoron.uhabits.utils.toThemedAndroidColor
|
import org.isoron.uhabits.utils.toThemedAndroidColor
|
||||||
|
|
||||||
class StreakCardView(context: Context, attrs: AttributeSet) : LinearLayout(context, attrs) {
|
class StreakCardView(context: Context, attrs: AttributeSet) : LinearLayout(context, attrs) {
|
||||||
private val binding = ShowHabitStreakBinding.inflate(LayoutInflater.from(context), this)
|
private val binding = ShowHabitStreakBinding.inflate(LayoutInflater.from(context), this)
|
||||||
fun update(data: StreakCardViewModel) {
|
fun setState(state: StreakCardState) {
|
||||||
val color = data.color.toThemedAndroidColor(context)
|
val color = state.color.toThemedAndroidColor(context)
|
||||||
binding.title.setTextColor(color)
|
binding.title.setTextColor(color)
|
||||||
binding.streakChart.setColor(color)
|
binding.streakChart.setColor(color)
|
||||||
binding.streakChart.setStreaks(data.bestStreaks)
|
binding.streakChart.setStreaks(state.bestStreaks)
|
||||||
postInvalidate()
|
postInvalidate()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ import android.widget.LinearLayout
|
|||||||
import org.isoron.uhabits.R
|
import org.isoron.uhabits.R
|
||||||
import org.isoron.uhabits.activities.habits.list.views.toShortString
|
import org.isoron.uhabits.activities.habits.list.views.toShortString
|
||||||
import org.isoron.uhabits.core.models.Frequency
|
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.databinding.ShowHabitSubtitleBinding
|
||||||
import org.isoron.uhabits.utils.InterfaceUtils
|
import org.isoron.uhabits.utils.InterfaceUtils
|
||||||
import org.isoron.uhabits.utils.formatTime
|
import org.isoron.uhabits.utils.formatTime
|
||||||
@@ -47,27 +47,27 @@ class SubtitleCardView(context: Context, attrs: AttributeSet) : LinearLayout(con
|
|||||||
}
|
}
|
||||||
|
|
||||||
@SuppressLint("SetTextI18n")
|
@SuppressLint("SetTextI18n")
|
||||||
fun update(data: SubtitleCardViewModel) {
|
fun setState(state: SubtitleCardState) {
|
||||||
val color = data.color.toThemedAndroidColor(context)
|
val color = state.color.toThemedAndroidColor(context)
|
||||||
val reminder = data.reminder
|
val reminder = state.reminder
|
||||||
binding.frequencyLabel.text = data.frequency.format(resources)
|
binding.frequencyLabel.text = state.frequency.format(resources)
|
||||||
binding.questionLabel.setTextColor(color)
|
binding.questionLabel.setTextColor(color)
|
||||||
binding.questionLabel.text = data.question
|
binding.questionLabel.text = state.question
|
||||||
binding.reminderLabel.text = if (reminder != null) {
|
binding.reminderLabel.text = if (reminder != null) {
|
||||||
formatTime(context, reminder.hour, reminder.minute)
|
formatTime(context, reminder.hour, reminder.minute)
|
||||||
} else {
|
} else {
|
||||||
resources.getString(R.string.reminder_off)
|
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.questionLabel.visibility = View.VISIBLE
|
||||||
binding.targetIcon.visibility = View.VISIBLE
|
binding.targetIcon.visibility = View.VISIBLE
|
||||||
binding.targetText.visibility = View.VISIBLE
|
binding.targetText.visibility = View.VISIBLE
|
||||||
if (!data.isNumerical) {
|
if (!state.isNumerical) {
|
||||||
binding.targetIcon.visibility = View.GONE
|
binding.targetIcon.visibility = View.GONE
|
||||||
binding.targetText.visibility = View.GONE
|
binding.targetText.visibility = View.GONE
|
||||||
}
|
}
|
||||||
if (data.question.isEmpty()) {
|
if (state.question.isEmpty()) {
|
||||||
binding.questionLabel.visibility = View.GONE
|
binding.questionLabel.visibility = View.GONE
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -24,17 +24,17 @@ import android.util.AttributeSet
|
|||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.widget.LinearLayout
|
import android.widget.LinearLayout
|
||||||
import org.isoron.uhabits.R
|
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.databinding.ShowHabitTargetBinding
|
||||||
import org.isoron.uhabits.utils.toThemedAndroidColor
|
import org.isoron.uhabits.utils.toThemedAndroidColor
|
||||||
|
|
||||||
class TargetCardView(context: Context, attrs: AttributeSet) : LinearLayout(context, attrs) {
|
class TargetCardView(context: Context, attrs: AttributeSet) : LinearLayout(context, attrs) {
|
||||||
private val binding = ShowHabitTargetBinding.inflate(LayoutInflater.from(context), this)
|
private val binding = ShowHabitTargetBinding.inflate(LayoutInflater.from(context), this)
|
||||||
fun update(data: TargetCardViewModel) {
|
fun setState(state: TargetCardState) {
|
||||||
val androidColor = data.color.toThemedAndroidColor(context)
|
val androidColor = state.color.toThemedAndroidColor(context)
|
||||||
binding.targetChart.setValues(data.values)
|
binding.targetChart.setValues(state.values)
|
||||||
binding.targetChart.setTargets(data.targets)
|
binding.targetChart.setTargets(state.targets)
|
||||||
binding.targetChart.setLabels(data.intervals.map { intervalToLabel(resources, it) })
|
binding.targetChart.setLabels(state.intervals.map { intervalToLabel(resources, it) })
|
||||||
binding.title.setTextColor(androidColor)
|
binding.title.setTextColor(androidColor)
|
||||||
binding.targetChart.setColor(androidColor)
|
binding.targetChart.setColor(androidColor)
|
||||||
postInvalidate()
|
postInvalidate()
|
||||||
|
|||||||
@@ -46,9 +46,8 @@ class HistoryWidget(
|
|||||||
val widgetView = view as GraphWidgetView
|
val widgetView = view as GraphWidgetView
|
||||||
widgetView.setBackgroundAlpha(preferedBackgroundAlpha)
|
widgetView.setBackgroundAlpha(preferedBackgroundAlpha)
|
||||||
if (preferedBackgroundAlpha >= 255) widgetView.setShadowAlpha(0x4f)
|
if (preferedBackgroundAlpha >= 255) widgetView.setShadowAlpha(0x4f)
|
||||||
val model = HistoryCardPresenter().present(
|
val model = HistoryCardPresenter.buildState(
|
||||||
habit = habit,
|
habit = habit,
|
||||||
isSkipEnabled = prefs.isSkipEnabled,
|
|
||||||
firstWeekday = prefs.firstWeekday,
|
firstWeekday = prefs.firstWeekday,
|
||||||
theme = WidgetTheme(),
|
theme = WidgetTheme(),
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -37,8 +37,7 @@ class ScoreWidget(
|
|||||||
pendingIntentFactory.showHabit(habit)
|
pendingIntentFactory.showHabit(habit)
|
||||||
|
|
||||||
override fun refreshData(view: View) {
|
override fun refreshData(view: View) {
|
||||||
val presenter = ScoreCardPresenter()
|
val viewModel = ScoreCardPresenter.buildState(
|
||||||
val viewModel = presenter.present(
|
|
||||||
habit = habit,
|
habit = habit,
|
||||||
firstWeekday = prefs.firstWeekdayInt,
|
firstWeekday = prefs.firstWeekdayInt,
|
||||||
spinnerPosition = prefs.scoreCardSpinnerPosition
|
spinnerPosition = prefs.scoreCardSpinnerPosition
|
||||||
|
|||||||
@@ -45,8 +45,7 @@ class TargetWidget(
|
|||||||
widgetView.setBackgroundAlpha(preferedBackgroundAlpha)
|
widgetView.setBackgroundAlpha(preferedBackgroundAlpha)
|
||||||
if (preferedBackgroundAlpha >= 255) widgetView.setShadowAlpha(0x4f)
|
if (preferedBackgroundAlpha >= 255) widgetView.setShadowAlpha(0x4f)
|
||||||
val chart = (widgetView.dataView as TargetChart)
|
val chart = (widgetView.dataView as TargetChart)
|
||||||
val presenter = TargetCardPresenter()
|
val data = TargetCardPresenter.buildState(habit, prefs.firstWeekdayInt)
|
||||||
val data = presenter.present(habit, prefs.firstWeekdayInt)
|
|
||||||
chart.setColor(data.color.toThemedAndroidColor(context))
|
chart.setColor(data.color.toThemedAndroidColor(context))
|
||||||
chart.setTargets(data.targets)
|
chart.setTargets(data.targets)
|
||||||
chart.setLabels(data.intervals.map { intervalToLabel(context.resources, it) })
|
chart.setLabels(data.intervals.map { intervalToLabel(context.resources, it) })
|
||||||
|
|||||||
@@ -19,86 +19,112 @@
|
|||||||
|
|
||||||
package org.isoron.uhabits.core.ui.screens.habits.show
|
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.Habit
|
||||||
|
import org.isoron.uhabits.core.models.HabitList
|
||||||
import org.isoron.uhabits.core.models.PaletteColor
|
import org.isoron.uhabits.core.models.PaletteColor
|
||||||
import org.isoron.uhabits.core.preferences.Preferences
|
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.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.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.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.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.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.ScoreCardPresenter
|
||||||
import org.isoron.uhabits.core.ui.screens.habits.show.views.ScoreCardViewModel
|
import org.isoron.uhabits.core.ui.screens.habits.show.views.ScoreCardState
|
||||||
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.core.ui.screens.habits.show.views.StreakCartPresenter
|
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.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.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
|
import org.isoron.uhabits.core.ui.views.Theme
|
||||||
|
|
||||||
data class ShowHabitViewModel(
|
data class ShowHabitState(
|
||||||
val title: String = "",
|
val title: String = "",
|
||||||
val isNumerical: Boolean = false,
|
val isNumerical: Boolean = false,
|
||||||
val color: PaletteColor = PaletteColor(1),
|
val color: PaletteColor = PaletteColor(1),
|
||||||
val subtitle: SubtitleCardViewModel,
|
val subtitle: SubtitleCardState,
|
||||||
val overview: OverviewCardViewModel,
|
val overview: OverviewCardState,
|
||||||
val notes: NotesCardViewModel,
|
val notes: NotesCardState,
|
||||||
val target: TargetCardViewModel,
|
val target: TargetCardState,
|
||||||
val streaks: StreakCardViewModel,
|
val streaks: StreakCardState,
|
||||||
val scores: ScoreCardViewModel,
|
val scores: ScoreCardState,
|
||||||
val frequency: FrequencyCardViewModel,
|
val frequency: FrequencyCardState,
|
||||||
val history: HistoryCardViewModel,
|
val history: HistoryCardState,
|
||||||
val bar: BarCardViewModel,
|
val bar: BarCardState,
|
||||||
)
|
)
|
||||||
|
|
||||||
class ShowHabitPresenter {
|
class ShowHabitPresenter(
|
||||||
fun present(
|
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,
|
habit: Habit,
|
||||||
preferences: Preferences,
|
preferences: Preferences,
|
||||||
theme: Theme,
|
theme: Theme,
|
||||||
): ShowHabitViewModel {
|
): ShowHabitState {
|
||||||
return ShowHabitViewModel(
|
return ShowHabitState(
|
||||||
title = habit.name,
|
title = habit.name,
|
||||||
color = habit.color,
|
color = habit.color,
|
||||||
isNumerical = habit.isNumerical,
|
isNumerical = habit.isNumerical,
|
||||||
subtitle = SubtitleCardPresenter().present(
|
subtitle = SubtitleCardPresenter.buildState(
|
||||||
habit = habit,
|
habit = habit,
|
||||||
),
|
),
|
||||||
overview = OverviewCardPresenter().present(
|
overview = OverviewCardPresenter.buildState(
|
||||||
habit = habit,
|
habit = habit,
|
||||||
),
|
),
|
||||||
notes = NotesCardPresenter().present(
|
notes = NotesCardPresenter.buildState(
|
||||||
habit = habit,
|
habit = habit,
|
||||||
),
|
),
|
||||||
target = TargetCardPresenter().present(
|
target = TargetCardPresenter.buildState(
|
||||||
habit = habit,
|
habit = habit,
|
||||||
firstWeekday = preferences.firstWeekdayInt,
|
firstWeekday = preferences.firstWeekdayInt,
|
||||||
),
|
),
|
||||||
streaks = StreakCartPresenter().present(
|
streaks = StreakCartPresenter.buildState(
|
||||||
habit = habit,
|
habit = habit,
|
||||||
),
|
),
|
||||||
scores = ScoreCardPresenter().present(
|
scores = ScoreCardPresenter.buildState(
|
||||||
spinnerPosition = preferences.scoreCardSpinnerPosition,
|
spinnerPosition = preferences.scoreCardSpinnerPosition,
|
||||||
habit = habit,
|
habit = habit,
|
||||||
firstWeekday = preferences.firstWeekdayInt,
|
firstWeekday = preferences.firstWeekdayInt,
|
||||||
),
|
),
|
||||||
frequency = FrequencyCardPresenter().present(
|
frequency = FrequencyCardPresenter.buildState(
|
||||||
habit = habit,
|
habit = habit,
|
||||||
firstWeekday = preferences.firstWeekdayInt,
|
firstWeekday = preferences.firstWeekdayInt,
|
||||||
),
|
),
|
||||||
history = HistoryCardPresenter().present(
|
history = HistoryCardPresenter.buildState(
|
||||||
habit = habit,
|
habit = habit,
|
||||||
firstWeekday = preferences.firstWeekday,
|
firstWeekday = preferences.firstWeekday,
|
||||||
isSkipEnabled = preferences.isSkipEnabled,
|
|
||||||
theme = theme,
|
theme = theme,
|
||||||
),
|
),
|
||||||
bar = BarCardPresenter().present(
|
bar = BarCardPresenter.buildState(
|
||||||
habit = habit,
|
habit = habit,
|
||||||
firstWeekday = preferences.firstWeekdayInt,
|
firstWeekday = preferences.firstWeekdayInt,
|
||||||
boolSpinnerPosition = preferences.barCardBoolSpinnerPosition,
|
boolSpinnerPosition = preferences.barCardBoolSpinnerPosition,
|
||||||
@@ -107,4 +133,10 @@ class ShowHabitPresenter {
|
|||||||
),
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Screen :
|
||||||
|
BarCardPresenter.Screen,
|
||||||
|
ScoreCardPresenter.Screen,
|
||||||
|
HistoryCardPresenter.Screen
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,109 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2017 Álinson Santos Xavier <isoron@gmail.com>
|
|
||||||
*
|
|
||||||
* This file is part of Loop Habit Tracker.
|
|
||||||
*
|
|
||||||
* Loop Habit Tracker is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by the
|
|
||||||
* Free Software Foundation, either version 3 of the License, or (at your
|
|
||||||
* option) any later version.
|
|
||||||
*
|
|
||||||
* Loop Habit Tracker is distributed in the hope that it will be useful, but
|
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
||||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
|
||||||
* more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License along
|
|
||||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
package org.isoron.uhabits.core.ui.screens.habits.show
|
|
||||||
|
|
||||||
import org.isoron.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()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -30,7 +30,7 @@ import org.isoron.uhabits.core.utils.DateUtils
|
|||||||
import java.io.File
|
import java.io.File
|
||||||
import java.util.Random
|
import java.util.Random
|
||||||
|
|
||||||
class ShowHabitMenuBehavior(
|
class ShowHabitMenuPresenter(
|
||||||
private val commandRunner: CommandRunner,
|
private val commandRunner: CommandRunner,
|
||||||
private val habit: Habit,
|
private val habit: Habit,
|
||||||
private val habitList: HabitList,
|
private val habitList: HabitList,
|
||||||
@@ -85,9 +85,7 @@ class ShowHabitMenuBehavior(
|
|||||||
fun showEditHabitScreen(habit: Habit)
|
fun showEditHabitScreen(habit: Habit)
|
||||||
fun showMessage(m: Message?)
|
fun showMessage(m: Message?)
|
||||||
fun showSendFileScreen(filename: String)
|
fun showSendFileScreen(filename: String)
|
||||||
fun showDeleteConfirmationScreen(
|
fun showDeleteConfirmationScreen(callback: OnConfirmedCallback)
|
||||||
callback: OnConfirmedCallback
|
|
||||||
)
|
|
||||||
fun close()
|
fun close()
|
||||||
fun refresh()
|
fun refresh()
|
||||||
}
|
}
|
||||||
@@ -23,10 +23,11 @@ import org.isoron.uhabits.core.models.Entry
|
|||||||
import org.isoron.uhabits.core.models.Habit
|
import org.isoron.uhabits.core.models.Habit
|
||||||
import org.isoron.uhabits.core.models.PaletteColor
|
import org.isoron.uhabits.core.models.PaletteColor
|
||||||
import org.isoron.uhabits.core.models.groupedSum
|
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.ui.views.Theme
|
||||||
import org.isoron.uhabits.core.utils.DateUtils
|
import org.isoron.uhabits.core.utils.DateUtils
|
||||||
|
|
||||||
data class BarCardViewModel(
|
data class BarCardState(
|
||||||
val theme: Theme,
|
val theme: Theme,
|
||||||
val boolSpinnerPosition: Int,
|
val boolSpinnerPosition: Int,
|
||||||
val bucketSize: Int,
|
val bucketSize: Int,
|
||||||
@@ -36,17 +37,21 @@ data class BarCardViewModel(
|
|||||||
val numericalSpinnerPosition: Int,
|
val numericalSpinnerPosition: Int,
|
||||||
)
|
)
|
||||||
|
|
||||||
class BarCardPresenter {
|
class BarCardPresenter(
|
||||||
|
val preferences: Preferences,
|
||||||
|
val screen: Screen,
|
||||||
|
) {
|
||||||
|
companion object {
|
||||||
val numericalBucketSizes = intArrayOf(1, 7, 31, 92, 365)
|
val numericalBucketSizes = intArrayOf(1, 7, 31, 92, 365)
|
||||||
val boolBucketSizes = intArrayOf(7, 31, 92, 365)
|
val boolBucketSizes = intArrayOf(7, 31, 92, 365)
|
||||||
|
|
||||||
fun present(
|
fun buildState(
|
||||||
habit: Habit,
|
habit: Habit,
|
||||||
firstWeekday: Int,
|
firstWeekday: Int,
|
||||||
numericalSpinnerPosition: Int,
|
numericalSpinnerPosition: Int,
|
||||||
boolSpinnerPosition: Int,
|
boolSpinnerPosition: Int,
|
||||||
theme: Theme,
|
theme: Theme,
|
||||||
): BarCardViewModel {
|
): BarCardState {
|
||||||
val bucketSize = if (habit.isNumerical) {
|
val bucketSize = if (habit.isNumerical) {
|
||||||
numericalBucketSizes[numericalSpinnerPosition]
|
numericalBucketSizes[numericalSpinnerPosition]
|
||||||
} else {
|
} else {
|
||||||
@@ -59,7 +64,7 @@ class BarCardPresenter {
|
|||||||
firstWeekday = firstWeekday,
|
firstWeekday = firstWeekday,
|
||||||
isNumerical = habit.isNumerical,
|
isNumerical = habit.isNumerical,
|
||||||
)
|
)
|
||||||
return BarCardViewModel(
|
return BarCardState(
|
||||||
theme = theme,
|
theme = theme,
|
||||||
entries = entries,
|
entries = entries,
|
||||||
bucketSize = bucketSize,
|
bucketSize = bucketSize,
|
||||||
@@ -69,4 +74,22 @@ class BarCardPresenter {
|
|||||||
boolSpinnerPosition = boolSpinnerPosition,
|
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()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,21 +24,23 @@ import org.isoron.uhabits.core.models.PaletteColor
|
|||||||
import org.isoron.uhabits.core.models.Timestamp
|
import org.isoron.uhabits.core.models.Timestamp
|
||||||
import java.util.HashMap
|
import java.util.HashMap
|
||||||
|
|
||||||
data class FrequencyCardViewModel(
|
data class FrequencyCardState(
|
||||||
val color: PaletteColor,
|
val color: PaletteColor,
|
||||||
val firstWeekday: Int,
|
val firstWeekday: Int,
|
||||||
val frequency: HashMap<Timestamp, Array<Int>>,
|
val frequency: HashMap<Timestamp, Array<Int>>,
|
||||||
)
|
)
|
||||||
|
|
||||||
class FrequencyCardPresenter {
|
class FrequencyCardPresenter {
|
||||||
fun present(
|
companion object {
|
||||||
|
fun buildState(
|
||||||
habit: Habit,
|
habit: Habit,
|
||||||
firstWeekday: Int,
|
firstWeekday: Int,
|
||||||
) = FrequencyCardViewModel(
|
) = FrequencyCardState(
|
||||||
color = habit.color,
|
color = habit.color,
|
||||||
frequency = habit.originalEntries.computeWeekdayFrequency(
|
frequency = habit.originalEntries.computeWeekdayFrequency(
|
||||||
isNumerical = habit.isNumerical
|
isNumerical = habit.isNumerical
|
||||||
),
|
),
|
||||||
firstWeekday = firstWeekday,
|
firstWeekday = firstWeekday,
|
||||||
)
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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.DayOfWeek
|
||||||
import org.isoron.platform.time.LocalDate
|
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
|
||||||
import org.isoron.uhabits.core.models.Entry.Companion.SKIP
|
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_AUTO
|
||||||
import org.isoron.uhabits.core.models.Entry.Companion.YES_MANUAL
|
import org.isoron.uhabits.core.models.Entry.Companion.YES_MANUAL
|
||||||
import org.isoron.uhabits.core.models.Habit
|
import org.isoron.uhabits.core.models.Habit
|
||||||
|
import org.isoron.uhabits.core.models.HabitList
|
||||||
import org.isoron.uhabits.core.models.PaletteColor
|
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.HistoryChart
|
||||||
|
import org.isoron.uhabits.core.ui.views.OnDateClickedListener
|
||||||
import org.isoron.uhabits.core.ui.views.Theme
|
import org.isoron.uhabits.core.ui.views.Theme
|
||||||
import org.isoron.uhabits.core.utils.DateUtils
|
import org.isoron.uhabits.core.utils.DateUtils
|
||||||
import kotlin.math.max
|
import kotlin.math.max
|
||||||
|
import kotlin.math.roundToInt
|
||||||
|
|
||||||
data class HistoryCardViewModel(
|
data class HistoryCardState(
|
||||||
val color: PaletteColor,
|
val color: PaletteColor,
|
||||||
val firstWeekday: DayOfWeek,
|
val firstWeekday: DayOfWeek,
|
||||||
val series: List<HistoryChart.Square>,
|
val series: List<HistoryChart.Square>,
|
||||||
@@ -40,13 +47,59 @@ data class HistoryCardViewModel(
|
|||||||
val today: LocalDate,
|
val today: LocalDate,
|
||||||
)
|
)
|
||||||
|
|
||||||
class HistoryCardPresenter {
|
class HistoryCardPresenter(
|
||||||
fun present(
|
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 {
|
||||||
|
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,
|
habit: Habit,
|
||||||
firstWeekday: DayOfWeek,
|
firstWeekday: DayOfWeek,
|
||||||
isSkipEnabled: Boolean,
|
|
||||||
theme: Theme,
|
theme: Theme,
|
||||||
): HistoryCardViewModel {
|
): HistoryCardState {
|
||||||
val today = DateUtils.getTodayWithOffset()
|
val today = DateUtils.getTodayWithOffset()
|
||||||
val oldest = habit.computedEntries.getKnown().lastOrNull()?.timestamp ?: today
|
val oldest = habit.computedEntries.getKnown().lastOrNull()?.timestamp ?: today
|
||||||
val entries = habit.computedEntries.getByInterval(oldest, today)
|
val entries = habit.computedEntries.getByInterval(oldest, today)
|
||||||
@@ -70,7 +123,7 @@ class HistoryCardPresenter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return HistoryCardViewModel(
|
return HistoryCardState(
|
||||||
color = habit.color,
|
color = habit.color,
|
||||||
firstWeekday = firstWeekday,
|
firstWeekday = firstWeekday,
|
||||||
today = today.toLocalDate(),
|
today = today.toLocalDate(),
|
||||||
@@ -78,4 +131,15 @@ class HistoryCardPresenter {
|
|||||||
series = series,
|
series = series,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Screen {
|
||||||
|
fun showHistoryEditorDialog(listener: OnDateClickedListener)
|
||||||
|
fun showFeedback()
|
||||||
|
fun showNumberPicker(
|
||||||
|
value: Double,
|
||||||
|
unit: String,
|
||||||
|
callback: ListHabitsBehavior.NumberPickerCallback,
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,12 +21,14 @@ package org.isoron.uhabits.core.ui.screens.habits.show.views
|
|||||||
|
|
||||||
import org.isoron.uhabits.core.models.Habit
|
import org.isoron.uhabits.core.models.Habit
|
||||||
|
|
||||||
data class NotesCardViewModel(
|
data class NotesCardState(
|
||||||
val description: String,
|
val description: String,
|
||||||
)
|
)
|
||||||
|
|
||||||
class NotesCardPresenter {
|
class NotesCardPresenter {
|
||||||
fun present(habit: Habit) = NotesCardViewModel(
|
companion object {
|
||||||
|
fun buildState(habit: Habit) = NotesCardState(
|
||||||
description = habit.description,
|
description = habit.description,
|
||||||
)
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ import org.isoron.uhabits.core.models.Habit
|
|||||||
import org.isoron.uhabits.core.models.PaletteColor
|
import org.isoron.uhabits.core.models.PaletteColor
|
||||||
import org.isoron.uhabits.core.utils.DateUtils
|
import org.isoron.uhabits.core.utils.DateUtils
|
||||||
|
|
||||||
data class OverviewCardViewModel(
|
data class OverviewCardState(
|
||||||
val color: PaletteColor,
|
val color: PaletteColor,
|
||||||
val scoreMonthDiff: Float,
|
val scoreMonthDiff: Float,
|
||||||
val scoreYearDiff: Float,
|
val scoreYearDiff: Float,
|
||||||
@@ -33,7 +33,8 @@ data class OverviewCardViewModel(
|
|||||||
)
|
)
|
||||||
|
|
||||||
class OverviewCardPresenter {
|
class OverviewCardPresenter {
|
||||||
fun present(habit: Habit): OverviewCardViewModel {
|
companion object {
|
||||||
|
fun buildState(habit: Habit): OverviewCardState {
|
||||||
val today = DateUtils.getTodayWithOffset()
|
val today = DateUtils.getTodayWithOffset()
|
||||||
val lastMonth = today.minus(30)
|
val lastMonth = today.minus(30)
|
||||||
val lastYear = today.minus(365)
|
val lastYear = today.minus(365)
|
||||||
@@ -45,7 +46,7 @@ class OverviewCardPresenter {
|
|||||||
.filter { it.value == Entry.YES_MANUAL }
|
.filter { it.value == Entry.YES_MANUAL }
|
||||||
.count()
|
.count()
|
||||||
.toLong()
|
.toLong()
|
||||||
return OverviewCardViewModel(
|
return OverviewCardState(
|
||||||
color = habit.color,
|
color = habit.color,
|
||||||
scoreToday = scoreToday,
|
scoreToday = scoreToday,
|
||||||
scoreMonthDiff = scoreToday - scoreLastMonth,
|
scoreMonthDiff = scoreToday - scoreLastMonth,
|
||||||
@@ -53,4 +54,5 @@ class OverviewCardPresenter {
|
|||||||
totalCount = totalCount,
|
totalCount = totalCount,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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.Habit
|
||||||
import org.isoron.uhabits.core.models.PaletteColor
|
import org.isoron.uhabits.core.models.PaletteColor
|
||||||
import org.isoron.uhabits.core.models.Score
|
import org.isoron.uhabits.core.models.Score
|
||||||
|
import org.isoron.uhabits.core.preferences.Preferences
|
||||||
import org.isoron.uhabits.core.utils.DateUtils
|
import org.isoron.uhabits.core.utils.DateUtils
|
||||||
|
|
||||||
data class ScoreCardViewModel(
|
data class ScoreCardState(
|
||||||
val scores: List<Score>,
|
val scores: List<Score>,
|
||||||
val bucketSize: Int,
|
val bucketSize: Int,
|
||||||
val spinnerPosition: Int,
|
val spinnerPosition: Int,
|
||||||
val color: PaletteColor,
|
val color: PaletteColor,
|
||||||
)
|
)
|
||||||
|
|
||||||
class ScoreCardPresenter {
|
class ScoreCardPresenter(
|
||||||
|
val preferences: Preferences,
|
||||||
|
val screen: Screen,
|
||||||
|
) {
|
||||||
companion object {
|
companion object {
|
||||||
val BUCKET_SIZES = intArrayOf(1, 7, 31, 92, 365)
|
val BUCKET_SIZES = intArrayOf(1, 7, 31, 92, 365)
|
||||||
fun getTruncateField(bucketSize: Int): DateUtils.TruncateField {
|
fun getTruncateField(bucketSize: Int): DateUtils.TruncateField {
|
||||||
@@ -44,13 +48,12 @@ class ScoreCardPresenter {
|
|||||||
else -> return DateUtils.TruncateField.MONTH
|
else -> return DateUtils.TruncateField.MONTH
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
fun present(
|
fun buildState(
|
||||||
habit: Habit,
|
habit: Habit,
|
||||||
firstWeekday: Int,
|
firstWeekday: Int,
|
||||||
spinnerPosition: Int,
|
spinnerPosition: Int,
|
||||||
): ScoreCardViewModel {
|
): ScoreCardState {
|
||||||
val bucketSize = BUCKET_SIZES[spinnerPosition]
|
val bucketSize = BUCKET_SIZES[spinnerPosition]
|
||||||
val today = DateUtils.getTodayWithOffset()
|
val today = DateUtils.getTodayWithOffset()
|
||||||
val oldest = habit.computedEntries.getKnown().lastOrNull()?.timestamp ?: today
|
val oldest = habit.computedEntries.getKnown().lastOrNull()?.timestamp ?: today
|
||||||
@@ -69,11 +72,23 @@ class ScoreCardPresenter {
|
|||||||
it.timestamp
|
it.timestamp
|
||||||
}.reversed()
|
}.reversed()
|
||||||
|
|
||||||
return ScoreCardViewModel(
|
return ScoreCardState(
|
||||||
color = habit.color,
|
color = habit.color,
|
||||||
scores = scores,
|
scores = scores,
|
||||||
bucketSize = bucketSize,
|
bucketSize = bucketSize,
|
||||||
spinnerPosition = spinnerPosition,
|
spinnerPosition = spinnerPosition,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun onSpinnerPosition(position: Int) {
|
||||||
|
preferences.scoreCardSpinnerPosition = position
|
||||||
|
screen.updateWidgets()
|
||||||
|
screen.refresh()
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Screen {
|
||||||
|
fun updateWidgets()
|
||||||
|
fun refresh()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,16 +23,18 @@ import org.isoron.uhabits.core.models.Habit
|
|||||||
import org.isoron.uhabits.core.models.PaletteColor
|
import org.isoron.uhabits.core.models.PaletteColor
|
||||||
import org.isoron.uhabits.core.models.Streak
|
import org.isoron.uhabits.core.models.Streak
|
||||||
|
|
||||||
data class StreakCardViewModel(
|
data class StreakCardState(
|
||||||
val color: PaletteColor,
|
val color: PaletteColor,
|
||||||
val bestStreaks: List<Streak>
|
val bestStreaks: List<Streak>
|
||||||
)
|
)
|
||||||
|
|
||||||
class StreakCartPresenter {
|
class StreakCartPresenter {
|
||||||
fun present(habit: Habit): StreakCardViewModel {
|
companion object {
|
||||||
return StreakCardViewModel(
|
fun buildState(habit: Habit): StreakCardState {
|
||||||
|
return StreakCardState(
|
||||||
color = habit.color,
|
color = habit.color,
|
||||||
bestStreaks = habit.streaks.getBest(10),
|
bestStreaks = habit.streaks.getBest(10),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ import org.isoron.uhabits.core.models.Habit
|
|||||||
import org.isoron.uhabits.core.models.PaletteColor
|
import org.isoron.uhabits.core.models.PaletteColor
|
||||||
import org.isoron.uhabits.core.models.Reminder
|
import org.isoron.uhabits.core.models.Reminder
|
||||||
|
|
||||||
data class SubtitleCardViewModel(
|
data class SubtitleCardState(
|
||||||
val color: PaletteColor,
|
val color: PaletteColor,
|
||||||
val frequency: Frequency,
|
val frequency: Frequency,
|
||||||
val isNumerical: Boolean,
|
val isNumerical: Boolean,
|
||||||
@@ -35,9 +35,10 @@ data class SubtitleCardViewModel(
|
|||||||
)
|
)
|
||||||
|
|
||||||
class SubtitleCardPresenter {
|
class SubtitleCardPresenter {
|
||||||
fun present(
|
companion object {
|
||||||
|
fun buildState(
|
||||||
habit: Habit,
|
habit: Habit,
|
||||||
): SubtitleCardViewModel = SubtitleCardViewModel(
|
): SubtitleCardState = SubtitleCardState(
|
||||||
color = habit.color,
|
color = habit.color,
|
||||||
frequency = habit.frequency,
|
frequency = habit.frequency,
|
||||||
isNumerical = habit.isNumerical,
|
isNumerical = habit.isNumerical,
|
||||||
@@ -46,4 +47,5 @@ class SubtitleCardPresenter {
|
|||||||
targetValue = habit.targetValue,
|
targetValue = habit.targetValue,
|
||||||
unit = habit.unit,
|
unit = habit.unit,
|
||||||
)
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ import org.isoron.uhabits.core.utils.DateUtils
|
|||||||
import java.util.ArrayList
|
import java.util.ArrayList
|
||||||
import java.util.Calendar
|
import java.util.Calendar
|
||||||
|
|
||||||
data class TargetCardViewModel(
|
data class TargetCardState(
|
||||||
val color: PaletteColor,
|
val color: PaletteColor,
|
||||||
val values: List<Double> = listOf(),
|
val values: List<Double> = listOf(),
|
||||||
val targets: List<Double> = listOf(),
|
val targets: List<Double> = listOf(),
|
||||||
@@ -34,10 +34,11 @@ data class TargetCardViewModel(
|
|||||||
)
|
)
|
||||||
|
|
||||||
class TargetCardPresenter {
|
class TargetCardPresenter {
|
||||||
fun present(
|
companion object {
|
||||||
|
fun buildState(
|
||||||
habit: Habit,
|
habit: Habit,
|
||||||
firstWeekday: Int,
|
firstWeekday: Int,
|
||||||
): TargetCardViewModel {
|
): TargetCardState {
|
||||||
val today = DateUtils.getTodayWithOffset()
|
val today = DateUtils.getTodayWithOffset()
|
||||||
val oldest = habit.computedEntries.getKnown().lastOrNull()?.timestamp ?: today
|
val oldest = habit.computedEntries.getKnown().lastOrNull()?.timestamp ?: today
|
||||||
val entries = habit.computedEntries.getByInterval(oldest, today)
|
val entries = habit.computedEntries.getByInterval(oldest, today)
|
||||||
@@ -100,11 +101,12 @@ class TargetCardPresenter {
|
|||||||
intervals.add(91)
|
intervals.add(91)
|
||||||
intervals.add(365)
|
intervals.add(365)
|
||||||
|
|
||||||
return TargetCardViewModel(
|
return TargetCardState(
|
||||||
color = habit.color,
|
color = habit.color,
|
||||||
values = values,
|
values = values,
|
||||||
targets = targets,
|
targets = targets,
|
||||||
intervals = intervals,
|
intervals = intervals,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,25 +31,25 @@ import static org.hamcrest.CoreMatchers.equalTo;
|
|||||||
import static org.junit.Assert.assertThat;
|
import static org.junit.Assert.assertThat;
|
||||||
import static org.mockito.Mockito.*;
|
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 Habit habit;
|
||||||
|
|
||||||
private ShowHabitMenuBehavior menu;
|
private ShowHabitMenuPresenter menu;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setUp() throws Exception
|
public void setUp() throws Exception
|
||||||
{
|
{
|
||||||
super.setUp();
|
super.setUp();
|
||||||
system = mock(ShowHabitMenuBehavior.System.class);
|
system = mock(ShowHabitMenuPresenter.System.class);
|
||||||
screen = mock(ShowHabitMenuBehavior.Screen.class);
|
screen = mock(ShowHabitMenuPresenter.Screen.class);
|
||||||
|
|
||||||
habit = fixtures.createShortHabit();
|
habit = fixtures.createShortHabit();
|
||||||
menu = new ShowHabitMenuBehavior(commandRunner, habit, habitList, screen, system, taskRunner);
|
menu = new ShowHabitMenuPresenter(commandRunner, habit, habitList, screen, system, taskRunner);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
Reference in New Issue
Block a user