From dbe2b28dfede64ed2d7523e00903915c8b6d212b Mon Sep 17 00:00:00 2001 From: razeeman Date: Sat, 21 Dec 2024 09:51:42 +0300 Subject: [PATCH] connect limits logic to views --- .../core/extension/ViewDataExensions.kt | 16 + .../ChartFilterViewDataInteractor.kt | 3 +- .../RecordTypesViewDataInteractor.kt | 3 +- .../core/mapper/GoalViewDataMapper.kt | 26 +- .../core/mapper/RecordTypeViewDataMapper.kt | 55 +- .../simpletimetracker/core/utils/ViewUtis.kt | 6 + .../24.json | 669 ++++++++++++++++++ .../data_local/backup/BackupRepoImpl.kt | 14 +- .../RecordTypeGoalDataLocalMapper.kt | 4 +- ...RunningRecordFromChangeScreenInteractor.kt | 6 + .../domain/model/RecordTypeGoal.kt | 6 +- .../interactor/ArchiveViewDataInteractor.kt | 3 +- .../recordType/RecordTypeAdapterDelegate.kt | 4 +- .../recordType/RecordTypeViewData.kt | 3 +- ...RunningRecordTypeSpecialAdapterDelegate.kt | 4 +- .../RunningRecordTypeSpecialViewData.kt | 3 +- .../runningRecord/GoalTimeViewData.kt | 9 +- .../RunningRecordAdapterDelegate.kt | 6 + .../StatisticsGoalAdapterDelegate.kt | 2 +- .../statisticsGoal/StatisticsGoalViewData.kt | 3 +- .../layout/item_statistics_goal_layout.xml | 2 +- .../ChangeActivityFilterViewDataInteractor.kt | 3 +- .../ChangeCategoryViewDataInteractor.kt | 5 +- .../ChangeComplexRuleViewDataInteractor.kt | 3 +- .../delegate/GoalsViewModelDelegateImpl.kt | 8 +- .../mapper/GoalsViewDataMapper.kt | 2 +- .../ChangeRecordTypeGoalSubtypeViewData.kt | 2 - .../ChangeRecordTagViewDataInteractor.kt | 5 +- .../mapper/ChangeRunningRecordMapper.kt | 6 + .../view/ChangeRunningRecordFragment.kt | 6 + .../dialog/DataEditTypeSelectionViewModel.kt | 3 +- .../ArchiveDialogViewDataInteractor.kt | 3 +- .../cardOrder/viewModel/CardOrderViewModel.kt | 3 +- .../cardSize/mapper/CardSizeViewDataMapper.kt | 3 +- .../DefaultTypesSelectionViewModel.kt | 3 +- .../TypesSelectionViewDataInteractor.kt | 3 +- ...icationActivitySwitchControlsInteractor.kt | 5 +- .../manager/NotificationControlsManager.kt | 15 +- .../manager/NotificationControlsParams.kt | 3 +- .../NotificationGoalParamsInteractor.kt | 39 +- .../manager/NotificationGoalTimeManager.kt | 19 +- .../manager/NotificationGoalTimeParams.kt | 2 + .../customView/NotificationIconView.kt | 22 +- .../NotificationTypeInteractorImpl.kt | 23 +- .../manager/NotificationTypeManager.kt | 7 +- .../layout/notification_icon_view_layout.xml | 3 +- .../src/main/res/values/attrs.xml | 3 +- .../RecordsFilterViewDataInteractor.kt | 3 +- .../RunningRecordsViewDataInteractor.kt | 2 +- ...rtialRestoreSelectionViewDataInteractor.kt | 3 +- .../StatisticsDetailChartInteractor.kt | 32 +- .../StatisticsDetailGoalsInteractor.kt | 6 + .../StatisticsDetailStreaksInteractor.kt | 62 +- .../mapper/StatisticsDetailViewDataMapper.kt | 14 +- ...tatisticsDetailStreaksViewModelDelegate.kt | 16 +- .../feature_views/GoalCheckmarkView.kt | 81 ++- .../feature_views/RecordTypeView.kt | 22 +- .../feature_views/RunningRecordView.kt | 6 + .../feature_views/StatisticsGoalView.kt | 15 +- .../res/drawable/record_type_check_cross.xml | 9 + .../res/layout/goal_checkmark_view_layout.xml | 5 +- .../res/layout/record_running_view_layout.xml | 4 +- .../res/layout/record_type_view_layout.xml | 3 +- .../layout/statistics_goal_view_layout.xml | 6 +- .../src/main/res/values/attrs.xml | 14 +- .../single/WidgetSingleProvider.kt | 15 +- .../viewModel/WidgetUniversalViewModel.kt | 2 +- .../screen/ChangeRunningRecordParams.kt | 13 +- resources/src/main/res/values-ar/strings.xml | 2 +- resources/src/main/res/values-ca/strings.xml | 4 +- resources/src/main/res/values-de/strings.xml | 2 +- resources/src/main/res/values-es/strings.xml | 2 +- resources/src/main/res/values-fa/strings.xml | 2 +- resources/src/main/res/values-fr/strings.xml | 2 +- resources/src/main/res/values-hi/strings.xml | 2 +- resources/src/main/res/values-in/strings.xml | 2 +- resources/src/main/res/values-it/strings.xml | 2 +- resources/src/main/res/values-iw/strings.xml | 2 +- resources/src/main/res/values-ja/strings.xml | 2 +- resources/src/main/res/values-ko/strings.xml | 2 +- resources/src/main/res/values-nl/strings.xml | 2 +- resources/src/main/res/values-pl/strings.xml | 2 +- .../src/main/res/values-pt-rPT/strings.xml | 2 +- resources/src/main/res/values-pt/strings.xml | 2 +- resources/src/main/res/values-ro/strings.xml | 4 +- resources/src/main/res/values-ru/strings.xml | 2 +- resources/src/main/res/values-sv/strings.xml | 2 +- resources/src/main/res/values-tr/strings.xml | 2 +- resources/src/main/res/values-uk/strings.xml | 2 +- resources/src/main/res/values-vi/strings.xml | 2 +- .../src/main/res/values-zh-rTW/strings.xml | 2 +- resources/src/main/res/values-zh/strings.xml | 2 +- resources/src/main/res/values/strings.xml | 2 +- 93 files changed, 1170 insertions(+), 263 deletions(-) create mode 100644 data_local/schemas/com.example.util.simpletimetracker.data_local.database.AppDatabase/24.json create mode 100644 features/feature_views/src/main/res/drawable/record_type_check_cross.xml diff --git a/core/src/main/java/com/example/util/simpletimetracker/core/extension/ViewDataExensions.kt b/core/src/main/java/com/example/util/simpletimetracker/core/extension/ViewDataExensions.kt index c94497f72..7d465fc67 100644 --- a/core/src/main/java/com/example/util/simpletimetracker/core/extension/ViewDataExensions.kt +++ b/core/src/main/java/com/example/util/simpletimetracker/core/extension/ViewDataExensions.kt @@ -48,6 +48,7 @@ fun ChangeRunningRecordParams.Preview.GoalTimeParams.toViewData(): GoalTimeViewD return GoalTimeViewData( text = this.text, complete = this.complete, + state = this.state.toViewData(), ) } @@ -55,9 +56,24 @@ fun GoalTimeViewData.toParams(): ChangeRunningRecordParams.Preview.GoalTimeParam return ChangeRunningRecordParams.Preview.GoalTimeParams( text = this.text, complete = this.complete, + state = this.state.toParams(), ) } +fun ChangeRunningRecordParams.Preview.GoalSubtypeParams.toViewData(): GoalTimeViewData.Subtype { + return when (this) { + is ChangeRunningRecordParams.Preview.GoalSubtypeParams.Goal -> GoalTimeViewData.Subtype.Goal + is ChangeRunningRecordParams.Preview.GoalSubtypeParams.Limit -> GoalTimeViewData.Subtype.Limit + } +} + +fun GoalTimeViewData.Subtype.toParams(): ChangeRunningRecordParams.Preview.GoalSubtypeParams { + return when (this) { + is GoalTimeViewData.Subtype.Goal -> ChangeRunningRecordParams.Preview.GoalSubtypeParams.Goal + is GoalTimeViewData.Subtype.Limit -> ChangeRunningRecordParams.Preview.GoalSubtypeParams.Limit + } +} + fun ChangeRecordDateTimeStateParams.toViewData(): ChangeRecordDateTimeState { val state = when (val state = this.state) { is ChangeRecordDateTimeStateParams.State.DateTime -> { diff --git a/core/src/main/java/com/example/util/simpletimetracker/core/interactor/ChartFilterViewDataInteractor.kt b/core/src/main/java/com/example/util/simpletimetracker/core/interactor/ChartFilterViewDataInteractor.kt index 22cb0d218..c438202cf 100644 --- a/core/src/main/java/com/example/util/simpletimetracker/core/interactor/ChartFilterViewDataInteractor.kt +++ b/core/src/main/java/com/example/util/simpletimetracker/core/interactor/ChartFilterViewDataInteractor.kt @@ -10,6 +10,7 @@ import com.example.util.simpletimetracker.domain.model.Category import com.example.util.simpletimetracker.domain.model.RecordTag import com.example.util.simpletimetracker.domain.model.RecordType import com.example.util.simpletimetracker.feature_base_adapter.ViewHolderType +import com.example.util.simpletimetracker.feature_views.GoalCheckmarkView import javax.inject.Inject class ChartFilterViewDataInteractor @Inject constructor( @@ -43,7 +44,7 @@ class ChartFilterViewDataInteractor @Inject constructor( isFiltered = type.id in typeIdsFiltered, numberOfCards = numberOfCards, isDarkTheme = isDarkTheme, - isChecked = null, + checkState = GoalCheckmarkView.CheckState.HIDDEN, isComplete = false, ) } diff --git a/core/src/main/java/com/example/util/simpletimetracker/core/interactor/RecordTypesViewDataInteractor.kt b/core/src/main/java/com/example/util/simpletimetracker/core/interactor/RecordTypesViewDataInteractor.kt index ce932d8e0..1d28122ea 100644 --- a/core/src/main/java/com/example/util/simpletimetracker/core/interactor/RecordTypesViewDataInteractor.kt +++ b/core/src/main/java/com/example/util/simpletimetracker/core/interactor/RecordTypesViewDataInteractor.kt @@ -4,6 +4,7 @@ import com.example.util.simpletimetracker.feature_base_adapter.ViewHolderType import com.example.util.simpletimetracker.core.mapper.RecordTypeViewDataMapper import com.example.util.simpletimetracker.domain.interactor.PrefsInteractor import com.example.util.simpletimetracker.domain.interactor.RecordTypeInteractor +import com.example.util.simpletimetracker.feature_views.GoalCheckmarkView import javax.inject.Inject class RecordTypesViewDataInteractor @Inject constructor( @@ -24,7 +25,7 @@ class RecordTypesViewDataInteractor @Inject constructor( recordType = it, numberOfCards = numberOfCards, isDarkTheme = isDarkTheme, - isChecked = null, + checkState = GoalCheckmarkView.CheckState.HIDDEN, isComplete = false, ) } diff --git a/core/src/main/java/com/example/util/simpletimetracker/core/mapper/GoalViewDataMapper.kt b/core/src/main/java/com/example/util/simpletimetracker/core/mapper/GoalViewDataMapper.kt index 4ba0f7d8f..74ba9976e 100644 --- a/core/src/main/java/com/example/util/simpletimetracker/core/mapper/GoalViewDataMapper.kt +++ b/core/src/main/java/com/example/util/simpletimetracker/core/mapper/GoalViewDataMapper.kt @@ -14,6 +14,7 @@ import com.example.util.simpletimetracker.domain.model.RecordTypeGoal import com.example.util.simpletimetracker.domain.model.Statistics import com.example.util.simpletimetracker.feature_base_adapter.runningRecord.GoalTimeViewData import com.example.util.simpletimetracker.feature_base_adapter.statisticsGoal.StatisticsGoalViewData +import com.example.util.simpletimetracker.feature_views.GoalCheckmarkView import javax.inject.Inject import kotlin.math.roundToLong @@ -33,6 +34,7 @@ class GoalViewDataMapper @Inject constructor( val noGoal = GoalTimeViewData( text = "", complete = false, + state = GoalTimeViewData.Subtype.Goal, ) if (goal == null || goal.value <= 0L || !goalsVisible) { return noGoal @@ -78,9 +80,15 @@ class GoalViewDataMapper @Inject constructor( "$typeString $formatted" } + val state = when (goal.subtype) { + is RecordTypeGoal.Subtype.Goal -> GoalTimeViewData.Subtype.Goal + is RecordTypeGoal.Subtype.Limit -> GoalTimeViewData.Subtype.Limit + } + return GoalTimeViewData( text = durationLeftString, complete = complete, + state = state, ) } @@ -184,7 +192,15 @@ class GoalViewDataMapper @Inject constructor( is RecordTypeGoal.Type.Count -> statistics?.data?.count.orZero() } - val goalComplete = goalValue - current <= 0L + val goalSubtype = goal.subtype + val goalState = if (goalValue - current <= 0L) { + when (goalSubtype) { + is RecordTypeGoal.Subtype.Goal -> GoalCheckmarkView.CheckState.GOAL_REACHED + is RecordTypeGoal.Subtype.Limit -> GoalCheckmarkView.CheckState.LIMIT_REACHED + } + } else { + GoalCheckmarkView.CheckState.HIDDEN + } val (currentValueString, goalValueString) = when (goal.type) { is RecordTypeGoal.Type.Duration -> { mapDuration(current) to mapDuration(goalValue) @@ -193,8 +209,10 @@ class GoalViewDataMapper @Inject constructor( mapCount(current) to mapCount(goalValue) } } - val goalHint = resourceRepo.getString(R.string.change_record_type_goal_time_hint) - .lowercase() + val goalHint = when (goalSubtype) { + is RecordTypeGoal.Subtype.Goal -> R.string.change_record_type_goal_time_hint + is RecordTypeGoal.Subtype.Limit -> R.string.change_record_type_limit_time_hint + }.let(resourceRepo::getString).lowercase() val goalString = "$goalHint - $goalValueString" val goalPercent = if (goalValue == 0L) { 0 @@ -206,7 +224,7 @@ class GoalViewDataMapper @Inject constructor( goalCurrent = currentValueString, goal = goalString, goalPercent = goalPercent.let { "$it%" }, - goalComplete = goalComplete, + goalState = goalState, percent = goalPercent, ) } diff --git a/core/src/main/java/com/example/util/simpletimetracker/core/mapper/RecordTypeViewDataMapper.kt b/core/src/main/java/com/example/util/simpletimetracker/core/mapper/RecordTypeViewDataMapper.kt index f1b095a9c..c359efefc 100644 --- a/core/src/main/java/com/example/util/simpletimetracker/core/mapper/RecordTypeViewDataMapper.kt +++ b/core/src/main/java/com/example/util/simpletimetracker/core/mapper/RecordTypeViewDataMapper.kt @@ -15,6 +15,7 @@ import com.example.util.simpletimetracker.feature_base_adapter.ViewHolderType import com.example.util.simpletimetracker.feature_base_adapter.empty.EmptyViewData import com.example.util.simpletimetracker.feature_base_adapter.recordType.RecordTypeViewData import com.example.util.simpletimetracker.feature_base_adapter.recordTypeSpecial.RunningRecordTypeSpecialViewData +import com.example.util.simpletimetracker.feature_views.GoalCheckmarkView import com.example.util.simpletimetracker.feature_views.viewData.RecordTypeIcon import javax.inject.Inject @@ -48,7 +49,7 @@ class RecordTypeViewDataMapper @Inject constructor( recordType: RecordType, numberOfCards: Int, isDarkTheme: Boolean, - isChecked: Boolean?, + checkState: GoalCheckmarkView.CheckState, isComplete: Boolean, ): RecordTypeViewData { return RecordTypeViewData( @@ -60,7 +61,7 @@ class RecordTypeViewDataMapper @Inject constructor( width = recordTypeCardSizeMapper.toCardWidth(numberOfCards), height = recordTypeCardSizeMapper.toCardHeight(numberOfCards), asRow = recordTypeCardSizeMapper.toCardAsRow(numberOfCards), - isChecked = isChecked, + checkState = checkState, isComplete = isComplete, ) } @@ -70,14 +71,14 @@ class RecordTypeViewDataMapper @Inject constructor( numberOfCards: Int, isDarkTheme: Boolean, isFiltered: Boolean, - isChecked: Boolean?, + checkState: GoalCheckmarkView.CheckState, isComplete: Boolean, ): RecordTypeViewData { val default = map( recordType = recordType, numberOfCards = numberOfCards, isDarkTheme = isDarkTheme, - isChecked = isChecked, + checkState = checkState, isComplete = isComplete, ) @@ -103,7 +104,7 @@ class RecordTypeViewDataMapper @Inject constructor( icon = RecordTypeIcon.Image(R.drawable.add), numberOfCards = numberOfCards, isDarkTheme = isDarkTheme, - isChecked = null, + checkState = GoalCheckmarkView.CheckState.HIDDEN, ) } @@ -117,7 +118,7 @@ class RecordTypeViewDataMapper @Inject constructor( icon = RecordTypeIcon.Image(R.drawable.add), numberOfCards = numberOfCards, isDarkTheme = isDarkTheme, - isChecked = null, + checkState = GoalCheckmarkView.CheckState.HIDDEN, ) } @@ -131,7 +132,7 @@ class RecordTypeViewDataMapper @Inject constructor( icon = RecordTypeIcon.Image(R.drawable.repeat), numberOfCards = numberOfCards, isDarkTheme = isDarkTheme, - isChecked = null, + checkState = GoalCheckmarkView.CheckState.HIDDEN, ) } @@ -146,8 +147,12 @@ class RecordTypeViewDataMapper @Inject constructor( icon = RecordTypeIcon.Image(R.drawable.pomodoro), numberOfCards = numberOfCards, isDarkTheme = isDarkTheme, - // Somewhat weird logic, null - means do not show, false - red dot not checked. - isChecked = if (isPomodoroStarted) false else null, + // Somewhat weird logic, GOAL_NOT_REACHED - red dot not checked. + checkState = if (isPomodoroStarted) { + GoalCheckmarkView.CheckState.GOAL_NOT_REACHED + } else { + GoalCheckmarkView.CheckState.HIDDEN + }, ) } @@ -155,7 +160,7 @@ class RecordTypeViewDataMapper @Inject constructor( type: RecordType, goals: Map>, allDailyCurrents: Map, - ): Boolean? { + ): GoalCheckmarkView.CheckState { return mapGoalCheckmark( goal = goals[type.id].orEmpty().getDaily(), dailyCurrent = allDailyCurrents[type.id], @@ -165,7 +170,7 @@ class RecordTypeViewDataMapper @Inject constructor( fun mapGoalCheckmark( goal: RecordTypeGoal?, dailyCurrent: GetCurrentRecordsDurationInteractor.Result?, - ): Boolean? { + ): GoalCheckmarkView.CheckState { val goalValue = when (goal?.type) { is RecordTypeGoal.Type.Duration -> goal.value * 1000 is RecordTypeGoal.Type.Count -> goal.value @@ -177,8 +182,28 @@ class RecordTypeViewDataMapper @Inject constructor( else -> 0 } val valueLeft = goalValue - current - - return if (goal != null) valueLeft <= 0L else null + val isLimit = goal?.subtype == RecordTypeGoal.Subtype.Limit + + // TODO GOAL excess for goal count? + // TODO GOAL detailed stats, excess graph, count deficit when should have a goal. + // TODO GOAL streaks, skip count days when should not have a goal (daily goals). + return if (goal != null) { + if (valueLeft <= 0L) { + if (isLimit) { + GoalCheckmarkView.CheckState.LIMIT_REACHED + } else { + GoalCheckmarkView.CheckState.GOAL_REACHED + } + } else { + if (isLimit) { + GoalCheckmarkView.CheckState.LIMIT_NOT_REACHED + } else { + GoalCheckmarkView.CheckState.GOAL_NOT_REACHED + } + } + } else { + GoalCheckmarkView.CheckState.HIDDEN + } } private fun mapToSpecial( @@ -187,7 +212,7 @@ class RecordTypeViewDataMapper @Inject constructor( icon: RecordTypeIcon, numberOfCards: Int, isDarkTheme: Boolean, - isChecked: Boolean?, + checkState: GoalCheckmarkView.CheckState, ): RunningRecordTypeSpecialViewData { return RunningRecordTypeSpecialViewData( type = type, @@ -197,7 +222,7 @@ class RecordTypeViewDataMapper @Inject constructor( width = recordTypeCardSizeMapper.toCardWidth(numberOfCards), height = recordTypeCardSizeMapper.toCardHeight(numberOfCards), asRow = recordTypeCardSizeMapper.toCardAsRow(numberOfCards), - isChecked = isChecked, + checkState = checkState, ) } diff --git a/core/src/main/java/com/example/util/simpletimetracker/core/utils/ViewUtis.kt b/core/src/main/java/com/example/util/simpletimetracker/core/utils/ViewUtis.kt index 2dea0feb0..3e3ab5103 100644 --- a/core/src/main/java/com/example/util/simpletimetracker/core/utils/ViewUtis.kt +++ b/core/src/main/java/com/example/util/simpletimetracker/core/utils/ViewUtis.kt @@ -4,8 +4,10 @@ import androidx.cardview.widget.CardView import androidx.recyclerview.widget.RecyclerView import com.example.util.simpletimetracker.core.R import com.example.util.simpletimetracker.domain.interactor.UpdateRunningRecordFromChangeScreenInteractor +import com.example.util.simpletimetracker.domain.interactor.UpdateRunningRecordFromChangeScreenInteractor.GoalState import com.example.util.simpletimetracker.feature_base_adapter.ViewHolderType import com.example.util.simpletimetracker.feature_base_adapter.runningRecord.RunningRecordViewData +import com.example.util.simpletimetracker.feature_views.GoalCheckmarkView.CheckState import com.example.util.simpletimetracker.feature_views.RunningRecordView import com.example.util.simpletimetracker.feature_views.extension.getThemedAttr @@ -44,6 +46,10 @@ fun updateRunningRecordPreview( if (it.itemGoalTime.isNotEmpty() && update.goalText.isNotEmpty()) { it.itemGoalTime = update.goalText it.itemGoalTimeComplete = update.goalComplete + it.itemGoalTimeCheck = when (update.goalState) { + is GoalState.Goal -> CheckState.GOAL_REACHED + is GoalState.Limit -> CheckState.LIMIT_REACHED + } } update.additionalData?.let { additionalUpdate -> diff --git a/data_local/schemas/com.example.util.simpletimetracker.data_local.database.AppDatabase/24.json b/data_local/schemas/com.example.util.simpletimetracker.data_local.database.AppDatabase/24.json new file mode 100644 index 000000000..baf99c0fc --- /dev/null +++ b/data_local/schemas/com.example.util.simpletimetracker.data_local.database.AppDatabase/24.json @@ -0,0 +1,669 @@ +{ + "formatVersion": 1, + "database": { + "version": 24, + "identityHash": "62da5bd067e4030ae4d3c173dbd6a5ff", + "entities": [ + { + "tableName": "records", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `type_id` INTEGER NOT NULL, `time_started` INTEGER NOT NULL, `time_ended` INTEGER NOT NULL, `comment` TEXT NOT NULL, `tag_id` INTEGER NOT NULL)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "typeId", + "columnName": "type_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "timeStarted", + "columnName": "time_started", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "timeEnded", + "columnName": "time_ended", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "comment", + "columnName": "comment", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "tagId", + "columnName": "tag_id", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": true, + "columnNames": [ + "id" + ] + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "recordTypes", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `name` TEXT NOT NULL, `icon` TEXT NOT NULL, `color` INTEGER NOT NULL, `color_int` TEXT NOT NULL, `hidden` INTEGER NOT NULL, `instant` INTEGER NOT NULL, `instantDuration` INTEGER NOT NULL, `note` TEXT NOT NULL)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "icon", + "columnName": "icon", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "color", + "columnName": "color", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "colorInt", + "columnName": "color_int", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "hidden", + "columnName": "hidden", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "instant", + "columnName": "instant", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "defaultDuration", + "columnName": "instantDuration", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "note", + "columnName": "note", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": true, + "columnNames": [ + "id" + ] + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "runningRecords", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `time_started` INTEGER NOT NULL, `comment` TEXT NOT NULL, `tag_id` INTEGER NOT NULL, PRIMARY KEY(`id`))", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "timeStarted", + "columnName": "time_started", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "comment", + "columnName": "comment", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "tagId", + "columnName": "tag_id", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "id" + ] + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "categories", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `name` TEXT NOT NULL, `color` INTEGER NOT NULL, `color_int` TEXT NOT NULL, `note` TEXT NOT NULL)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "color", + "columnName": "color", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "colorInt", + "columnName": "color_int", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "note", + "columnName": "note", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": true, + "columnNames": [ + "id" + ] + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "recordTypeCategory", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`record_type_id` INTEGER NOT NULL, `category_id` INTEGER NOT NULL, PRIMARY KEY(`record_type_id`, `category_id`))", + "fields": [ + { + "fieldPath": "recordTypeId", + "columnName": "record_type_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "categoryId", + "columnName": "category_id", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "record_type_id", + "category_id" + ] + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "recordTags", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `type_id` INTEGER NOT NULL, `name` TEXT NOT NULL, `icon` TEXT NOT NULL, `color` INTEGER NOT NULL, `color_int` TEXT NOT NULL, `icon_color_source` INTEGER NOT NULL, `archived` INTEGER NOT NULL, `note` TEXT NOT NULL)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "typeId", + "columnName": "type_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "icon", + "columnName": "icon", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "color", + "columnName": "color", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "colorInt", + "columnName": "color_int", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "iconColorSource", + "columnName": "icon_color_source", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "archived", + "columnName": "archived", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "note", + "columnName": "note", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": true, + "columnNames": [ + "id" + ] + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "recordToRecordTag", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`record_id` INTEGER NOT NULL, `record_tag_id` INTEGER NOT NULL, PRIMARY KEY(`record_id`, `record_tag_id`))", + "fields": [ + { + "fieldPath": "recordId", + "columnName": "record_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "recordTagId", + "columnName": "record_tag_id", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "record_id", + "record_tag_id" + ] + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "runningRecordToRecordTag", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`running_record_id` INTEGER NOT NULL, `record_tag_id` INTEGER NOT NULL, PRIMARY KEY(`running_record_id`, `record_tag_id`))", + "fields": [ + { + "fieldPath": "runningRecordId", + "columnName": "running_record_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "recordTagId", + "columnName": "record_tag_id", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "running_record_id", + "record_tag_id" + ] + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "recordTypeToTag", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`record_type_id` INTEGER NOT NULL, `record_tag_id` INTEGER NOT NULL, PRIMARY KEY(`record_type_id`, `record_tag_id`))", + "fields": [ + { + "fieldPath": "recordTypeId", + "columnName": "record_type_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "tagId", + "columnName": "record_tag_id", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "record_type_id", + "record_tag_id" + ] + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "recordTypeToDefaultTag", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`record_type_id` INTEGER NOT NULL, `record_tag_id` INTEGER NOT NULL, PRIMARY KEY(`record_type_id`, `record_tag_id`))", + "fields": [ + { + "fieldPath": "recordTypeId", + "columnName": "record_type_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "tagId", + "columnName": "record_tag_id", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "record_type_id", + "record_tag_id" + ] + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "activityFilters", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `selectedIds` TEXT NOT NULL, `type` INTEGER NOT NULL, `name` TEXT NOT NULL, `color` INTEGER NOT NULL, `color_int` TEXT NOT NULL, `selected` INTEGER NOT NULL)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "selectedIds", + "columnName": "selectedIds", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "type", + "columnName": "type", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "color", + "columnName": "color", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "colorInt", + "columnName": "color_int", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "selected", + "columnName": "selected", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": true, + "columnNames": [ + "id" + ] + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "favouriteComments", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `comment` TEXT NOT NULL)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "comment", + "columnName": "comment", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": true, + "columnNames": [ + "id" + ] + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "recordTypeGoals", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `type_id` INTEGER NOT NULL, `range` INTEGER NOT NULL, `type` INTEGER NOT NULL, `goalType` INTEGER NOT NULL, `value` INTEGER NOT NULL, `category_id` INTEGER NOT NULL, `days_of_week` TEXT NOT NULL)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "typeId", + "columnName": "type_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "range", + "columnName": "range", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "type", + "columnName": "type", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "goalType", + "columnName": "goalType", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "value", + "columnName": "value", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "categoryId", + "columnName": "category_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "daysOfWeek", + "columnName": "days_of_week", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": true, + "columnNames": [ + "id" + ] + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "favouriteIcons", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `icon` TEXT NOT NULL)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "icon", + "columnName": "icon", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": true, + "columnNames": [ + "id" + ] + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "complexRules", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `disabled` INTEGER NOT NULL, `actionType` INTEGER NOT NULL, `actionSetTagIds` TEXT NOT NULL, `conditionStartingTypeIds` TEXT NOT NULL, `conditionCurrentTypeIds` TEXT NOT NULL, `conditionDaysOfWeek` TEXT NOT NULL)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "disabled", + "columnName": "disabled", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "action", + "columnName": "actionType", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "actionSetTagIds", + "columnName": "actionSetTagIds", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "conditionStartingTypeIds", + "columnName": "conditionStartingTypeIds", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "conditionCurrentTypeIds", + "columnName": "conditionCurrentTypeIds", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "conditionDaysOfWeek", + "columnName": "conditionDaysOfWeek", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": true, + "columnNames": [ + "id" + ] + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "favouriteColors", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `color_int` TEXT NOT NULL)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "colorInt", + "columnName": "color_int", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": true, + "columnNames": [ + "id" + ] + }, + "indices": [], + "foreignKeys": [] + } + ], + "views": [], + "setupQueries": [ + "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", + "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '62da5bd067e4030ae4d3c173dbd6a5ff')" + ] + } +} \ No newline at end of file diff --git a/data_local/src/main/java/com/example/util/simpletimetracker/data_local/backup/BackupRepoImpl.kt b/data_local/src/main/java/com/example/util/simpletimetracker/data_local/backup/BackupRepoImpl.kt index 669b2bb5c..85bc94c3a 100644 --- a/data_local/src/main/java/com/example/util/simpletimetracker/data_local/backup/BackupRepoImpl.kt +++ b/data_local/src/main/java/com/example/util/simpletimetracker/data_local/backup/BackupRepoImpl.kt @@ -505,7 +505,7 @@ class BackupRepoImpl @Inject constructor( is RecordTypeGoal.Type.Duration -> 0L is RecordTypeGoal.Type.Count -> 1L }.toString() - val subtypeString = when (recordTypeGoal.subType) { + val subtypeString = when (recordTypeGoal.subtype) { is RecordTypeGoal.Subtype.Goal -> 0L is RecordTypeGoal.Subtype.Limit -> 1L }.toString() @@ -556,7 +556,7 @@ class BackupRepoImpl @Inject constructor( val monthlyGoalTime = parts.getOrNull(10)?.toLongOrNull().orZero() // Didn't exist when goal time was in type db, no need to migrate. val daysOfWeek = DayOfWeek.entries - val subType = RecordTypeGoal.Subtype.Goal + val subtype = RecordTypeGoal.Subtype.Goal val goalTimes = mutableListOf().apply { if (goalTime != 0L) { @@ -565,7 +565,7 @@ class BackupRepoImpl @Inject constructor( idData = RecordTypeGoal.IdData.Type(typeId), range = RecordTypeGoal.Range.Session, type = RecordTypeGoal.Type.Duration(goalTime), - subType = subType, + subtype = subtype, daysOfWeek = daysOfWeek, ).let(::add) } @@ -574,7 +574,7 @@ class BackupRepoImpl @Inject constructor( idData = RecordTypeGoal.IdData.Type(typeId), range = RecordTypeGoal.Range.Daily, type = RecordTypeGoal.Type.Duration(dailyGoalTime), - subType = subType, + subtype = subtype, daysOfWeek = daysOfWeek, ).let(::add) } @@ -583,7 +583,7 @@ class BackupRepoImpl @Inject constructor( idData = RecordTypeGoal.IdData.Type(typeId), range = RecordTypeGoal.Range.Weekly, type = RecordTypeGoal.Type.Duration(weeklyGoalTime), - subType = subType, + subtype = subtype, daysOfWeek = daysOfWeek, ).let(::add) } @@ -592,7 +592,7 @@ class BackupRepoImpl @Inject constructor( idData = RecordTypeGoal.IdData.Type(typeId), range = RecordTypeGoal.Range.Monthly, type = RecordTypeGoal.Type.Duration(monthlyGoalTime), - subType = subType, + subtype = subtype, daysOfWeek = daysOfWeek, ).let(::add) } @@ -765,7 +765,7 @@ class BackupRepoImpl @Inject constructor( else -> RecordTypeGoal.Type.Duration(value) } }, - subType = run { + subtype = run { when (parts.getOrNull(8)?.toLongOrNull()) { 0L -> RecordTypeGoal.Subtype.Goal 1L -> RecordTypeGoal.Subtype.Limit diff --git a/data_local/src/main/java/com/example/util/simpletimetracker/data_local/recordType/RecordTypeGoalDataLocalMapper.kt b/data_local/src/main/java/com/example/util/simpletimetracker/data_local/recordType/RecordTypeGoalDataLocalMapper.kt index 61959347f..f4040f899 100644 --- a/data_local/src/main/java/com/example/util/simpletimetracker/data_local/recordType/RecordTypeGoalDataLocalMapper.kt +++ b/data_local/src/main/java/com/example/util/simpletimetracker/data_local/recordType/RecordTypeGoalDataLocalMapper.kt @@ -29,7 +29,7 @@ class RecordTypeGoalDataLocalMapper @Inject constructor( 1L -> RecordTypeGoal.Type.Count(dbo.value) else -> RecordTypeGoal.Type.Duration(dbo.value) }, - subType = when (dbo.subType) { + subtype = when (dbo.subType) { 0L -> RecordTypeGoal.Subtype.Goal 1L -> RecordTypeGoal.Subtype.Limit else -> RecordTypeGoal.Subtype.Goal @@ -52,7 +52,7 @@ class RecordTypeGoalDataLocalMapper @Inject constructor( is RecordTypeGoal.Type.Duration -> 0L is RecordTypeGoal.Type.Count -> 1L }, - subType = when (domain.subType) { + subType = when (domain.subtype) { is RecordTypeGoal.Subtype.Goal -> 0L is RecordTypeGoal.Subtype.Limit -> 1L }, diff --git a/domain/src/main/java/com/example/util/simpletimetracker/domain/interactor/UpdateRunningRecordFromChangeScreenInteractor.kt b/domain/src/main/java/com/example/util/simpletimetracker/domain/interactor/UpdateRunningRecordFromChangeScreenInteractor.kt index 90ecef45b..e893b2040 100644 --- a/domain/src/main/java/com/example/util/simpletimetracker/domain/interactor/UpdateRunningRecordFromChangeScreenInteractor.kt +++ b/domain/src/main/java/com/example/util/simpletimetracker/domain/interactor/UpdateRunningRecordFromChangeScreenInteractor.kt @@ -27,6 +27,7 @@ class UpdateRunningRecordFromChangeScreenInteractor @Inject constructor() { val timerTotal: String, val goalText: String, val goalComplete: Boolean, + val goalState: GoalState, val additionalData: AdditionalData?, ) @@ -35,4 +36,9 @@ class UpdateRunningRecordFromChangeScreenInteractor @Inject constructor() { val timeStarted: String, val comment: String, ) + + sealed interface GoalState { + object Goal : GoalState + object Limit : GoalState + } } \ No newline at end of file diff --git a/domain/src/main/java/com/example/util/simpletimetracker/domain/model/RecordTypeGoal.kt b/domain/src/main/java/com/example/util/simpletimetracker/domain/model/RecordTypeGoal.kt index 70cbedb14..5955896bf 100644 --- a/domain/src/main/java/com/example/util/simpletimetracker/domain/model/RecordTypeGoal.kt +++ b/domain/src/main/java/com/example/util/simpletimetracker/domain/model/RecordTypeGoal.kt @@ -5,7 +5,7 @@ data class RecordTypeGoal( val idData: IdData, val range: Range, val type: Type, - val subType: Subtype, + val subtype: Subtype, val daysOfWeek: List, ) { @@ -31,7 +31,7 @@ data class RecordTypeGoal( } sealed interface Subtype { - data object Goal: Subtype - data object Limit: Subtype + data object Goal : Subtype + data object Limit : Subtype } } \ No newline at end of file diff --git a/features/feature_archive/src/main/java/com/example/util/simpletimetracker/feature_archive/interactor/ArchiveViewDataInteractor.kt b/features/feature_archive/src/main/java/com/example/util/simpletimetracker/feature_archive/interactor/ArchiveViewDataInteractor.kt index b28fa809d..7c1125839 100644 --- a/features/feature_archive/src/main/java/com/example/util/simpletimetracker/feature_archive/interactor/ArchiveViewDataInteractor.kt +++ b/features/feature_archive/src/main/java/com/example/util/simpletimetracker/feature_archive/interactor/ArchiveViewDataInteractor.kt @@ -11,6 +11,7 @@ import com.example.util.simpletimetracker.feature_archive.viewData.ArchiveViewDa import com.example.util.simpletimetracker.feature_base_adapter.ViewHolderType import com.example.util.simpletimetracker.feature_base_adapter.divider.DividerViewData import com.example.util.simpletimetracker.feature_base_adapter.hint.HintViewData +import com.example.util.simpletimetracker.feature_views.GoalCheckmarkView import javax.inject.Inject class ArchiveViewDataInteractor @Inject constructor( @@ -39,7 +40,7 @@ class ArchiveViewDataInteractor @Inject constructor( numberOfCards = numberOfCards, isDarkTheme = isDarkTheme, isFiltered = false, - isChecked = null, + checkState = GoalCheckmarkView.CheckState.HIDDEN, isComplete = false, ) } diff --git a/features/feature_base_adapter/src/main/java/com/example/util/simpletimetracker/feature_base_adapter/recordType/RecordTypeAdapterDelegate.kt b/features/feature_base_adapter/src/main/java/com/example/util/simpletimetracker/feature_base_adapter/recordType/RecordTypeAdapterDelegate.kt index c725a2d60..5662d6881 100644 --- a/features/feature_base_adapter/src/main/java/com/example/util/simpletimetracker/feature_base_adapter/recordType/RecordTypeAdapterDelegate.kt +++ b/features/feature_base_adapter/src/main/java/com/example/util/simpletimetracker/feature_base_adapter/recordType/RecordTypeAdapterDelegate.kt @@ -1,7 +1,6 @@ package com.example.util.simpletimetracker.feature_base_adapter.recordType import androidx.core.view.ViewCompat -import com.example.util.simpletimetracker.domain.extension.orFalse import com.example.util.simpletimetracker.feature_base_adapter.createRecyclerBindingAdapterDelegate import com.example.util.simpletimetracker.feature_views.TransitionNames import com.example.util.simpletimetracker.feature_views.extension.dpToPx @@ -33,8 +32,7 @@ fun createRecordTypeAdapterDelegate( itemIconColor = item.iconColor itemIconAlpha = item.iconAlpha itemName = item.name - itemWithCheck = item.isChecked != null - itemIsChecked = item.isChecked.orFalse() + itemCheckState = item.checkState itemCompleteIsAnimated = true itemIsComplete = item.isComplete getCheckmarkOutline().itemIsFiltered = item.itemIsFiltered diff --git a/features/feature_base_adapter/src/main/java/com/example/util/simpletimetracker/feature_base_adapter/recordType/RecordTypeViewData.kt b/features/feature_base_adapter/src/main/java/com/example/util/simpletimetracker/feature_base_adapter/recordType/RecordTypeViewData.kt index fa23a50c7..e2fc59102 100644 --- a/features/feature_base_adapter/src/main/java/com/example/util/simpletimetracker/feature_base_adapter/recordType/RecordTypeViewData.kt +++ b/features/feature_base_adapter/src/main/java/com/example/util/simpletimetracker/feature_base_adapter/recordType/RecordTypeViewData.kt @@ -2,6 +2,7 @@ package com.example.util.simpletimetracker.feature_base_adapter.recordType import androidx.annotation.ColorInt import com.example.util.simpletimetracker.feature_base_adapter.ViewHolderType +import com.example.util.simpletimetracker.feature_views.GoalCheckmarkView.CheckState import com.example.util.simpletimetracker.feature_views.viewData.RecordTypeIcon data class RecordTypeViewData( @@ -14,7 +15,7 @@ data class RecordTypeViewData( val width: Int? = null, val height: Int? = null, val asRow: Boolean = false, - val isChecked: Boolean? = null, + val checkState: CheckState = CheckState.HIDDEN, val itemIsFiltered: Boolean = false, val isComplete: Boolean = false, ) : ViewHolderType { diff --git a/features/feature_base_adapter/src/main/java/com/example/util/simpletimetracker/feature_base_adapter/recordTypeSpecial/RunningRecordTypeSpecialAdapterDelegate.kt b/features/feature_base_adapter/src/main/java/com/example/util/simpletimetracker/feature_base_adapter/recordTypeSpecial/RunningRecordTypeSpecialAdapterDelegate.kt index bb79d1ed7..bd1a6c3d2 100644 --- a/features/feature_base_adapter/src/main/java/com/example/util/simpletimetracker/feature_base_adapter/recordTypeSpecial/RunningRecordTypeSpecialAdapterDelegate.kt +++ b/features/feature_base_adapter/src/main/java/com/example/util/simpletimetracker/feature_base_adapter/recordTypeSpecial/RunningRecordTypeSpecialAdapterDelegate.kt @@ -1,6 +1,5 @@ package com.example.util.simpletimetracker.feature_base_adapter.recordTypeSpecial -import com.example.util.simpletimetracker.domain.extension.orFalse import com.example.util.simpletimetracker.feature_base_adapter.createRecyclerBindingAdapterDelegate import com.example.util.simpletimetracker.feature_views.extension.dpToPx import com.example.util.simpletimetracker.feature_views.extension.setOnClickWith @@ -25,8 +24,7 @@ fun createRunningRecordTypeSpecialAdapterDelegate( itemColor = item.color itemIcon = item.iconId itemName = item.name - itemWithCheck = item.isChecked != null - itemIsChecked = item.isChecked.orFalse() + itemCheckState = item.checkState setOnClickWith(item, onItemClick) } } \ No newline at end of file diff --git a/features/feature_base_adapter/src/main/java/com/example/util/simpletimetracker/feature_base_adapter/recordTypeSpecial/RunningRecordTypeSpecialViewData.kt b/features/feature_base_adapter/src/main/java/com/example/util/simpletimetracker/feature_base_adapter/recordTypeSpecial/RunningRecordTypeSpecialViewData.kt index f729f0a89..641e3a432 100644 --- a/features/feature_base_adapter/src/main/java/com/example/util/simpletimetracker/feature_base_adapter/recordTypeSpecial/RunningRecordTypeSpecialViewData.kt +++ b/features/feature_base_adapter/src/main/java/com/example/util/simpletimetracker/feature_base_adapter/recordTypeSpecial/RunningRecordTypeSpecialViewData.kt @@ -2,6 +2,7 @@ package com.example.util.simpletimetracker.feature_base_adapter.recordTypeSpecia import androidx.annotation.ColorInt import com.example.util.simpletimetracker.feature_base_adapter.ViewHolderType +import com.example.util.simpletimetracker.feature_views.GoalCheckmarkView.CheckState import com.example.util.simpletimetracker.feature_views.viewData.RecordTypeIcon data class RunningRecordTypeSpecialViewData( @@ -12,7 +13,7 @@ data class RunningRecordTypeSpecialViewData( val width: Int, val height: Int, val asRow: Boolean = false, - val isChecked: Boolean? = null, + val checkState: CheckState = CheckState.HIDDEN, ) : ViewHolderType { override fun getUniqueId(): Long = type.hashCode().toLong() diff --git a/features/feature_base_adapter/src/main/java/com/example/util/simpletimetracker/feature_base_adapter/runningRecord/GoalTimeViewData.kt b/features/feature_base_adapter/src/main/java/com/example/util/simpletimetracker/feature_base_adapter/runningRecord/GoalTimeViewData.kt index 7109fd4c5..ae007f7b2 100644 --- a/features/feature_base_adapter/src/main/java/com/example/util/simpletimetracker/feature_base_adapter/runningRecord/GoalTimeViewData.kt +++ b/features/feature_base_adapter/src/main/java/com/example/util/simpletimetracker/feature_base_adapter/runningRecord/GoalTimeViewData.kt @@ -3,4 +3,11 @@ package com.example.util.simpletimetracker.feature_base_adapter.runningRecord data class GoalTimeViewData( val text: String, val complete: Boolean, -) \ No newline at end of file + val state: Subtype, +) { + + sealed interface Subtype { + data object Goal : Subtype + data object Limit : Subtype + } +} \ No newline at end of file diff --git a/features/feature_base_adapter/src/main/java/com/example/util/simpletimetracker/feature_base_adapter/runningRecord/RunningRecordAdapterDelegate.kt b/features/feature_base_adapter/src/main/java/com/example/util/simpletimetracker/feature_base_adapter/runningRecord/RunningRecordAdapterDelegate.kt index 31e63f174..acc743990 100644 --- a/features/feature_base_adapter/src/main/java/com/example/util/simpletimetracker/feature_base_adapter/runningRecord/RunningRecordAdapterDelegate.kt +++ b/features/feature_base_adapter/src/main/java/com/example/util/simpletimetracker/feature_base_adapter/runningRecord/RunningRecordAdapterDelegate.kt @@ -3,6 +3,8 @@ package com.example.util.simpletimetracker.feature_base_adapter.runningRecord import androidx.core.view.ViewCompat import com.example.util.simpletimetracker.domain.extension.orFalse import com.example.util.simpletimetracker.feature_base_adapter.createRecyclerBindingAdapterDelegate +import com.example.util.simpletimetracker.feature_base_adapter.runningRecord.GoalTimeViewData.Subtype +import com.example.util.simpletimetracker.feature_views.GoalCheckmarkView.CheckState import com.example.util.simpletimetracker.feature_views.extension.setOnClick import com.example.util.simpletimetracker.feature_views.extension.setOnLongClick import com.example.util.simpletimetracker.feature_base_adapter.databinding.ItemRunningRecordLayoutBinding as Binding @@ -41,6 +43,10 @@ fun createRunningRecordAdapterDelegate( if (rebind || updates.contains(ViewData.UPDATE_GOAL_TIME).orFalse()) { itemGoalTime = item.goalTime.text itemGoalTimeComplete = item.goalTime.complete + itemGoalTimeCheck = when (item.goalTime.state) { + is Subtype.Goal -> CheckState.GOAL_REACHED + is Subtype.Limit -> CheckState.LIMIT_REACHED + } } if (rebind || updates.contains(ViewData.UPDATE_ICON).orFalse()) { itemIcon = item.iconId diff --git a/features/feature_base_adapter/src/main/java/com/example/util/simpletimetracker/feature_base_adapter/statisticsGoal/StatisticsGoalAdapterDelegate.kt b/features/feature_base_adapter/src/main/java/com/example/util/simpletimetracker/feature_base_adapter/statisticsGoal/StatisticsGoalAdapterDelegate.kt index 8954e54f9..a0be351e7 100644 --- a/features/feature_base_adapter/src/main/java/com/example/util/simpletimetracker/feature_base_adapter/statisticsGoal/StatisticsGoalAdapterDelegate.kt +++ b/features/feature_base_adapter/src/main/java/com/example/util/simpletimetracker/feature_base_adapter/statisticsGoal/StatisticsGoalAdapterDelegate.kt @@ -19,7 +19,7 @@ fun createStatisticsGoalAdapterDelegate( itemGoalCurrent = item.goal.goalCurrent itemGoal = item.goal.goal itemGoalPercent = item.goal.goalPercent - itemGoalTimeComplete = item.goal.goalComplete + itemGoalState = item.goal.goalState if (item.icon != null) { itemIconVisible = true diff --git a/features/feature_base_adapter/src/main/java/com/example/util/simpletimetracker/feature_base_adapter/statisticsGoal/StatisticsGoalViewData.kt b/features/feature_base_adapter/src/main/java/com/example/util/simpletimetracker/feature_base_adapter/statisticsGoal/StatisticsGoalViewData.kt index 5a22fa7a6..9f5bfa7e9 100644 --- a/features/feature_base_adapter/src/main/java/com/example/util/simpletimetracker/feature_base_adapter/statisticsGoal/StatisticsGoalViewData.kt +++ b/features/feature_base_adapter/src/main/java/com/example/util/simpletimetracker/feature_base_adapter/statisticsGoal/StatisticsGoalViewData.kt @@ -2,6 +2,7 @@ package com.example.util.simpletimetracker.feature_base_adapter.statisticsGoal import androidx.annotation.ColorInt import com.example.util.simpletimetracker.feature_base_adapter.ViewHolderType +import com.example.util.simpletimetracker.feature_views.GoalCheckmarkView import com.example.util.simpletimetracker.feature_views.viewData.RecordTypeIcon data class StatisticsGoalViewData( @@ -20,7 +21,7 @@ data class StatisticsGoalViewData( val goalCurrent: String, val goal: String, val goalPercent: String, - val goalComplete: Boolean, + val goalState: GoalCheckmarkView.CheckState, val percent: Long, ) } \ No newline at end of file diff --git a/features/feature_base_adapter/src/main/res/layout/item_statistics_goal_layout.xml b/features/feature_base_adapter/src/main/res/layout/item_statistics_goal_layout.xml index fcce2306c..c8f7c93af 100644 --- a/features/feature_base_adapter/src/main/res/layout/item_statistics_goal_layout.xml +++ b/features/feature_base_adapter/src/main/res/layout/item_statistics_goal_layout.xml @@ -12,5 +12,5 @@ tools:itemGoal="goal 8h 30m" tools:itemGoalCurrent="1h 30m" tools:itemGoalPercent="33%" - tools:itemGoalTimeComplete="false" + tools:itemCheckState="goalReached" tools:itemName="Statistics" /> \ No newline at end of file diff --git a/features/feature_change_activity_filter/src/main/java/com/example/util/simpletimetracker/feature_change_activity_filter/interactor/ChangeActivityFilterViewDataInteractor.kt b/features/feature_change_activity_filter/src/main/java/com/example/util/simpletimetracker/feature_change_activity_filter/interactor/ChangeActivityFilterViewDataInteractor.kt index f93614c3b..727ac044c 100644 --- a/features/feature_change_activity_filter/src/main/java/com/example/util/simpletimetracker/feature_change_activity_filter/interactor/ChangeActivityFilterViewDataInteractor.kt +++ b/features/feature_change_activity_filter/src/main/java/com/example/util/simpletimetracker/feature_change_activity_filter/interactor/ChangeActivityFilterViewDataInteractor.kt @@ -10,6 +10,7 @@ import com.example.util.simpletimetracker.domain.model.ActivityFilter import com.example.util.simpletimetracker.feature_base_adapter.ViewHolderType import com.example.util.simpletimetracker.feature_base_adapter.divider.DividerViewData import com.example.util.simpletimetracker.feature_change_activity_filter.viewData.ChangeActivityFilterTypesViewData +import com.example.util.simpletimetracker.feature_views.GoalCheckmarkView import javax.inject.Inject class ChangeActivityFilterViewDataInteractor @Inject constructor( @@ -36,7 +37,7 @@ class ChangeActivityFilterViewDataInteractor @Inject constructor( recordType = it, numberOfCards = numberOfCards, isDarkTheme = isDarkTheme, - isChecked = null, + checkState = GoalCheckmarkView.CheckState.HIDDEN, isComplete = false, ) } diff --git a/features/feature_change_category/src/main/java/com/example/util/simpletimetracker/feature_change_category/interactor/ChangeCategoryViewDataInteractor.kt b/features/feature_change_category/src/main/java/com/example/util/simpletimetracker/feature_change_category/interactor/ChangeCategoryViewDataInteractor.kt index 6fd5becae..800bdac7b 100644 --- a/features/feature_change_category/src/main/java/com/example/util/simpletimetracker/feature_change_category/interactor/ChangeCategoryViewDataInteractor.kt +++ b/features/feature_change_category/src/main/java/com/example/util/simpletimetracker/feature_change_category/interactor/ChangeCategoryViewDataInteractor.kt @@ -7,6 +7,7 @@ import com.example.util.simpletimetracker.core.mapper.RecordTypeViewDataMapper import com.example.util.simpletimetracker.domain.interactor.PrefsInteractor import com.example.util.simpletimetracker.domain.interactor.RecordTypeInteractor import com.example.util.simpletimetracker.feature_change_category.viewData.ChangeCategoryTypesViewData +import com.example.util.simpletimetracker.feature_views.GoalCheckmarkView import javax.inject.Inject class ChangeCategoryViewDataInteractor @Inject constructor( @@ -36,7 +37,7 @@ class ChangeCategoryViewDataInteractor @Inject constructor( recordType = it, numberOfCards = numberOfCards, isDarkTheme = isDarkTheme, - isChecked = null, + checkState = GoalCheckmarkView.CheckState.HIDDEN, isComplete = false, ) }.let(viewData::addAll) @@ -50,7 +51,7 @@ class ChangeCategoryViewDataInteractor @Inject constructor( recordType = it, numberOfCards = numberOfCards, isDarkTheme = isDarkTheme, - isChecked = null, + checkState = GoalCheckmarkView.CheckState.HIDDEN, isComplete = false, ) }.let(viewData::addAll) diff --git a/features/feature_change_complex_rule/src/main/java/com/example/util/simpletimetracker/feature_change_complex_rule/interactor/ChangeComplexRuleViewDataInteractor.kt b/features/feature_change_complex_rule/src/main/java/com/example/util/simpletimetracker/feature_change_complex_rule/interactor/ChangeComplexRuleViewDataInteractor.kt index 9d9e59477..d58e05fd1 100644 --- a/features/feature_change_complex_rule/src/main/java/com/example/util/simpletimetracker/feature_change_complex_rule/interactor/ChangeComplexRuleViewDataInteractor.kt +++ b/features/feature_change_complex_rule/src/main/java/com/example/util/simpletimetracker/feature_change_complex_rule/interactor/ChangeComplexRuleViewDataInteractor.kt @@ -17,6 +17,7 @@ import com.example.util.simpletimetracker.feature_change_complex_rule.adapter.Ch import com.example.util.simpletimetracker.feature_change_complex_rule.mapper.ChangeComplexRuleViewDataMapper import com.example.util.simpletimetracker.feature_change_complex_rule.viewData.ChangeComplexRuleActionChooserViewData import com.example.util.simpletimetracker.feature_change_complex_rule.viewData.ChangeComplexRuleTypesChooserViewData +import com.example.util.simpletimetracker.feature_views.GoalCheckmarkView import javax.inject.Inject class ChangeComplexRuleViewDataInteractor @Inject constructor( @@ -70,7 +71,7 @@ class ChangeComplexRuleViewDataInteractor @Inject constructor( recordType = it, numberOfCards = numberOfCards, isDarkTheme = isDarkTheme, - isChecked = null, + checkState = GoalCheckmarkView.CheckState.HIDDEN, isComplete = false, ) } diff --git a/features/feature_change_goals/src/main/java/com/example/util/simpletimetracker/feature_change_goals/delegate/GoalsViewModelDelegateImpl.kt b/features/feature_change_goals/src/main/java/com/example/util/simpletimetracker/feature_change_goals/delegate/GoalsViewModelDelegateImpl.kt index 69c056c43..0e188e21e 100644 --- a/features/feature_change_goals/src/main/java/com/example/util/simpletimetracker/feature_change_goals/delegate/GoalsViewModelDelegateImpl.kt +++ b/features/feature_change_goals/src/main/java/com/example/util/simpletimetracker/feature_change_goals/delegate/GoalsViewModelDelegateImpl.kt @@ -69,7 +69,7 @@ class GoalsViewModelDelegateImpl @Inject constructor( updateGoalsViewData() } - override fun onGoalSubTypeSelected(range: RecordTypeGoal.Range, viewData : ButtonsRowViewData) { + override fun onGoalSubTypeSelected(range: RecordTypeGoal.Range, viewData: ButtonsRowViewData) { if (viewData !is ChangeRecordTypeGoalSubtypeViewData) return val newSubType = viewData.subtype if (newGoalsState.getCurrentState(range).subtype::class.java == newSubType::class.java) return @@ -157,7 +157,7 @@ class GoalsViewModelDelegateImpl @Inject constructor( idData = id, range = goalRange, type = type, - subType = goalType, + subtype = goalType, daysOfWeek = daysOfWeek, ).let { recordTypeGoalInteractor.add(it) @@ -202,7 +202,7 @@ class GoalsViewModelDelegateImpl @Inject constructor( ): ChangeRecordTypeGoalsState.GoalState { return ChangeRecordTypeGoalsState.GoalState( type = goal.type, - subtype = goal.subType, + subtype = goal.subtype, ) } @@ -238,7 +238,7 @@ class GoalsViewModelDelegateImpl @Inject constructor( } private fun ChangeRecordTypeGoalsState.getCurrentState( - range: RecordTypeGoal.Range + range: RecordTypeGoal.Range, ): ChangeRecordTypeGoalsState.GoalState { return when (range) { is RecordTypeGoal.Range.Session -> session diff --git a/features/feature_change_goals/src/main/java/com/example/util/simpletimetracker/feature_change_goals/mapper/GoalsViewDataMapper.kt b/features/feature_change_goals/src/main/java/com/example/util/simpletimetracker/feature_change_goals/mapper/GoalsViewDataMapper.kt index 472f7e389..af22cd86f 100644 --- a/features/feature_change_goals/src/main/java/com/example/util/simpletimetracker/feature_change_goals/mapper/GoalsViewDataMapper.kt +++ b/features/feature_change_goals/src/main/java/com/example/util/simpletimetracker/feature_change_goals/mapper/GoalsViewDataMapper.kt @@ -90,7 +90,7 @@ class GoalsViewDataMapper @Inject constructor( fun getDefaultGoal(): ChangeRecordTypeGoalsState.GoalState { return ChangeRecordTypeGoalsState.GoalState( type = RecordTypeGoal.Type.Duration(0), - subtype = RecordTypeGoal.Subtype.Goal + subtype = RecordTypeGoal.Subtype.Goal, ) } diff --git a/features/feature_change_goals/src/main/java/com/example/util/simpletimetracker/feature_change_goals/viewData/ChangeRecordTypeGoalSubtypeViewData.kt b/features/feature_change_goals/src/main/java/com/example/util/simpletimetracker/feature_change_goals/viewData/ChangeRecordTypeGoalSubtypeViewData.kt index a89cf2030..f7ddf22ad 100644 --- a/features/feature_change_goals/src/main/java/com/example/util/simpletimetracker/feature_change_goals/viewData/ChangeRecordTypeGoalSubtypeViewData.kt +++ b/features/feature_change_goals/src/main/java/com/example/util/simpletimetracker/feature_change_goals/viewData/ChangeRecordTypeGoalSubtypeViewData.kt @@ -1,9 +1,7 @@ package com.example.util.simpletimetracker.feature_change_goals.viewData import com.example.util.simpletimetracker.core.view.buttonsRowView.ButtonsRowViewData -import com.example.util.simpletimetracker.domain.model.ChartFilterType import com.example.util.simpletimetracker.domain.model.RecordTypeGoal -import com.example.util.simpletimetracker.feature_base_adapter.ViewHolderType data class ChangeRecordTypeGoalSubtypeViewData( val subtype: RecordTypeGoal.Subtype, diff --git a/features/feature_change_record_tag/src/main/java/com/example/util/simpletimetracker/feature_change_record_tag/interactor/ChangeRecordTagViewDataInteractor.kt b/features/feature_change_record_tag/src/main/java/com/example/util/simpletimetracker/feature_change_record_tag/interactor/ChangeRecordTagViewDataInteractor.kt index 0c9c971ce..83a310254 100644 --- a/features/feature_change_record_tag/src/main/java/com/example/util/simpletimetracker/feature_change_record_tag/interactor/ChangeRecordTagViewDataInteractor.kt +++ b/features/feature_change_record_tag/src/main/java/com/example/util/simpletimetracker/feature_change_record_tag/interactor/ChangeRecordTagViewDataInteractor.kt @@ -8,6 +8,7 @@ import com.example.util.simpletimetracker.feature_base_adapter.ViewHolderType import com.example.util.simpletimetracker.feature_base_adapter.divider.DividerViewData import com.example.util.simpletimetracker.feature_change_record_tag.mapper.ChangeRecordTagMapper import com.example.util.simpletimetracker.feature_change_record_tag.viewData.ChangeRecordTagTypesViewData +import com.example.util.simpletimetracker.feature_views.GoalCheckmarkView import javax.inject.Inject class ChangeRecordTagViewDataInteractor @Inject constructor( @@ -66,7 +67,7 @@ class ChangeRecordTagViewDataInteractor @Inject constructor( recordType = it, numberOfCards = numberOfCards, isDarkTheme = isDarkTheme, - isChecked = null, + checkState = GoalCheckmarkView.CheckState.HIDDEN, isComplete = false, ) }.let(viewData::addAll) @@ -80,7 +81,7 @@ class ChangeRecordTagViewDataInteractor @Inject constructor( recordType = it, numberOfCards = numberOfCards, isDarkTheme = isDarkTheme, - isChecked = null, + checkState = GoalCheckmarkView.CheckState.HIDDEN, isComplete = false, ) }.let(viewData::addAll) diff --git a/features/feature_change_running_record/src/main/java/com/example/util/simpletimetracker/feature_change_running_record/mapper/ChangeRunningRecordMapper.kt b/features/feature_change_running_record/src/main/java/com/example/util/simpletimetracker/feature_change_running_record/mapper/ChangeRunningRecordMapper.kt index 105a49883..08d4ff0d5 100644 --- a/features/feature_change_running_record/src/main/java/com/example/util/simpletimetracker/feature_change_running_record/mapper/ChangeRunningRecordMapper.kt +++ b/features/feature_change_running_record/src/main/java/com/example/util/simpletimetracker/feature_change_running_record/mapper/ChangeRunningRecordMapper.kt @@ -1,6 +1,8 @@ package com.example.util.simpletimetracker.feature_change_running_record.mapper import com.example.util.simpletimetracker.domain.interactor.UpdateRunningRecordFromChangeScreenInteractor +import com.example.util.simpletimetracker.domain.interactor.UpdateRunningRecordFromChangeScreenInteractor.GoalState +import com.example.util.simpletimetracker.feature_base_adapter.runningRecord.GoalTimeViewData.Subtype import com.example.util.simpletimetracker.feature_base_adapter.runningRecord.RunningRecordViewData import javax.inject.Inject @@ -16,6 +18,10 @@ class ChangeRunningRecordMapper @Inject constructor() { timerTotal = recordPreview.timerTotal, goalText = recordPreview.goalTime.text, goalComplete = recordPreview.goalTime.complete, + goalState = when (recordPreview.goalTime.state) { + is Subtype.Goal -> GoalState.Goal + is Subtype.Limit -> GoalState.Limit + }, additionalData = if (fullUpdate) { UpdateRunningRecordFromChangeScreenInteractor.AdditionalData( tagName = recordPreview.tagName, diff --git a/features/feature_change_running_record/src/main/java/com/example/util/simpletimetracker/feature_change_running_record/view/ChangeRunningRecordFragment.kt b/features/feature_change_running_record/src/main/java/com/example/util/simpletimetracker/feature_change_running_record/view/ChangeRunningRecordFragment.kt index e1312bac1..34c250978 100644 --- a/features/feature_change_running_record/src/main/java/com/example/util/simpletimetracker/feature_change_running_record/view/ChangeRunningRecordFragment.kt +++ b/features/feature_change_running_record/src/main/java/com/example/util/simpletimetracker/feature_change_running_record/view/ChangeRunningRecordFragment.kt @@ -12,10 +12,12 @@ import com.example.util.simpletimetracker.core.extension.setSharedTransitions import com.example.util.simpletimetracker.core.extension.toViewData import com.example.util.simpletimetracker.core.utils.InsetConfiguration import com.example.util.simpletimetracker.core.utils.fragmentArgumentDelegate +import com.example.util.simpletimetracker.feature_base_adapter.runningRecord.GoalTimeViewData.Subtype import com.example.util.simpletimetracker.feature_base_adapter.runningRecord.RunningRecordViewData import com.example.util.simpletimetracker.feature_change_record.view.ChangeRecordCore import com.example.util.simpletimetracker.feature_change_running_record.viewData.ChangeRunningRecordViewData import com.example.util.simpletimetracker.feature_change_running_record.viewModel.ChangeRunningRecordViewModel +import com.example.util.simpletimetracker.feature_views.GoalCheckmarkView.CheckState import com.example.util.simpletimetracker.feature_views.extension.animateColor import com.example.util.simpletimetracker.feature_views.extension.setOnClick import com.example.util.simpletimetracker.navigation.Router @@ -153,6 +155,10 @@ class ChangeRunningRecordFragment : itemTimerTotal = item.recordPreview.timerTotal itemGoalTime = item.recordPreview.goalTime.text itemGoalTimeComplete = item.recordPreview.goalTime.complete + itemGoalTimeCheck = when (item.recordPreview.goalTime.state) { + is Subtype.Goal -> CheckState.GOAL_REACHED + is Subtype.Limit -> CheckState.LIMIT_REACHED + } itemComment = item.recordPreview.comment itemNowIconVisible = item.recordPreview.nowIconVisible diff --git a/features/feature_data_edit/src/main/java/com/example/util/simpletimetracker/feature_data_edit/dialog/DataEditTypeSelectionViewModel.kt b/features/feature_data_edit/src/main/java/com/example/util/simpletimetracker/feature_data_edit/dialog/DataEditTypeSelectionViewModel.kt index 18d68be32..3970ea9cb 100644 --- a/features/feature_data_edit/src/main/java/com/example/util/simpletimetracker/feature_data_edit/dialog/DataEditTypeSelectionViewModel.kt +++ b/features/feature_data_edit/src/main/java/com/example/util/simpletimetracker/feature_data_edit/dialog/DataEditTypeSelectionViewModel.kt @@ -12,6 +12,7 @@ import com.example.util.simpletimetracker.feature_base_adapter.ViewHolderType import com.example.util.simpletimetracker.feature_base_adapter.hint.HintViewData import com.example.util.simpletimetracker.feature_base_adapter.loader.LoaderViewData import com.example.util.simpletimetracker.feature_data_edit.R +import com.example.util.simpletimetracker.feature_views.GoalCheckmarkView import dagger.hilt.android.lifecycle.HiltViewModel import javax.inject.Inject import kotlinx.coroutines.launch @@ -45,7 +46,7 @@ class DataEditTypeSelectionViewModel @Inject constructor( recordType = type, numberOfCards = numberOfCards, isDarkTheme = isDarkTheme, - isChecked = null, + checkState = GoalCheckmarkView.CheckState.HIDDEN, isComplete = false, ) } diff --git a/features/feature_dialogs/src/main/java/com/example/util/simpletimetracker/feature_dialogs/archive/interactor/ArchiveDialogViewDataInteractor.kt b/features/feature_dialogs/src/main/java/com/example/util/simpletimetracker/feature_dialogs/archive/interactor/ArchiveDialogViewDataInteractor.kt index 5a698c8e1..4d92dc505 100644 --- a/features/feature_dialogs/src/main/java/com/example/util/simpletimetracker/feature_dialogs/archive/interactor/ArchiveDialogViewDataInteractor.kt +++ b/features/feature_dialogs/src/main/java/com/example/util/simpletimetracker/feature_dialogs/archive/interactor/ArchiveDialogViewDataInteractor.kt @@ -13,6 +13,7 @@ import com.example.util.simpletimetracker.feature_dialogs.R import com.example.util.simpletimetracker.feature_dialogs.archive.viewData.ArchiveDialogButtonsViewData import com.example.util.simpletimetracker.feature_dialogs.archive.viewData.ArchiveDialogInfoViewData import com.example.util.simpletimetracker.feature_dialogs.archive.viewData.ArchiveDialogTitleViewData +import com.example.util.simpletimetracker.feature_views.GoalCheckmarkView import javax.inject.Inject class ArchiveDialogViewDataInteractor @Inject constructor( @@ -35,7 +36,7 @@ class ArchiveDialogViewDataInteractor @Inject constructor( recordType = type, numberOfCards = numberOfCards, isDarkTheme = isDarkTheme, - isChecked = null, + checkState = GoalCheckmarkView.CheckState.HIDDEN, isComplete = false, ) val recordsCount = recordInteractor.getByType(listOf(typeId)).size diff --git a/features/feature_dialogs/src/main/java/com/example/util/simpletimetracker/feature_dialogs/cardOrder/viewModel/CardOrderViewModel.kt b/features/feature_dialogs/src/main/java/com/example/util/simpletimetracker/feature_dialogs/cardOrder/viewModel/CardOrderViewModel.kt index c3ae8590d..b9b49d8fb 100644 --- a/features/feature_dialogs/src/main/java/com/example/util/simpletimetracker/feature_dialogs/cardOrder/viewModel/CardOrderViewModel.kt +++ b/features/feature_dialogs/src/main/java/com/example/util/simpletimetracker/feature_dialogs/cardOrder/viewModel/CardOrderViewModel.kt @@ -16,6 +16,7 @@ import com.example.util.simpletimetracker.feature_base_adapter.ViewHolderType import com.example.util.simpletimetracker.feature_base_adapter.category.CategoryViewData import com.example.util.simpletimetracker.feature_base_adapter.loader.LoaderViewData import com.example.util.simpletimetracker.feature_base_adapter.recordType.RecordTypeViewData +import com.example.util.simpletimetracker.feature_views.GoalCheckmarkView import com.example.util.simpletimetracker.navigation.params.screen.CardOrderDialogParams import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.GlobalScope @@ -106,7 +107,7 @@ class CardOrderViewModel @Inject constructor( recordType = type, numberOfCards = numberOfCards, isDarkTheme = isDarkTheme, - isChecked = null, + checkState = GoalCheckmarkView.CheckState.HIDDEN, isComplete = false, ) } diff --git a/features/feature_dialogs/src/main/java/com/example/util/simpletimetracker/feature_dialogs/cardSize/mapper/CardSizeViewDataMapper.kt b/features/feature_dialogs/src/main/java/com/example/util/simpletimetracker/feature_dialogs/cardSize/mapper/CardSizeViewDataMapper.kt index 6a9011f65..c044fc0f1 100644 --- a/features/feature_dialogs/src/main/java/com/example/util/simpletimetracker/feature_dialogs/cardSize/mapper/CardSizeViewDataMapper.kt +++ b/features/feature_dialogs/src/main/java/com/example/util/simpletimetracker/feature_dialogs/cardSize/mapper/CardSizeViewDataMapper.kt @@ -7,6 +7,7 @@ import com.example.util.simpletimetracker.feature_base_adapter.recordType.Record import com.example.util.simpletimetracker.domain.model.RecordType import com.example.util.simpletimetracker.feature_dialogs.cardSize.viewData.CardSizeButtonsViewData import com.example.util.simpletimetracker.feature_dialogs.cardSize.viewData.CardSizeDefaultButtonViewData +import com.example.util.simpletimetracker.feature_views.GoalCheckmarkView import javax.inject.Inject class CardSizeViewDataMapper @Inject constructor( @@ -23,7 +24,7 @@ class CardSizeViewDataMapper @Inject constructor( recordType = recordType, numberOfCards = numberOfCards, isDarkTheme = isDarkTheme, - isChecked = null, + checkState = GoalCheckmarkView.CheckState.HIDDEN, isComplete = false, ) } diff --git a/features/feature_dialogs/src/main/java/com/example/util/simpletimetracker/feature_dialogs/defaultTypesSelection/viewModel/DefaultTypesSelectionViewModel.kt b/features/feature_dialogs/src/main/java/com/example/util/simpletimetracker/feature_dialogs/defaultTypesSelection/viewModel/DefaultTypesSelectionViewModel.kt index 275d09f8d..3ca5e7260 100644 --- a/features/feature_dialogs/src/main/java/com/example/util/simpletimetracker/feature_dialogs/defaultTypesSelection/viewModel/DefaultTypesSelectionViewModel.kt +++ b/features/feature_dialogs/src/main/java/com/example/util/simpletimetracker/feature_dialogs/defaultTypesSelection/viewModel/DefaultTypesSelectionViewModel.kt @@ -20,6 +20,7 @@ import com.example.util.simpletimetracker.feature_base_adapter.loader.LoaderView import com.example.util.simpletimetracker.feature_base_adapter.recordType.RecordTypeViewData import com.example.util.simpletimetracker.feature_dialogs.R import com.example.util.simpletimetracker.feature_dialogs.defaultTypesSelection.interactor.GetDefaultRecordTypesInteractor +import com.example.util.simpletimetracker.feature_views.GoalCheckmarkView import com.example.util.simpletimetracker.navigation.Router import com.example.util.simpletimetracker.navigation.params.screen.StandardDialogParams import dagger.hilt.android.lifecycle.HiltViewModel @@ -131,7 +132,7 @@ class DefaultTypesSelectionViewModel @Inject constructor( recordType = type, numberOfCards = numberOfCards, isDarkTheme = isDarkTheme, - isChecked = null, + checkState = GoalCheckmarkView.CheckState.HIDDEN, isComplete = false, ) } diff --git a/features/feature_dialogs/src/main/java/com/example/util/simpletimetracker/feature_dialogs/typesSelection/interactor/TypesSelectionViewDataInteractor.kt b/features/feature_dialogs/src/main/java/com/example/util/simpletimetracker/feature_dialogs/typesSelection/interactor/TypesSelectionViewDataInteractor.kt index c63178aec..bb650a4a3 100644 --- a/features/feature_dialogs/src/main/java/com/example/util/simpletimetracker/feature_dialogs/typesSelection/interactor/TypesSelectionViewDataInteractor.kt +++ b/features/feature_dialogs/src/main/java/com/example/util/simpletimetracker/feature_dialogs/typesSelection/interactor/TypesSelectionViewDataInteractor.kt @@ -13,6 +13,7 @@ import com.example.util.simpletimetracker.feature_base_adapter.empty.EmptyViewDa import com.example.util.simpletimetracker.feature_base_adapter.info.InfoViewData import com.example.util.simpletimetracker.feature_dialogs.R import com.example.util.simpletimetracker.feature_dialogs.typesSelection.model.TypesSelectionCacheHolder +import com.example.util.simpletimetracker.feature_views.GoalCheckmarkView import com.example.util.simpletimetracker.navigation.params.screen.TypesSelectionDialogParams import javax.inject.Inject @@ -69,7 +70,7 @@ class TypesSelectionViewDataInteractor @Inject constructor( recordType = type.data, numberOfCards = numberOfCards, isDarkTheme = isDarkTheme, - isChecked = null, + checkState = GoalCheckmarkView.CheckState.HIDDEN, isComplete = false, ) } diff --git a/features/feature_notification/src/main/java/com/example/util/simpletimetracker/feature_notification/activitySwitch/interactor/GetNotificationActivitySwitchControlsInteractor.kt b/features/feature_notification/src/main/java/com/example/util/simpletimetracker/feature_notification/activitySwitch/interactor/GetNotificationActivitySwitchControlsInteractor.kt index 6d218b9f4..8f31661ef 100644 --- a/features/feature_notification/src/main/java/com/example/util/simpletimetracker/feature_notification/activitySwitch/interactor/GetNotificationActivitySwitchControlsInteractor.kt +++ b/features/feature_notification/src/main/java/com/example/util/simpletimetracker/feature_notification/activitySwitch/interactor/GetNotificationActivitySwitchControlsInteractor.kt @@ -13,6 +13,7 @@ import com.example.util.simpletimetracker.domain.model.RecordType import com.example.util.simpletimetracker.domain.model.RecordTypeGoal import com.example.util.simpletimetracker.feature_notification.R import com.example.util.simpletimetracker.feature_notification.activitySwitch.manager.NotificationControlsParams +import com.example.util.simpletimetracker.feature_views.GoalCheckmarkView import com.example.util.simpletimetracker.feature_views.viewData.RecordTypeIcon import javax.inject.Inject @@ -48,7 +49,7 @@ class GetNotificationActivitySwitchControlsInteractor @Inject constructor( id = REPEAT_BUTTON_ITEM_ID, icon = viewData.iconId, color = viewData.color, - isChecked = null, + checkState = GoalCheckmarkView.CheckState.HIDDEN, isComplete = false, ).let(::listOf) } else { @@ -62,7 +63,7 @@ class GetNotificationActivitySwitchControlsInteractor @Inject constructor( id = type.id, icon = type.icon.let(iconMapper::mapIcon), color = type.color.let { colorMapper.mapToColorInt(it, isDarkTheme) }, - isChecked = recordTypeViewDataMapper.mapGoalCheckmark( + checkState = recordTypeViewDataMapper.mapGoalCheckmark( type = type, goals = goals, allDailyCurrents = allDailyCurrents, diff --git a/features/feature_notification/src/main/java/com/example/util/simpletimetracker/feature_notification/activitySwitch/manager/NotificationControlsManager.kt b/features/feature_notification/src/main/java/com/example/util/simpletimetracker/feature_notification/activitySwitch/manager/NotificationControlsManager.kt index 3e261d93b..dc02aba31 100644 --- a/features/feature_notification/src/main/java/com/example/util/simpletimetracker/feature_notification/activitySwitch/manager/NotificationControlsManager.kt +++ b/features/feature_notification/src/main/java/com/example/util/simpletimetracker/feature_notification/activitySwitch/manager/NotificationControlsManager.kt @@ -9,11 +9,11 @@ import android.view.View import android.widget.RemoteViews import com.example.util.simpletimetracker.core.extension.allowVmViolations import com.example.util.simpletimetracker.core.utils.PendingIntents -import com.example.util.simpletimetracker.domain.extension.orFalse import com.example.util.simpletimetracker.feature_notification.R import com.example.util.simpletimetracker.feature_notification.activitySwitch.mapper.NotificationControlsMapper import com.example.util.simpletimetracker.feature_notification.recevier.NotificationReceiver import com.example.util.simpletimetracker.feature_notification.recordType.customView.NotificationIconView +import com.example.util.simpletimetracker.feature_views.GoalCheckmarkView import com.example.util.simpletimetracker.feature_views.extension.getBitmapFromView import com.example.util.simpletimetracker.feature_views.extension.measureExactly import com.example.util.simpletimetracker.feature_views.viewData.RecordTypeIcon @@ -102,7 +102,7 @@ class NotificationControlsManager @Inject constructor( getTypeControlView( icon = it.icon, color = color, - isChecked = it.isChecked, + checkState = it.checkState, isComplete = it.isComplete, intent = getPendingSelfIntent( context = context, @@ -125,7 +125,7 @@ class NotificationControlsManager @Inject constructor( getTypeControlView( icon = null, color = null, - isChecked = null, + checkState = GoalCheckmarkView.CheckState.HIDDEN, isComplete = false, intent = null, ).let { @@ -233,7 +233,7 @@ class NotificationControlsManager @Inject constructor( private fun getTypeControlView( icon: RecordTypeIcon?, color: Int?, - isChecked: Boolean?, + checkState: GoalCheckmarkView.CheckState, isComplete: Boolean, intent: PendingIntent?, ): RemoteViews { @@ -243,7 +243,7 @@ class NotificationControlsManager @Inject constructor( val bitmap = getIconBitmap( icon = icon, color = color, - isChecked = isChecked, + checkState = checkState, isComplete = isComplete, ) setViewVisibility(R.id.containerNotificationType, View.VISIBLE) @@ -306,14 +306,13 @@ class NotificationControlsManager @Inject constructor( private fun getIconBitmap( icon: RecordTypeIcon, color: Int, - isChecked: Boolean? = null, + checkState: GoalCheckmarkView.CheckState = GoalCheckmarkView.CheckState.HIDDEN, isComplete: Boolean = false, ): Bitmap = synchronized(iconView) { return iconView.apply { itemIcon = icon itemColor = color - itemWithCheck = isChecked != null - itemIsChecked = isChecked.orFalse() + itemCheckState = checkState itemIsComplete = isComplete measureExactly(iconSize) }.getBitmapFromView() diff --git a/features/feature_notification/src/main/java/com/example/util/simpletimetracker/feature_notification/activitySwitch/manager/NotificationControlsParams.kt b/features/feature_notification/src/main/java/com/example/util/simpletimetracker/feature_notification/activitySwitch/manager/NotificationControlsParams.kt index 562654ab6..1f3eaef1e 100644 --- a/features/feature_notification/src/main/java/com/example/util/simpletimetracker/feature_notification/activitySwitch/manager/NotificationControlsParams.kt +++ b/features/feature_notification/src/main/java/com/example/util/simpletimetracker/feature_notification/activitySwitch/manager/NotificationControlsParams.kt @@ -1,5 +1,6 @@ package com.example.util.simpletimetracker.feature_notification.activitySwitch.manager +import com.example.util.simpletimetracker.feature_views.GoalCheckmarkView import com.example.util.simpletimetracker.feature_views.viewData.RecordTypeIcon sealed interface NotificationControlsParams { @@ -22,7 +23,7 @@ sealed interface NotificationControlsParams { val id: Long, val icon: RecordTypeIcon, val color: Int, - val isChecked: Boolean?, + val checkState: GoalCheckmarkView.CheckState, val isComplete: Boolean, ) diff --git a/features/feature_notification/src/main/java/com/example/util/simpletimetracker/feature_notification/goalTime/interactor/NotificationGoalParamsInteractor.kt b/features/feature_notification/src/main/java/com/example/util/simpletimetracker/feature_notification/goalTime/interactor/NotificationGoalParamsInteractor.kt index 62f5bf963..4a763ae6d 100644 --- a/features/feature_notification/src/main/java/com/example/util/simpletimetracker/feature_notification/goalTime/interactor/NotificationGoalParamsInteractor.kt +++ b/features/feature_notification/src/main/java/com/example/util/simpletimetracker/feature_notification/goalTime/interactor/NotificationGoalParamsInteractor.kt @@ -22,6 +22,7 @@ import com.example.util.simpletimetracker.domain.interactor.RecordTypeInteractor import com.example.util.simpletimetracker.domain.model.RecordTypeGoal import com.example.util.simpletimetracker.feature_notification.R import com.example.util.simpletimetracker.feature_notification.goalTime.manager.NotificationGoalTimeParams +import com.example.util.simpletimetracker.feature_views.GoalCheckmarkView import com.example.util.simpletimetracker.feature_views.viewData.RecordTypeIcon import javax.inject.Inject @@ -56,24 +57,33 @@ class NotificationGoalParamsInteractor @Inject constructor( } val isDarkTheme = prefsInteractor.getDarkMode() - val goalValueString = when (type) { - // ex. 5h 30m + val goal = when (type) { is Type.Duration -> { when (range) { is RecordTypeGoal.Range.Session -> goals.getSessionDuration() is RecordTypeGoal.Range.Daily -> goals.getDailyDuration() is RecordTypeGoal.Range.Weekly -> goals.getWeeklyDuration() is RecordTypeGoal.Range.Monthly -> goals.getMonthlyDuration() - }.value.let(timeMapper::formatDuration) + } } - // ex. 3 Records is Type.Count -> { when (range) { is RecordTypeGoal.Range.Session -> goals.getSessionCount() is RecordTypeGoal.Range.Daily -> goals.getDailyCount() is RecordTypeGoal.Range.Weekly -> goals.getWeeklyCount() is RecordTypeGoal.Range.Monthly -> goals.getMonthlyCount() - }.value.let { + } + } + } + + val goalValueString = when (type) { + // ex. 5h 30m + is Type.Duration -> { + goal.value.let(timeMapper::formatDuration) + } + // ex. 3 Records + is Type.Count -> { + goal.value.let { "$it " + resourceRepo.getQuantityString( stringResId = R.plurals.statistics_detail_times_tracked, quantity = it.toInt(), @@ -89,12 +99,24 @@ class NotificationGoalParamsInteractor @Inject constructor( is RecordTypeGoal.Range.Monthly -> R.string.change_record_type_monthly_goal_time }.let(resourceRepo::getString).let { "($it)" } - val description = resourceRepo.getString(R.string.notification_goal_time_description) + + val subtype = goal?.subtype ?: RecordTypeGoal.Subtype.Goal + + val goalSubtypeString = when (subtype) { + is RecordTypeGoal.Subtype.Goal -> R.string.notification_goal_time_description + is RecordTypeGoal.Subtype.Limit -> R.string.notification_limit_time_description + }.let(resourceRepo::getString) + + val description = goalSubtypeString + " - " + goalValueString + " " + goalTypeString + val checkState = when (subtype) { + is RecordTypeGoal.Subtype.Goal -> GoalCheckmarkView.CheckState.GOAL_REACHED + is RecordTypeGoal.Subtype.Limit -> GoalCheckmarkView.CheckState.LIMIT_REACHED + } + return NotificationGoalTimeParams( idData = idData, goalRange = range, @@ -106,11 +128,12 @@ class NotificationGoalParamsInteractor @Inject constructor( ?: Color.TRANSPARENT, text = recordType?.name ?: category?.name ?: "", description = description, + checkState = checkState, ) } sealed interface Type { - object Duration : Type - object Count : Type + data object Duration : Type + data object Count : Type } } \ No newline at end of file diff --git a/features/feature_notification/src/main/java/com/example/util/simpletimetracker/feature_notification/goalTime/manager/NotificationGoalTimeManager.kt b/features/feature_notification/src/main/java/com/example/util/simpletimetracker/feature_notification/goalTime/manager/NotificationGoalTimeManager.kt index 34fd3a97d..11c8519ed 100644 --- a/features/feature_notification/src/main/java/com/example/util/simpletimetracker/feature_notification/goalTime/manager/NotificationGoalTimeManager.kt +++ b/features/feature_notification/src/main/java/com/example/util/simpletimetracker/feature_notification/goalTime/manager/NotificationGoalTimeManager.kt @@ -9,9 +9,7 @@ import android.content.Intent import android.media.RingtoneManager import android.os.Build import android.view.ContextThemeWrapper -import android.view.View import android.widget.RemoteViews -import androidx.appcompat.widget.AppCompatImageView import androidx.core.app.NotificationCompat import androidx.core.app.NotificationManagerCompat import com.example.util.simpletimetracker.core.extension.allowVmViolations @@ -19,6 +17,7 @@ import com.example.util.simpletimetracker.core.utils.PendingIntents import com.example.util.simpletimetracker.domain.model.RecordTypeGoal import com.example.util.simpletimetracker.feature_notification.R import com.example.util.simpletimetracker.feature_notification.recordType.customView.NotificationIconView +import com.example.util.simpletimetracker.feature_views.GoalCheckmarkView import com.example.util.simpletimetracker.feature_views.extension.getBitmapFromView import com.example.util.simpletimetracker.feature_views.extension.measureExactly import com.example.util.simpletimetracker.navigation.Router @@ -37,17 +36,14 @@ class NotificationGoalTimeManager @Inject constructor( private val iconView = allowVmViolations { NotificationIconView(ContextThemeWrapper(context, R.style.AppTheme)) } + private val checkView = allowVmViolations { + GoalCheckmarkView(ContextThemeWrapper(context, R.style.AppTheme)) + } private val iconSize by lazy { context.resources.getDimensionPixelSize(R.dimen.notification_icon_size) } - private val checkView = allowVmViolations { - AppCompatImageView(ContextThemeWrapper(context, R.style.AppTheme)) - }.apply { - val size = context.resources.getDimensionPixelSize(R.dimen.notification_icon_half_size) - val specWidth = View.MeasureSpec.makeMeasureSpec(size, View.MeasureSpec.EXACTLY) - val specHeight = View.MeasureSpec.makeMeasureSpec(size, View.MeasureSpec.EXACTLY) - measure(specWidth, specHeight) - layout(0, 0, measuredWidth, measuredHeight) + private val checkSize by lazy { + context.resources.getDimensionPixelSize(R.dimen.notification_icon_half_size) } fun show(params: NotificationGoalTimeParams) { @@ -121,7 +117,8 @@ class NotificationGoalTimeManager @Inject constructor( } val checkBitmap = synchronized(checkView) { checkView.apply { - setBackgroundResource(R.drawable.spinner_check_mark) + itemCheckState = params.checkState + measureExactly(checkSize) }.getBitmapFromView() } diff --git a/features/feature_notification/src/main/java/com/example/util/simpletimetracker/feature_notification/goalTime/manager/NotificationGoalTimeParams.kt b/features/feature_notification/src/main/java/com/example/util/simpletimetracker/feature_notification/goalTime/manager/NotificationGoalTimeParams.kt index d924a310c..add009662 100644 --- a/features/feature_notification/src/main/java/com/example/util/simpletimetracker/feature_notification/goalTime/manager/NotificationGoalTimeParams.kt +++ b/features/feature_notification/src/main/java/com/example/util/simpletimetracker/feature_notification/goalTime/manager/NotificationGoalTimeParams.kt @@ -1,6 +1,7 @@ package com.example.util.simpletimetracker.feature_notification.goalTime.manager import com.example.util.simpletimetracker.domain.model.RecordTypeGoal +import com.example.util.simpletimetracker.feature_views.GoalCheckmarkView import com.example.util.simpletimetracker.feature_views.viewData.RecordTypeIcon data class NotificationGoalTimeParams( @@ -10,4 +11,5 @@ data class NotificationGoalTimeParams( val color: Int, val text: String, val description: String, + val checkState: GoalCheckmarkView.CheckState, ) \ No newline at end of file diff --git a/features/feature_notification/src/main/java/com/example/util/simpletimetracker/feature_notification/recordType/customView/NotificationIconView.kt b/features/feature_notification/src/main/java/com/example/util/simpletimetracker/feature_notification/recordType/customView/NotificationIconView.kt index 113cce087..83fbf8040 100644 --- a/features/feature_notification/src/main/java/com/example/util/simpletimetracker/feature_notification/recordType/customView/NotificationIconView.kt +++ b/features/feature_notification/src/main/java/com/example/util/simpletimetracker/feature_notification/recordType/customView/NotificationIconView.kt @@ -10,6 +10,7 @@ import android.widget.RelativeLayout import androidx.core.view.isVisible import com.example.util.simpletimetracker.feature_notification.R import com.example.util.simpletimetracker.feature_notification.databinding.NotificationIconViewLayoutBinding +import com.example.util.simpletimetracker.feature_views.GoalCheckmarkView.CheckState import com.example.util.simpletimetracker.feature_views.viewData.RecordTypeIcon class NotificationIconView @JvmOverloads constructor( @@ -38,12 +39,11 @@ class NotificationIconView @JvmOverloads constructor( .let(RecordTypeIcon::Image) } - if (hasValue(R.styleable.NotificationIconView_itemWithCheck)) { - itemWithCheck = getBoolean(R.styleable.NotificationIconView_itemWithCheck, false) - } - - if (hasValue(R.styleable.NotificationIconView_itemIsChecked)) { - itemIsChecked = getBoolean(R.styleable.NotificationIconView_itemIsChecked, false) + if (hasValue(R.styleable.NotificationIconView_itemCheckState)) { + itemCheckState = getInt( + R.styleable.NotificationIconView_itemCheckState, + CheckState.HIDDEN.value, + ).let(CheckState.Companion::fromValue) } if (hasValue(R.styleable.NotificationIconView_itemIsComplete)) { @@ -67,15 +67,9 @@ class NotificationIconView @JvmOverloads constructor( field = value } - var itemWithCheck: Boolean = false - set(value) { - binding.viewNotificationIconCheckmark.itemWithCheck = value - field = value - } - - var itemIsChecked: Boolean = false + var itemCheckState: CheckState = CheckState.HIDDEN set(value) { - binding.viewNotificationIconCheckmark.itemIsChecked = value + binding.viewNotificationIconCheckmark.itemCheckState = value field = value } diff --git a/features/feature_notification/src/main/java/com/example/util/simpletimetracker/feature_notification/recordType/interactor/NotificationTypeInteractorImpl.kt b/features/feature_notification/src/main/java/com/example/util/simpletimetracker/feature_notification/recordType/interactor/NotificationTypeInteractorImpl.kt index 996e52027..605fd5a13 100644 --- a/features/feature_notification/src/main/java/com/example/util/simpletimetracker/feature_notification/recordType/interactor/NotificationTypeInteractorImpl.kt +++ b/features/feature_notification/src/main/java/com/example/util/simpletimetracker/feature_notification/recordType/interactor/NotificationTypeInteractorImpl.kt @@ -123,7 +123,7 @@ class NotificationTypeInteractorImpl @Inject constructor( show( recordType = recordType, - goalTime = goalTime, + goal = goalTime, runningRecord = runningRecord ?: return, recordTags = recordTags.filter { it.id in runningRecord.tagIds }, dailyCurrent = getCurrentRecordsDurationInteractor.getDailyCurrent(runningRecord), @@ -192,7 +192,7 @@ class NotificationTypeInteractorImpl @Inject constructor( } show( recordType = recordTypes[runningRecord.id], - goalTime = goalTime, + goal = goalTime, runningRecord = runningRecord, recordTags = recordTags.filter { it.id in runningRecord.tagIds }, dailyCurrent = getCurrentRecordsDurationInteractor.getDailyCurrent(runningRecord), @@ -212,7 +212,7 @@ class NotificationTypeInteractorImpl @Inject constructor( private fun show( recordType: RecordType?, - goalTime: RecordTypeGoal?, + goal: RecordTypeGoal?, runningRecord: RunningRecord, recordTags: List, dailyCurrent: GetCurrentRecordsDurationInteractor.Result, @@ -223,6 +223,17 @@ class NotificationTypeInteractorImpl @Inject constructor( ) { if (recordType == null) return + val goalSubtype = goal?.subtype ?: RecordTypeGoal.Subtype.Goal + val goalSubtypeString = when (goalSubtype) { + is RecordTypeGoal.Subtype.Goal -> R.string.change_record_type_goal_time_hint + is RecordTypeGoal.Subtype.Limit -> R.string.change_record_type_limit_time_hint + }.let(resourceRepo::getString).lowercase() + val goalTime = goal.value + .takeIf { it > 0 } + ?.let(timeMapper::formatDuration) + ?.let { "$goalSubtypeString $it" } + .orEmpty() + NotificationTypeParams( id = recordType.id, icon = recordType.icon.let(iconMapper::mapIcon), @@ -240,11 +251,7 @@ class NotificationTypeInteractorImpl @Inject constructor( totalDuration = dailyCurrent.let { if (it.durationDiffersFromCurrent) it.duration else null }, - goalTime = goalTime.value - .takeIf { it > 0 } - ?.let(timeMapper::formatDuration) - ?.let { resourceRepo.getString(R.string.running_record_goal_time, it) } - .orEmpty(), + goalTime = goalTime, stopButton = resourceRepo.getString(R.string.notification_record_type_stop), controls = controls, ).let(notificationTypeManager::show) diff --git a/features/feature_notification/src/main/java/com/example/util/simpletimetracker/feature_notification/recordType/manager/NotificationTypeManager.kt b/features/feature_notification/src/main/java/com/example/util/simpletimetracker/feature_notification/recordType/manager/NotificationTypeManager.kt index 677273e03..db5c52ad8 100644 --- a/features/feature_notification/src/main/java/com/example/util/simpletimetracker/feature_notification/recordType/manager/NotificationTypeManager.kt +++ b/features/feature_notification/src/main/java/com/example/util/simpletimetracker/feature_notification/recordType/manager/NotificationTypeManager.kt @@ -16,12 +16,12 @@ import androidx.core.app.NotificationCompat import androidx.core.app.NotificationManagerCompat import com.example.util.simpletimetracker.core.extension.allowVmViolations import com.example.util.simpletimetracker.core.utils.PendingIntents -import com.example.util.simpletimetracker.domain.extension.orFalse import com.example.util.simpletimetracker.feature_notification.R import com.example.util.simpletimetracker.feature_notification.activitySwitch.manager.NotificationControlsManager import com.example.util.simpletimetracker.feature_notification.activitySwitch.manager.NotificationControlsManager.Companion.ARGS_TYPE_ID import com.example.util.simpletimetracker.feature_notification.recevier.NotificationReceiver import com.example.util.simpletimetracker.feature_notification.recordType.customView.NotificationIconView +import com.example.util.simpletimetracker.feature_views.GoalCheckmarkView import com.example.util.simpletimetracker.feature_views.extension.getBitmapFromView import com.example.util.simpletimetracker.feature_views.extension.measureExactly import com.example.util.simpletimetracker.feature_views.viewData.RecordTypeIcon @@ -156,14 +156,13 @@ class NotificationTypeManager @Inject constructor( private fun getIconBitmap( icon: RecordTypeIcon, color: Int, - isChecked: Boolean? = null, + checkState: GoalCheckmarkView.CheckState = GoalCheckmarkView.CheckState.HIDDEN, isComplete: Boolean = false, ): Bitmap = synchronized(iconView) { return iconView.apply { itemIcon = icon itemColor = color - itemWithCheck = isChecked != null - itemIsChecked = isChecked.orFalse() + itemCheckState = checkState itemIsComplete = isComplete measureExactly(iconSize) }.getBitmapFromView() diff --git a/features/feature_notification/src/main/res/layout/notification_icon_view_layout.xml b/features/feature_notification/src/main/res/layout/notification_icon_view_layout.xml index fa6991dde..3621c0454 100644 --- a/features/feature_notification/src/main/res/layout/notification_icon_view_layout.xml +++ b/features/feature_notification/src/main/res/layout/notification_icon_view_layout.xml @@ -26,8 +26,7 @@ android:layout_width="14dp" android:layout_height="14dp" android:layout_alignParentEnd="true" - tools:itemIsChecked="true" - tools:itemWithCheck="true" /> + tools:itemCheckState="goalReached" /> - - + diff --git a/features/feature_records_filter/src/main/java/com/example/util/simpletimetracker/feature_records_filter/interactor/RecordsFilterViewDataInteractor.kt b/features/feature_records_filter/src/main/java/com/example/util/simpletimetracker/feature_records_filter/interactor/RecordsFilterViewDataInteractor.kt index 4fe0d76d1..a32c030fa 100644 --- a/features/feature_records_filter/src/main/java/com/example/util/simpletimetracker/feature_records_filter/interactor/RecordsFilterViewDataInteractor.kt +++ b/features/feature_records_filter/src/main/java/com/example/util/simpletimetracker/feature_records_filter/interactor/RecordsFilterViewDataInteractor.kt @@ -64,6 +64,7 @@ import com.example.util.simpletimetracker.feature_records_filter.model.RecordFil import com.example.util.simpletimetracker.feature_records_filter.model.RecordsFilterSelectedRecordsViewData import com.example.util.simpletimetracker.feature_records_filter.model.RecordsFilterSelectionState import com.example.util.simpletimetracker.feature_records_filter.viewData.RecordsFilterSelectionButtonType +import com.example.util.simpletimetracker.feature_views.GoalCheckmarkView import com.example.util.simpletimetracker.navigation.params.screen.DateTimeDialogParams import com.example.util.simpletimetracker.navigation.params.screen.DateTimeDialogType import com.example.util.simpletimetracker.navigation.params.screen.RecordsFilterParams @@ -326,7 +327,7 @@ class RecordsFilterViewDataInteractor @Inject constructor( numberOfCards = numberOfCards, isDarkTheme = isDarkTheme, isFiltered = type.id !in allSelectedTypeIds, - isChecked = null, + checkState = GoalCheckmarkView.CheckState.HIDDEN, isComplete = false, ) } diff --git a/features/feature_running_records/src/main/java/com/example/util/simpletimetracker/feature_running_records/interactor/RunningRecordsViewDataInteractor.kt b/features/feature_running_records/src/main/java/com/example/util/simpletimetracker/feature_running_records/interactor/RunningRecordsViewDataInteractor.kt index 9c459ddf4..1ee3529be 100644 --- a/features/feature_running_records/src/main/java/com/example/util/simpletimetracker/feature_running_records/interactor/RunningRecordsViewDataInteractor.kt +++ b/features/feature_running_records/src/main/java/com/example/util/simpletimetracker/feature_running_records/interactor/RunningRecordsViewDataInteractor.kt @@ -132,7 +132,7 @@ class RunningRecordsViewDataInteractor @Inject constructor( isFiltered = it.id in recordTypesRunning, numberOfCards = numberOfCards, isDarkTheme = isDarkTheme, - isChecked = recordTypeViewDataMapper.mapGoalCheckmark( + checkState = recordTypeViewDataMapper.mapGoalCheckmark( type = it, goals = goals, allDailyCurrents = allDailyCurrents, diff --git a/features/feature_settings/src/main/java/com/example/util/simpletimetracker/feature_settings/partialRestoreSelection/PartialRestoreSelectionViewDataInteractor.kt b/features/feature_settings/src/main/java/com/example/util/simpletimetracker/feature_settings/partialRestoreSelection/PartialRestoreSelectionViewDataInteractor.kt index 84576ebc3..49339358f 100644 --- a/features/feature_settings/src/main/java/com/example/util/simpletimetracker/feature_settings/partialRestoreSelection/PartialRestoreSelectionViewDataInteractor.kt +++ b/features/feature_settings/src/main/java/com/example/util/simpletimetracker/feature_settings/partialRestoreSelection/PartialRestoreSelectionViewDataInteractor.kt @@ -25,6 +25,7 @@ import com.example.util.simpletimetracker.feature_base_adapter.category.Category import com.example.util.simpletimetracker.feature_base_adapter.color.ColorViewData import com.example.util.simpletimetracker.feature_settings.partialRestore.model.PartialRestoreFilterType import com.example.util.simpletimetracker.feature_settings.partialRestoreSelection.model.PartialRestoreSelectionDialogParams +import com.example.util.simpletimetracker.feature_views.GoalCheckmarkView import javax.inject.Inject class PartialRestoreSelectionViewDataInteractor @Inject constructor( @@ -71,7 +72,7 @@ class PartialRestoreSelectionViewDataInteractor @Inject constructor( numberOfCards = numberOfCards, isDarkTheme = isDarkTheme, isFiltered = it.id in dataIdsFiltered, - isChecked = null, + checkState = GoalCheckmarkView.CheckState.HIDDEN, isComplete = false, ) } diff --git a/features/feature_statistics_detail/src/main/java/com/example/util/simpletimetracker/feature_statistics_detail/interactor/StatisticsDetailChartInteractor.kt b/features/feature_statistics_detail/src/main/java/com/example/util/simpletimetracker/feature_statistics_detail/interactor/StatisticsDetailChartInteractor.kt index e5a3dc98b..9bb7a6ac9 100644 --- a/features/feature_statistics_detail/src/main/java/com/example/util/simpletimetracker/feature_statistics_detail/interactor/StatisticsDetailChartInteractor.kt +++ b/features/feature_statistics_detail/src/main/java/com/example/util/simpletimetracker/feature_statistics_detail/interactor/StatisticsDetailChartInteractor.kt @@ -174,12 +174,20 @@ class StatisticsDetailChartInteractor @Inject constructor( goals: List, appliedChartGrouping: ChartGrouping, ): Long { - return when (appliedChartGrouping) { - ChartGrouping.DAILY -> goals.getDailyDuration().value - ChartGrouping.WEEKLY -> goals.getWeeklyDuration().value - ChartGrouping.MONTHLY -> goals.getMonthlyDuration().value - ChartGrouping.YEARLY -> 0 - } * 1000 + return getGoal( + goals = goals, + appliedChartGrouping = appliedChartGrouping, + ).value * 1000 + } + + fun getGoalSubtype( + goals: List, + appliedChartGrouping: ChartGrouping, + ): RecordTypeGoal.Subtype { + return getGoal( + goals = goals, + appliedChartGrouping = appliedChartGrouping, + )?.subtype ?: RecordTypeGoal.Subtype.Goal } fun getChartData( @@ -555,6 +563,18 @@ class StatisticsDetailChartInteractor @Inject constructor( filter.getTypeIds().size > 1 } + private fun getGoal( + goals: List, + appliedChartGrouping: ChartGrouping, + ): RecordTypeGoal? { + return when (appliedChartGrouping) { + ChartGrouping.DAILY -> goals.getDailyDuration() + ChartGrouping.WEEKLY -> goals.getWeeklyDuration() + ChartGrouping.MONTHLY -> goals.getMonthlyDuration() + ChartGrouping.YEARLY -> null + } + } + data class CompositeChartData( val availableChartGroupings: List, val appliedChartGrouping: ChartGrouping, diff --git a/features/feature_statistics_detail/src/main/java/com/example/util/simpletimetracker/feature_statistics_detail/interactor/StatisticsDetailGoalsInteractor.kt b/features/feature_statistics_detail/src/main/java/com/example/util/simpletimetracker/feature_statistics_detail/interactor/StatisticsDetailGoalsInteractor.kt index d025bebd9..08ff870cc 100644 --- a/features/feature_statistics_detail/src/main/java/com/example/util/simpletimetracker/feature_statistics_detail/interactor/StatisticsDetailGoalsInteractor.kt +++ b/features/feature_statistics_detail/src/main/java/com/example/util/simpletimetracker/feature_statistics_detail/interactor/StatisticsDetailGoalsInteractor.kt @@ -88,17 +88,23 @@ class StatisticsDetailGoalsInteractor @Inject constructor( goals = goals, appliedChartGrouping = compositeData.appliedChartGrouping, ) + val goalSubtype = chartInteractor.getGoalSubtype( + goals = goals, + appliedChartGrouping = compositeData.appliedChartGrouping, + ) return@withContext StatisticsDetailGoalsCompositeViewData( viewData = statisticsDetailViewDataMapper.mapGoalChartViewData( goalData = statisticsDetailViewDataMapper.mapGoalData( data = data, goalValue = goalValue, + goalSubtype = goalSubtype, isDarkTheme = isDarkTheme, ), goalChartPrevData = statisticsDetailViewDataMapper.mapGoalData( data = prevData, goalValue = goalValue, + goalSubtype = goalSubtype, isDarkTheme = isDarkTheme, ), goalValue = goalValue, diff --git a/features/feature_statistics_detail/src/main/java/com/example/util/simpletimetracker/feature_statistics_detail/interactor/StatisticsDetailStreaksInteractor.kt b/features/feature_statistics_detail/src/main/java/com/example/util/simpletimetracker/feature_statistics_detail/interactor/StatisticsDetailStreaksInteractor.kt index ad629e7a7..6c80e5c29 100644 --- a/features/feature_statistics_detail/src/main/java/com/example/util/simpletimetracker/feature_statistics_detail/interactor/StatisticsDetailStreaksInteractor.kt +++ b/features/feature_statistics_detail/src/main/java/com/example/util/simpletimetracker/feature_statistics_detail/interactor/StatisticsDetailStreaksInteractor.kt @@ -69,8 +69,8 @@ class StatisticsDetailStreaksInteractor @Inject constructor( rangePosition: Int, streaksType: StreaksType, streaksGoal: StreaksGoal, - goalType: RecordTypeGoal.Type?, - compareGoalType: RecordTypeGoal.Type?, + goal: RecordTypeGoal?, + compareGoal: RecordTypeGoal?, ): StatisticsDetailStreaksViewData = withContext(Dispatchers.Default) { val calendar = Calendar.getInstance() val firstDayOfWeek = prefsInteractor.getFirstDayOfWeek() @@ -91,7 +91,7 @@ class StatisticsDetailStreaksInteractor @Inject constructor( startOfDayShift = startOfDayShift, streaksType = streaksType, streaksGoal = streaksGoal, - goalType = goalType, + goal = goal, ) val compareStatsData = if (showComparison) { mapStatsData( @@ -102,7 +102,7 @@ class StatisticsDetailStreaksInteractor @Inject constructor( startOfDayShift = startOfDayShift, streaksType = streaksType, streaksGoal = streaksGoal, - goalType = compareGoalType, + goal = compareGoal, ) } else { null @@ -185,8 +185,8 @@ class StatisticsDetailStreaksInteractor @Inject constructor( fun mapToStreaksGoalViewData( streaksGoal: StreaksGoal, - dailyGoal: RecordTypeGoal.Type?, - compareGoalType: RecordTypeGoal.Type?, + dailyGoal: RecordTypeGoal?, + compareGoalType: RecordTypeGoal?, rangeLength: RangeLength, ): List { if (dailyGoal == null && compareGoalType == null) { @@ -232,7 +232,7 @@ class StatisticsDetailStreaksInteractor @Inject constructor( startOfDayShift: Long, streaksType: StreaksType, streaksGoal: StreaksGoal, - goalType: RecordTypeGoal.Type?, + goal: RecordTypeGoal?, ): IntermediateData { val stats = calculate( range = range, @@ -241,7 +241,7 @@ class StatisticsDetailStreaksInteractor @Inject constructor( startOfDayShift = startOfDayShift, streaksType = streaksType, streaksGoal = streaksGoal, - goalType = goalType, + goal = goal, rangeLength = rangeLength, ) @@ -256,7 +256,7 @@ class StatisticsDetailStreaksInteractor @Inject constructor( startOfDayShift = startOfDayShift, streaksType = streaksType, streaksGoal = streaksGoal, - goalType = goalType, + goal = goal, rangeLength = rangeLength, ).currentStreak stats.copy(currentStreak = currentStreak) @@ -282,14 +282,22 @@ class StatisticsDetailStreaksInteractor @Inject constructor( startOfDayShift: Long, streaksType: StreaksType, streaksGoal: StreaksGoal, - goalType: RecordTypeGoal.Type?, + goal: RecordTypeGoal?, rangeLength: RangeLength, ): IntermediateData { - val defaultGoal = RecordTypeGoal.Type.Duration(1) - val goal = if (streaksGoal == StreaksGoal.GOAL) { - goalType ?: defaultGoal + // If doesn't have a goal - count any duration. + val defaultGoalType = RecordTypeGoal.Type.Duration(1) + val defaultGoalSubtype = RecordTypeGoal.Subtype.Goal + + val goalType = if (streaksGoal == StreaksGoal.GOAL) { + goal?.type ?: defaultGoalType + } else { + defaultGoalType + } + val goalSubtype = if (streaksGoal == StreaksGoal.GOAL) { + goal?.subtype ?: defaultGoalSubtype } else { - defaultGoal + defaultGoalSubtype } // Pair of day start to data on this day (duration or count). val durations: List> = getRanges( @@ -318,15 +326,15 @@ class StatisticsDetailStreaksInteractor @Inject constructor( ), ) }.run { - when (goal) { + when (goalType) { is RecordTypeGoal.Type.Count -> count().toLong() is RecordTypeGoal.Type.Duration -> sumOf(Range::duration) } } } - val goalValue = when (goal) { - is RecordTypeGoal.Type.Duration -> goal.value * 1000 - is RecordTypeGoal.Type.Count -> goal.value + val goalValue = when (goalType) { + is RecordTypeGoal.Type.Duration -> goalType.value * 1000 + is RecordTypeGoal.Type.Count -> goalType.value } val data: MutableList = mutableListOf() @@ -335,13 +343,17 @@ class StatisticsDetailStreaksInteractor @Inject constructor( var streakStart: Long = 0 var streakEnd: Long = 0 durations.forEachIndexed { index, duration -> + val isReached = when (goalSubtype) { + is RecordTypeGoal.Subtype.Goal -> duration.second >= goalValue + is RecordTypeGoal.Subtype.Limit -> duration.second <= goalValue + } val isLast = index == durations.size - 1 - if (duration.second >= goalValue) { + if (isReached) { counter++ if (streakStart == 0L) streakStart = duration.first streakEnd = duration.first } - if (duration.second < goalValue || isLast) { + if (!isReached || isLast) { // Series of one day makes no sense. if (counter > 1) { data += IntermediateData.Streak( @@ -353,7 +365,7 @@ class StatisticsDetailStreaksInteractor @Inject constructor( } if (counter > longestStreak) longestStreak = counter } - if (duration.second < goalValue && !isLast) { + if (!isReached && !isLast) { counter = 0 streakStart = 0 streakEnd = 0 @@ -369,6 +381,7 @@ class StatisticsDetailStreaksInteractor @Inject constructor( firstDayOfWeek = firstDayOfWeek, startOfDayShift = startOfDayShift, goalValue = goalValue, + goalSubtype = goalSubtype, rangeLength = rangeLength, ) @@ -454,6 +467,7 @@ class StatisticsDetailStreaksInteractor @Inject constructor( firstDayOfWeek: DayOfWeek, startOfDayShift: Long, goalValue: Long, + goalSubtype: RecordTypeGoal.Subtype, rangeLength: RangeLength, ): List { val days = listOf( @@ -492,13 +506,17 @@ class StatisticsDetailStreaksInteractor @Inject constructor( return dummyDays + data .map { + val isReached = when (goalSubtype) { + is RecordTypeGoal.Subtype.Goal -> it.second >= goalValue + is RecordTypeGoal.Subtype.Limit -> it.second <= goalValue + } val rangeStart = calendar.shiftTimeStamp(it.first, -startOfDayShift) val monthLegend = if (!isCalendarShownInOneRow) { timeMapper.formatShortMonth(rangeStart) } else { "" } - if (it.second >= goalValue) { + if (isReached) { SeriesCalendarView.ViewData.Present(rangeStart, monthLegend) } else { SeriesCalendarView.ViewData.NotPresent(rangeStart, monthLegend) diff --git a/features/feature_statistics_detail/src/main/java/com/example/util/simpletimetracker/feature_statistics_detail/mapper/StatisticsDetailViewDataMapper.kt b/features/feature_statistics_detail/src/main/java/com/example/util/simpletimetracker/feature_statistics_detail/mapper/StatisticsDetailViewDataMapper.kt index 46d5e0a4a..3fb8fd658 100644 --- a/features/feature_statistics_detail/src/main/java/com/example/util/simpletimetracker/feature_statistics_detail/mapper/StatisticsDetailViewDataMapper.kt +++ b/features/feature_statistics_detail/src/main/java/com/example/util/simpletimetracker/feature_statistics_detail/mapper/StatisticsDetailViewDataMapper.kt @@ -18,6 +18,7 @@ import com.example.util.simpletimetracker.domain.model.Range import com.example.util.simpletimetracker.domain.model.RangeLength import com.example.util.simpletimetracker.domain.model.RecordTag import com.example.util.simpletimetracker.domain.model.RecordType +import com.example.util.simpletimetracker.domain.model.RecordTypeGoal import com.example.util.simpletimetracker.feature_base_adapter.ViewHolderType import com.example.util.simpletimetracker.feature_statistics_detail.R import com.example.util.simpletimetracker.feature_statistics_detail.adapter.StatisticsDetailBarChartViewData @@ -667,18 +668,27 @@ class StatisticsDetailViewDataMapper @Inject constructor( fun mapGoalData( data: List, goalValue: Long, + goalSubtype: RecordTypeGoal.Subtype, isDarkTheme: Boolean, ): List { if (goalValue == 0L) return emptyList() val greenColor = resourceRepo.getThemedAttr(R.attr.appPositiveColor, isDarkTheme) val redColor = resourceRepo.getThemedAttr(R.attr.appNegativeColor, isDarkTheme) + val positiveColor = when (goalSubtype) { + is RecordTypeGoal.Subtype.Goal -> greenColor + is RecordTypeGoal.Subtype.Limit -> redColor + } + val negativeColor = when (goalSubtype) { + is RecordTypeGoal.Subtype.Goal -> redColor + is RecordTypeGoal.Subtype.Limit -> greenColor + } return data.map { dataPart -> val totalDuration = dataPart.durations.sumOf { it.first } // Show difference from goal value only on days // when there were records tracked. val goalDuration = if (totalDuration != 0L) totalDuration - goalValue else 0L - val color = if (goalDuration >= 0) greenColor else redColor + val color = if (goalDuration >= 0) positiveColor else negativeColor ChartBarDataDuration( legend = dataPart.legend, durations = listOf(goalDuration to color), @@ -705,7 +715,7 @@ class StatisticsDetailViewDataMapper @Inject constructor( val chartData = mapChartData( data = goalData, - goal = goalValue, + goal = 0, // Don't show goal on goal graph. rangeLength = rangeLength, showSelectedBarOnStart = true, useSingleColor = false, diff --git a/features/feature_statistics_detail/src/main/java/com/example/util/simpletimetracker/feature_statistics_detail/viewModel/delegate/StatisticsDetailStreaksViewModelDelegate.kt b/features/feature_statistics_detail/src/main/java/com/example/util/simpletimetracker/feature_statistics_detail/viewModel/delegate/StatisticsDetailStreaksViewModelDelegate.kt index 97b34886f..80cf1321f 100644 --- a/features/feature_statistics_detail/src/main/java/com/example/util/simpletimetracker/feature_statistics_detail/viewModel/delegate/StatisticsDetailStreaksViewModelDelegate.kt +++ b/features/feature_statistics_detail/src/main/java/com/example/util/simpletimetracker/feature_statistics_detail/viewModel/delegate/StatisticsDetailStreaksViewModelDelegate.kt @@ -44,8 +44,8 @@ class StatisticsDetailStreaksViewModelDelegate @Inject constructor( private var parent: StatisticsDetailViewModelDelegate.Parent? = null private var streaksType: StreaksType = StreaksType.LONGEST private var streaksGoal: StreaksGoal = StreaksGoal.ANY - private var dailyGoal: Result? = null - private var compareDailyGoal: Result? = null + private var dailyGoal: Result? = null + private var compareDailyGoal: Result? = null override fun attach(parent: StatisticsDetailViewModelDelegate.Parent) { this.parent = parent @@ -99,12 +99,12 @@ class StatisticsDetailStreaksViewModelDelegate @Inject constructor( private suspend fun getDailyGoalType( filters: List, - ): RecordTypeGoal.Type? { + ): RecordTypeGoal? { return statisticsDetailGetGoalFromFilterInteractor.execute(filters) - .getDaily()?.type + .getDaily() } - private suspend fun getDailyGoal(): RecordTypeGoal.Type? { + private suspend fun getDailyGoal(): RecordTypeGoal? { // Initialize if null. val goal = dailyGoal val parent = parent ?: return null @@ -116,7 +116,7 @@ class StatisticsDetailStreaksViewModelDelegate @Inject constructor( } } - private suspend fun getCompareDailyGoal(): RecordTypeGoal.Type? { + private suspend fun getCompareDailyGoal(): RecordTypeGoal? { // Initialize if null. val goal = compareDailyGoal val parent = parent ?: return null @@ -143,8 +143,8 @@ class StatisticsDetailStreaksViewModelDelegate @Inject constructor( rangePosition = parent.rangePosition, streaksType = streaksType, streaksGoal = streaksGoal, - goalType = getDailyGoal(), - compareGoalType = getCompareDailyGoal(), + goal = getDailyGoal(), + compareGoal = getCompareDailyGoal(), ) } diff --git a/features/feature_views/src/main/java/com/example/util/simpletimetracker/feature_views/GoalCheckmarkView.kt b/features/feature_views/src/main/java/com/example/util/simpletimetracker/feature_views/GoalCheckmarkView.kt index f14d1eae2..920e2177a 100644 --- a/features/feature_views/src/main/java/com/example/util/simpletimetracker/feature_views/GoalCheckmarkView.kt +++ b/features/feature_views/src/main/java/com/example/util/simpletimetracker/feature_views/GoalCheckmarkView.kt @@ -26,12 +26,11 @@ class GoalCheckmarkView @JvmOverloads constructor( context.obtainStyledAttributes(attrs, R.styleable.GoalCheckmarkView, defStyleAttr, 0) .run { - if (hasValue(R.styleable.GoalCheckmarkView_itemWithCheck)) { - itemWithCheck = getBoolean(R.styleable.GoalCheckmarkView_itemWithCheck, false) - } - - if (hasValue(R.styleable.GoalCheckmarkView_itemIsChecked)) { - itemIsChecked = getBoolean(R.styleable.GoalCheckmarkView_itemIsChecked, false) + if (hasValue(R.styleable.GoalCheckmarkView_itemCheckState)) { + itemCheckState = getInt( + R.styleable.GoalCheckmarkView_itemCheckState, + CheckState.HIDDEN.value, + ).let(CheckState.Companion::fromValue) } if (hasValue(R.styleable.GoalCheckmarkView_itemIsFiltered)) { @@ -42,13 +41,7 @@ class GoalCheckmarkView @JvmOverloads constructor( } } - var itemWithCheck: Boolean = false - set(value) { - field = value - setCheckmark() - } - - var itemIsChecked: Boolean = false + var itemCheckState: CheckState = CheckState.HIDDEN set(value) { field = value setCheckmark() @@ -61,19 +54,57 @@ class GoalCheckmarkView @JvmOverloads constructor( } private fun setCheckmark() = with(binding) { - if (itemWithCheck) { - ivGoalCheckmarkItemCheckOutline.isVisible = true - val colorAttr = if (itemIsChecked) R.attr.appIconColor else R.attr.colorSecondary - val color = ColorStateList.valueOf(context.getThemedAttr(colorAttr)) - ivGoalCheckmarkItemCheckOutline.imageTintList = color - ivGoalCheckmarkItemCheckBorder.isVisible = !itemIsChecked - ivGoalCheckmarkItemCheck.isVisible = itemIsChecked + when (itemCheckState) { + CheckState.HIDDEN -> { + ivGoalCheckmarkItemCheckOutline.isVisible = false + ivGoalCheckmarkItemCheckBorder.isVisible = false + ivGoalCheckmarkItemCheck.isVisible = false + ivGoalCheckmarkItemCheckFiltered.isVisible = false + } + CheckState.GOAL_NOT_REACHED -> { + ivGoalCheckmarkItemCheckOutline.isVisible = true + val color = ColorStateList.valueOf(context.getThemedAttr(R.attr.colorSecondary)) + ivGoalCheckmarkItemCheckOutline.imageTintList = color + ivGoalCheckmarkItemCheckBorder.isVisible = true + ivGoalCheckmarkItemCheck.isVisible = false + } + CheckState.GOAL_REACHED, CheckState.LIMIT_NOT_REACHED -> { + ivGoalCheckmarkItemCheckOutline.isVisible = true + val color = ColorStateList.valueOf(context.getThemedAttr(R.attr.appIconColor)) + ivGoalCheckmarkItemCheckOutline.imageTintList = color + ivGoalCheckmarkItemCheckBorder.isVisible = false + ivGoalCheckmarkItemCheck.isVisible = true + ivGoalCheckmarkItemCheck.setImageResource(R.drawable.record_type_check_mark) + } + CheckState.LIMIT_REACHED -> { + ivGoalCheckmarkItemCheckOutline.isVisible = true + val color = ColorStateList.valueOf(context.getThemedAttr(R.attr.colorSecondary)) + ivGoalCheckmarkItemCheckOutline.imageTintList = color + ivGoalCheckmarkItemCheckBorder.isVisible = false + ivGoalCheckmarkItemCheck.isVisible = true + ivGoalCheckmarkItemCheck.setImageResource(R.drawable.record_type_check_cross) + } + } + + if (itemCheckState != CheckState.HIDDEN) { ivGoalCheckmarkItemCheckFiltered.isVisible = itemIsFiltered - } else { - ivGoalCheckmarkItemCheckOutline.isVisible = false - ivGoalCheckmarkItemCheckBorder.isVisible = false - ivGoalCheckmarkItemCheck.isVisible = false - ivGoalCheckmarkItemCheckFiltered.isVisible = false + } + } + + enum class CheckState(val value: Int) { + HIDDEN(value = 0), + GOAL_NOT_REACHED(value = 1), + GOAL_REACHED(value = 2), + LIMIT_NOT_REACHED(value = 3), + LIMIT_REACHED(value = 4), + ; + + companion object { + fun fromValue(value: Int): CheckState { + return CheckState.entries.firstOrNull { + it.value == value + } ?: HIDDEN + } } } } \ No newline at end of file diff --git a/features/feature_views/src/main/java/com/example/util/simpletimetracker/feature_views/RecordTypeView.kt b/features/feature_views/src/main/java/com/example/util/simpletimetracker/feature_views/RecordTypeView.kt index 2c99185af..d14535f8d 100644 --- a/features/feature_views/src/main/java/com/example/util/simpletimetracker/feature_views/RecordTypeView.kt +++ b/features/feature_views/src/main/java/com/example/util/simpletimetracker/feature_views/RecordTypeView.kt @@ -9,6 +9,7 @@ import android.widget.RelativeLayout import androidx.cardview.widget.CardView import androidx.constraintlayout.widget.ConstraintSet import androidx.core.view.isVisible +import com.example.util.simpletimetracker.feature_views.GoalCheckmarkView.CheckState import com.example.util.simpletimetracker.feature_views.databinding.RecordTypeViewLayoutBinding import com.example.util.simpletimetracker.feature_views.extension.animateAlpha import com.example.util.simpletimetracker.feature_views.extension.setMargins @@ -61,12 +62,11 @@ class RecordTypeView @JvmOverloads constructor( itemIsRow = getBoolean(R.styleable.RecordTypeView_itemIsRow, false) } - if (hasValue(R.styleable.RecordTypeView_itemWithCheck)) { - itemWithCheck = getBoolean(R.styleable.RecordTypeView_itemWithCheck, false) - } - - if (hasValue(R.styleable.RecordTypeView_itemIsChecked)) { - itemIsChecked = getBoolean(R.styleable.RecordTypeView_itemIsChecked, false) + if (hasValue(R.styleable.RecordTypeView_itemCheckState)) { + itemCheckState = getInt( + R.styleable.RecordTypeView_itemCheckState, + CheckState.HIDDEN.value, + ).let(CheckState.Companion::fromValue) } if (hasValue(R.styleable.RecordTypeView_itemIsComplete)) { @@ -118,15 +118,9 @@ class RecordTypeView @JvmOverloads constructor( field = value } - var itemWithCheck: Boolean = false - set(value) { - binding.viewRecordTypeItemCheckmark.itemWithCheck = value - field = value - } - - var itemIsChecked: Boolean = false + var itemCheckState: CheckState = CheckState.HIDDEN set(value) { - binding.viewRecordTypeItemCheckmark.itemIsChecked = value + binding.viewRecordTypeItemCheckmark.itemCheckState = value field = value } diff --git a/features/feature_views/src/main/java/com/example/util/simpletimetracker/feature_views/RunningRecordView.kt b/features/feature_views/src/main/java/com/example/util/simpletimetracker/feature_views/RunningRecordView.kt index 4abc7b3fb..73cd18ac2 100644 --- a/features/feature_views/src/main/java/com/example/util/simpletimetracker/feature_views/RunningRecordView.kt +++ b/features/feature_views/src/main/java/com/example/util/simpletimetracker/feature_views/RunningRecordView.kt @@ -92,6 +92,12 @@ class RunningRecordView @JvmOverloads constructor( field = value } + var itemGoalTimeCheck: GoalCheckmarkView.CheckState = GoalCheckmarkView.CheckState.HIDDEN + set(value) { + binding.ivRunningRecordItemGoalTimeCheck.itemCheckState = value + field = value + } + var itemComment: String = "" set(value) { binding.tvRunningRecordItemComment.text = value diff --git a/features/feature_views/src/main/java/com/example/util/simpletimetracker/feature_views/StatisticsGoalView.kt b/features/feature_views/src/main/java/com/example/util/simpletimetracker/feature_views/StatisticsGoalView.kt index 59f701772..b3d43cbee 100644 --- a/features/feature_views/src/main/java/com/example/util/simpletimetracker/feature_views/StatisticsGoalView.kt +++ b/features/feature_views/src/main/java/com/example/util/simpletimetracker/feature_views/StatisticsGoalView.kt @@ -8,6 +8,7 @@ import android.view.View import androidx.cardview.widget.CardView import androidx.core.content.ContextCompat import com.example.util.simpletimetracker.feature_views.ColorUtils.normalizeLightness +import com.example.util.simpletimetracker.feature_views.GoalCheckmarkView.CheckState import com.example.util.simpletimetracker.feature_views.databinding.StatisticsGoalViewLayoutBinding import com.example.util.simpletimetracker.feature_views.extension.visible import com.example.util.simpletimetracker.feature_views.viewData.RecordTypeIcon @@ -69,10 +70,10 @@ class StatisticsGoalView @JvmOverloads constructor( setGoalPercentVisibility() } - var itemGoalTimeComplete: Boolean = false + var itemGoalState: CheckState = CheckState.HIDDEN set(value) { field = value - binding.ivStatisticsGoalItemCheck.visible = value + binding.ivStatisticsGoalItemCheck.itemCheckState = value setGoalPercentVisibility() } @@ -131,8 +132,11 @@ class StatisticsGoalView @JvmOverloads constructor( itemGoalPercent = getString(R.styleable.StatisticsGoalView_itemGoalPercent).orEmpty() } - if (hasValue(R.styleable.StatisticsGoalView_itemGoalTimeComplete)) { - itemGoalTimeComplete = getBoolean(R.styleable.StatisticsGoalView_itemGoalTimeComplete, false) + if (hasValue(R.styleable.StatisticsGoalView_itemCheckState)) { + itemGoalState = getInt( + R.styleable.StatisticsGoalView_itemCheckState, + CheckState.HIDDEN.value, + ).let(CheckState.Companion::fromValue) } recycle() @@ -145,9 +149,8 @@ class StatisticsGoalView @JvmOverloads constructor( } private fun setGoalPercentVisibility() { - binding.ivStatisticsGoalItemCheck.visible = itemGoalTimeComplete binding.tvStatisticsGoalItemPercent.visibility = when { - itemGoalTimeComplete -> View.INVISIBLE + itemGoalState != CheckState.HIDDEN -> View.INVISIBLE itemGoalPercent.isEmpty() -> View.GONE else -> View.VISIBLE } diff --git a/features/feature_views/src/main/res/drawable/record_type_check_cross.xml b/features/feature_views/src/main/res/drawable/record_type_check_cross.xml new file mode 100644 index 000000000..18308c0f4 --- /dev/null +++ b/features/feature_views/src/main/res/drawable/record_type_check_cross.xml @@ -0,0 +1,9 @@ + + + diff --git a/features/feature_views/src/main/res/layout/goal_checkmark_view_layout.xml b/features/feature_views/src/main/res/layout/goal_checkmark_view_layout.xml index 37dd0b2cf..35589caf9 100644 --- a/features/feature_views/src/main/res/layout/goal_checkmark_view_layout.xml +++ b/features/feature_views/src/main/res/layout/goal_checkmark_view_layout.xml @@ -2,6 +2,7 @@ @@ -22,7 +23,7 @@ android:layout_height="match_parent" android:tint="@color/colorPrimaryDark" android:visibility="gone" - app:srcCompat="@drawable/record_type_check_mark" + tools:srcCompat="@drawable/record_type_check_mark" tools:visibility="visible" /> diff --git a/features/feature_views/src/main/res/layout/record_running_view_layout.xml b/features/feature_views/src/main/res/layout/record_running_view_layout.xml index 5394db0c3..25153fb81 100644 --- a/features/feature_views/src/main/res/layout/record_running_view_layout.xml +++ b/features/feature_views/src/main/res/layout/record_running_view_layout.xml @@ -142,7 +142,7 @@ tools:text="goal 30m 10s" tools:visibility="visible" /> - + app:itemCheckState="goalReached" /> - + app:layout_constraintTop_toTopOf="@id/tvStatisticsGoalItemPercent" + tools:itemCheckState="goalReached" /> - - + + + + + + + @@ -56,8 +61,7 @@ - - + @@ -106,7 +110,7 @@ - + diff --git a/features/feature_widget/src/main/java/com/example/util/simpletimetracker/feature_widget/single/WidgetSingleProvider.kt b/features/feature_widget/src/main/java/com/example/util/simpletimetracker/feature_widget/single/WidgetSingleProvider.kt index 022aa8b0b..6135574d7 100644 --- a/features/feature_widget/src/main/java/com/example/util/simpletimetracker/feature_widget/single/WidgetSingleProvider.kt +++ b/features/feature_widget/src/main/java/com/example/util/simpletimetracker/feature_widget/single/WidgetSingleProvider.kt @@ -24,7 +24,6 @@ import com.example.util.simpletimetracker.core.repo.ResourceRepo import com.example.util.simpletimetracker.core.utils.PendingIntents import com.example.util.simpletimetracker.domain.REPEAT_BUTTON_ITEM_ID import com.example.util.simpletimetracker.domain.extension.getDaily -import com.example.util.simpletimetracker.domain.extension.orFalse import com.example.util.simpletimetracker.domain.interactor.AddRunningRecordMediator import com.example.util.simpletimetracker.domain.interactor.PrefsInteractor import com.example.util.simpletimetracker.domain.interactor.RecordInteractor @@ -35,6 +34,7 @@ import com.example.util.simpletimetracker.domain.interactor.RunningRecordInterac import com.example.util.simpletimetracker.domain.interactor.WidgetInteractor import com.example.util.simpletimetracker.domain.model.RecordDataSelectionDialogResult import com.example.util.simpletimetracker.feature_views.ColorUtils +import com.example.util.simpletimetracker.feature_views.GoalCheckmarkView import com.example.util.simpletimetracker.feature_views.RecordTypeView import com.example.util.simpletimetracker.feature_views.extension.getBitmapFromView import com.example.util.simpletimetracker.feature_views.extension.measureExactly @@ -173,7 +173,7 @@ class WidgetSingleProvider : AppWidgetProvider() { recordTypeName = viewData.name, recordTypeColor = viewData.color, isColored = false, - isChecked = null, + checkState = GoalCheckmarkView.CheckState.HIDDEN, isComplete = false, backgroundTransparency = backgroundTransparency, ) @@ -190,13 +190,13 @@ class WidgetSingleProvider : AppWidgetProvider() { } else { null } - val isChecked = if (recordType != null) { + val checkState = if (recordType != null) { recordTypeViewDataMapper.mapGoalCheckmark( goal = goal, dailyCurrent = dailyCurrent, ) } else { - null + GoalCheckmarkView.CheckState.HIDDEN } val isColored = when { runningRecord != null -> recordType != null @@ -211,7 +211,7 @@ class WidgetSingleProvider : AppWidgetProvider() { recordTypeColor = recordType?.color ?.let { colorMapper.mapToColorInt(it, isDarkTheme) }, isColored = isColored, - isChecked = isChecked, + checkState = checkState, isComplete = recordTypeId in completeTypesStateInteractor.widgetTypeIds, backgroundTransparency = backgroundTransparency, ) @@ -254,7 +254,7 @@ class WidgetSingleProvider : AppWidgetProvider() { recordTypeName: String?, recordTypeColor: Int?, isColored: Boolean, - isChecked: Boolean?, + checkState: GoalCheckmarkView.CheckState, isComplete: Boolean, backgroundTransparency: Long, ): View { @@ -285,8 +285,7 @@ class WidgetSingleProvider : AppWidgetProvider() { itemName = name itemIconColor = textColor itemColor = color - itemWithCheck = isChecked != null - itemIsChecked = isChecked.orFalse() + itemCheckState = checkState itemCompleteIsAnimated = false itemIsComplete = isComplete } diff --git a/features/feature_widget/src/main/java/com/example/util/simpletimetracker/feature_widget/universal/activity/viewModel/WidgetUniversalViewModel.kt b/features/feature_widget/src/main/java/com/example/util/simpletimetracker/feature_widget/universal/activity/viewModel/WidgetUniversalViewModel.kt index 924f5bde4..fa2ba3fc3 100644 --- a/features/feature_widget/src/main/java/com/example/util/simpletimetracker/feature_widget/universal/activity/viewModel/WidgetUniversalViewModel.kt +++ b/features/feature_widget/src/main/java/com/example/util/simpletimetracker/feature_widget/universal/activity/viewModel/WidgetUniversalViewModel.kt @@ -186,7 +186,7 @@ class WidgetUniversalViewModel @Inject constructor( isFiltered = it.id in recordTypesRunning, numberOfCards = numberOfCards, isDarkTheme = isDarkTheme, - isChecked = recordTypeViewDataMapper.mapGoalCheckmark( + checkState = recordTypeViewDataMapper.mapGoalCheckmark( type = it, goals = goals, allDailyCurrents = allDailyCurrents, diff --git a/navigation/src/main/java/com/example/util/simpletimetracker/navigation/params/screen/ChangeRunningRecordParams.kt b/navigation/src/main/java/com/example/util/simpletimetracker/navigation/params/screen/ChangeRunningRecordParams.kt index 5d5531043..e1c0efd17 100644 --- a/navigation/src/main/java/com/example/util/simpletimetracker/navigation/params/screen/ChangeRunningRecordParams.kt +++ b/navigation/src/main/java/com/example/util/simpletimetracker/navigation/params/screen/ChangeRunningRecordParams.kt @@ -30,15 +30,24 @@ data class ChangeRunningRecordParams( data class GoalTimeParams( val text: String, val complete: Boolean, + val state: GoalSubtypeParams, ) : Parcelable + + sealed interface GoalSubtypeParams : Parcelable { + @Parcelize + data object Goal : GoalSubtypeParams + + @Parcelize + data object Limit : GoalSubtypeParams + } } sealed class From : Parcelable { @Parcelize - object Records : From() + data object Records : From() @Parcelize - object RunningRecords : From() + data object RunningRecords : From() } companion object { diff --git a/resources/src/main/res/values-ar/strings.xml b/resources/src/main/res/values-ar/strings.xml index 25ece9ffc..e3b189d89 100644 --- a/resources/src/main/res/values-ar/strings.xml +++ b/resources/src/main/res/values-ar/strings.xml @@ -59,7 +59,6 @@ غير متتبع غير مصنف تعدد المهام - الهدف %s لم تضاف أنشطة اختر وسوم متتبعة الآن @@ -500,6 +499,7 @@ مذكر النشاط هل مازلت تنشط: %s? تم الوصول للهدف + تم الوصول إلى الحد بُدء في %s انتهى عند %s أوقف diff --git a/resources/src/main/res/values-ca/strings.xml b/resources/src/main/res/values-ca/strings.xml index 750c65581..5678a0a08 100644 --- a/resources/src/main/res/values-ca/strings.xml +++ b/resources/src/main/res/values-ca/strings.xml @@ -59,7 +59,6 @@ Sense enregistrar Sense categoria Multitasca - objectiu %s No s\'ha afegit cap activitat Seleccioneu etiqueta Ara @@ -499,7 +498,8 @@ Exemple:
No us oblideu d\'enregistrar el temps Recordatori d\'activitat Encara estàs fent: %s? - Heu assolit l\'objectiu + heu assolit l\'objectiu + límit assolit Començat a %s S\'ha acabat a les %s Atura diff --git a/resources/src/main/res/values-de/strings.xml b/resources/src/main/res/values-de/strings.xml index 7b71f6933..44740a775 100644 --- a/resources/src/main/res/values-de/strings.xml +++ b/resources/src/main/res/values-de/strings.xml @@ -59,7 +59,6 @@ Nicht erfasste Zeit Nicht kategorisiert Multitasking - ziel %s Keine Aktivitäten hinzugefügt Wählen Sie ein Datensatz-Tag aus Jetzt @@ -500,6 +499,7 @@ Beispiel:
Aktivitätserinnerung Machst du immer noch: %s? ziel erreicht + grenze erreicht Gestartet bei %s Fertiggestellt um %s Stoppen diff --git a/resources/src/main/res/values-es/strings.xml b/resources/src/main/res/values-es/strings.xml index b027bd038..b569e8d41 100644 --- a/resources/src/main/res/values-es/strings.xml +++ b/resources/src/main/res/values-es/strings.xml @@ -59,7 +59,6 @@ Sin seguimiento Sin categorizar Tarea múltiple - objetivo %s No se añadieron actividades Seleccione etiqueta Ahora @@ -500,6 +499,7 @@ Ejemplo:
Recordatorio de actividad ¿Sigues haciendo: %s? objetivo alcanzado + límite alcanzado Comenzó en %s Terminado en %s Detener diff --git a/resources/src/main/res/values-fa/strings.xml b/resources/src/main/res/values-fa/strings.xml index 4686e4e36..4d3c887a6 100644 --- a/resources/src/main/res/values-fa/strings.xml +++ b/resources/src/main/res/values-fa/strings.xml @@ -59,7 +59,6 @@ اندازه گیری نشده دسته بندی نشده چند وظیفه ای - هدف %s فعالیتی اضافه نشده انتخاب برچسب تاریخچه اکنون @@ -500,6 +499,7 @@ یادآور فعالیت آیا هنوز درحال انجام: %s ? به هدف خود رسیدید + حد رسیده است شروع شده در %s در %s به پایان رسید توقف diff --git a/resources/src/main/res/values-fr/strings.xml b/resources/src/main/res/values-fr/strings.xml index 3719841ef..e4e652dfa 100644 --- a/resources/src/main/res/values-fr/strings.xml +++ b/resources/src/main/res/values-fr/strings.xml @@ -59,7 +59,6 @@ Non suivi Non classé Multitâche - objectif %s Aucune activité ajoutée Sélectionnez une étiquette d\'enregistrement À présent @@ -500,6 +499,7 @@ Exemple:
Rappel d\'activité Faites-vous toujours : %s ? objectif atteint + limite atteinte Commencé à %s Terminé à %s Arrêt diff --git a/resources/src/main/res/values-hi/strings.xml b/resources/src/main/res/values-hi/strings.xml index 0f392f1a0..311d3c38e 100644 --- a/resources/src/main/res/values-hi/strings.xml +++ b/resources/src/main/res/values-hi/strings.xml @@ -59,7 +59,6 @@ ट्रैक न किए गए अवर्गीकृत बहु-कार्य - लक्ष्य %s कोई गतिविधियाँ जोड़ी गईं रिकॉर्ड टैग का चयन करें अब @@ -500,6 +499,7 @@ csv फ़ाइल में कॉमा से अलग किए गए य गतिविधि अनुस्मारक क्या आप अब भी कर रहे हैं: %s? लक्ष्य तक पहुंच गया + हद हो गई %s पर शुरू किया %s पर समाप्त हुआ रुकना diff --git a/resources/src/main/res/values-in/strings.xml b/resources/src/main/res/values-in/strings.xml index c8cdedcc8..1531b2b81 100644 --- a/resources/src/main/res/values-in/strings.xml +++ b/resources/src/main/res/values-in/strings.xml @@ -59,7 +59,6 @@ Tidak dilacak Tidak dikategorikan Multitugas - tujuan %s Tidak ada kegiatan yang ditambahkan Pilih label rekaman Sekarang @@ -500,6 +499,7 @@ Contoh:
Pengingat aktivitas Apakah Anda masih melakukan: %s? tujuan tercapai + batas tercapai Dimulai pada %s Selesai pada %s Berhenti diff --git a/resources/src/main/res/values-it/strings.xml b/resources/src/main/res/values-it/strings.xml index 7a6e0d7d6..d7d9539ed 100644 --- a/resources/src/main/res/values-it/strings.xml +++ b/resources/src/main/res/values-it/strings.xml @@ -59,7 +59,6 @@ Non tracciato Non categorizzato Multitasking - obiettivo %s Nessuna attività aggiunta Seleziona etichetta per la registrazione Adesso @@ -500,6 +499,7 @@ Esempio:
Avviso di attività Stai ancora facendo: %s? raggiunto obiettivo + raggiunto limite Iniziato alle %s Finito alle %s Fermare diff --git a/resources/src/main/res/values-iw/strings.xml b/resources/src/main/res/values-iw/strings.xml index e15994fcd..5d93ee8c4 100644 --- a/resources/src/main/res/values-iw/strings.xml +++ b/resources/src/main/res/values-iw/strings.xml @@ -59,7 +59,6 @@ לא במעקב לא בקטגוריה ריבוי משימות - יעד %s לא נוספו פעילויות בחר תגית רשומה עכשיו @@ -500,6 +499,7 @@ תזכורת פעילות את/ה עדיין עושה: %s? מטרה הושגה + הגבול הגיע התחיל בשעה %s הסתיים ב-%s עצור diff --git a/resources/src/main/res/values-ja/strings.xml b/resources/src/main/res/values-ja/strings.xml index 87ed51713..f68a89be1 100644 --- a/resources/src/main/res/values-ja/strings.xml +++ b/resources/src/main/res/values-ja/strings.xml @@ -59,7 +59,6 @@ 未計測 未分類 マルチタスク - 目標 %s アクティビティがありません 計測タグを選択 @@ -500,6 +499,7 @@ CSV ファイルには、カンマで区切られた次の列が含まれてい アクティビティリマインダー まだやってますか: %s? 目標到達 + 限界に達しました %s に開始 %sに終了しました ストップ diff --git a/resources/src/main/res/values-ko/strings.xml b/resources/src/main/res/values-ko/strings.xml index 8880874af..943ef48c1 100644 --- a/resources/src/main/res/values-ko/strings.xml +++ b/resources/src/main/res/values-ko/strings.xml @@ -59,7 +59,6 @@ 미기록 미분류됨 멀티태스크 - 목표 %s 추가된 활동이 없습니다 기록 태그를 선택하세요 지금 @@ -500,6 +499,7 @@ csv 파일은 다음과 같은 열(column)들을 가져야합니다:
활동 알림 아직도 하고있나요?: %s 목표 달성 + 한도에 도달함 %s에 시작함 %s에 완료됨 정지 diff --git a/resources/src/main/res/values-nl/strings.xml b/resources/src/main/res/values-nl/strings.xml index 9689aa0dd..bc82ab9d0 100644 --- a/resources/src/main/res/values-nl/strings.xml +++ b/resources/src/main/res/values-nl/strings.xml @@ -59,7 +59,6 @@ Niet bijgehouden Niet gecategoriseerd Multitasken - doel %s Geen activiteiten toegevoegd Selecteer recordlabel Nu @@ -500,6 +499,7 @@ Voorbeeld:
Activiteitsherinnering Ben je nog steeds bezig met: %s? doel bereikt + limiet bereikt Gestart om %s Klaar om %s Beëindigen diff --git a/resources/src/main/res/values-pl/strings.xml b/resources/src/main/res/values-pl/strings.xml index 55b422881..6be78c79e 100644 --- a/resources/src/main/res/values-pl/strings.xml +++ b/resources/src/main/res/values-pl/strings.xml @@ -59,7 +59,6 @@ Nieśledzony Bez kategorii Wielozadaniowość - cel %s Brak dodanych aktywności Wybierz tag aktywności Teraz @@ -500,6 +499,7 @@ Przykład:
Przypomnienie o aktywności Czy nadal robisz: %s? cel osiągnięty + limit osiągnięty Rozpoczęto o %s Zakończono o %s Zatrzymaj diff --git a/resources/src/main/res/values-pt-rPT/strings.xml b/resources/src/main/res/values-pt-rPT/strings.xml index c51a594a7..5154f1d81 100644 --- a/resources/src/main/res/values-pt-rPT/strings.xml +++ b/resources/src/main/res/values-pt-rPT/strings.xml @@ -59,7 +59,6 @@ Não registado Sem categoria Multitarefa - meta %s Nenhuma atividade adicionada Selecionar um etiqueta de registo Agora @@ -500,6 +499,7 @@ Exemplo:
Notificação de atividade Ainda a fazer: %s? meta atingida + limite atingido Iniciado às %s Terminou em %s Parar diff --git a/resources/src/main/res/values-pt/strings.xml b/resources/src/main/res/values-pt/strings.xml index 00304eabe..85cc8a1f6 100644 --- a/resources/src/main/res/values-pt/strings.xml +++ b/resources/src/main/res/values-pt/strings.xml @@ -59,7 +59,6 @@ Não monitorado Sem categoria Multitarefa - meta %s Nenhuma atividade adicionada Selecione uma tag de registro Agora @@ -500,6 +499,7 @@ Exemplo:
Lembrete de atividade Você ainda está fazendo: %s? meta atingida + limite atingido Iniciado às %s Terminou em %s Parar diff --git a/resources/src/main/res/values-ro/strings.xml b/resources/src/main/res/values-ro/strings.xml index 15af86c15..b0ad7444d 100644 --- a/resources/src/main/res/values-ro/strings.xml +++ b/resources/src/main/res/values-ro/strings.xml @@ -59,7 +59,6 @@ Neurmărit Necategorizat Multitask - Țel %s Nu sunt activități adăugate Alege eticheta Acum @@ -499,7 +498,8 @@ Examplu:
Nu uita să urmărești timpul Memento activitate Înca mai faci: %s? - Țel atins + țel atins + limita atinsa Început la %s Terminat la %s Stop diff --git a/resources/src/main/res/values-ru/strings.xml b/resources/src/main/res/values-ru/strings.xml index b3a3f11be..dec0567f3 100644 --- a/resources/src/main/res/values-ru/strings.xml +++ b/resources/src/main/res/values-ru/strings.xml @@ -59,7 +59,6 @@ Без отслеживания Без категории Многозадачность - цель %s Активности не добавлены Выберите тег для записи Сейчас @@ -500,6 +499,7 @@ CSV-файл должен содержать следующие столбцы, Напоминание об активности Вы все еще делаете: %s? цель достигнута + лимит достигнут Начато в %s Завершено в %s Стоп diff --git a/resources/src/main/res/values-sv/strings.xml b/resources/src/main/res/values-sv/strings.xml index 87f3f5956..411580595 100644 --- a/resources/src/main/res/values-sv/strings.xml +++ b/resources/src/main/res/values-sv/strings.xml @@ -59,7 +59,6 @@ Okategoriserad Okategoriserad Multi aktivitet - mål %s Inga tillagda aktiviteter Välj händelsetagg Nu @@ -500,6 +499,7 @@ Exempel:
Aktivitetspåminnelse Gör du fortfarande: %s? mål uppnått + gräns nådd Påbörjade %s Avslutade vid %s Sluta diff --git a/resources/src/main/res/values-tr/strings.xml b/resources/src/main/res/values-tr/strings.xml index e04b7b8d2..2232430e5 100644 --- a/resources/src/main/res/values-tr/strings.xml +++ b/resources/src/main/res/values-tr/strings.xml @@ -59,7 +59,6 @@ Takipsiz Kategorize edilmemiş Çoklu görev - hedef %s Aktivite eklenmedi Kayıt etiketi seçin Şimdi @@ -500,6 +499,7 @@ CSV dosyası virgülle ayrılmış şu sütunları içermelidir:
Etkinlik hatırlatıcısı Hala şunu yapıyor musunuz: %s? hedef ulaşıldı + sınıra ulaşıldı Başlangıç zamanı %s %s\'de tamamlandı Durmak diff --git a/resources/src/main/res/values-uk/strings.xml b/resources/src/main/res/values-uk/strings.xml index 9ad4f798e..a2cd00fe4 100644 --- a/resources/src/main/res/values-uk/strings.xml +++ b/resources/src/main/res/values-uk/strings.xml @@ -59,7 +59,6 @@ Без відстеження Без категорії Багатозадачність - ціль %s Жодної активності не додано Виберіть тег запису Тепер @@ -500,6 +499,7 @@ Нагадування про активність Ви все ще робите: %s? ціль досягнута + обмеження досягнуто Почато в %s Завершено о %s Стоп diff --git a/resources/src/main/res/values-vi/strings.xml b/resources/src/main/res/values-vi/strings.xml index 21ddb9ecb..aa59aab4e 100644 --- a/resources/src/main/res/values-vi/strings.xml +++ b/resources/src/main/res/values-vi/strings.xml @@ -59,7 +59,6 @@ Chưa theo dõi Chưa phân loại Đa nhiệm - mục tiêu %s Chưa thêm hoạt động nào Chọn thẻ bản ghi Bây giờ @@ -500,6 +499,7 @@ Ví dụ:
Lời nhắc hoạt động Bạn vẫn đang làm: %s? đã đạt mục tiêu + đạt đến giới hạn Bắt đầu lúc %s Đã hoàn tất lúc %s Dừng lại diff --git a/resources/src/main/res/values-zh-rTW/strings.xml b/resources/src/main/res/values-zh-rTW/strings.xml index d7b708a94..0b3d89977 100644 --- a/resources/src/main/res/values-zh-rTW/strings.xml +++ b/resources/src/main/res/values-zh-rTW/strings.xml @@ -59,7 +59,6 @@ 不追蹤 未分類 多任務 - 目標 %s 未有已加入的活動 選擇記錄標記 現在 @@ -500,6 +499,7 @@ csv 文件必須包含以逗號分隔的這些列:
活動提醒 你還在做:%s? 目標時達成 + 達到限制 開始於 %s 於 %s 完成 停止 diff --git a/resources/src/main/res/values-zh/strings.xml b/resources/src/main/res/values-zh/strings.xml index d79060c9e..1250c45e0 100644 --- a/resources/src/main/res/values-zh/strings.xml +++ b/resources/src/main/res/values-zh/strings.xml @@ -59,7 +59,6 @@ 未追踪 未分类 多任务 - 目标 %s 未添加任何活动 选择记录标签 现在 @@ -500,6 +499,7 @@ csv 文件必须包含以逗号分隔的这些列:
活动提醒 你还在做:%s? 达到的目标 + 达到限制 从 %s 开始 于 %s 完成 停止 diff --git a/resources/src/main/res/values/strings.xml b/resources/src/main/res/values/strings.xml index 8045084dd..d82f9c655 100644 --- a/resources/src/main/res/values/strings.xml +++ b/resources/src/main/res/values/strings.xml @@ -59,7 +59,6 @@ Untracked Uncategorized Multitask - goal %s No activities added Select record tag Now @@ -500,6 +499,7 @@ Example:
Activity reminder Are you still doing: %s? goal reached + limit reached Started at %s Finished at %s Stop