Skip to content

Commit 6e801f4

Browse files
committed
move comment selection to delegate
1 parent 468c0cf commit 6e801f4

14 files changed

Lines changed: 324 additions & 323 deletions

File tree

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package com.example.util.simpletimetracker.core.delegates.commentSelection.interactor
2+
3+
import com.example.util.simpletimetracker.core.R
4+
import com.example.util.simpletimetracker.core.interactor.RecordCommentSearchViewDataInteractor
5+
import com.example.util.simpletimetracker.core.mapper.ColorMapper
6+
import com.example.util.simpletimetracker.core.repo.ResourceRepo
7+
import com.example.util.simpletimetracker.domain.favourite.interactor.FavouriteCommentInteractor
8+
import com.example.util.simpletimetracker.domain.prefs.interactor.PrefsInteractor
9+
import com.example.util.simpletimetracker.feature_base_adapter.ViewHolderType
10+
import com.example.util.simpletimetracker.feature_base_adapter.commentChangeField.ChangeRecordCommentFieldViewData
11+
import javax.inject.Inject
12+
13+
class CommentSelectionDelegateViewDataInteractor @Inject constructor(
14+
private val prefsInteractor: PrefsInteractor,
15+
private val favouriteCommentInteractor: FavouriteCommentInteractor,
16+
private val resourceRepo: ResourceRepo,
17+
private val colorMapper: ColorMapper,
18+
private val recordCommentSearchViewDataInteractor: RecordCommentSearchViewDataInteractor,
19+
) {
20+
21+
// TODO replace fav to text button?
22+
suspend fun getCommentsViewData(
23+
comment: String,
24+
typeId: Long,
25+
fromCommentChange: Boolean,
26+
): List<ViewHolderType> {
27+
val items = mutableListOf<ViewHolderType>()
28+
val isDarkTheme = prefsInteractor.getDarkMode()
29+
val isFavourite = favouriteCommentInteractor.get(comment) != null
30+
31+
ChangeRecordCommentFieldViewData(
32+
// Only one at the time.
33+
id = 1L,
34+
// Do not update text if update coming from typing.
35+
text = if (fromCommentChange) null else comment,
36+
iconColor = if (isFavourite) {
37+
resourceRepo.getThemedAttr(R.attr.colorAccent, isDarkTheme)
38+
} else {
39+
colorMapper.toInactiveColor(isDarkTheme)
40+
},
41+
).let(items::add)
42+
43+
items += recordCommentSearchViewDataInteractor.getViewData(
44+
comment = comment,
45+
typeId = typeId,
46+
)
47+
48+
return items
49+
}
50+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
package com.example.util.simpletimetracker.core.delegates.commentSelection.viewDelegate
2+
3+
import androidx.recyclerview.widget.RecyclerView
4+
import androidx.viewbinding.ViewBinding
5+
import com.example.util.simpletimetracker.core.base.BaseFragment
6+
import com.example.util.simpletimetracker.core.delegates.commentSelection.viewModelDelegate.CommentSelectionViewModelDelegate
7+
import com.example.util.simpletimetracker.feature_base_adapter.BaseRecyclerAdapter
8+
import com.example.util.simpletimetracker.feature_base_adapter.commentChangeField.createChangeRecordCommentFieldAdapterDelegate
9+
import com.example.util.simpletimetracker.feature_base_adapter.emptySpace.createEmptySpaceAdapterDelegate
10+
import com.example.util.simpletimetracker.feature_base_adapter.hint.createHintAdapterDelegate
11+
import com.example.util.simpletimetracker.feature_base_adapter.recordComment.createRecordCommentAdapterDelegate
12+
import com.example.util.simpletimetracker.feature_base_adapter.recordFilter.createFilterAdapterDelegate
13+
import com.google.android.flexbox.FlexDirection
14+
import com.google.android.flexbox.FlexWrap
15+
import com.google.android.flexbox.FlexboxLayoutManager
16+
import com.google.android.flexbox.JustifyContent
17+
import kotlin.text.replace
18+
19+
class CommentSelectionViewDelegate(
20+
private val viewModel: CommentSelectionViewModelDelegate,
21+
) {
22+
23+
private val commentsAdapter: BaseRecyclerAdapter by lazy {
24+
BaseRecyclerAdapter(
25+
createHintAdapterDelegate(),
26+
createEmptySpaceAdapterDelegate(),
27+
createChangeRecordCommentFieldAdapterDelegate(
28+
afterTextChange = viewModel::onCommentChange,
29+
onFavouriteClick = viewModel::onFavouriteCommentClick,
30+
),
31+
createRecordCommentAdapterDelegate(
32+
onItemClick = viewModel::onCommentClick,
33+
),
34+
createFilterAdapterDelegate(
35+
onClick = viewModel::onCommentFilterClick,
36+
),
37+
)
38+
}
39+
40+
fun initUi(
41+
recycler: RecyclerView,
42+
) {
43+
recycler.apply {
44+
layoutManager = FlexboxLayoutManager(context).apply {
45+
flexDirection = FlexDirection.ROW
46+
justifyContent = JustifyContent.CENTER
47+
flexWrap = FlexWrap.WRAP
48+
}
49+
adapter = commentsAdapter
50+
}
51+
}
52+
53+
fun <T : ViewBinding> initViewModel(
54+
fragment: BaseFragment<T>,
55+
) = with(viewModel) {
56+
with(fragment) {
57+
comments.observe(commentsAdapter::replace)
58+
}
59+
}
60+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
package com.example.util.simpletimetracker.core.delegates.commentSelection.viewModelDelegate
2+
3+
import androidx.lifecycle.LiveData
4+
import androidx.lifecycle.MutableLiveData
5+
import com.example.util.simpletimetracker.core.base.ViewModelDelegate
6+
import com.example.util.simpletimetracker.core.delegates.commentSelection.interactor.CommentSelectionDelegateViewDataInteractor
7+
import com.example.util.simpletimetracker.core.extension.set
8+
import com.example.util.simpletimetracker.core.interactor.RecordCommentSearchViewDataInteractor
9+
import com.example.util.simpletimetracker.core.viewData.CommentFilterTypeViewData
10+
import com.example.util.simpletimetracker.domain.extension.addOrRemove
11+
import com.example.util.simpletimetracker.domain.extension.orZero
12+
import com.example.util.simpletimetracker.domain.favourite.interactor.FavouriteCommentInteractor
13+
import com.example.util.simpletimetracker.domain.favourite.model.FavouriteComment
14+
import com.example.util.simpletimetracker.domain.prefs.interactor.PrefsInteractor
15+
import com.example.util.simpletimetracker.feature_base_adapter.ViewHolderType
16+
import com.example.util.simpletimetracker.feature_base_adapter.recordComment.RecordCommentViewData
17+
import com.example.util.simpletimetracker.feature_base_adapter.recordFilter.FilterViewData
18+
import kotlinx.coroutines.Job
19+
import kotlinx.coroutines.launch
20+
import javax.inject.Inject
21+
22+
interface CommentSelectionViewModelDelegate {
23+
val comments: LiveData<List<ViewHolderType>>
24+
25+
fun attach(parent: Parent)
26+
fun onCommentChange(comment: String)
27+
fun onCommentFilterClick(item: FilterViewData)
28+
fun onFavouriteCommentClick()
29+
fun onCommentClick(item: RecordCommentViewData)
30+
31+
interface Parent {
32+
fun getParams(): Params
33+
suspend fun onCommentClick()
34+
fun onCommentChange()
35+
36+
data class Params(
37+
val recordTypeId: Long?,
38+
)
39+
}
40+
}
41+
42+
class CommentSelectionViewModelDelegateImpl @Inject constructor(
43+
private val commentSelectionDelegateViewDataInteractor: CommentSelectionDelegateViewDataInteractor,
44+
private val recordCommentSearchViewDataInteractor: RecordCommentSearchViewDataInteractor,
45+
private val favouriteCommentInteractor: FavouriteCommentInteractor,
46+
private val prefsInteractor: PrefsInteractor,
47+
) :
48+
CommentSelectionViewModelDelegate,
49+
ViewModelDelegate() {
50+
51+
override val comments: LiveData<List<ViewHolderType>> = MutableLiveData(emptyList())
52+
53+
var newComment: String = ""
54+
55+
private var parent: CommentSelectionViewModelDelegate.Parent? = null
56+
private var commentLoadJob: Job? = null
57+
58+
override fun attach(parent: CommentSelectionViewModelDelegate.Parent) {
59+
this.parent = parent
60+
}
61+
62+
override fun onCommentClick(item: RecordCommentViewData) {
63+
delegateScope.launch {
64+
if (item.text == newComment) return@launch
65+
newComment = item.text
66+
parent?.onCommentClick()
67+
updateCommentsViewData()
68+
}
69+
}
70+
71+
override fun onCommentFilterClick(item: FilterViewData) {
72+
delegateScope.launch {
73+
val data = item.type as? CommentFilterTypeViewData ?: return@launch
74+
val type = recordCommentSearchViewDataInteractor.map(data)
75+
val newFilters = prefsInteractor.getHiddenCommentFilters().toMutableSet()
76+
newFilters.addOrRemove(type)
77+
prefsInteractor.setHiddenCommentFilters(newFilters.toSet())
78+
updateCommentsViewData()
79+
}
80+
}
81+
82+
override fun onFavouriteCommentClick() {
83+
if (newComment.isEmpty()) return
84+
delegateScope.launch {
85+
favouriteCommentInteractor.get(newComment)
86+
?.let { favouriteCommentInteractor.remove(it.id) }
87+
?: run {
88+
val favourite = FavouriteComment(comment = newComment)
89+
favouriteCommentInteractor.add(favourite)
90+
}
91+
updateCommentsViewData()
92+
}
93+
}
94+
95+
override fun onCommentChange(comment: String) {
96+
if (comment == newComment) return
97+
newComment = comment
98+
parent?.onCommentChange()
99+
updateCommentsViewData(fromCommentChange = true)
100+
}
101+
102+
fun updateCommentsViewData(
103+
fromCommentChange: Boolean = false,
104+
) {
105+
commentLoadJob?.cancel()
106+
commentLoadJob = delegateScope.launch {
107+
comments.set(loadCommentsViewData(fromCommentChange))
108+
}
109+
}
110+
111+
private suspend fun loadCommentsViewData(
112+
fromCommentChange: Boolean,
113+
): List<ViewHolderType> {
114+
return commentSelectionDelegateViewDataInteractor.getCommentsViewData(
115+
comment = newComment,
116+
typeId = parent?.getParams()?.recordTypeId.orZero(),
117+
fromCommentChange = fromCommentChange,
118+
)
119+
}
120+
}

core/src/main/java/com/example/util/simpletimetracker/core/delegates/iconSelection/viewModelDelegate/IconSelectionViewModelDelegate.kt

Lines changed: 9 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import com.example.util.simpletimetracker.core.delegates.iconSelection.viewData.
1212
import com.example.util.simpletimetracker.core.delegates.iconSelection.viewData.IconSelectionSwitchViewData
1313
import com.example.util.simpletimetracker.core.delegates.iconSelection.viewData.IconSelectionViewData
1414
import com.example.util.simpletimetracker.core.delegates.iconSelection.viewData.IconSelectionScrollViewData
15+
import com.example.util.simpletimetracker.core.extension.lazySuspend
1516
import com.example.util.simpletimetracker.core.extension.set
1617
import com.example.util.simpletimetracker.core.mapper.IconEmojiMapper
1718
import com.example.util.simpletimetracker.feature_base_adapter.buttonsRow.view.ButtonsRowViewData
@@ -73,26 +74,17 @@ class IconSelectionViewModelDelegateImpl @Inject constructor(
7374
) : IconSelectionViewModelDelegate,
7475
ViewModelDelegate() {
7576

76-
override val icons: LiveData<IconSelectionStateViewData> by lazy {
77-
return@lazy MutableLiveData<IconSelectionStateViewData>().let { initial ->
78-
delegateScope.launch { initial.value = loadIconsViewData() }
79-
initial
80-
}
77+
override val icons: LiveData<IconSelectionStateViewData> by lazySuspend {
78+
loadIconsViewData()
8179
}
82-
override val iconCategories: LiveData<List<ViewHolderType>> by lazy {
83-
return@lazy MutableLiveData<List<ViewHolderType>>().let { initial ->
84-
delegateScope.launch { initial.value = loadIconCategoriesViewData(selectedIndex = 0) }
85-
initial
86-
}
80+
override val iconCategories: LiveData<List<ViewHolderType>> by lazySuspend {
81+
loadIconCategoriesViewData(selectedIndex = 0)
8782
}
88-
override val iconsTypeViewData: LiveData<List<ViewHolderType>> by lazy {
89-
return@lazy MutableLiveData(loadIconsTypeViewData())
83+
override val iconsTypeViewData: LiveData<List<ViewHolderType>> by lazySuspend {
84+
loadIconsTypeViewData()
9085
}
91-
override val iconSelectorViewData: LiveData<IconSelectionSelectorStateViewData> by lazy {
92-
return@lazy MutableLiveData<IconSelectionSelectorStateViewData>().let { initial ->
93-
delegateScope.launch { initial.value = loadIconSelectorViewData() }
94-
initial
95-
}
86+
override val iconSelectorViewData: LiveData<IconSelectionSelectorStateViewData> by lazySuspend {
87+
loadIconSelectorViewData()
9688
}
9789
override val iconsScrollPosition: LiveData<IconSelectionScrollViewData> = MutableLiveData()
9890
override val expandIconTypeSwitch: LiveData<Unit> = MutableLiveData()

features/feature_change_record/src/main/java/com/example/util/simpletimetracker/feature_change_record/adapter/ChangeRecordCommentFieldAdapterDelegate.kt renamed to features/feature_base_adapter/src/main/java/com/example/util/simpletimetracker/feature_base_adapter/commentChangeField/ChangeRecordCommentFieldAdapterDelegate.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package com.example.util.simpletimetracker.feature_change_record.adapter
1+
package com.example.util.simpletimetracker.feature_base_adapter.commentChangeField
22

33
import android.content.res.ColorStateList
44
import android.text.TextWatcher
@@ -8,8 +8,8 @@ import androidx.core.widget.doAfterTextChanged
88
import com.example.util.simpletimetracker.feature_base_adapter.ViewHolderType
99
import com.example.util.simpletimetracker.feature_base_adapter.createRecyclerBindingAdapterDelegate
1010
import com.example.util.simpletimetracker.feature_views.extension.setOnClick
11-
import com.example.util.simpletimetracker.feature_change_record.adapter.ChangeRecordCommentFieldViewData as ViewData
12-
import com.example.util.simpletimetracker.feature_change_record.databinding.ChangeRecordCommentFieldItemBinding as Binding
11+
import com.example.util.simpletimetracker.feature_base_adapter.commentChangeField.ChangeRecordCommentFieldViewData as ViewData
12+
import com.example.util.simpletimetracker.feature_base_adapter.databinding.ChangeRecordCommentFieldItemBinding as Binding
1313

1414
fun createChangeRecordCommentFieldAdapterDelegate(
1515
afterTextChange: (String) -> Unit,

features/feature_change_record/src/main/res/layout/change_record_comment_field_item.xml renamed to features/feature_base_adapter/src/main/res/layout/change_record_comment_field_item.xml

File renamed without changes.

features/feature_change_record/src/main/java/com/example/util/simpletimetracker/feature_change_record/interactor/ChangeRecordViewDataInteractor.kt

Lines changed: 0 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,14 @@
11
package com.example.util.simpletimetracker.feature_change_record.interactor
22

3-
import com.example.util.simpletimetracker.core.interactor.RecordCommentSearchViewDataInteractor
4-
import com.example.util.simpletimetracker.core.mapper.ColorMapper
53
import com.example.util.simpletimetracker.core.mapper.TimeMapper
64
import com.example.util.simpletimetracker.core.repo.ResourceRepo
75
import com.example.util.simpletimetracker.core.view.timeAdjustment.TimeAdjustmentView
8-
import com.example.util.simpletimetracker.domain.favourite.interactor.FavouriteCommentInteractor
96
import com.example.util.simpletimetracker.domain.prefs.interactor.PrefsInteractor
107
import com.example.util.simpletimetracker.domain.record.model.Record
118
import com.example.util.simpletimetracker.domain.recordTag.interactor.RecordTagInteractor
129
import com.example.util.simpletimetracker.domain.recordType.interactor.RecordTypeInteractor
1310
import com.example.util.simpletimetracker.feature_base_adapter.ViewHolderType
1411
import com.example.util.simpletimetracker.feature_change_record.R
15-
import com.example.util.simpletimetracker.feature_change_record.adapter.ChangeRecordCommentFieldViewData
1612
import com.example.util.simpletimetracker.feature_change_record.mapper.ChangeRecordViewDataMapper
1713
import com.example.util.simpletimetracker.feature_change_record.model.ChangeRecordDateTimeFieldsState
1814
import com.example.util.simpletimetracker.feature_change_record.viewData.ChangeRecordViewData
@@ -22,12 +18,9 @@ class ChangeRecordViewDataInteractor @Inject constructor(
2218
private val prefsInteractor: PrefsInteractor,
2319
private val recordTypeInteractor: RecordTypeInteractor,
2420
private val recordTagInteractor: RecordTagInteractor,
25-
private val favouriteCommentInteractor: FavouriteCommentInteractor,
2621
private val changeRecordViewDataMapper: ChangeRecordViewDataMapper,
2722
private val resourceRepo: ResourceRepo,
2823
private val timeMapper: TimeMapper,
29-
private val colorMapper: ColorMapper,
30-
private val recordCommentSearchViewDataInteractor: RecordCommentSearchViewDataInteractor,
3124
) {
3225

3326
suspend fun getPreviewViewData(
@@ -54,36 +47,6 @@ class ChangeRecordViewDataInteractor @Inject constructor(
5447
)
5548
}
5649

57-
// TODO replace fav to text button?
58-
suspend fun getCommentsViewData(
59-
comment: String,
60-
typeId: Long,
61-
fromCommentChange: Boolean,
62-
): List<ViewHolderType> {
63-
val items = mutableListOf<ViewHolderType>()
64-
val isDarkTheme = prefsInteractor.getDarkMode()
65-
val isFavourite = favouriteCommentInteractor.get(comment) != null
66-
67-
ChangeRecordCommentFieldViewData(
68-
// Only one at the time.
69-
id = 1L,
70-
// Do not update text if update coming from typing.
71-
text = if (fromCommentChange) null else comment,
72-
iconColor = if (isFavourite) {
73-
resourceRepo.getColor(R.color.colorSecondary)
74-
} else {
75-
colorMapper.toInactiveColor(isDarkTheme)
76-
},
77-
).let(items::add)
78-
79-
items += recordCommentSearchViewDataInteractor.getViewData(
80-
comment = comment,
81-
typeId = typeId,
82-
)
83-
84-
return items
85-
}
86-
8750
fun getTimeAdjustmentItems(
8851
dateTimeFieldState: ChangeRecordDateTimeFieldsState.State,
8952
): List<ViewHolderType> {

0 commit comments

Comments
 (0)