Skip to content

Commit 5a0b0c5

Browse files
committed
change stat detail total preview
1 parent dac3623 commit 5a0b0c5

8 files changed

Lines changed: 165 additions & 38 deletions

File tree

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
package com.example.util.simpletimetracker.core.interactor
2+
3+
import com.example.util.simpletimetracker.domain.category.interactor.CategoryInteractor
4+
import com.example.util.simpletimetracker.domain.category.model.Category
5+
import com.example.util.simpletimetracker.domain.record.model.RecordsFilter
6+
import com.example.util.simpletimetracker.domain.recordTag.interactor.RecordTagInteractor
7+
import com.example.util.simpletimetracker.domain.recordTag.model.RecordTag
8+
import com.example.util.simpletimetracker.domain.recordType.interactor.RecordTypeInteractor
9+
import com.example.util.simpletimetracker.domain.recordType.model.RecordType
10+
import com.example.util.simpletimetracker.domain.statistics.model.ChartFilterType
11+
import javax.inject.Inject
12+
import kotlin.collections.plus
13+
14+
class GetTotalStatisticsFilterInteractor @Inject constructor(
15+
private val recordTypeInteractor: RecordTypeInteractor,
16+
private val categoryInteractor: CategoryInteractor,
17+
private val recordTagInteractor: RecordTagInteractor,
18+
) {
19+
20+
suspend fun execute(
21+
filterType: ChartFilterType
22+
): RecordsFilter {
23+
return when (filterType) {
24+
ChartFilterType.ACTIVITY -> {
25+
val typeIds = recordTypeInteractor.getAll()
26+
.map(RecordType::id)
27+
RecordsFilter.Activity(selected = typeIds, filtered = emptyList())
28+
}
29+
ChartFilterType.CATEGORY -> {
30+
val categoryIds = categoryInteractor.getAll()
31+
.map(Category::id)
32+
val items = categoryIds
33+
.map(RecordsFilter.CategoryItem::Categorized) +
34+
RecordsFilter.CategoryItem.Uncategorized
35+
RecordsFilter.Category(selected = items, filtered = emptyList())
36+
}
37+
ChartFilterType.RECORD_TAG -> {
38+
val tagIds = recordTagInteractor.getAll()
39+
.map(RecordTag::id)
40+
val items = tagIds
41+
.map(RecordsFilter.TagItem::Tagged) +
42+
RecordsFilter.TagItem.Untagged
43+
RecordsFilter.Tags(selected = items, filtered = emptyList())
44+
}
45+
}
46+
}
47+
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
package com.example.util.simpletimetracker.domain.base
22

3+
// TODO change to sealed class?
34
const val UNTRACKED_ITEM_ID = -1L
45
const val UNCATEGORIZED_ITEM_ID = -2L
56
const val MULTITASK_ITEM_ID = -3L
67
const val REPEAT_BUTTON_ITEM_ID = -4L
78
const val ARCHIVED_BUTTON_ITEM_ID = -5L
9+
const val STATISTICS_TOTAL_ITEM_ID = -6L

features/feature_statistics/src/main/java/com/example/util/simpletimetracker/feature_statistics/interactor/StatisticsDetailTotalNavigator.kt

Lines changed: 5 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,8 @@ package com.example.util.simpletimetracker.feature_statistics.interactor
22

33
import com.example.util.simpletimetracker.core.extension.toParams
44
import com.example.util.simpletimetracker.core.interactor.GetStatisticsDetailRangeInteractor
5-
import com.example.util.simpletimetracker.domain.category.interactor.CategoryInteractor
6-
import com.example.util.simpletimetracker.domain.category.model.Category
5+
import com.example.util.simpletimetracker.core.interactor.GetTotalStatisticsFilterInteractor
76
import com.example.util.simpletimetracker.domain.prefs.interactor.PrefsInteractor
8-
import com.example.util.simpletimetracker.domain.recordTag.interactor.RecordTagInteractor
9-
import com.example.util.simpletimetracker.domain.recordType.interactor.RecordTypeInteractor
10-
import com.example.util.simpletimetracker.domain.statistics.model.ChartFilterType
11-
import com.example.util.simpletimetracker.domain.recordTag.model.RecordTag
12-
import com.example.util.simpletimetracker.domain.recordType.model.RecordType
137
import com.example.util.simpletimetracker.domain.record.model.RecordsFilter
148
import com.example.util.simpletimetracker.navigation.Router
159
import com.example.util.simpletimetracker.navigation.params.screen.StatisticsDetailParams
@@ -19,37 +13,15 @@ class StatisticsDetailTotalNavigator @Inject constructor(
1913
private val router: Router,
2014
private val prefsInteractor: PrefsInteractor,
2115
private val getStatisticsDetailRangeInteractor: GetStatisticsDetailRangeInteractor,
22-
private val recordTypeInteractor: RecordTypeInteractor,
23-
private val categoryInteractor: CategoryInteractor,
24-
private val recordTagInteractor: RecordTagInteractor,
16+
private val getTotalStatisticsFilterInteractor: GetTotalStatisticsFilterInteractor,
2517
) {
2618

2719
suspend fun execute(
2820
shift: Int,
2921
) {
30-
val filter = when (prefsInteractor.getChartFilterType()) {
31-
ChartFilterType.ACTIVITY -> {
32-
val typeIds = recordTypeInteractor.getAll()
33-
.map(RecordType::id)
34-
RecordsFilter.Activity(selected = typeIds, filtered = emptyList())
35-
}
36-
ChartFilterType.CATEGORY -> {
37-
val categoryIds = categoryInteractor.getAll()
38-
.map(Category::id)
39-
val items = categoryIds
40-
.map(RecordsFilter.CategoryItem::Categorized) +
41-
RecordsFilter.CategoryItem.Uncategorized
42-
RecordsFilter.Category(selected = items, filtered = emptyList())
43-
}
44-
ChartFilterType.RECORD_TAG -> {
45-
val tagIds = recordTagInteractor.getAll()
46-
.map(RecordTag::id)
47-
val items = tagIds
48-
.map(RecordsFilter.TagItem::Tagged) +
49-
RecordsFilter.TagItem.Untagged
50-
RecordsFilter.Tags(selected = items, filtered = emptyList())
51-
}
52-
}
22+
val filter = getTotalStatisticsFilterInteractor.execute(
23+
filterType = prefsInteractor.getChartFilterType(),
24+
)
5325

5426
val params = StatisticsDetailParams(
5527
transitionName = "",

features/feature_statistics_detail/src/main/java/com/example/util/simpletimetracker/feature_statistics_detail/interactor/StatisticsDetailAdjacentActivitiesInteractor.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ class StatisticsDetailAdjacentActivitiesInteractor @Inject constructor(
6969
statisticsDetailViewDataMapper.mapToPreview(
7070
recordType = recordTypes[typeId] ?: return@mapIndexedNotNull null,
7171
isDarkTheme = isDarkTheme,
72-
isFirst = false,
72+
showName = false,
7373
isForComparison = false,
7474
).copy(name = "$correctedPercent%")
7575
}

features/feature_statistics_detail/src/main/java/com/example/util/simpletimetracker/feature_statistics_detail/interactor/StatisticsDetailPreviewInteractor.kt

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,12 +50,20 @@ class StatisticsDetailPreviewInteractor @Inject constructor(
5050

5151
suspend fun getPreviewData(
5252
filterParams: List<RecordsFilter>,
53+
total: Boolean,
5354
isExpanded: Boolean,
5455
isForComparison: Boolean,
5556
): List<ViewHolderType> = withContext(Dispatchers.Default) {
5657
val isDarkTheme = prefsInteractor.getDarkMode()
5758
val previewType = getPreviewType(filterParams)
5859

60+
fun mapTotal(): List<ViewHolderType> {
61+
return statisticsDetailViewDataMapper.mapToTotalPreview(
62+
isDarkTheme = isDarkTheme,
63+
isForComparison = isForComparison,
64+
).let(::listOf)
65+
}
66+
5967
suspend fun mapActivities(
6068
selectedIds: List<Long>,
6169
): List<ViewHolderType> {
@@ -65,7 +73,7 @@ class StatisticsDetailPreviewInteractor @Inject constructor(
6573
statisticsDetailViewDataMapper.mapToPreview(
6674
recordType = type,
6775
isDarkTheme = isDarkTheme,
68-
isFirst = index == 0,
76+
showName = !total && index == 0,
6977
isForComparison = isForComparison,
7078
)
7179
}
@@ -139,6 +147,8 @@ class StatisticsDetailPreviewInteractor @Inject constructor(
139147
val selectedIds = records.map { it.typeIds }.flatten().distinct()
140148
mapActivities(selectedIds)
141149
}
150+
}.let {
151+
if (total) mapTotal() + it else it
142152
}.let {
143153
if (it.size > MAX_PREVIEWS_COUNT && !isExpanded) {
144154
val type = if (isForComparison) {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
package com.example.util.simpletimetracker.feature_statistics_detail.interactor
2+
3+
import com.example.util.simpletimetracker.core.interactor.GetTotalStatisticsFilterInteractor
4+
import com.example.util.simpletimetracker.domain.record.model.RecordsFilter
5+
import com.example.util.simpletimetracker.domain.statistics.model.ChartFilterType
6+
import javax.inject.Inject
7+
8+
class StatisticsDetailTotalRecordsSelectedInteractor @Inject constructor(
9+
private val getTotalStatisticsFilterInteractor: GetTotalStatisticsFilterInteractor,
10+
) {
11+
12+
suspend fun execute(
13+
currentFilter: List<RecordsFilter>,
14+
): Boolean {
15+
if (currentFilter.size != 1) return false
16+
val onlyFilter = currentFilter.firstOrNull() ?: return false
17+
val chartFilter = when (onlyFilter) {
18+
is RecordsFilter.Activity -> ChartFilterType.ACTIVITY
19+
is RecordsFilter.Category -> ChartFilterType.CATEGORY
20+
is RecordsFilter.Tags -> ChartFilterType.RECORD_TAG
21+
else -> return false
22+
}
23+
val totalFilter = getTotalStatisticsFilterInteractor.execute(chartFilter)
24+
return totalFilter.prepareForComparison() == onlyFilter.prepareForComparison()
25+
}
26+
27+
private fun RecordsFilter.prepareForComparison(): RecordsFilter {
28+
fun List<RecordsFilter.CategoryItem>.prepare(): List<RecordsFilter.CategoryItem> {
29+
return this.sortedBy {
30+
when (it) {
31+
is RecordsFilter.CategoryItem.Categorized -> it.categoryId
32+
is RecordsFilter.CategoryItem.Uncategorized -> -1
33+
}
34+
}
35+
}
36+
37+
fun List<RecordsFilter.TagItem>.prepare(): List<RecordsFilter.TagItem> {
38+
return this.sortedBy {
39+
when (it) {
40+
is RecordsFilter.TagItem.Tagged -> it.tagId
41+
is RecordsFilter.TagItem.Untagged -> -1
42+
}
43+
}
44+
}
45+
46+
return when (this) {
47+
is RecordsFilter.Activity -> {
48+
this.copy(
49+
selected = this.selected.sorted(),
50+
filtered = this.filtered.sorted(),
51+
)
52+
}
53+
is RecordsFilter.Category -> {
54+
this.copy(
55+
selected = this.selected.prepare(),
56+
filtered = this.filtered.prepare(),
57+
)
58+
}
59+
is RecordsFilter.Tags -> {
60+
this.copy(
61+
selected = this.selected.prepare(),
62+
filtered = this.filtered.prepare(),
63+
)
64+
}
65+
else -> this
66+
}
67+
}
68+
}

features/feature_statistics_detail/src/main/java/com/example/util/simpletimetracker/feature_statistics_detail/mapper/StatisticsDetailViewDataMapper.kt

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import com.example.util.simpletimetracker.core.repo.ResourceRepo
1212
import com.example.util.simpletimetracker.domain.base.DurationFormat
1313
import com.example.util.simpletimetracker.domain.base.MULTITASK_ITEM_ID
1414
import com.example.util.simpletimetracker.domain.base.OneShotValue
15+
import com.example.util.simpletimetracker.domain.base.STATISTICS_TOTAL_ITEM_ID
1516
import com.example.util.simpletimetracker.domain.base.UNTRACKED_ITEM_ID
1617
import com.example.util.simpletimetracker.domain.category.model.Category
1718
import com.example.util.simpletimetracker.domain.daysOfWeek.model.DayOfWeek
@@ -61,7 +62,7 @@ class StatisticsDetailViewDataMapper @Inject constructor(
6162
fun mapToPreview(
6263
recordType: RecordType,
6364
isDarkTheme: Boolean,
64-
isFirst: Boolean,
65+
showName: Boolean,
6566
isForComparison: Boolean,
6667
): StatisticsDetailPreviewViewData {
6768
return StatisticsDetailPreviewViewData(
@@ -71,7 +72,7 @@ class StatisticsDetailViewDataMapper @Inject constructor(
7172
} else {
7273
StatisticsDetailPreviewViewData.Type.FILTER
7374
},
74-
name = recordType.name.takeIf { isFirst }.orEmpty(),
75+
name = recordType.name.takeIf { showName }.orEmpty(),
7576
iconId = recordType.icon
7677
.let(iconMapper::mapIcon),
7778
color = recordType.color
@@ -210,6 +211,23 @@ class StatisticsDetailViewDataMapper @Inject constructor(
210211
)
211212
}
212213

214+
fun mapToTotalPreview(
215+
isDarkTheme: Boolean,
216+
isForComparison: Boolean,
217+
): StatisticsDetailPreviewViewData {
218+
return StatisticsDetailPreviewViewData(
219+
id = STATISTICS_TOTAL_ITEM_ID,
220+
type = if (isForComparison) {
221+
StatisticsDetailPreviewViewData.Type.COMPARISON
222+
} else {
223+
StatisticsDetailPreviewViewData.Type.FILTER
224+
},
225+
name = resourceRepo.getString(R.string.statistics_total_tracked),
226+
iconId = null,
227+
color = colorMapper.toUntrackedColor(isDarkTheme),
228+
)
229+
}
230+
213231
fun mapToChartViewData(
214232
data: List<ChartBarDataDuration>,
215233
prevData: List<ChartBarDataDuration>,

features/feature_statistics_detail/src/main/java/com/example/util/simpletimetracker/feature_statistics_detail/viewModel/delegate/StatisticsDetailPreviewViewModelDelegate.kt

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,22 @@ import androidx.lifecycle.LiveData
44
import com.example.util.simpletimetracker.core.base.ViewModelDelegate
55
import com.example.util.simpletimetracker.core.extension.lazySuspend
66
import com.example.util.simpletimetracker.core.extension.set
7+
import com.example.util.simpletimetracker.core.extension.toModel
8+
import com.example.util.simpletimetracker.domain.extension.orFalse
9+
import com.example.util.simpletimetracker.domain.record.model.RecordsFilter
710
import com.example.util.simpletimetracker.feature_statistics_detail.interactor.StatisticsDetailPreviewInteractor
11+
import com.example.util.simpletimetracker.feature_statistics_detail.interactor.StatisticsDetailTotalRecordsSelectedInteractor
812
import com.example.util.simpletimetracker.feature_statistics_detail.viewData.StatisticsDetailPreview
913
import com.example.util.simpletimetracker.feature_statistics_detail.viewData.StatisticsDetailPreviewCompositeViewData
1014
import com.example.util.simpletimetracker.feature_statistics_detail.viewData.StatisticsDetailPreviewMoreViewData
1115
import com.example.util.simpletimetracker.feature_statistics_detail.viewData.StatisticsDetailPreviewViewData
16+
import com.example.util.simpletimetracker.navigation.params.screen.RecordsFilterParam
1217
import kotlinx.coroutines.launch
1318
import javax.inject.Inject
1419

1520
class StatisticsDetailPreviewViewModelDelegate @Inject constructor(
1621
private val previewInteractor: StatisticsDetailPreviewInteractor,
22+
private val totalRecordsSelectedInteractor: StatisticsDetailTotalRecordsSelectedInteractor,
1723
) : StatisticsDetailViewModelDelegate, ViewModelDelegate() {
1824

1925
val viewData: LiveData<StatisticsDetailPreviewCompositeViewData?> by lazySuspend {
@@ -44,14 +50,18 @@ class StatisticsDetailPreviewViewModelDelegate @Inject constructor(
4450

4551
private suspend fun loadViewData(): StatisticsDetailPreviewCompositeViewData? {
4652
val parent = parent ?: return null
53+
val currentFilter = parent.filter
54+
val total = totalRecordsSelectedInteractor.execute(currentFilter)
4755

4856
val data = previewInteractor.getPreviewData(
49-
filterParams = parent.filter,
57+
filterParams = currentFilter,
58+
total = total,
5059
isExpanded = previewsExpanded,
5160
isForComparison = false,
5261
)
5362
val comparisonData = previewInteractor.getPreviewData(
5463
filterParams = parent.comparisonFilter,
64+
total = false,
5565
isExpanded = previewsComparisonExpanded,
5666
isForComparison = true,
5767
)

0 commit comments

Comments
 (0)