Skip to content

Commit 6f7b1b7

Browse files
committed
refactor goal currents
1 parent e2ed1cd commit 6f7b1b7

File tree

6 files changed

+90
-93
lines changed

6 files changed

+90
-93
lines changed

core/src/main/java/com/example/util/simpletimetracker/core/interactor/GetCurrentRecordsDurationInteractor.kt

Lines changed: 34 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import com.example.util.simpletimetracker.domain.record.mapper.RangeMapper
55
import com.example.util.simpletimetracker.domain.record.model.Range
66
import com.example.util.simpletimetracker.domain.statistics.model.RangeLength
77
import com.example.util.simpletimetracker.domain.record.model.Record
8+
import com.example.util.simpletimetracker.domain.record.model.RecordBase
89
import com.example.util.simpletimetracker.domain.record.model.RunningRecord
910
import java.lang.Long.max
1011
import javax.inject.Inject
@@ -22,18 +23,6 @@ class GetCurrentRecordsDurationInteractor @Inject constructor(
2223
return getRangeCurrent(typeId, runningRecord, RangeLength.Day)
2324
}
2425

25-
suspend fun getDailyCurrent(runningRecord: RunningRecord): Result {
26-
return getRangeCurrent(runningRecord.id, runningRecord, RangeLength.Day)
27-
}
28-
29-
suspend fun getWeeklyCurrent(runningRecord: RunningRecord): Result {
30-
return getRangeCurrent(runningRecord.id, runningRecord, RangeLength.Week)
31-
}
32-
33-
suspend fun getMonthlyCurrent(runningRecord: RunningRecord): Result {
34-
return getRangeCurrent(runningRecord.id, runningRecord, RangeLength.Month)
35-
}
36-
3726
suspend fun getAllCurrents(
3827
typeIds: List<Long>,
3928
runningRecords: List<RunningRecord>,
@@ -48,8 +37,30 @@ class GetCurrentRecordsDurationInteractor @Inject constructor(
4837

4938
return typeIds.associateWith { typeId ->
5039
getRangeCurrent(
51-
filterRecords = { records -> records.filter { it.typeId == typeId } },
52-
runningRecords = runningRecords.filter { it.id == typeId },
40+
filter = { record -> typeId in record.typeIds },
41+
allRunningRecords = runningRecords,
42+
range = range,
43+
rangeRecords = rangeRecords,
44+
)
45+
}
46+
}
47+
48+
suspend fun getAllCategoryCurrents(
49+
recordTypeCategories: Map<Long, List<Long>>,
50+
runningRecords: List<RunningRecord>,
51+
rangeLength: RangeLength,
52+
): Map<Long, Result> {
53+
val range = getRange(rangeLength)
54+
val rangeRecords = getRangeRecords(
55+
rangeLength = rangeLength,
56+
range = range,
57+
typeIds = recordTypeCategories.values.flatten().distinct(),
58+
)
59+
60+
return recordTypeCategories.mapValues { (_, typeIds) ->
61+
getRangeCurrent(
62+
filter = { record -> record.typeIds.any { it in typeIds } },
63+
allRunningRecords = runningRecords,
5364
range = range,
5465
rangeRecords = rangeRecords,
5566
)
@@ -67,12 +78,8 @@ class GetCurrentRecordsDurationInteractor @Inject constructor(
6778

6879
return tagIds.associateWith { tagId ->
6980
getRangeCurrent(
70-
filterRecords = { records ->
71-
records.filter { record -> record.tags.any { it.tagId == tagId } }
72-
},
73-
runningRecords = runningRecords.filter { record ->
74-
record.tags.any { it.tagId in tagIds }
75-
},
81+
filter = { record -> record.tags.any { it.tagId == tagId } },
82+
allRunningRecords = runningRecords,
7683
range = range,
7784
rangeRecords = rangeRecords,
7885
)
@@ -90,22 +97,10 @@ class GetCurrentRecordsDurationInteractor @Inject constructor(
9097
)
9198
}
9299

93-
private suspend fun getRangeCurrent(
100+
suspend fun getRangeCurrent(
94101
typeId: Long,
95102
runningRecord: RunningRecord?,
96103
rangeLength: RangeLength,
97-
): Result {
98-
return getRangeCurrent(
99-
typeId = typeId,
100-
runningRecords = listOfNotNull(runningRecord),
101-
rangeLength = rangeLength,
102-
)
103-
}
104-
105-
private suspend fun getRangeCurrent(
106-
typeId: Long,
107-
runningRecords: List<RunningRecord>,
108-
rangeLength: RangeLength,
109104
): Result {
110105
val range = getRange(rangeLength)
111106
val rangeRecords = getRangeRecords(
@@ -115,19 +110,20 @@ class GetCurrentRecordsDurationInteractor @Inject constructor(
115110
)
116111

117112
return getRangeCurrent(
118-
filterRecords = { records -> records.filter { it.typeId == typeId } },
119-
runningRecords = runningRecords,
113+
filter = { record -> typeId in record.typeIds },
114+
allRunningRecords = listOfNotNull(runningRecord),
120115
range = range,
121116
rangeRecords = rangeRecords,
122117
)
123118
}
124119

125120
private fun getRangeCurrent(
126-
filterRecords: (List<Record>) -> List<Record>,
127-
runningRecords: List<RunningRecord>,
121+
filter: (RecordBase) -> Boolean,
122+
allRunningRecords: List<RunningRecord>,
128123
range: Range,
129124
rangeRecords: List<Record>,
130125
): Result {
126+
val runningRecords = allRunningRecords.filter(filter)
131127
val current = System.currentTimeMillis()
132128
val currentRunning = runningRecords.sumOf { runningRecord ->
133129
current - runningRecord.timeStarted
@@ -137,7 +133,7 @@ class GetCurrentRecordsDurationInteractor @Inject constructor(
137133
}
138134
val currentRunningCount = runningRecords.size
139135

140-
val records = filterRecords(rangeRecords)
136+
val records = rangeRecords.filter(filter)
141137
.map { rangeMapper.clampToRange(it, range) }
142138
val duration = records
143139
.let(rangeMapper::mapToDuration)

core/src/main/java/com/example/util/simpletimetracker/core/interactor/GetRunningRecordViewDataMediator.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ class GetRunningRecordViewDataMediator @Inject constructor(
2929
showSeconds: Boolean,
3030
): RunningRecordViewData {
3131
val dailyCurrent = if ((goals.getDaily() != null && goalsVisible) || totalDurationVisible) {
32-
getCurrentRecordsDurationInteractor.getDailyCurrent(record)
32+
getCurrentRecordsDurationInteractor.getDailyCurrent(typeId = record.id, runningRecord = record)
3333
} else {
3434
null
3535
}

domain/src/main/java/com/example/util/simpletimetracker/domain/recordType/extension/GoalsExtensions.kt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,16 @@ import com.example.util.simpletimetracker.domain.daysOfWeek.model.DayOfWeek
55
import com.example.util.simpletimetracker.domain.recordType.model.RecordTypeGoal
66
import com.example.util.simpletimetracker.domain.recordType.model.RecordTypeGoal.Range
77
import com.example.util.simpletimetracker.domain.recordType.model.RecordTypeGoal.Type
8+
import com.example.util.simpletimetracker.domain.statistics.model.RangeLength
9+
10+
fun Range.toRangeLength(): RangeLength? {
11+
return when (this) {
12+
is Range.Session -> return null
13+
is Range.Daily -> RangeLength.Day
14+
is Range.Weekly -> RangeLength.Week
15+
is Range.Monthly -> RangeLength.Month
16+
}
17+
}
818

919
fun List<RecordTypeGoal>.getSession(): RecordTypeGoal? {
1020
return firstOrNull { it.range is Range.Session }

features/feature_notification/src/main/java/com/example/util/simpletimetracker/feature_notification/goalTime/interactor/NotificationGoalCountInteractorImpl.kt

Lines changed: 20 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -8,17 +8,15 @@ import com.example.util.simpletimetracker.domain.notifications.interactor.Notifi
88
import com.example.util.simpletimetracker.domain.category.interactor.RecordTypeCategoryInteractor
99
import com.example.util.simpletimetracker.domain.recordType.interactor.RecordTypeGoalInteractor
1010
import com.example.util.simpletimetracker.domain.record.interactor.RunningRecordInteractor
11-
import com.example.util.simpletimetracker.domain.statistics.model.RangeLength
1211
import com.example.util.simpletimetracker.domain.category.model.RecordTypeCategory
1312
import com.example.util.simpletimetracker.domain.notifications.interactor.ActivityStartedStoppedBroadcastInteractor
1413
import com.example.util.simpletimetracker.domain.recordType.model.RecordTypeGoal
1514
import com.example.util.simpletimetracker.domain.recordType.model.RecordTypeGoal.Range
1615
import com.example.util.simpletimetracker.domain.recordType.model.RecordTypeGoal.Type
1716
import com.example.util.simpletimetracker.domain.record.model.RunningRecord
17+
import com.example.util.simpletimetracker.domain.recordType.extension.toRangeLength
1818
import com.example.util.simpletimetracker.feature_notification.goalTime.manager.NotificationGoalTimeManager
1919
import javax.inject.Inject
20-
import kotlin.collections.component1
21-
import kotlin.collections.component2
2220

2321
class NotificationGoalCountInteractorImpl @Inject constructor(
2422
private val recordTypeGoalInteractor: RecordTypeGoalInteractor,
@@ -46,7 +44,7 @@ class NotificationGoalCountInteractorImpl @Inject constructor(
4644
// No count goals - exit.
4745
if (goals.isEmpty()) return
4846

49-
listOf(Range.Daily, Range.Weekly, Range.Monthly).forEach { goalRange ->
47+
getAllGoalRanges().forEach { goalRange ->
5048
checkType(
5149
goalRange = goalRange,
5250
goals = goals,
@@ -83,7 +81,7 @@ class NotificationGoalCountInteractorImpl @Inject constructor(
8381
// For each goal check current results.
8482
val runningRecords = runningRecordInteractor.getAll()
8583

86-
listOf(Range.Daily, Range.Weekly, Range.Monthly).forEach { goalRange ->
84+
getAllGoalRanges().forEach { goalRange ->
8785
checkCategory(
8886
goalRange = goalRange,
8987
goals = affectedCategoryGoals,
@@ -117,7 +115,7 @@ class NotificationGoalCountInteractorImpl @Inject constructor(
117115
// For each goal check current results.
118116
val runningRecords = runningRecordInteractor.getAll()
119117

120-
listOf(Range.Daily, Range.Weekly, Range.Monthly).forEach { goalRange ->
118+
getAllGoalRanges().forEach { goalRange ->
121119
checkTag(
122120
goalRange = goalRange,
123121
goals = affectedTagGoals,
@@ -135,12 +133,11 @@ class NotificationGoalCountInteractorImpl @Inject constructor(
135133
val goal = filterGoalsFromRange<RecordTypeGoal.IdData.Type>(goalRange, goals).firstOrNull()
136134
if (goal == null) return
137135

138-
val current = when (goalRange) {
139-
is Range.Session -> return
140-
is Range.Daily -> getCurrentRecordsDurationInteractor.getDailyCurrent(runningRecord)
141-
is Range.Weekly -> getCurrentRecordsDurationInteractor.getWeeklyCurrent(runningRecord)
142-
is Range.Monthly -> getCurrentRecordsDurationInteractor.getMonthlyCurrent(runningRecord)
143-
}.count
136+
val current = getCurrentRecordsDurationInteractor.getRangeCurrent(
137+
typeId = runningRecord.id,
138+
runningRecord = runningRecord,
139+
rangeLength = goalRange.toRangeLength() ?: return,
140+
).count
144141

145142
if (current == goal.value) {
146143
show(
@@ -159,37 +156,15 @@ class NotificationGoalCountInteractorImpl @Inject constructor(
159156
val rangeGoals = filterGoalsFromRange<RecordTypeGoal.IdData.Category>(goalRange, goals)
160157
if (rangeGoals.isEmpty()) return
161158

162-
val allTypeIdsFromTheseCategories = categoriesWithThisType.values
163-
.flatten().distinct()
164-
val allCurrents = getCurrentRecordsDurationInteractor.getAllCurrents(
165-
typeIds = allTypeIdsFromTheseCategories,
159+
val allCurrents = getCurrentRecordsDurationInteractor.getAllCategoryCurrents(
160+
recordTypeCategories = categoriesWithThisType,
166161
runningRecords = runningRecords,
167-
rangeLength = when (goalRange) {
168-
is Range.Session -> return
169-
is Range.Daily -> RangeLength.Day
170-
is Range.Weekly -> RangeLength.Week
171-
is Range.Monthly -> RangeLength.Month
172-
},
162+
rangeLength = goalRange.toRangeLength() ?: return,
173163
)
174164

175-
val thisRangeCurrents = categoriesWithThisType.mapNotNull { (categoryId, typeIds) ->
176-
val currents = allCurrents
177-
.filter { it.key in typeIds }
178-
.values
179-
.toList()
180-
val current = GetCurrentRecordsDurationInteractor.Result(
181-
range = allCurrents.values.firstOrNull()?.range ?: return@mapNotNull null,
182-
duration = currents.sumOf { it.duration },
183-
count = currents.sumOf { it.count },
184-
durationDiffersFromCurrent = currents.any { it.durationDiffersFromCurrent },
185-
)
186-
categoryId to current
187-
}.toMap()
188-
189165
rangeGoals.forEach { goal ->
190-
val categoryId = (goal.idData as? RecordTypeGoal.IdData.Category)?.value
191-
?: return@forEach
192-
val current = thisRangeCurrents[categoryId]?.count.orZero()
166+
val categoryId = goal.idData.value
167+
val current = allCurrents[categoryId]?.count.orZero()
193168
if (current == goal.value) {
194169
show(
195170
idData = RecordTypeGoal.IdData.Category(categoryId),
@@ -211,17 +186,11 @@ class NotificationGoalCountInteractorImpl @Inject constructor(
211186
val allCurrents = getCurrentRecordsDurationInteractor.getAllTagCurrents(
212187
tagIds = allTags,
213188
runningRecords = runningRecords,
214-
rangeLength = when (goalRange) {
215-
is Range.Session -> return
216-
is Range.Daily -> RangeLength.Day
217-
is Range.Weekly -> RangeLength.Week
218-
is Range.Monthly -> RangeLength.Month
219-
},
189+
rangeLength = goalRange.toRangeLength() ?: return,
220190
)
221191

222192
rangeGoals.forEach { goal ->
223-
val tagId = (goal.idData as? RecordTypeGoal.IdData.Tag)?.value
224-
?: return@forEach
193+
val tagId = goal.idData.value
225194
val current = allCurrents[tagId]?.count.orZero()
226195
if (current == goal.value) {
227196
show(
@@ -267,4 +236,8 @@ class NotificationGoalCountInteractorImpl @Inject constructor(
267236
)
268237
}
269238
}
239+
240+
private fun getAllGoalRanges(): List<Range> {
241+
return listOf(Range.Daily, Range.Weekly, Range.Monthly)
242+
}
270243
}

features/feature_notification/src/main/java/com/example/util/simpletimetracker/feature_notification/goalTime/interactor/NotificationGoalTimeInteractorImpl.kt

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import com.example.util.simpletimetracker.domain.notifications.interactor.Activi
1515
import com.example.util.simpletimetracker.domain.recordType.model.RecordTypeGoal
1616
import com.example.util.simpletimetracker.domain.recordType.model.RecordTypeGoal.Range
1717
import com.example.util.simpletimetracker.domain.record.model.RunningRecord
18+
import com.example.util.simpletimetracker.domain.recordType.extension.toRangeLength
1819
import com.example.util.simpletimetracker.feature_notification.goalTime.manager.NotificationGoalTimeManager
1920
import com.example.util.simpletimetracker.feature_notification.goalTime.scheduler.NotificationGoalTimeScheduler
2021
import javax.inject.Inject
@@ -33,6 +34,14 @@ import javax.inject.Inject
3334
* - remove category
3435
* - change type categories
3536
* - change category activities
37+
*
38+
* Tag goal can be changed:
39+
* - add / change / remove running record
40+
* - add / change / remove record
41+
* - add / change / remove tag goal
42+
* - remove tag
43+
* - change record tags
44+
* - change running record tags
3645
*/
3746
class NotificationGoalTimeInteractorImpl @Inject constructor(
3847
private val recordTypeGoalInteractor: RecordTypeGoalInteractor,
@@ -207,11 +216,14 @@ class NotificationGoalTimeInteractorImpl @Inject constructor(
207216
}.value * 1000
208217

209218
if (goal > 0) {
210-
val current = when (goalRange) {
211-
is Range.Session -> System.currentTimeMillis() - runningRecord.timeStarted
212-
is Range.Daily -> getCurrentRecordsDurationInteractor.getDailyCurrent(runningRecord).duration
213-
is Range.Weekly -> getCurrentRecordsDurationInteractor.getWeeklyCurrent(runningRecord).duration
214-
is Range.Monthly -> getCurrentRecordsDurationInteractor.getMonthlyCurrent(runningRecord).duration
219+
val current = if (goalRange is Range.Session) {
220+
System.currentTimeMillis() - runningRecord.timeStarted
221+
} else {
222+
getCurrentRecordsDurationInteractor.getRangeCurrent(
223+
typeId = runningRecord.id,
224+
runningRecord = runningRecord,
225+
rangeLength = goalRange.toRangeLength() ?: return,
226+
).duration
215227
}
216228

217229
if (goal > current) {

features/feature_notification/src/main/java/com/example/util/simpletimetracker/feature_notification/recordType/interactor/NotificationTypeInteractorImpl.kt

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,10 @@ class NotificationTypeInteractorImpl @Inject constructor(
130130
goal = goalTime,
131131
runningRecord = runningRecord,
132132
recordTags = recordTags,
133-
dailyCurrent = getCurrentRecordsDurationInteractor.getDailyCurrent(runningRecord),
133+
dailyCurrent = getCurrentRecordsDurationInteractor.getDailyCurrent(
134+
typeId = typeId,
135+
runningRecord = runningRecord,
136+
),
134137
isDarkTheme = isDarkTheme,
135138
useMilitaryTime = useMilitaryTime,
136139
showSeconds = showSeconds,
@@ -209,7 +212,10 @@ class NotificationTypeInteractorImpl @Inject constructor(
209212
goal = goalTime,
210213
runningRecord = runningRecord,
211214
recordTags = recordTags,
212-
dailyCurrent = getCurrentRecordsDurationInteractor.getDailyCurrent(runningRecord),
215+
dailyCurrent = getCurrentRecordsDurationInteractor.getDailyCurrent(
216+
typeId = runningRecord.id,
217+
runningRecord = runningRecord,
218+
),
213219
isDarkTheme = isDarkTheme,
214220
useMilitaryTime = useMilitaryTime,
215221
showSeconds = showSeconds,

0 commit comments

Comments
 (0)