diff --git a/core/src/main/java/com/example/util/simpletimetracker/core/interactor/FilterGoalsByDayOfWeekInteractor.kt b/core/src/main/java/com/example/util/simpletimetracker/core/interactor/FilterGoalsByDayOfWeekInteractor.kt new file mode 100644 index 00000000..4861c253 --- /dev/null +++ b/core/src/main/java/com/example/util/simpletimetracker/core/interactor/FilterGoalsByDayOfWeekInteractor.kt @@ -0,0 +1,47 @@ +package com.example.util.simpletimetracker.core.interactor + +import com.example.util.simpletimetracker.core.mapper.TimeMapper +import com.example.util.simpletimetracker.domain.extension.filterDaysOfWeek +import com.example.util.simpletimetracker.domain.interactor.PrefsInteractor +import com.example.util.simpletimetracker.domain.model.Range +import com.example.util.simpletimetracker.domain.model.RangeLength +import com.example.util.simpletimetracker.domain.model.RecordTypeGoal +import java.util.Calendar +import javax.inject.Inject + +class FilterGoalsByDayOfWeekInteractor @Inject constructor( + private val timeMapper: TimeMapper, + private val prefsInteractor: PrefsInteractor, +) { + + fun execute( + goals: List, + range: Range, + startOfDayShift: Long, + ): List { + val dayOfWeek = timeMapper.getDayOfWeek( + timestamp = range.timeStarted, + calendar = Calendar.getInstance(), + startOfDayShift = startOfDayShift, + ) + return goals.filterDaysOfWeek(dayOfWeek) + } + + suspend fun execute( + goals: List, + ): List { + val firstDayOfWeek = prefsInteractor.getFirstDayOfWeek() + val startOfDayShift = prefsInteractor.getStartOfDayShift() + + return execute( + goals = goals, + range = timeMapper.getRangeStartAndEnd( + rangeLength = RangeLength.Day, + shift = 0, + firstDayOfWeek = firstDayOfWeek, + startOfDayShift = startOfDayShift, + ), + startOfDayShift = startOfDayShift, + ) + } +} \ No newline at end of file diff --git a/core/src/main/java/com/example/util/simpletimetracker/core/interactor/StatisticsMediator.kt b/core/src/main/java/com/example/util/simpletimetracker/core/interactor/StatisticsMediator.kt index 4f78f355..78bab885 100644 --- a/core/src/main/java/com/example/util/simpletimetracker/core/interactor/StatisticsMediator.kt +++ b/core/src/main/java/com/example/util/simpletimetracker/core/interactor/StatisticsMediator.kt @@ -12,7 +12,6 @@ import com.example.util.simpletimetracker.domain.interactor.StatisticsInteractor import com.example.util.simpletimetracker.domain.interactor.StatisticsTagInteractor import com.example.util.simpletimetracker.domain.model.ChartFilterType import com.example.util.simpletimetracker.domain.model.Range -import com.example.util.simpletimetracker.domain.model.RangeLength import com.example.util.simpletimetracker.domain.model.RecordType import com.example.util.simpletimetracker.domain.model.Statistics import javax.inject.Inject @@ -30,20 +29,10 @@ class StatisticsMediator @Inject constructor( suspend fun getStatistics( filterType: ChartFilterType, filteredIds: List, - rangeLength: RangeLength, - shift: Int, + range: Range, ): List { - val firstDayOfWeek = prefsInteractor.getFirstDayOfWeek() - val startOfDayShift = prefsInteractor.getStartOfDayShift() val showUntracked = prefsInteractor.getShowUntrackedInStatistics() - val range = timeMapper.getRangeStartAndEnd( - rangeLength = rangeLength, - shift = shift, - firstDayOfWeek = firstDayOfWeek, - startOfDayShift = startOfDayShift, - ) - return getFromRange( filterType = filterType, range = range, diff --git a/core/src/main/java/com/example/util/simpletimetracker/core/mapper/TimeMapper.kt b/core/src/main/java/com/example/util/simpletimetracker/core/mapper/TimeMapper.kt index 65c0e0f0..5d0fbd4b 100644 --- a/core/src/main/java/com/example/util/simpletimetracker/core/mapper/TimeMapper.kt +++ b/core/src/main/java/com/example/util/simpletimetracker/core/mapper/TimeMapper.kt @@ -585,11 +585,11 @@ class TimeMapper @Inject constructor( startOfDayShift: Long, ): DayOfWeek { return calendar - .apply { timeInMillis = timestamp } - .let { - it.timeInMillis -= startOfDayShift - it.get(Calendar.DAY_OF_WEEK) + .apply { + timeInMillis = timestamp + shift(-startOfDayShift) } + .get(Calendar.DAY_OF_WEEK) .let(::toDayOfWeek) } diff --git a/data_local/src/main/java/com/example/util/simpletimetracker/data_local/repo/RecordRepoImpl.kt b/data_local/src/main/java/com/example/util/simpletimetracker/data_local/repo/RecordRepoImpl.kt index 12f8e896..eaa2f748 100644 --- a/data_local/src/main/java/com/example/util/simpletimetracker/data_local/repo/RecordRepoImpl.kt +++ b/data_local/src/main/java/com/example/util/simpletimetracker/data_local/repo/RecordRepoImpl.kt @@ -78,8 +78,10 @@ class RecordRepoImpl @Inject constructor( logMessage = "getFromRange", accessCache = { getFromRangeCache.get(cacheKey) }, accessSource = { - recordDao.getFromRange(range.timeStarted, range.timeEnded) - .map(recordDataLocalMapper::map) + recordDao.getFromRange( + start = range.timeStarted, + end = range.timeEnded, + ).map(recordDataLocalMapper::map) }, afterSourceAccess = { getFromRangeCache.put(cacheKey, it) }, ) diff --git a/data_local/src/main/java/com/example/util/simpletimetracker/data_local/repo/RecordTypeGoalRepoImpl.kt b/data_local/src/main/java/com/example/util/simpletimetracker/data_local/repo/RecordTypeGoalRepoImpl.kt index ccd50cd8..cb58d274 100644 --- a/data_local/src/main/java/com/example/util/simpletimetracker/data_local/repo/RecordTypeGoalRepoImpl.kt +++ b/data_local/src/main/java/com/example/util/simpletimetracker/data_local/repo/RecordTypeGoalRepoImpl.kt @@ -2,6 +2,7 @@ package com.example.util.simpletimetracker.data_local.repo import com.example.util.simpletimetracker.data_local.database.RecordTypeGoalDao import com.example.util.simpletimetracker.data_local.mapper.RecordTypeGoalDataLocalMapper +import com.example.util.simpletimetracker.data_local.utils.logDataAccess import com.example.util.simpletimetracker.data_local.utils.removeIf import com.example.util.simpletimetracker.data_local.utils.withLockedCache import com.example.util.simpletimetracker.domain.model.RecordTypeGoal @@ -84,6 +85,7 @@ class RecordTypeGoalRepoImpl @Inject constructor( ) private suspend fun initializeCache() { + logDataAccess("initializeCache") cache = dao.getAll().map(mapper::map) } diff --git a/data_local/src/main/java/com/example/util/simpletimetracker/data_local/repo/RunningRecordRepoImpl.kt b/data_local/src/main/java/com/example/util/simpletimetracker/data_local/repo/RunningRecordRepoImpl.kt index ff46083c..9f233cdb 100644 --- a/data_local/src/main/java/com/example/util/simpletimetracker/data_local/repo/RunningRecordRepoImpl.kt +++ b/data_local/src/main/java/com/example/util/simpletimetracker/data_local/repo/RunningRecordRepoImpl.kt @@ -12,8 +12,8 @@ import javax.inject.Singleton @Singleton class RunningRecordRepoImpl @Inject constructor( - private val runningRecordDao: RunningRecordDao, - private val runningRunningRecordLocalMapper: RunningRecordDataLocalMapper, + private val dao: RunningRecordDao, + private val mapper: RunningRecordDataLocalMapper, ) : RunningRecordRepo { private var cache: List? = null @@ -22,37 +22,37 @@ class RunningRecordRepoImpl @Inject constructor( override suspend fun isEmpty(): Boolean = mutex.withLockedCache( logMessage = "isEmpty", accessCache = { cache?.isEmpty() }, - accessSource = { runningRecordDao.isEmpty() == 0L }, + accessSource = { dao.isEmpty() == 0L }, ) override suspend fun getAll(): List = mutex.withLockedCache( logMessage = "getAll", accessCache = { cache }, - accessSource = { runningRecordDao.getAll().map(runningRunningRecordLocalMapper::map) }, + accessSource = { dao.getAll().map(mapper::map) }, afterSourceAccess = { cache = it }, ) override suspend fun get(id: Long): RunningRecord? = mutex.withLockedCache( logMessage = "get", accessCache = { cache?.firstOrNull { it.id == id } }, - accessSource = { runningRecordDao.get(id)?.let(runningRunningRecordLocalMapper::map) }, + accessSource = { dao.get(id)?.let(mapper::map) }, ) override suspend fun add(runningRecord: RunningRecord): Long = mutex.withLockedCache( logMessage = "add", - accessSource = { runningRecordDao.insert(runningRecord.let(runningRunningRecordLocalMapper::map)) }, + accessSource = { dao.insert(runningRecord.let(mapper::map)) }, afterSourceAccess = { cache = null }, ) override suspend fun remove(id: Long) = mutex.withLockedCache( logMessage = "remove", - accessSource = { runningRecordDao.delete(id) }, + accessSource = { dao.delete(id) }, afterSourceAccess = { cache = cache?.removeIf { it.id == id } }, ) override suspend fun clear() = mutex.withLockedCache( logMessage = "clear", - accessSource = { runningRecordDao.clear() }, + accessSource = { dao.clear() }, afterSourceAccess = { cache = null }, ) } \ No newline at end of file diff --git a/domain/src/main/java/com/example/util/simpletimetracker/domain/extension/GoalsExtensions.kt b/domain/src/main/java/com/example/util/simpletimetracker/domain/extension/GoalsExtensions.kt index a75b9a1f..66675027 100644 --- a/domain/src/main/java/com/example/util/simpletimetracker/domain/extension/GoalsExtensions.kt +++ b/domain/src/main/java/com/example/util/simpletimetracker/domain/extension/GoalsExtensions.kt @@ -1,5 +1,6 @@ package com.example.util.simpletimetracker.domain.extension +import com.example.util.simpletimetracker.domain.model.DayOfWeek import com.example.util.simpletimetracker.domain.model.RecordTypeGoal import com.example.util.simpletimetracker.domain.model.RecordTypeGoal.Range import com.example.util.simpletimetracker.domain.model.RecordTypeGoal.Type @@ -72,4 +73,10 @@ fun List.hasDailyDuration(): Boolean { return getDailyDuration() != null } +fun List.filterDaysOfWeek(dayOfWeek: DayOfWeek): List { + return filter { + if (it.range is Range.Daily) dayOfWeek in it.daysOfWeek else true + } +} + val RecordTypeGoal?.value: Long get() = this?.type?.value.orZero() diff --git a/features/feature_change_running_record/src/main/java/com/example/util/simpletimetracker/feature_change_running_record/interactor/ChangeRunningRecordViewDataInteractor.kt b/features/feature_change_running_record/src/main/java/com/example/util/simpletimetracker/feature_change_running_record/interactor/ChangeRunningRecordViewDataInteractor.kt index 7ac83a04..9c57ee67 100644 --- a/features/feature_change_running_record/src/main/java/com/example/util/simpletimetracker/feature_change_running_record/interactor/ChangeRunningRecordViewDataInteractor.kt +++ b/features/feature_change_running_record/src/main/java/com/example/util/simpletimetracker/feature_change_running_record/interactor/ChangeRunningRecordViewDataInteractor.kt @@ -1,5 +1,6 @@ package com.example.util.simpletimetracker.feature_change_running_record.interactor +import com.example.util.simpletimetracker.core.interactor.FilterGoalsByDayOfWeekInteractor import com.example.util.simpletimetracker.core.interactor.GetRunningRecordViewDataMediator import com.example.util.simpletimetracker.core.mapper.TimeMapper import com.example.util.simpletimetracker.domain.extension.orZero @@ -19,6 +20,7 @@ class ChangeRunningRecordViewDataInteractor @Inject constructor( private val recordTypeGoalInteractor: RecordTypeGoalInteractor, private val timeMapper: TimeMapper, private val getRunningRecordViewDataMediator: GetRunningRecordViewDataMediator, + private val filterGoalsByDayOfWeekInteractor: FilterGoalsByDayOfWeekInteractor, ) { suspend fun getPreviewViewData( @@ -26,12 +28,13 @@ class ChangeRunningRecordViewDataInteractor @Inject constructor( params: ChangeRunningRecordParams, ): ChangeRunningRecordViewData { val type = recordTypeInteractor.get(record.id) - val goals = recordTypeGoalInteractor.getByType(type?.id.orZero()) val isDarkTheme = prefsInteractor.getDarkMode() val useMilitaryTime = prefsInteractor.getUseMilitaryTimeFormat() val showSeconds = prefsInteractor.getShowSeconds() val useProportionalMinutes = prefsInteractor.getUseProportionalMinutes() val fromRecords = params.from is ChangeRunningRecordParams.From.Records + val goals = filterGoalsByDayOfWeekInteractor + .execute(recordTypeGoalInteractor.getByType(type?.id.orZero())) val recordPreview = if (type != null) { getRunningRecordViewDataMediator.execute( diff --git a/features/feature_goals/src/main/java/com/example/util/simpletimetracker/feature_goals/interactor/GoalsViewDataInteractor.kt b/features/feature_goals/src/main/java/com/example/util/simpletimetracker/feature_goals/interactor/GoalsViewDataInteractor.kt index 99e938e1..68a83ed1 100644 --- a/features/feature_goals/src/main/java/com/example/util/simpletimetracker/feature_goals/interactor/GoalsViewDataInteractor.kt +++ b/features/feature_goals/src/main/java/com/example/util/simpletimetracker/feature_goals/interactor/GoalsViewDataInteractor.kt @@ -1,13 +1,16 @@ package com.example.util.simpletimetracker.feature_goals.interactor +import com.example.util.simpletimetracker.core.interactor.FilterGoalsByDayOfWeekInteractor import com.example.util.simpletimetracker.core.interactor.StatisticsMediator import com.example.util.simpletimetracker.core.mapper.GoalViewDataMapper +import com.example.util.simpletimetracker.core.mapper.TimeMapper import com.example.util.simpletimetracker.core.repo.ResourceRepo import com.example.util.simpletimetracker.core.viewData.StatisticsDataHolder import com.example.util.simpletimetracker.domain.interactor.PrefsInteractor import com.example.util.simpletimetracker.domain.interactor.RecordTypeGoalInteractor import com.example.util.simpletimetracker.domain.interactor.RecordTypeInteractor import com.example.util.simpletimetracker.domain.model.ChartFilterType +import com.example.util.simpletimetracker.domain.model.Range import com.example.util.simpletimetracker.domain.model.RangeLength import com.example.util.simpletimetracker.domain.model.RecordType import com.example.util.simpletimetracker.domain.model.RecordTypeGoal @@ -26,12 +29,16 @@ class GoalsViewDataInteractor @Inject constructor( private val prefsInteractor: PrefsInteractor, private val goalViewDataMapper: GoalViewDataMapper, private val resourceRepo: ResourceRepo, + private val timeMapper: TimeMapper, + private val filterGoalsByDayOfWeekInteractor: FilterGoalsByDayOfWeekInteractor, ) { suspend fun getViewData(): List = withContext(Dispatchers.Default) { val isDarkTheme = prefsInteractor.getDarkMode() val useProportionalMinutes = prefsInteractor.getUseProportionalMinutes() val showSeconds = prefsInteractor.getShowSeconds() + val firstDayOfWeek = prefsInteractor.getFirstDayOfWeek() + val startOfDayShift = prefsInteractor.getStartOfDayShift() val types = recordTypeInteractor.getAll().associateBy(RecordType::id) val goals = recordTypeGoalInteractor.getAll() @@ -66,10 +73,21 @@ class GoalsViewDataInteractor @Inject constructor( } } .map { rangeLength -> + val range = timeMapper.getRangeStartAndEnd( + rangeLength = rangeLength, + shift = 0, + firstDayOfWeek = firstDayOfWeek, + startOfDayShift = startOfDayShift, + ) getViewDataForRange( - goals = goals, + goals = filterGoalsByDayOfWeekInteractor.execute( + goals = goals, + range = range, + startOfDayShift = startOfDayShift, + ), types = types, rangeLength = rangeLength, + range = range, typeDataHolders = typeDataHolders, categoryDataHolders = categoryDataHolders, isDarkTheme = isDarkTheme, @@ -80,8 +98,8 @@ class GoalsViewDataInteractor @Inject constructor( .toList() return@withContext items + .flatten() .takeUnless { it.isEmpty() } - ?.flatten() ?: mapToEmpty() } @@ -89,6 +107,7 @@ class GoalsViewDataInteractor @Inject constructor( goals: List, types: Map, rangeLength: RangeLength, + range: Range, typeDataHolders: Map, categoryDataHolders: Map, isDarkTheme: Boolean, @@ -99,8 +118,7 @@ class GoalsViewDataInteractor @Inject constructor( val typeStatistics = statisticsMediator.getStatistics( filterType = ChartFilterType.ACTIVITY, filteredIds = emptyList(), - rangeLength = rangeLength, - shift = 0, + range = range, ) val typeItems = goalViewDataMapper.mapStatisticsList( goals = goals, @@ -117,8 +135,7 @@ class GoalsViewDataInteractor @Inject constructor( val categoryStatistics = statisticsMediator.getStatistics( filterType = ChartFilterType.CATEGORY, filteredIds = emptyList(), - rangeLength = rangeLength, - shift = 0, + range = range, ) val categoryItems = goalViewDataMapper.mapStatisticsList( goals = goals, diff --git a/features/feature_notification/src/main/java/com/example/util/simpletimetracker/feature_notification/goalTime/interactor/NotificationGoalCountInteractorImpl.kt b/features/feature_notification/src/main/java/com/example/util/simpletimetracker/feature_notification/goalTime/interactor/NotificationGoalCountInteractorImpl.kt index 468faaa2..f2f79f87 100644 --- a/features/feature_notification/src/main/java/com/example/util/simpletimetracker/feature_notification/goalTime/interactor/NotificationGoalCountInteractorImpl.kt +++ b/features/feature_notification/src/main/java/com/example/util/simpletimetracker/feature_notification/goalTime/interactor/NotificationGoalCountInteractorImpl.kt @@ -1,5 +1,6 @@ package com.example.util.simpletimetracker.feature_notification.goalTime.interactor +import com.example.util.simpletimetracker.core.interactor.FilterGoalsByDayOfWeekInteractor import com.example.util.simpletimetracker.core.interactor.GetCurrentRecordsDurationInteractor import com.example.util.simpletimetracker.domain.extension.orZero import com.example.util.simpletimetracker.domain.extension.value @@ -23,6 +24,7 @@ class NotificationGoalCountInteractorImpl @Inject constructor( private val manager: NotificationGoalTimeManager, private val notificationGoalParamsInteractor: NotificationGoalParamsInteractor, private val recordTypeCategoryInteractor: RecordTypeCategoryInteractor, + private val filterGoalsByDayOfWeekInteractor: FilterGoalsByDayOfWeekInteractor, ) : NotificationGoalCountInteractor { override suspend fun checkAndShow(typeId: Long) { @@ -31,9 +33,9 @@ class NotificationGoalCountInteractorImpl @Inject constructor( } private suspend fun checkAndShowType(typeId: Long) { - val runningRecord = runningRecordInteractor.get(typeId) - ?: return - val goals = recordTypeGoalInteractor.getByType(typeId) + val runningRecord = runningRecordInteractor.get(typeId) ?: return + val goals = filterGoalsByDayOfWeekInteractor + .execute(recordTypeGoalInteractor.getByType(typeId)) .filter { it.type is Type.Count } // No count goals - exit. @@ -66,8 +68,11 @@ class NotificationGoalCountInteractorImpl @Inject constructor( private suspend fun checkAndShowCategory(typeId: Long) { // Find all category goals. - val goals = recordTypeGoalInteractor.getAllCategoryGoals() + val goals = filterGoalsByDayOfWeekInteractor + .execute(recordTypeGoalInteractor.getAllCategoryGoals()) .filter { it.type is Type.Count } + + // No count goals - exit. if (goals.isEmpty()) return // Find all categories that hold this type. diff --git a/features/feature_notification/src/main/java/com/example/util/simpletimetracker/feature_notification/goalTime/interactor/NotificationGoalTimeInteractorImpl.kt b/features/feature_notification/src/main/java/com/example/util/simpletimetracker/feature_notification/goalTime/interactor/NotificationGoalTimeInteractorImpl.kt index b0fa75e9..4f084918 100644 --- a/features/feature_notification/src/main/java/com/example/util/simpletimetracker/feature_notification/goalTime/interactor/NotificationGoalTimeInteractorImpl.kt +++ b/features/feature_notification/src/main/java/com/example/util/simpletimetracker/feature_notification/goalTime/interactor/NotificationGoalTimeInteractorImpl.kt @@ -1,5 +1,6 @@ package com.example.util.simpletimetracker.feature_notification.goalTime.interactor +import com.example.util.simpletimetracker.core.interactor.FilterGoalsByDayOfWeekInteractor import com.example.util.simpletimetracker.core.interactor.GetCurrentRecordsDurationInteractor import com.example.util.simpletimetracker.domain.extension.orZero import com.example.util.simpletimetracker.domain.extension.value @@ -41,6 +42,7 @@ class NotificationGoalTimeInteractorImpl @Inject constructor( private val notificationGoalRangeEndInteractor: NotificationGoalRangeEndInteractor, private val notificationGoalParamsInteractor: NotificationGoalParamsInteractor, private val recordTypeCategoryInteractor: RecordTypeCategoryInteractor, + private val filterGoalsByDayOfWeekInteractor: FilterGoalsByDayOfWeekInteractor, ) : NotificationGoalTimeInteractor { override suspend fun checkAndReschedule(typeIds: List) { @@ -80,7 +82,11 @@ class NotificationGoalTimeInteractorImpl @Inject constructor( cancel(RecordTypeGoal.IdData.Type(typeId)) val runningRecord = runningRecordInteractor.get(typeId) ?: return - val goals = recordTypeGoalInteractor.getByType(typeId) + val goals = filterGoalsByDayOfWeekInteractor + .execute(recordTypeGoalInteractor.getByType(typeId)) + .filter { it.type is RecordTypeGoal.Type.Duration } + + if (goals.isEmpty()) return // Session checkType( @@ -117,8 +123,10 @@ class NotificationGoalTimeInteractorImpl @Inject constructor( private suspend fun checkAndRescheduleCategory(typeIds: List) { // Find all category goals. - val goals = recordTypeGoalInteractor.getAllCategoryGoals() + val goals = filterGoalsByDayOfWeekInteractor + .execute(recordTypeGoalInteractor.getAllCategoryGoals()) .filter { it.type is RecordTypeGoal.Type.Duration } + if (goals.isEmpty()) return // Find all categories that hold this types. 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 084f9162..7e89dc13 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 @@ -1,5 +1,6 @@ package com.example.util.simpletimetracker.feature_notification.recordType.interactor +import com.example.util.simpletimetracker.core.interactor.FilterGoalsByDayOfWeekInteractor import com.example.util.simpletimetracker.core.interactor.GetCurrentRecordsDurationInteractor import com.example.util.simpletimetracker.core.mapper.ColorMapper import com.example.util.simpletimetracker.core.mapper.IconMapper @@ -18,6 +19,7 @@ import com.example.util.simpletimetracker.domain.interactor.RecordTagInteractor import com.example.util.simpletimetracker.domain.interactor.RecordTypeGoalInteractor import com.example.util.simpletimetracker.domain.interactor.RecordTypeInteractor import com.example.util.simpletimetracker.domain.interactor.RunningRecordInteractor +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 @@ -41,6 +43,7 @@ class NotificationTypeInteractorImpl @Inject constructor( private val timeMapper: TimeMapper, private val recordTypeViewDataMapper: RecordTypeViewDataMapper, private val resourceRepo: ResourceRepo, + private val filterGoalsByDayOfWeekInteractor: FilterGoalsByDayOfWeekInteractor, ) : NotificationTypeInteractor { override suspend fun checkAndShow( @@ -52,7 +55,6 @@ class NotificationTypeInteractorImpl @Inject constructor( if (!prefsInteractor.getShowNotifications()) return val recordType = recordTypeInteractor.get(typeId) - val thisGoals = recordTypeGoalInteractor.getByType(typeId) val recordTypes = recordTypeInteractor.getAll().associateBy(RecordType::id) val runningRecord = runningRecordInteractor.get(typeId) val recordTags = recordTagInteractor.getAll() @@ -60,6 +62,19 @@ class NotificationTypeInteractorImpl @Inject constructor( val useMilitaryTime = prefsInteractor.getUseMilitaryTimeFormat() val showSeconds = prefsInteractor.getShowSeconds() val showControls = prefsInteractor.getShowNotificationsControls() + val firstDayOfWeek = prefsInteractor.getFirstDayOfWeek() + val startOfDayShift = prefsInteractor.getStartOfDayShift() + val range = timeMapper.getRangeStartAndEnd( + rangeLength = RangeLength.Day, + shift = 0, + firstDayOfWeek = firstDayOfWeek, + startOfDayShift = startOfDayShift, + ) + val thisGoals = filterGoalsByDayOfWeekInteractor.execute( + goals = recordTypeGoalInteractor.getByType(typeId), + range = range, + startOfDayShift = startOfDayShift + ) val goalTime = if (thisGoals.hasDailyDuration()) { thisGoals.getDailyDuration() } else { @@ -74,7 +89,11 @@ class NotificationTypeInteractorImpl @Inject constructor( } val controls = if (showControls) { val runningRecords = runningRecordInteractor.getAll() - val goals = recordTypeGoalInteractor.getAllTypeGoals().groupBy { it.idData.value } + val goals = filterGoalsByDayOfWeekInteractor.execute( + goals = recordTypeGoalInteractor.getAllTypeGoals(), + range = range, + startOfDayShift = startOfDayShift, + ).groupBy { it.idData.value } val allDailyCurrents = if (goals.isNotEmpty()) { getCurrentRecordsDurationInteractor.getAllDailyCurrents( typeIds = recordTypes.keys.toList(), @@ -127,13 +146,15 @@ class NotificationTypeInteractorImpl @Inject constructor( private suspend fun showAll() { val recordTypes = recordTypeInteractor.getAll().associateBy(RecordType::id) - val goals = recordTypeGoalInteractor.getAllTypeGoals().groupBy { it.idData.value } val recordTags = recordTagInteractor.getAll() val runningRecords = runningRecordInteractor.getAll() val isDarkTheme = prefsInteractor.getDarkMode() val useMilitaryTime = prefsInteractor.getUseMilitaryTimeFormat() val showSeconds = prefsInteractor.getShowSeconds() val showControls = prefsInteractor.getShowNotificationsControls() + val goals = filterGoalsByDayOfWeekInteractor + .execute(recordTypeGoalInteractor.getAllTypeGoals()) + .groupBy { it.idData.value } val controls = if (showControls) { val allDailyCurrents = if (goals.isNotEmpty()) { getCurrentRecordsDurationInteractor.getAllDailyCurrents( 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 1f023612..78ae779b 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 @@ -1,6 +1,7 @@ package com.example.util.simpletimetracker.feature_running_records.interactor import com.example.util.simpletimetracker.core.interactor.ActivityFilterViewDataInteractor +import com.example.util.simpletimetracker.core.interactor.FilterGoalsByDayOfWeekInteractor import com.example.util.simpletimetracker.core.interactor.GetCurrentRecordsDurationInteractor import com.example.util.simpletimetracker.core.interactor.GetRunningRecordViewDataMediator import com.example.util.simpletimetracker.core.interactor.RecordRepeatInteractor @@ -29,12 +30,12 @@ class RunningRecordsViewDataInteractor @Inject constructor( private val recordTypeViewDataMapper: RecordTypeViewDataMapper, private val getRunningRecordViewDataMediator: GetRunningRecordViewDataMediator, private val getCurrentRecordsDurationInteractor: GetCurrentRecordsDurationInteractor, + private val filterGoalsByDayOfWeekInteractor: FilterGoalsByDayOfWeekInteractor, ) { suspend fun getViewData(): List { val recordTypes = recordTypeInteractor.getAll() val recordTypesMap = recordTypes.associateBy(RecordType::id) - val goals = recordTypeGoalInteractor.getAllTypeGoals().groupBy { it.idData.value } val recordTags = recordTagInteractor.getAll() val runningRecords = runningRecordInteractor.getAll() val recordTypesRunning = runningRecords.map(RunningRecord::id) @@ -45,6 +46,9 @@ class RunningRecordsViewDataInteractor @Inject constructor( val useProportionalMinutes = prefsInteractor.getUseProportionalMinutes() val showFirstEnterHint = recordTypes.filterNot(RecordType::hidden).isEmpty() val showRepeatButton = recordRepeatInteractor.shouldShowButton() + val goals = filterGoalsByDayOfWeekInteractor + .execute(recordTypeGoalInteractor.getAllTypeGoals()) + .groupBy { it.idData.value } val allDailyCurrents = if (goals.isNotEmpty()) { getCurrentRecordsDurationInteractor.getAllDailyCurrents( typeIds = recordTypesMap.keys.toList(), diff --git a/features/feature_statistics/src/main/java/com/example/util/simpletimetracker/feature_statistics/interactor/StatisticsViewDataInteractor.kt b/features/feature_statistics/src/main/java/com/example/util/simpletimetracker/feature_statistics/interactor/StatisticsViewDataInteractor.kt index ae675307..4011875b 100644 --- a/features/feature_statistics/src/main/java/com/example/util/simpletimetracker/feature_statistics/interactor/StatisticsViewDataInteractor.kt +++ b/features/feature_statistics/src/main/java/com/example/util/simpletimetracker/feature_statistics/interactor/StatisticsViewDataInteractor.kt @@ -1,10 +1,12 @@ package com.example.util.simpletimetracker.feature_statistics.interactor +import com.example.util.simpletimetracker.core.interactor.FilterGoalsByDayOfWeekInteractor import com.example.util.simpletimetracker.core.interactor.StatisticsChartViewDataInteractor import com.example.util.simpletimetracker.core.interactor.StatisticsMediator import com.example.util.simpletimetracker.core.mapper.ColorMapper import com.example.util.simpletimetracker.core.mapper.GoalViewDataMapper import com.example.util.simpletimetracker.core.mapper.RangeViewDataMapper +import com.example.util.simpletimetracker.core.mapper.TimeMapper import com.example.util.simpletimetracker.domain.UNCATEGORIZED_ITEM_ID import com.example.util.simpletimetracker.domain.UNTRACKED_ITEM_ID import com.example.util.simpletimetracker.domain.interactor.PrefsInteractor @@ -35,9 +37,11 @@ class StatisticsViewDataInteractor @Inject constructor( private val statisticsViewDataMapper: StatisticsViewDataMapper, private val rangeViewDataMapper: RangeViewDataMapper, private val colorMapper: ColorMapper, + private val timeMapper: TimeMapper, private val goalViewDataMapper: GoalViewDataMapper, private val recordInteractor: RecordInteractor, private val runningRecordInteractor: RunningRecordInteractor, + private val filterGoalsByDayOfWeekInteractor: FilterGoalsByDayOfWeekInteractor, ) { fun mapFilter( @@ -91,6 +95,8 @@ class StatisticsViewDataInteractor @Inject constructor( val isDarkTheme = prefsInteractor.getDarkMode() val useProportionalMinutes = prefsInteractor.getUseProportionalMinutes() val showSeconds = prefsInteractor.getShowSeconds() + val firstDayOfWeek = prefsInteractor.getFirstDayOfWeek() + val startOfDayShift = prefsInteractor.getStartOfDayShift() val showDuration = rangeLength !is RangeLength.All val types = recordTypeInteractor.getAll().associateBy(RecordType::id) val showGoalsSeparately = prefsInteractor.getShowGoalsSeparately() @@ -106,11 +112,16 @@ class StatisticsViewDataInteractor @Inject constructor( filterType = filterType, types = types, ) + val range = timeMapper.getRangeStartAndEnd( + rangeLength = rangeLength, + shift = shift, + firstDayOfWeek = firstDayOfWeek, + startOfDayShift = startOfDayShift, + ) val statistics = statisticsMediator.getStatistics( filterType = filterType, filteredIds = filteredIds, - rangeLength = rangeLength, - shift = shift, + range = range, ) val chart = statisticsChartViewDataInteractor.getChart( filterType = filterType, @@ -152,7 +163,11 @@ class StatisticsViewDataInteractor @Inject constructor( ) { emptyList() } else { - val goals = recordTypeGoalInteractor.getAll() + val goals = filterGoalsByDayOfWeekInteractor.execute( + goals = recordTypeGoalInteractor.getAll(), + range = range, + startOfDayShift = startOfDayShift, + ) goalViewDataMapper.mapStatisticsList( goals = goals, types = types, 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 c4523cda..6629608e 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 @@ -11,6 +11,7 @@ import android.view.LayoutInflater import android.view.View import android.widget.FrameLayout import android.widget.RemoteViews +import com.example.util.simpletimetracker.core.interactor.FilterGoalsByDayOfWeekInteractor import com.example.util.simpletimetracker.core.interactor.GetCurrentRecordsDurationInteractor import com.example.util.simpletimetracker.core.interactor.RecordRepeatInteractor import com.example.util.simpletimetracker.core.mapper.ColorMapper @@ -23,8 +24,6 @@ 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 -import com.example.util.simpletimetracker.domain.interactor.RecordTagInteractor import com.example.util.simpletimetracker.domain.interactor.RecordTypeGoalInteractor import com.example.util.simpletimetracker.domain.interactor.RecordTypeInteractor import com.example.util.simpletimetracker.domain.interactor.RemoveRunningRecordMediator @@ -62,12 +61,6 @@ class WidgetSingleProvider : AppWidgetProvider() { @Inject lateinit var recordTypeGoalInteractor: RecordTypeGoalInteractor - @Inject - lateinit var recordInteractor: RecordInteractor - - @Inject - lateinit var recordTagInteractor: RecordTagInteractor - @Inject lateinit var widgetInteractor: WidgetInteractor @@ -92,6 +85,9 @@ class WidgetSingleProvider : AppWidgetProvider() { @Inject lateinit var getCurrentRecordsDurationInteractor: GetCurrentRecordsDurationInteractor + @Inject + lateinit var filterGoalsByDayOfWeekInteractor: FilterGoalsByDayOfWeekInteractor + private var typeIdsToUpdate: List = emptyList() override fun onReceive(context: Context?, intent: Intent?) { @@ -151,7 +147,9 @@ class WidgetSingleProvider : AppWidgetProvider() { } else { val recordType = recordTypeInteractor.get(recordTypeId) ?.takeUnless { it.hidden } - val goal = recordTypeGoalInteractor.getByType(recordTypeId).getDaily() + val goal = filterGoalsByDayOfWeekInteractor + .execute(recordTypeGoalInteractor.getByType(recordTypeId)) + .getDaily() val dailyCurrent = if (goal != null) { getCurrentRecordsDurationInteractor.getDailyCurrent( typeId = recordTypeId, diff --git a/features/feature_widget/src/main/java/com/example/util/simpletimetracker/feature_widget/statistics/WidgetStatisticsChartProvider.kt b/features/feature_widget/src/main/java/com/example/util/simpletimetracker/feature_widget/statistics/WidgetStatisticsChartProvider.kt index d5b8de02..8a8f875e 100644 --- a/features/feature_widget/src/main/java/com/example/util/simpletimetracker/feature_widget/statistics/WidgetStatisticsChartProvider.kt +++ b/features/feature_widget/src/main/java/com/example/util/simpletimetracker/feature_widget/statistics/WidgetStatisticsChartProvider.kt @@ -13,6 +13,7 @@ import android.view.View import android.widget.RemoteViews import com.example.util.simpletimetracker.core.interactor.StatisticsChartViewDataInteractor import com.example.util.simpletimetracker.core.interactor.StatisticsMediator +import com.example.util.simpletimetracker.core.mapper.TimeMapper import com.example.util.simpletimetracker.core.repo.ResourceRepo import com.example.util.simpletimetracker.core.utils.PendingIntents import com.example.util.simpletimetracker.core.utils.SHORTCUT_NAVIGATION_KEY @@ -57,6 +58,9 @@ class WidgetStatisticsChartProvider : AppWidgetProvider() { @Inject lateinit var resourceRepo: ResourceRepo + @Inject + lateinit var timeMapper: TimeMapper + override fun onUpdate( context: Context?, appWidgetManager: AppWidgetManager?, @@ -117,6 +121,8 @@ class WidgetStatisticsChartProvider : AppWidgetProvider() { val isDarkTheme = prefsInteractor.getDarkMode() val useProportionalMinutes = prefsInteractor.getUseProportionalMinutes() val showSeconds = prefsInteractor.getShowSeconds() + val firstDayOfWeek = prefsInteractor.getFirstDayOfWeek() + val startOfDayShift = prefsInteractor.getStartOfDayShift() val widgetData = prefsInteractor.getStatisticsWidget(appWidgetId) val backgroundTransparency = prefsInteractor.getWidgetBackgroundTransparencyPercent() val types = recordTypeInteractor.getAll().associateBy(RecordType::id) @@ -133,11 +139,16 @@ class WidgetStatisticsChartProvider : AppWidgetProvider() { filterType = filterType, types = types, ) + val range = timeMapper.getRangeStartAndEnd( + rangeLength = rangeLength, + shift = 0, + firstDayOfWeek = firstDayOfWeek, + startOfDayShift = startOfDayShift, + ) val statistics = statisticsMediator.getStatistics( filterType = filterType, filteredIds = filteredIds, - rangeLength = rangeLength, - shift = 0, + range = range, ) val chart = statisticsChartViewDataInteractor.getChart( filterType = filterType, 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 c3a12d35..a61a797c 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 @@ -6,6 +6,7 @@ import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.example.util.simpletimetracker.core.extension.set import com.example.util.simpletimetracker.core.interactor.ActivityFilterViewDataInteractor +import com.example.util.simpletimetracker.core.interactor.FilterGoalsByDayOfWeekInteractor import com.example.util.simpletimetracker.core.interactor.GetCurrentRecordsDurationInteractor import com.example.util.simpletimetracker.core.interactor.RecordRepeatInteractor import com.example.util.simpletimetracker.core.mapper.RecordTypeViewDataMapper @@ -46,6 +47,7 @@ class WidgetUniversalViewModel @Inject constructor( private val recordRepeatInteractor: RecordRepeatInteractor, private val recordTypeGoalInteractor: RecordTypeGoalInteractor, private val getCurrentRecordsDurationInteractor: GetCurrentRecordsDurationInteractor, + private val filterGoalsByDayOfWeekInteractor: FilterGoalsByDayOfWeekInteractor, ) : ViewModel() { val recordTypes: LiveData> by lazy { @@ -121,10 +123,12 @@ class WidgetUniversalViewModel @Inject constructor( private suspend fun loadRecordTypesViewData(): List { val runningRecords = runningRecordInteractor.getAll() val recordTypes = recordTypeInteractor.getAll() - val goals = recordTypeGoalInteractor.getAllTypeGoals().groupBy { it.idData.value } val recordTypesRunning = runningRecords.map(RunningRecord::id) val numberOfCards = prefsInteractor.getNumberOfCards() val isDarkTheme = prefsInteractor.getDarkMode() + val goals = filterGoalsByDayOfWeekInteractor + .execute(recordTypeGoalInteractor.getAllTypeGoals()) + .groupBy { it.idData.value } val allDailyCurrents = if (goals.isNotEmpty()) { getCurrentRecordsDurationInteractor.getAllDailyCurrents( typeIds = recordTypes.map(RecordType::id),