diff --git a/README.md b/README.md
index e875f92b5..ce807da1f 100644
--- a/README.md
+++ b/README.md
@@ -100,6 +100,7 @@ Simple app that helps track how much time you spend on all the useless activitie
│ ├── feature_settings # One of main tabs, settings.
│ ├── feature_statistics # One of main tabs, statistics.
│ ├── feature_statistics_detail # Screen showing detailed statistics.
+ │ ├── feature_suggestions # Screen for activity suggestions.
│ ├── feature_tag_selection # Screen for selecting tags.
│ ├── feature_views # Custom views.
│ ├── feature_wear # Phone app logic to connect to wear app.
diff --git a/app/build.gradle.kts b/app/build.gradle.kts
index 981b3cb3f..c24895211 100644
--- a/app/build.gradle.kts
+++ b/app/build.gradle.kts
@@ -109,6 +109,7 @@ dependencies {
implementation(project(":feature_goals"))
implementation(project(":feature_pomodoro"))
implementation(project(":feature_complex_rules"))
+ implementation(project(":feature_suggestions"))
implementation(project(":feature_change_complex_rule"))
implementation(project(":feature_change_goals"))
implementation(project(":feature_change_goals:api"))
diff --git a/app/src/main/java/com/example/util/simpletimetracker/di/NavigationScreenMapModule.kt b/app/src/main/java/com/example/util/simpletimetracker/di/NavigationScreenMapModule.kt
index eb97d5b48..11d35208d 100644
--- a/app/src/main/java/com/example/util/simpletimetracker/di/NavigationScreenMapModule.kt
+++ b/app/src/main/java/com/example/util/simpletimetracker/di/NavigationScreenMapModule.kt
@@ -13,6 +13,7 @@ import com.example.util.simpletimetracker.feature_statistics_detail.view.Statist
import com.example.util.simpletimetracker.navigation.NavigationData
import com.example.util.simpletimetracker.navigation.bundleCreator.BundleCreator
import com.example.util.simpletimetracker.navigation.bundleCreator.bundleCreatorDelegate
+import com.example.util.simpletimetracker.navigation.params.screen.ActivitySuggestionsParams
import com.example.util.simpletimetracker.navigation.params.screen.ArchiveParams
import com.example.util.simpletimetracker.navigation.params.screen.CategoriesParams
import com.example.util.simpletimetracker.navigation.params.screen.ChangeActivityFilterParams
@@ -162,6 +163,16 @@ class NavigationScreenMapModule {
)
}
+ @IntoMap
+ @Provides
+ @ScreenKey(ActivitySuggestionsParams::class)
+ fun activitySuggestions(): NavigationData {
+ return NavigationData(
+ R.id.action_to_activitySuggestionsFragment,
+ BundleCreator.empty(),
+ )
+ }
+
@IntoMap
@Provides
@ScreenKey(ChangeCategoryFromTagsParams::class)
diff --git a/app/src/main/res/navigation/nav_graph.xml b/app/src/main/res/navigation/nav_graph.xml
index 02e9b14e6..dae422bc9 100644
--- a/app/src/main/res/navigation/nav_graph.xml
+++ b/app/src/main/res/navigation/nav_graph.xml
@@ -37,6 +37,14 @@
app:popEnterAnim="@anim/slide_in_left"
app:popExitAnim="@anim/slide_out_right" />
+
+
+
,
records: List,
+ maxCount: Int,
): Map> {
val counts = mutableMapOf>()
val recordsSorted = records.sortedBy { it.timeStarted }
@@ -40,7 +41,7 @@ class CalculateAdjacentActivitiesInteractor @Inject constructor() {
return counts.mapValues { (_, counts) ->
counts.keys
.sortedByDescending { counts[it].orZero() }
- .take(MAX_COUNT)
+ .take(maxCount)
.map { CalculationResult(it, counts[it].orZero()) }
}
}
@@ -49,6 +50,7 @@ class CalculateAdjacentActivitiesInteractor @Inject constructor() {
fun calculateMultitasking(
typeId: Long,
records: List,
+ maxCount: Int,
): List {
val counts = mutableMapOf()
@@ -76,7 +78,7 @@ class CalculateAdjacentActivitiesInteractor @Inject constructor() {
return counts.keys
.sortedByDescending { counts[it].orZero() }
- .take(MAX_COUNT)
+ .take(maxCount)
.map { CalculationResult(it, counts[it].orZero()) }
}
@@ -84,8 +86,4 @@ class CalculateAdjacentActivitiesInteractor @Inject constructor() {
val typeId: Long,
val count: Long,
)
-
- companion object {
- private const val MAX_COUNT = 5
- }
}
\ No newline at end of file
diff --git a/domain/src/test/java/com/example/util/simpletimetracker/domain/mapper/CalculateAdjacentActivitiesInteractorTest.kt b/domain/src/test/java/com/example/util/simpletimetracker/domain/mapper/CalculateAdjacentActivitiesInteractorTest.kt
index b9fd7e5b9..ee8300046 100644
--- a/domain/src/test/java/com/example/util/simpletimetracker/domain/mapper/CalculateAdjacentActivitiesInteractorTest.kt
+++ b/domain/src/test/java/com/example/util/simpletimetracker/domain/mapper/CalculateAdjacentActivitiesInteractorTest.kt
@@ -23,6 +23,7 @@ class CalculateAdjacentActivitiesInteractorTest(
val actual = subject.calculateNextActivities(
typeIds = input.first,
records = input.second,
+ maxCount = 5,
)
assertEquals(
diff --git a/features/feature_base_adapter/src/main/java/com/example/util/simpletimetracker/feature_base_adapter/hint/HintAdapterDelegate.kt b/features/feature_base_adapter/src/main/java/com/example/util/simpletimetracker/feature_base_adapter/hint/HintAdapterDelegate.kt
index fc260e06f..e278a1834 100644
--- a/features/feature_base_adapter/src/main/java/com/example/util/simpletimetracker/feature_base_adapter/hint/HintAdapterDelegate.kt
+++ b/features/feature_base_adapter/src/main/java/com/example/util/simpletimetracker/feature_base_adapter/hint/HintAdapterDelegate.kt
@@ -1,5 +1,6 @@
package com.example.util.simpletimetracker.feature_base_adapter.hint
+import android.view.Gravity
import androidx.core.view.updatePadding
import com.example.util.simpletimetracker.feature_base_adapter.createRecyclerBindingAdapterDelegate
import com.example.util.simpletimetracker.feature_views.extension.dpToPx
@@ -10,6 +11,13 @@ fun createHintAdapterDelegate() = createRecyclerBindingAdapterDelegate
+ fun ViewData.Gravity.toViewData(): Int {
+ return when (this) {
+ ViewData.Gravity.CENTER -> Gravity.CENTER
+ ViewData.Gravity.START -> Gravity.START
+ }
+ }
+
with(binding) {
item as ViewData
@@ -18,5 +26,6 @@ fun createHintAdapterDelegate() = createRecyclerBindingAdapterDelegate
- params.width = item.width.dpToPx()
- params.height = item.height.dpToPx()
+ item.width?.dpToPx()?.let { params.width = it }
+ item.height?.dpToPx()?.let { params.height = it }
}
itemIsRow = item.asRow
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 641e3a432..4b850c772 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
@@ -10,8 +10,8 @@ data class RunningRecordTypeSpecialViewData(
val name: String,
val iconId: RecordTypeIcon,
@ColorInt val color: Int,
- val width: Int,
- val height: Int,
+ val width: Int?,
+ val height: Int?,
val asRow: Boolean = false,
val checkState: CheckState = CheckState.HIDDEN,
) : ViewHolderType {
diff --git a/features/feature_change_record/src/main/res/layout/change_record_core_layout.xml b/features/feature_change_record/src/main/res/layout/change_record_core_layout.xml
index 2ccefccbc..e4ae21adf 100644
--- a/features/feature_change_record/src/main/res/layout/change_record_core_layout.xml
+++ b/features/feature_change_record/src/main/res/layout/change_record_core_layout.xml
@@ -14,7 +14,7 @@
app:layout_constraintBottom_toTopOf="@id/dividerChangeRecordButton"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0"
- tools:visibility="gone">
+ tools:visibility="visible">
+ tools:visibility="gone" />
-
diff --git a/features/feature_dialogs/src/main/java/com/example/util/simpletimetracker/feature_dialogs/typesSelection/viewModel/TypesSelectionViewModel.kt b/features/feature_dialogs/src/main/java/com/example/util/simpletimetracker/feature_dialogs/typesSelection/viewModel/TypesSelectionViewModel.kt
index 6d104f62c..0ea2e21c1 100644
--- a/features/feature_dialogs/src/main/java/com/example/util/simpletimetracker/feature_dialogs/typesSelection/viewModel/TypesSelectionViewModel.kt
+++ b/features/feature_dialogs/src/main/java/com/example/util/simpletimetracker/feature_dialogs/typesSelection/viewModel/TypesSelectionViewModel.kt
@@ -67,6 +67,7 @@ class TypesSelectionViewModel @Inject constructor(
}
fun onShowAllClick() {
+ dataIdsSelected.clear()
dataIdsSelected.addAll(viewDataCache.map(TypesSelectionCacheHolder::id))
updateViewData()
}
diff --git a/features/feature_settings/api/src/main/java/com/example/util/simpletimetracker/feature_settings/api/SettingsBlock.kt b/features/feature_settings/api/src/main/java/com/example/util/simpletimetracker/feature_settings/api/SettingsBlock.kt
index 43cbcfa0d..95cc42ea6 100644
--- a/features/feature_settings/api/src/main/java/com/example/util/simpletimetracker/feature_settings/api/SettingsBlock.kt
+++ b/features/feature_settings/api/src/main/java/com/example/util/simpletimetracker/feature_settings/api/SettingsBlock.kt
@@ -84,6 +84,7 @@ enum class SettingsBlock {
AdditionalSendEvents,
AdditionalDataEdit,
AdditionalComplexRules,
+ AdditionalActivitySuggestions,
AdditionalBottom,
BackupTop,
diff --git a/features/feature_settings/src/main/java/com/example/util/simpletimetracker/feature_settings/interactor/SettingsAdditionalViewDataInteractor.kt b/features/feature_settings/src/main/java/com/example/util/simpletimetracker/feature_settings/interactor/SettingsAdditionalViewDataInteractor.kt
index dc0c91684..efd55c46c 100644
--- a/features/feature_settings/src/main/java/com/example/util/simpletimetracker/feature_settings/interactor/SettingsAdditionalViewDataInteractor.kt
+++ b/features/feature_settings/src/main/java/com/example/util/simpletimetracker/feature_settings/interactor/SettingsAdditionalViewDataInteractor.kt
@@ -182,6 +182,11 @@ class SettingsAdditionalViewDataInteractor @Inject constructor(
block = SettingsBlock.AdditionalComplexRules,
title = resourceRepo.getString(R.string.settings_complex_rules),
subtitle = "",
+ )
+ result += SettingsTextViewData(
+ block = SettingsBlock.AdditionalActivitySuggestions,
+ title = resourceRepo.getString(R.string.settings_activity_suggestions),
+ subtitle = "",
dividerIsVisible = false,
)
}
diff --git a/features/feature_settings/src/main/java/com/example/util/simpletimetracker/feature_settings/viewModel/delegate/SettingsAdditionalViewModelDelegate.kt b/features/feature_settings/src/main/java/com/example/util/simpletimetracker/feature_settings/viewModel/delegate/SettingsAdditionalViewModelDelegate.kt
index 9dd756f21..b00590537 100644
--- a/features/feature_settings/src/main/java/com/example/util/simpletimetracker/feature_settings/viewModel/delegate/SettingsAdditionalViewModelDelegate.kt
+++ b/features/feature_settings/src/main/java/com/example/util/simpletimetracker/feature_settings/viewModel/delegate/SettingsAdditionalViewModelDelegate.kt
@@ -18,6 +18,7 @@ import com.example.util.simpletimetracker.feature_settings.mapper.SettingsAutoma
import com.example.util.simpletimetracker.feature_settings.mapper.SettingsMapper
import com.example.util.simpletimetracker.feature_settings.viewModel.SettingsViewModel
import com.example.util.simpletimetracker.navigation.Router
+import com.example.util.simpletimetracker.navigation.params.screen.ActivitySuggestionsParams
import com.example.util.simpletimetracker.navigation.params.screen.ComplexRulesParams
import com.example.util.simpletimetracker.navigation.params.screen.DataEditParams
import com.example.util.simpletimetracker.navigation.params.screen.DurationDialogParams
@@ -71,6 +72,7 @@ class SettingsAdditionalViewModelDelegate @Inject constructor(
SettingsBlock.AdditionalKeepScreenOn -> onKeepScreenOnClicked()
SettingsBlock.AdditionalDataEdit -> onDataEditClick()
SettingsBlock.AdditionalComplexRules -> onComplexRulesClick()
+ SettingsBlock.AdditionalActivitySuggestions -> onActivitySuggestionsClick()
else -> {
// Do nothing
}
@@ -262,6 +264,10 @@ class SettingsAdditionalViewModelDelegate @Inject constructor(
router.navigate(ComplexRulesParams)
}
+ private fun onActivitySuggestionsClick() {
+ router.navigate(ActivitySuggestionsParams)
+ }
+
private fun onAutomatedTrackingHelpClick() {
delegateScope.launch {
val isDarkTheme = prefsInteractor.getDarkMode()
diff --git a/features/feature_statistics_detail/src/main/java/com/example/util/simpletimetracker/feature_statistics_detail/interactor/StatisticsDetailAdjacentActivitiesInteractor.kt b/features/feature_statistics_detail/src/main/java/com/example/util/simpletimetracker/feature_statistics_detail/interactor/StatisticsDetailAdjacentActivitiesInteractor.kt
index 96bebfbbd..e2e446965 100644
--- a/features/feature_statistics_detail/src/main/java/com/example/util/simpletimetracker/feature_statistics_detail/interactor/StatisticsDetailAdjacentActivitiesInteractor.kt
+++ b/features/feature_statistics_detail/src/main/java/com/example/util/simpletimetracker/feature_statistics_detail/interactor/StatisticsDetailAdjacentActivitiesInteractor.kt
@@ -41,10 +41,10 @@ class StatisticsDetailAdjacentActivitiesInteractor @Inject constructor(
val recordTypes = recordTypeInteractor.getAll().associateBy(RecordType::id)
val actualRecords = getRecords(rangeLength, rangePosition)
val nextActivitiesIds = calculateAdjacentActivitiesInteractor
- .calculateNextActivities(listOf(typeId), actualRecords)
+ .calculateNextActivities(listOf(typeId), actualRecords, MAX_COUNT)
.getOrElse(typeId) { emptyList() }
val multitaskingActivitiesIds = calculateAdjacentActivitiesInteractor
- .calculateMultitasking(typeId, actualRecords)
+ .calculateMultitasking(typeId, actualRecords, MAX_COUNT)
fun mapPreviews(typeToCounts: List): List {
val total = typeToCounts.sumOf(CalculationResult::count)
@@ -129,4 +129,8 @@ class StatisticsDetailAdjacentActivitiesInteractor @Inject constructor(
private fun getEmptyViewData(): List {
return emptyList()
}
+
+ companion object {
+ private const val MAX_COUNT = 5
+ }
}
\ No newline at end of file
diff --git a/features/feature_suggestions/.gitignore b/features/feature_suggestions/.gitignore
new file mode 100644
index 000000000..42afabfd2
--- /dev/null
+++ b/features/feature_suggestions/.gitignore
@@ -0,0 +1 @@
+/build
\ No newline at end of file
diff --git a/features/feature_suggestions/build.gradle.kts b/features/feature_suggestions/build.gradle.kts
new file mode 100644
index 000000000..0c18818b5
--- /dev/null
+++ b/features/feature_suggestions/build.gradle.kts
@@ -0,0 +1,21 @@
+import com.example.util.simpletimetracker.Base
+import com.example.util.simpletimetracker.applyAndroidLibrary
+
+plugins {
+ alias(libs.plugins.gradleLibrary)
+ alias(libs.plugins.kotlin)
+ alias(libs.plugins.ksp)
+ alias(libs.plugins.hilt)
+}
+
+applyAndroidLibrary()
+
+android {
+ namespace = "${Base.namespace}.feature_suggestions"
+}
+
+dependencies {
+ implementation(project(":core"))
+ implementation(libs.google.dagger)
+ ksp(libs.kapt.dagger)
+}
diff --git a/features/feature_suggestions/src/main/AndroidManifest.xml b/features/feature_suggestions/src/main/AndroidManifest.xml
new file mode 100644
index 000000000..7726109eb
--- /dev/null
+++ b/features/feature_suggestions/src/main/AndroidManifest.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/features/feature_suggestions/src/main/java/com/example/util/simpletimetracker/feature_suggestions/adapter/ActivitySuggestionAdapterDelegate.kt b/features/feature_suggestions/src/main/java/com/example/util/simpletimetracker/feature_suggestions/adapter/ActivitySuggestionAdapterDelegate.kt
new file mode 100644
index 000000000..7024f1c69
--- /dev/null
+++ b/features/feature_suggestions/src/main/java/com/example/util/simpletimetracker/feature_suggestions/adapter/ActivitySuggestionAdapterDelegate.kt
@@ -0,0 +1,40 @@
+package com.example.util.simpletimetracker.feature_suggestions.adapter
+
+import androidx.annotation.ColorInt
+import com.example.util.simpletimetracker.feature_base_adapter.ViewHolderType
+import com.example.util.simpletimetracker.feature_base_adapter.createRecyclerBindingAdapterDelegate
+import com.example.util.simpletimetracker.feature_views.viewData.RecordTypeIcon
+import com.example.util.simpletimetracker.feature_suggestions.adapter.ActivitySuggestionViewData as ViewData
+import com.example.util.simpletimetracker.feature_suggestions.databinding.ItemActivitySuggestionLayoutBinding as Binding
+
+fun createActivitySuggestionAdapterDelegate() = createRecyclerBindingAdapterDelegate(
+ Binding::inflate,
+) { binding, item, _ ->
+
+ with(binding.viewActivitySuggestionItem) {
+ item as ViewData
+
+ itemColor = item.color
+ itemIcon = item.iconId
+ itemIconColor = item.iconColor
+ itemName = item.name
+ }
+}
+
+data class ActivitySuggestionViewData(
+ val id: Id,
+ val name: String,
+ val iconId: RecordTypeIcon,
+ @ColorInt val iconColor: Int,
+ @ColorInt val color: Int,
+) : ViewHolderType {
+
+ override fun getUniqueId(): Long = id.hashCode().toLong()
+
+ override fun isValidType(other: ViewHolderType): Boolean = other is ViewData
+
+ data class Id(
+ val suggestionTypeId: Long,
+ val forTypeId: Long,
+ )
+}
\ No newline at end of file
diff --git a/features/feature_suggestions/src/main/java/com/example/util/simpletimetracker/feature_suggestions/adapter/ActivitySuggestionSpecialAdapterDelegate.kt b/features/feature_suggestions/src/main/java/com/example/util/simpletimetracker/feature_suggestions/adapter/ActivitySuggestionSpecialAdapterDelegate.kt
new file mode 100644
index 000000000..086718c4d
--- /dev/null
+++ b/features/feature_suggestions/src/main/java/com/example/util/simpletimetracker/feature_suggestions/adapter/ActivitySuggestionSpecialAdapterDelegate.kt
@@ -0,0 +1,47 @@
+package com.example.util.simpletimetracker.feature_suggestions.adapter
+
+import androidx.annotation.ColorInt
+import com.example.util.simpletimetracker.feature_base_adapter.ViewHolderType
+import com.example.util.simpletimetracker.feature_base_adapter.createRecyclerBindingAdapterDelegate
+import com.example.util.simpletimetracker.feature_views.extension.setOnClickWith
+import com.example.util.simpletimetracker.feature_views.viewData.RecordTypeIcon
+import com.example.util.simpletimetracker.feature_suggestions.adapter.ActivitySuggestionSpecialViewData as ViewData
+import com.example.util.simpletimetracker.feature_suggestions.databinding.ItemActivitySuggestionLayoutBinding as Binding
+
+fun createActivitySuggestionSpecialAdapterDelegate(
+ onItemClick: ((ViewData) -> Unit),
+) = createRecyclerBindingAdapterDelegate(
+ Binding::inflate,
+) { binding, item, _ ->
+
+ with(binding.viewActivitySuggestionItem) {
+ item as ViewData
+
+ itemColor = item.color
+ itemIcon = item.iconId
+ itemName = item.name
+ setOnClickWith(item, onItemClick)
+ }
+}
+
+data class ActivitySuggestionSpecialViewData(
+ val id: Id,
+ val name: String,
+ val iconId: RecordTypeIcon,
+ @ColorInt val color: Int,
+) : ViewHolderType {
+
+ override fun getUniqueId(): Long = id.hashCode().toLong()
+
+ override fun isValidType(other: ViewHolderType): Boolean = other is ViewData
+
+ data class Id(
+ val forTypeId: Long,
+ val type: Type,
+ )
+
+ sealed interface Type {
+ data object Add : Type
+ data object Calculate : Type
+ }
+}
\ No newline at end of file
diff --git a/features/feature_suggestions/src/main/java/com/example/util/simpletimetracker/feature_suggestions/adapter/ActivityiSuggestionsButtonAdapterDelegate.kt b/features/feature_suggestions/src/main/java/com/example/util/simpletimetracker/feature_suggestions/adapter/ActivityiSuggestionsButtonAdapterDelegate.kt
new file mode 100644
index 000000000..50586130a
--- /dev/null
+++ b/features/feature_suggestions/src/main/java/com/example/util/simpletimetracker/feature_suggestions/adapter/ActivityiSuggestionsButtonAdapterDelegate.kt
@@ -0,0 +1,51 @@
+package com.example.util.simpletimetracker.feature_suggestions.adapter
+
+import android.content.res.ColorStateList
+import androidx.annotation.ColorInt
+import androidx.annotation.DrawableRes
+import com.example.util.simpletimetracker.feature_base_adapter.ViewHolderType
+import com.example.util.simpletimetracker.feature_base_adapter.createRecyclerBindingAdapterDelegate
+import com.example.util.simpletimetracker.feature_views.extension.setOnClickWith
+import com.example.util.simpletimetracker.feature_suggestions.adapter.ActivitySuggestionsButtonViewData as ViewData
+import com.example.util.simpletimetracker.feature_suggestions.databinding.ItemActivitySuggestionsButtonBinding as Binding
+
+// TODO SUG refactor with record quick actions button, and complex rules button.
+// TODO SUG remove ripple from icon background if background is transparent.
+// TODO SUG change button background color to appInactive color.
+fun createActivitySuggestionsButtonAdapterDelegate(
+ onClick: (ViewData) -> Unit,
+) = createRecyclerBindingAdapterDelegate(
+ Binding::inflate,
+) { binding, item, _ ->
+
+ with(binding) {
+ item as ViewData
+
+ tvActivitySuggestionsButton.text = item.text
+ ivActivitySuggestionsButton.setImageResource(item.icon)
+ ivActivitySuggestionsButton.imageTintList = ColorStateList.valueOf(item.iconColor)
+ cardActivitySuggestionsButton.setCardBackgroundColor(item.iconBackgroundColor)
+ itemActivitySuggestionsButton.isEnabled = item.isEnabled
+ itemActivitySuggestionsButton.setOnClickWith(item, onClick)
+ }
+}
+
+data class ActivitySuggestionsButtonViewData(
+ val block: Block,
+ val text: String,
+ @DrawableRes val icon: Int,
+ @ColorInt val iconColor: Int,
+ @ColorInt val iconBackgroundColor: Int,
+ val isEnabled: Boolean,
+) : ViewHolderType {
+
+ override fun getUniqueId(): Long = block.ordinal.toLong()
+
+ override fun isValidType(other: ViewHolderType): Boolean =
+ other is ViewData
+
+ enum class Block {
+ ADD,
+ CALCULATE,
+ }
+}
\ No newline at end of file
diff --git a/features/feature_suggestions/src/main/java/com/example/util/simpletimetracker/feature_suggestions/interactor/ActivitySuggestionsCalculateInteractor.kt b/features/feature_suggestions/src/main/java/com/example/util/simpletimetracker/feature_suggestions/interactor/ActivitySuggestionsCalculateInteractor.kt
new file mode 100644
index 000000000..2b8978495
--- /dev/null
+++ b/features/feature_suggestions/src/main/java/com/example/util/simpletimetracker/feature_suggestions/interactor/ActivitySuggestionsCalculateInteractor.kt
@@ -0,0 +1,45 @@
+package com.example.util.simpletimetracker.feature_suggestions.interactor
+
+import com.example.util.simpletimetracker.core.mapper.TimeMapper
+import com.example.util.simpletimetracker.domain.prefs.interactor.PrefsInteractor
+import com.example.util.simpletimetracker.domain.record.interactor.CalculateAdjacentActivitiesInteractor
+import com.example.util.simpletimetracker.domain.record.interactor.RecordInteractor
+import com.example.util.simpletimetracker.domain.statistics.model.RangeLength
+import com.example.util.simpletimetracker.feature_suggestions.model.ActivitySuggestionModel
+import javax.inject.Inject
+
+class ActivitySuggestionsCalculateInteractor @Inject constructor(
+ private val timeMapper: TimeMapper,
+ private val prefsInteractor: PrefsInteractor,
+ private val recordInteractor: RecordInteractor,
+ private val calculateAdjacentActivitiesInteractor: CalculateAdjacentActivitiesInteractor,
+) {
+
+ suspend fun execute(
+ typeIds: List,
+ ): List {
+ // TODO SUG selectable range?
+ val range = timeMapper.getRangeStartAndEnd(
+ rangeLength = RangeLength.Year,
+ shift = 0,
+ firstDayOfWeek = prefsInteractor.getFirstDayOfWeek(),
+ startOfDayShift = prefsInteractor.getStartOfDayShift(),
+ )
+ val records = recordInteractor.getFromRange(range)
+
+ val data = calculateAdjacentActivitiesInteractor.calculateNextActivities(
+ typeIds = typeIds,
+ records = records,
+ maxCount = Int.MAX_VALUE,
+ )
+
+ return typeIds.mapNotNull { typeId ->
+ val thisTypeSuggestions = data[typeId]
+ ?: return@mapNotNull null
+ ActivitySuggestionModel(
+ typeId = typeId,
+ suggestions = thisTypeSuggestions.map { it.typeId },
+ )
+ }
+ }
+}
\ No newline at end of file
diff --git a/features/feature_suggestions/src/main/java/com/example/util/simpletimetracker/feature_suggestions/interactor/ActivitySuggestionsViewDataInteractor.kt b/features/feature_suggestions/src/main/java/com/example/util/simpletimetracker/feature_suggestions/interactor/ActivitySuggestionsViewDataInteractor.kt
new file mode 100644
index 000000000..c9e84ca90
--- /dev/null
+++ b/features/feature_suggestions/src/main/java/com/example/util/simpletimetracker/feature_suggestions/interactor/ActivitySuggestionsViewDataInteractor.kt
@@ -0,0 +1,209 @@
+package com.example.util.simpletimetracker.feature_suggestions.interactor
+
+import com.example.util.simpletimetracker.core.mapper.RecordTypeViewDataMapper
+import com.example.util.simpletimetracker.core.repo.ResourceRepo
+import com.example.util.simpletimetracker.domain.extension.plusAssign
+import com.example.util.simpletimetracker.domain.prefs.interactor.PrefsInteractor
+import com.example.util.simpletimetracker.domain.recordType.interactor.RecordTypeInteractor
+import com.example.util.simpletimetracker.domain.recordType.model.RecordType
+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.emptySpace.EmptySpaceViewData
+import com.example.util.simpletimetracker.feature_base_adapter.hint.HintViewData
+import com.example.util.simpletimetracker.feature_base_adapter.recordTypeSpecial.RunningRecordTypeSpecialViewData
+import com.example.util.simpletimetracker.feature_suggestions.R
+import com.example.util.simpletimetracker.feature_suggestions.adapter.ActivitySuggestionSpecialViewData
+import com.example.util.simpletimetracker.feature_suggestions.adapter.ActivitySuggestionViewData
+import com.example.util.simpletimetracker.feature_suggestions.adapter.ActivitySuggestionsButtonViewData
+import com.example.util.simpletimetracker.feature_suggestions.model.ActivitySuggestionModel
+import com.example.util.simpletimetracker.feature_views.viewData.RecordTypeIcon
+import javax.inject.Inject
+
+class ActivitySuggestionsViewDataInteractor @Inject constructor(
+ private val resourceRepo: ResourceRepo,
+ private val prefsInteractor: PrefsInteractor,
+ private val recordTypeInteractor: RecordTypeInteractor,
+ private val recordTypeViewDataMapper: RecordTypeViewDataMapper,
+) {
+
+ // TODO SUG translate strings
+ suspend fun getViewData(
+ suggestions: List,
+ ): List {
+ val isDarkTheme = prefsInteractor.getDarkMode()
+ val recordTypes = recordTypeInteractor.getAll().filter { !it.hidden }
+ val typesOrder = recordTypes.map(RecordType::id)
+ val recordTypesMap = recordTypes.associateBy(RecordType::id)
+ val selectedActivities = suggestions.map { it.typeId }
+ val suggestionsMap = suggestions.associateBy(ActivitySuggestionModel::typeId)
+
+ val result: MutableList = mutableListOf()
+
+ result += ActivitySuggestionsButtonViewData(
+ block = ActivitySuggestionsButtonViewData.Block.ADD,
+ text = resourceRepo.getString(R.string.change_record_message_choose_type),
+ icon = R.drawable.action_change_item,
+ iconColor = resourceRepo.getThemedAttr(R.attr.appLightTextColor, isDarkTheme),
+ iconBackgroundColor = resourceRepo.getColor(R.color.transparent),
+ isEnabled = true,
+ )
+
+ if (selectedActivities.isNotEmpty()) {
+ result += ActivitySuggestionsButtonViewData(
+ block = ActivitySuggestionsButtonViewData.Block.CALCULATE,
+ text = "Calculate from statistics", // TODO SUG
+ icon = R.drawable.statistics,
+ iconColor = resourceRepo.getThemedAttr(R.attr.appLightTextColor, isDarkTheme),
+ iconBackgroundColor = resourceRepo.getColor(R.color.transparent),
+ isEnabled = true,
+ )
+ }
+
+ selectedActivities.sortedBy {
+ typesOrder.indexOf(it).toLong()
+ }.forEachIndexed { index, typeId ->
+ if (index == 0) {
+ result += DividerViewData(id = 0)
+ }
+ if (index == 0) {
+ result += HintViewData(
+ text = resourceRepo.getString(R.string.change_record_type_field),
+ paddingTop = 0,
+ paddingBottom = 0,
+ gravity = HintViewData.Gravity.START,
+ )
+ }
+ result += recordTypeViewDataMapper.map(
+ recordType = recordTypesMap[typeId] ?: return@forEachIndexed,
+ isDarkTheme = isDarkTheme,
+ )
+ result += EmptySpaceViewData(
+ id = typeId,
+ wrapBefore = true,
+ )
+ if (index == 0) {
+ result += HintViewData(
+ text = resourceRepo.getString(R.string.settings_activity_suggestions),
+ paddingTop = 0,
+ paddingBottom = 0,
+ gravity = HintViewData.Gravity.START,
+ )
+ }
+ val thisTypeSuggestions = suggestionsMap[typeId]?.suggestions.orEmpty()
+ thisTypeSuggestions.forEach { suggestion ->
+ result += mapSuggestion(
+ forTypeId = typeId,
+ suggestionTypeId = suggestion,
+ recordTypesMap = recordTypesMap,
+ isDarkTheme = isDarkTheme,
+ )
+ }
+ result += mapAddSuggestionButton(
+ forTypeId = typeId,
+ hasAtLeastOneEntry = thisTypeSuggestions.isNotEmpty(),
+ isDarkTheme = isDarkTheme,
+ )
+ result += mapToCalculateSuggestionButton(
+ forTypeId = typeId,
+ isDarkTheme = isDarkTheme,
+ )
+ if (index < selectedActivities.size - 1) {
+ result += DividerViewData(id = typeId)
+ }
+ }
+
+ return result
+ }
+
+ private fun mapSuggestion(
+ forTypeId: Long,
+ suggestionTypeId: Long,
+ recordTypesMap: Map,
+ isDarkTheme: Boolean,
+ ): ActivitySuggestionViewData? {
+ return recordTypeViewDataMapper.map(
+ recordType = recordTypesMap[suggestionTypeId] ?: return null,
+ isDarkTheme = isDarkTheme,
+ ).let {
+ ActivitySuggestionViewData(
+ id = ActivitySuggestionViewData.Id(
+ suggestionTypeId = suggestionTypeId,
+ forTypeId = forTypeId,
+ ),
+ name = it.name,
+ iconId = it.iconId,
+ iconColor = it.iconColor,
+ color = it.color,
+ )
+ }
+ }
+
+ private fun mapAddSuggestionButton(
+ forTypeId: Long,
+ hasAtLeastOneEntry: Boolean,
+ isDarkTheme: Boolean,
+ ): ActivitySuggestionSpecialViewData {
+ return mapAddButton(
+ hasAtLeastOneEntry = hasAtLeastOneEntry,
+ isDarkTheme = isDarkTheme,
+ ).let {
+ ActivitySuggestionSpecialViewData(
+ id = ActivitySuggestionSpecialViewData.Id(
+ forTypeId = forTypeId,
+ type = ActivitySuggestionSpecialViewData.Type.Add,
+ ),
+ name = it.name,
+ iconId = it.iconId,
+ color = it.color,
+ )
+ }
+ }
+
+ private fun mapToCalculateSuggestionButton(
+ forTypeId: Long,
+ isDarkTheme: Boolean,
+ ): ActivitySuggestionSpecialViewData {
+ return recordTypeViewDataMapper.mapToAddItem(
+ numberOfCards = null,
+ isDarkTheme = isDarkTheme,
+ ).copy(
+ name = resourceRepo.getString(R.string.shortcut_navigation_statistics),
+ iconId = RecordTypeIcon.Image(R.drawable.statistics),
+ ).let {
+ ActivitySuggestionSpecialViewData(
+ id = ActivitySuggestionSpecialViewData.Id(
+ forTypeId = forTypeId,
+ type = ActivitySuggestionSpecialViewData.Type.Calculate,
+ ),
+ name = it.name,
+ iconId = it.iconId,
+ color = it.color,
+ )
+ }
+ }
+
+ private fun mapAddButton(
+ hasAtLeastOneEntry: Boolean,
+ isDarkTheme: Boolean,
+ ): RunningRecordTypeSpecialViewData {
+ val name = if (hasAtLeastOneEntry) {
+ R.string.data_edit_button_change
+ } else {
+ R.string.running_records_add_type
+ }.let(resourceRepo::getString)
+
+ val iconId = if (hasAtLeastOneEntry) {
+ R.drawable.action_change_item
+ } else {
+ R.drawable.add
+ }.let(RecordTypeIcon::Image)
+
+ return recordTypeViewDataMapper.mapToAddItem(
+ numberOfCards = null,
+ isDarkTheme = isDarkTheme,
+ ).copy(
+ name = name,
+ iconId = iconId,
+ )
+ }
+}
\ No newline at end of file
diff --git a/features/feature_suggestions/src/main/java/com/example/util/simpletimetracker/feature_suggestions/model/ActivitySuggestionModel.kt b/features/feature_suggestions/src/main/java/com/example/util/simpletimetracker/feature_suggestions/model/ActivitySuggestionModel.kt
new file mode 100644
index 000000000..8cd21d60f
--- /dev/null
+++ b/features/feature_suggestions/src/main/java/com/example/util/simpletimetracker/feature_suggestions/model/ActivitySuggestionModel.kt
@@ -0,0 +1,6 @@
+package com.example.util.simpletimetracker.feature_suggestions.model
+
+data class ActivitySuggestionModel(
+ val typeId: Long,
+ val suggestions: List,
+)
\ No newline at end of file
diff --git a/features/feature_suggestions/src/main/java/com/example/util/simpletimetracker/feature_suggestions/view/ActivitySuggestionsFragment.kt b/features/feature_suggestions/src/main/java/com/example/util/simpletimetracker/feature_suggestions/view/ActivitySuggestionsFragment.kt
new file mode 100644
index 000000000..63a3ee708
--- /dev/null
+++ b/features/feature_suggestions/src/main/java/com/example/util/simpletimetracker/feature_suggestions/view/ActivitySuggestionsFragment.kt
@@ -0,0 +1,76 @@
+package com.example.util.simpletimetracker.feature_suggestions.view
+
+import android.view.LayoutInflater
+import android.view.ViewGroup
+import androidx.fragment.app.viewModels
+import com.example.util.simpletimetracker.core.base.BaseFragment
+import com.example.util.simpletimetracker.core.dialog.TypesSelectionDialogListener
+import com.example.util.simpletimetracker.core.utils.InsetConfiguration
+import com.example.util.simpletimetracker.feature_base_adapter.BaseRecyclerAdapter
+import com.example.util.simpletimetracker.feature_base_adapter.divider.createDividerAdapterDelegate
+import com.example.util.simpletimetracker.feature_base_adapter.emptySpace.createEmptySpaceAdapterDelegate
+import com.example.util.simpletimetracker.feature_base_adapter.hint.createHintAdapterDelegate
+import com.example.util.simpletimetracker.feature_base_adapter.loader.createLoaderAdapterDelegate
+import com.example.util.simpletimetracker.feature_base_adapter.recordType.createRecordTypeAdapterDelegate
+import com.example.util.simpletimetracker.feature_suggestions.adapter.createActivitySuggestionAdapterDelegate
+import com.example.util.simpletimetracker.feature_suggestions.adapter.createActivitySuggestionSpecialAdapterDelegate
+import com.example.util.simpletimetracker.feature_suggestions.adapter.createActivitySuggestionsButtonAdapterDelegate
+import com.example.util.simpletimetracker.feature_suggestions.viewModel.ActivitySuggestionsViewModel
+import com.example.util.simpletimetracker.feature_views.extension.setOnClick
+import com.google.android.flexbox.FlexDirection
+import com.google.android.flexbox.FlexWrap
+import com.google.android.flexbox.FlexboxLayoutManager
+import com.google.android.flexbox.JustifyContent
+import dagger.hilt.android.AndroidEntryPoint
+import com.example.util.simpletimetracker.feature_suggestions.databinding.ActivitySuggestionsFragmentBinding as Binding
+
+@AndroidEntryPoint
+class ActivitySuggestionsFragment :
+ BaseFragment(),
+ TypesSelectionDialogListener {
+
+ override val inflater: (LayoutInflater, ViewGroup?, Boolean) -> Binding =
+ Binding::inflate
+
+ override var insetConfiguration: InsetConfiguration =
+ InsetConfiguration.ApplyToView { binding.root }
+
+ private val viewModel: ActivitySuggestionsViewModel by viewModels()
+
+ private val viewDataAdapter: BaseRecyclerAdapter by lazy {
+ BaseRecyclerAdapter(
+ createDividerAdapterDelegate(),
+ createEmptySpaceAdapterDelegate(),
+ createLoaderAdapterDelegate(),
+ createHintAdapterDelegate(),
+ createRecordTypeAdapterDelegate(),
+ createActivitySuggestionAdapterDelegate(),
+ createActivitySuggestionSpecialAdapterDelegate(throttle(viewModel::onSpecialSuggestionClick)),
+ createActivitySuggestionsButtonAdapterDelegate(throttle(viewModel::onItemButtonClick)),
+ )
+ }
+
+ override fun initUi(): Unit = with(binding) {
+ rvActivitySuggestionsList.apply {
+ layoutManager = FlexboxLayoutManager(requireContext()).apply {
+ flexDirection = FlexDirection.ROW
+ justifyContent = JustifyContent.FLEX_START
+ flexWrap = FlexWrap.WRAP
+ }
+ adapter = viewDataAdapter
+ setHasFixedSize(true)
+ }
+ }
+
+ override fun initUx() = with(binding) {
+ btnActivitySuggestionsSave.setOnClick(throttle(viewModel::onSaveClick))
+ }
+
+ override fun initViewModel(): Unit = with(viewModel) {
+ viewData.observe(viewDataAdapter::replace)
+ }
+
+ override fun onDataSelected(dataIds: List, tag: String?) {
+ viewModel.onTypesSelected(dataIds, tag)
+ }
+}
diff --git a/features/feature_suggestions/src/main/java/com/example/util/simpletimetracker/feature_suggestions/viewModel/ActivitySuggestionsViewModel.kt b/features/feature_suggestions/src/main/java/com/example/util/simpletimetracker/feature_suggestions/viewModel/ActivitySuggestionsViewModel.kt
new file mode 100644
index 000000000..35b2db010
--- /dev/null
+++ b/features/feature_suggestions/src/main/java/com/example/util/simpletimetracker/feature_suggestions/viewModel/ActivitySuggestionsViewModel.kt
@@ -0,0 +1,148 @@
+package com.example.util.simpletimetracker.feature_suggestions.viewModel
+
+import androidx.lifecycle.LiveData
+import androidx.lifecycle.viewModelScope
+import com.example.util.simpletimetracker.core.base.BaseViewModel
+import com.example.util.simpletimetracker.core.extension.lazySuspend
+import com.example.util.simpletimetracker.core.extension.set
+import com.example.util.simpletimetracker.core.repo.ResourceRepo
+import com.example.util.simpletimetracker.feature_base_adapter.ViewHolderType
+import com.example.util.simpletimetracker.feature_base_adapter.loader.LoaderViewData
+import com.example.util.simpletimetracker.feature_suggestions.R
+import com.example.util.simpletimetracker.feature_suggestions.adapter.ActivitySuggestionSpecialViewData
+import com.example.util.simpletimetracker.feature_suggestions.adapter.ActivitySuggestionsButtonViewData
+import com.example.util.simpletimetracker.feature_suggestions.interactor.ActivitySuggestionsCalculateInteractor
+import com.example.util.simpletimetracker.feature_suggestions.interactor.ActivitySuggestionsViewDataInteractor
+import com.example.util.simpletimetracker.feature_suggestions.model.ActivitySuggestionModel
+import com.example.util.simpletimetracker.navigation.Router
+import com.example.util.simpletimetracker.navigation.params.screen.TypesSelectionDialogParams
+import dagger.hilt.android.lifecycle.HiltViewModel
+import kotlinx.coroutines.launch
+import javax.inject.Inject
+
+@HiltViewModel
+class ActivitySuggestionsViewModel @Inject constructor(
+ private val router: Router,
+ private val resourceRepo: ResourceRepo,
+ private val activitySuggestionsViewDataInteractor: ActivitySuggestionsViewDataInteractor,
+ private val activitySuggestionsCalculateInteractor: ActivitySuggestionsCalculateInteractor,
+) : BaseViewModel() {
+
+ val viewData: LiveData> by lazySuspend {
+ listOf(LoaderViewData()).also { updateViewData() }
+ }
+
+ private var suggestions: List = emptyList()
+ private var selectingSuggestionsForTypeId: Long = 0L
+
+ fun onTypesSelected(typeIds: List, tag: String?) = viewModelScope.launch {
+ when (tag) {
+ ACTIVITY_SUGGESTIONS_TYPE_SELECTION_TAG -> {
+ suggestions = typeIds.map { typeId ->
+ ActivitySuggestionModel(
+ typeId = typeId,
+ suggestions = suggestions.firstOrNull {
+ it.typeId == typeId
+ }?.suggestions.orEmpty(),
+ )
+ }
+ updateViewData()
+ }
+ ACTIVITY_SUGGESTIONS_SUGGESTION_SELECTION_TAG -> {
+ suggestions = suggestions.map { suggestion ->
+ val newSuggestions = if (
+ suggestion.typeId == selectingSuggestionsForTypeId
+ ) {
+ typeIds
+ } else {
+ suggestion.suggestions
+ }
+ ActivitySuggestionModel(
+ typeId = suggestion.typeId,
+ suggestions = newSuggestions,
+ )
+ }
+ updateViewData()
+ }
+ }
+ }
+
+ fun onSpecialSuggestionClick(item: ActivitySuggestionSpecialViewData) {
+ when (item.id.type) {
+ is ActivitySuggestionSpecialViewData.Type.Add -> {
+ val forTypeId = item.id.forTypeId
+ selectingSuggestionsForTypeId = forTypeId
+ TypesSelectionDialogParams(
+ tag = ACTIVITY_SUGGESTIONS_SUGGESTION_SELECTION_TAG,
+ title = resourceRepo.getString(R.string.change_record_message_choose_type),
+ subtitle = "", // TODO SUG add hint
+ type = TypesSelectionDialogParams.Type.Activity,
+ selectedTypeIds = suggestions.firstOrNull {
+ it.typeId == forTypeId
+ }?.suggestions.orEmpty(),
+ isMultiSelectAvailable = true,
+ idsShouldBeVisible = emptyList(),
+ showHints = true,
+ ).let(router::navigate)
+ }
+ is ActivitySuggestionSpecialViewData.Type.Calculate -> viewModelScope.launch {
+ val forTypeId = item.id.forTypeId
+ selectingSuggestionsForTypeId = forTypeId
+ val newData = activitySuggestionsCalculateInteractor
+ .execute(listOf(forTypeId))
+ .firstOrNull { it.typeId == forTypeId }
+ ?.suggestions
+ .orEmpty()
+ // TODO SUG do better
+ onTypesSelected(newData, ACTIVITY_SUGGESTIONS_SUGGESTION_SELECTION_TAG)
+ }
+ }
+ }
+
+ fun onItemButtonClick(viewData: ActivitySuggestionsButtonViewData) {
+ when (viewData.block) {
+ ActivitySuggestionsButtonViewData.Block.ADD -> {
+ TypesSelectionDialogParams(
+ tag = ACTIVITY_SUGGESTIONS_TYPE_SELECTION_TAG,
+ title = resourceRepo.getString(R.string.change_record_message_choose_type),
+ subtitle = "Suggestions will be shown for selected activities", // TODO SUG
+ type = TypesSelectionDialogParams.Type.Activity,
+ selectedTypeIds = suggestions.map { it.typeId },
+ isMultiSelectAvailable = true,
+ idsShouldBeVisible = emptyList(),
+ showHints = true,
+ ).let(router::navigate)
+ }
+ ActivitySuggestionsButtonViewData.Block.CALCULATE -> viewModelScope.launch {
+ val selectedTypeIds = suggestions.map { it.typeId }
+ suggestions = activitySuggestionsCalculateInteractor.execute(selectedTypeIds)
+ updateViewData()
+ }
+ }
+ }
+
+ fun onSaveClick() {
+ viewModelScope.launch {
+ // TODO SUG
+ router.back()
+ }
+ }
+
+ private fun updateViewData() = viewModelScope.launch {
+ val data = loadViewData()
+ viewData.set(data)
+ }
+
+ private suspend fun loadViewData(): List {
+ return activitySuggestionsViewDataInteractor.getViewData(
+ suggestions = suggestions,
+ )
+ }
+
+ companion object {
+ private const val ACTIVITY_SUGGESTIONS_TYPE_SELECTION_TAG =
+ "ACTIVITY_SUGGESTIONS_TYPE_SELECTION_TAG"
+ private const val ACTIVITY_SUGGESTIONS_SUGGESTION_SELECTION_TAG =
+ "ACTIVITY_SUGGESTIONS_SUGGESTION_SELECTION_TAG"
+ }
+}
diff --git a/features/feature_suggestions/src/main/res/layout/activity_suggestions_fragment.xml b/features/feature_suggestions/src/main/res/layout/activity_suggestions_fragment.xml
new file mode 100644
index 000000000..7912b7b2f
--- /dev/null
+++ b/features/feature_suggestions/src/main/res/layout/activity_suggestions_fragment.xml
@@ -0,0 +1,66 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/features/feature_suggestions/src/main/res/layout/item_activity_suggestion_layout.xml b/features/feature_suggestions/src/main/res/layout/item_activity_suggestion_layout.xml
new file mode 100644
index 000000000..4bb8caa71
--- /dev/null
+++ b/features/feature_suggestions/src/main/res/layout/item_activity_suggestion_layout.xml
@@ -0,0 +1,10 @@
+
+
\ No newline at end of file
diff --git a/features/feature_suggestions/src/main/res/layout/item_activity_suggestions_button.xml b/features/feature_suggestions/src/main/res/layout/item_activity_suggestions_button.xml
new file mode 100644
index 000000000..132581b69
--- /dev/null
+++ b/features/feature_suggestions/src/main/res/layout/item_activity_suggestions_button.xml
@@ -0,0 +1,58 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/navigation/src/main/java/com/example/util/simpletimetracker/navigation/params/screen/ActivitySuggestionsParams.kt b/navigation/src/main/java/com/example/util/simpletimetracker/navigation/params/screen/ActivitySuggestionsParams.kt
new file mode 100644
index 000000000..808116ca4
--- /dev/null
+++ b/navigation/src/main/java/com/example/util/simpletimetracker/navigation/params/screen/ActivitySuggestionsParams.kt
@@ -0,0 +1,3 @@
+package com.example.util.simpletimetracker.navigation.params.screen
+
+object ActivitySuggestionsParams : ScreenParams
\ No newline at end of file
diff --git a/resources/src/main/res/values/strings.xml b/resources/src/main/res/values/strings.xml
index d82f9c655..f0dae4016 100644
--- a/resources/src/main/res/values/strings.xml
+++ b/resources/src/main/res/values/strings.xml
@@ -188,6 +188,9 @@
Choose action
Choose conditions
+
+ Shows suggestions for the next activity based on current or last activity
+
Activity filters
Filter removed
@@ -326,6 +329,7 @@
Archive
Data edit
Complex rules
+ Activity suggestions
Edit categories and tags
Assign categories to activities and tags to records.
Show record tag selection