Skip to content

Commit 1f88cc0

Browse files
committed
add quick action to move record
1 parent a158130 commit 1f88cc0

File tree

42 files changed

+297
-5
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+297
-5
lines changed

core/src/main/java/com/example/util/simpletimetracker/core/mapper/RecordQuickActionMapper.kt

+4
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import com.example.util.simpletimetracker.domain.recordAction.model.RecordQuickA
1111
import com.example.util.simpletimetracker.domain.recordAction.model.RecordQuickAction.CONTINUE
1212
import com.example.util.simpletimetracker.domain.recordAction.model.RecordQuickAction.DUPLICATE
1313
import com.example.util.simpletimetracker.domain.recordAction.model.RecordQuickAction.MERGE
14+
import com.example.util.simpletimetracker.domain.recordAction.model.RecordQuickAction.MOVE
1415
import com.example.util.simpletimetracker.domain.recordAction.model.RecordQuickAction.REPEAT
1516
import com.example.util.simpletimetracker.domain.recordAction.model.RecordQuickAction.SPLIT
1617
import com.example.util.simpletimetracker.domain.recordAction.model.RecordQuickAction.STOP
@@ -25,6 +26,7 @@ class RecordQuickActionMapper @Inject constructor(
2526
CONTINUE -> R.string.change_record_continue
2627
REPEAT -> R.string.change_record_repeat
2728
DUPLICATE -> R.string.change_record_duplicate
29+
MOVE -> R.string.change_record_move
2830
MERGE -> R.string.change_record_merge
2931
SPLIT -> R.string.change_record_split
3032
ADJUST -> R.string.change_record_adjust
@@ -40,6 +42,7 @@ class RecordQuickActionMapper @Inject constructor(
4042
CONTINUE -> R.drawable.action_continue
4143
REPEAT -> R.drawable.repeat
4244
DUPLICATE -> R.drawable.action_copy
45+
MOVE -> R.drawable.action_move
4346
MERGE -> R.drawable.action_merge
4447
SPLIT -> R.drawable.action_divide
4548
ADJUST -> R.drawable.action_change
@@ -54,6 +57,7 @@ class RecordQuickActionMapper @Inject constructor(
5457
CONTINUE -> R.color.red_300
5558
REPEAT -> R.color.purple_300
5659
DUPLICATE -> R.color.indigo_300
60+
MOVE -> R.color.indigo_300
5761
MERGE -> R.color.light_blue_300
5862
STOP -> R.color.teal_300
5963
CHANGE_ACTIVITY, CHANGE_TAG -> R.color.green_300
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<vector xmlns:android="http://schemas.android.com/apk/res/android"
2+
android:width="24dp"
3+
android:height="24dp"
4+
android:viewportWidth="24"
5+
android:viewportHeight="24">
6+
<path
7+
android:fillColor="#FF000000"
8+
android:pathData="M18.4,10.6C16.55,8.99 14.15,8 11.5,8c-4.65,0 -8.58,3.03 -9.96,7.22L3.9,16c1.05,-3.19 4.05,-5.5 7.6,-5.5 1.95,0 3.73,0.72 5.12,1.88L13,16h9V7l-3.6,3.6z"/>
9+
</vector>

domain/src/main/java/com/example/util/simpletimetracker/domain/recordAction/model/RecordQuickAction.kt

+1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ enum class RecordQuickAction {
44
CONTINUE,
55
REPEAT,
66
DUPLICATE,
7+
MOVE,
78
MERGE,
89
SPLIT,
910
ADJUST,

features/feature_change_record/src/main/java/com/example/util/simpletimetracker/feature_change_record/mapper/ChangeRecordActionsDelegateMapper.kt

+24
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import com.example.util.simpletimetracker.feature_change_record.viewModel.Change
66
import com.example.util.simpletimetracker.feature_change_record.viewModel.ChangeRecordActionsDelegate.Parent.ViewDataParams
77
import com.example.util.simpletimetracker.feature_change_record.viewModel.ChangeRecordActionsDuplicateDelegate
88
import com.example.util.simpletimetracker.feature_change_record.viewModel.ChangeRecordActionsMergeDelegate
9+
import com.example.util.simpletimetracker.feature_change_record.viewModel.ChangeRecordActionsMoveDelegate
910
import com.example.util.simpletimetracker.feature_change_record.viewModel.ChangeRecordActionsRepeatDelegate
1011
import com.example.util.simpletimetracker.feature_change_record.viewModel.ChangeRecordActionsSplitDelegate
1112
import javax.inject.Inject
@@ -111,6 +112,21 @@ class ChangeRecordActionsDelegateMapper @Inject constructor() {
111112
}
112113
}
113114

115+
fun getMoveActionsDelegateParent(
116+
parent: ChangeRecordActionsDelegate.Parent?,
117+
updateViewData: () -> Unit,
118+
): ChangeRecordActionsMoveDelegate.Parent {
119+
return object : ChangeRecordActionsMoveDelegate.Parent {
120+
override fun getViewDataParams(): ChangeRecordActionsMoveDelegate.Parent.ViewDataParams? {
121+
return parent?.getViewDataParams()?.mapMoveParams()
122+
}
123+
124+
override fun update() {
125+
updateViewData()
126+
}
127+
}
128+
}
129+
114130
fun getMergeDelegateParent(
115131
parent: ChangeRecordActionsDelegate.Parent?,
116132
updateViewData: () -> Unit,
@@ -190,6 +206,14 @@ class ChangeRecordActionsDelegateMapper @Inject constructor() {
190206
)
191207
}
192208

209+
private fun ViewDataParams.mapMoveParams(): ChangeRecordActionsMoveDelegate.Parent.ViewDataParams {
210+
return ChangeRecordActionsMoveDelegate.Parent.ViewDataParams(
211+
newTimeStarted = baseParams.newTimeStarted,
212+
isAvailable = moveParams.isAvailable,
213+
isButtonEnabled = baseParams.isButtonEnabled,
214+
)
215+
}
216+
193217
private fun ViewDataParams.mapMergeParams(): ChangeRecordActionsMergeDelegate.Parent.ViewDataParams {
194218
return ChangeRecordActionsMergeDelegate.Parent.ViewDataParams(
195219
mergeAvailable = mergeParams.mergeAvailable,

features/feature_change_record/src/main/java/com/example/util/simpletimetracker/feature_change_record/mapper/ChangeRecordViewDataMapper.kt

+1
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,7 @@ class ChangeRecordViewDataMapper @Inject constructor(
149149
RecordQuickAction.CONTINUE -> ChangeRecordActionsBlock.ContinueButton
150150
RecordQuickAction.REPEAT -> ChangeRecordActionsBlock.RepeatButton
151151
RecordQuickAction.DUPLICATE -> ChangeRecordActionsBlock.DuplicateButton
152+
RecordQuickAction.MOVE -> ChangeRecordActionsBlock.MoveButton
152153
RecordQuickAction.MERGE -> ChangeRecordActionsBlock.MergeButton
153154
RecordQuickAction.SPLIT -> ChangeRecordActionsBlock.SplitButton
154155
RecordQuickAction.ADJUST -> ChangeRecordActionsBlock.AdjustButton

features/feature_change_record/src/main/java/com/example/util/simpletimetracker/feature_change_record/model/ChangeRecordActionsBlock.kt

+1
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,6 @@ enum class ChangeRecordActionsBlock {
1313
ContinueButton,
1414
RepeatButton,
1515
DuplicateButton,
16+
MoveButton,
1617
MergeButton,
1718
}

features/feature_change_record/src/main/java/com/example/util/simpletimetracker/feature_change_record/viewModel/ChangeRecordActionsDelegate.kt

+7
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ interface ChangeRecordActionsDelegate {
1212

1313
fun updateViewData()
1414

15+
fun checkIfTypeSelected(): Boolean
16+
1517
fun onRecordChangeButtonClick(
1618
onProceed: suspend () -> Unit,
1719
checkTypeSelected: Boolean = true,
@@ -27,6 +29,7 @@ interface ChangeRecordActionsDelegate {
2729
val baseParams: BaseParams,
2830
val splitParams: SplitParams,
2931
val duplicateParams: DuplicateParams,
32+
val moveParams: MoveParams,
3033
val continueParams: ContinueParams,
3134
val repeatParams: RepeatParams,
3235
val adjustParams: AdjustParams,
@@ -52,6 +55,10 @@ interface ChangeRecordActionsDelegate {
5255
val isAvailable: Boolean,
5356
)
5457

58+
data class MoveParams(
59+
val isAvailable: Boolean,
60+
)
61+
5562
data class ContinueParams(
5663
val originalRecordId: Long,
5764
val isAvailable: Boolean,

features/feature_change_record/src/main/java/com/example/util/simpletimetracker/feature_change_record/viewModel/ChangeRecordActionsDelegateHolder.kt

+12
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ class ChangeRecordActionsDelegateHolder @Inject constructor(
1010
val continueDelegate: ChangeRecordActionsContinueDelegate,
1111
val repeatDelegate: ChangeRecordActionsRepeatDelegate,
1212
val duplicateDelegate: ChangeRecordActionsDuplicateDelegate,
13+
val moveDelegate: ChangeRecordActionsMoveDelegate,
1314
private val changeRecordActionsDelegateMapper: ChangeRecordActionsDelegateMapper,
1415
) {
1516

@@ -19,6 +20,7 @@ class ChangeRecordActionsDelegateHolder @Inject constructor(
1920
continueDelegate,
2021
repeatDelegate,
2122
duplicateDelegate,
23+
moveDelegate,
2224
mergeDelegate,
2325
)
2426

@@ -30,6 +32,7 @@ class ChangeRecordActionsDelegateHolder @Inject constructor(
3032
continueDelegate.attach(getContinueActionsDelegateParent(parent))
3133
repeatDelegate.attach(getRepeatActionsDelegateParent(parent))
3234
duplicateDelegate.attach(getDuplicateActionsDelegateParent(parent))
35+
moveDelegate.attach(getMoveActionsDelegateParent(parent))
3336
mergeDelegate.attach(getMergeDelegateParent(parent))
3437
}
3538

@@ -78,6 +81,15 @@ class ChangeRecordActionsDelegateHolder @Inject constructor(
7881
)
7982
}
8083

84+
private fun getMoveActionsDelegateParent(
85+
parent: ChangeRecordActionsDelegate.Parent,
86+
): ChangeRecordActionsMoveDelegate.Parent {
87+
return changeRecordActionsDelegateMapper.getMoveActionsDelegateParent(
88+
parent = parent,
89+
updateViewData = parent::updateViewData,
90+
)
91+
}
92+
8193
private fun getMergeDelegateParent(
8294
parent: ChangeRecordActionsDelegate.Parent,
8395
): ChangeRecordActionsMergeDelegate.Parent {

features/feature_change_record/src/main/java/com/example/util/simpletimetracker/feature_change_record/viewModel/ChangeRecordActionsDelegateImpl.kt

+9
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ 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.domain.extension.orFalse
78
import com.example.util.simpletimetracker.feature_base_adapter.ViewHolderType
89
import com.example.util.simpletimetracker.feature_base_adapter.button.ButtonViewData
910
import com.example.util.simpletimetracker.feature_base_adapter.divider.DividerViewData
@@ -84,6 +85,7 @@ class ChangeRecordActionsDelegateImpl @Inject constructor(
8485
ChangeRecordActionsBlock.ContinueButton -> onContinueClick()
8586
ChangeRecordActionsBlock.RepeatButton -> onRepeatClick()
8687
ChangeRecordActionsBlock.DuplicateButton -> onDuplicateClick()
88+
ChangeRecordActionsBlock.MoveButton -> onMoveClick()
8789
ChangeRecordActionsBlock.MergeButton -> onMergeClick()
8890
else -> {
8991
// Do nothing.
@@ -116,6 +118,13 @@ class ChangeRecordActionsDelegateImpl @Inject constructor(
116118
)
117119
}
118120

121+
private fun onMoveClick() {
122+
if (!parent?.checkIfTypeSelected().orFalse()) return
123+
delegateScope.launch {
124+
delegateHolder.moveDelegate.onMoveClickDelegate()
125+
}
126+
}
127+
119128
private fun onMergeClick() {
120129
parent?.onRecordChangeButtonClick(
121130
onProceed = delegateHolder.mergeDelegate::onMergeClickDelegate,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
package com.example.util.simpletimetracker.feature_change_record.viewModel
2+
3+
import com.example.util.simpletimetracker.core.repo.ResourceRepo
4+
import com.example.util.simpletimetracker.domain.extension.plusAssign
5+
import com.example.util.simpletimetracker.domain.prefs.interactor.PrefsInteractor
6+
import com.example.util.simpletimetracker.domain.recordAction.model.RecordQuickAction
7+
import com.example.util.simpletimetracker.feature_base_adapter.ViewHolderType
8+
import com.example.util.simpletimetracker.feature_base_adapter.hint.HintViewData
9+
import com.example.util.simpletimetracker.feature_change_record.R
10+
import com.example.util.simpletimetracker.feature_change_record.mapper.ChangeRecordViewDataMapper
11+
import com.example.util.simpletimetracker.navigation.Router
12+
import com.example.util.simpletimetracker.navigation.params.screen.DateTimeDialogParams
13+
import com.example.util.simpletimetracker.navigation.params.screen.DateTimeDialogType
14+
import javax.inject.Inject
15+
16+
class ChangeRecordActionsMoveDelegate @Inject constructor(
17+
private val router: Router,
18+
private val resourceRepo: ResourceRepo,
19+
private val prefsInteractor: PrefsInteractor,
20+
private val changeRecordViewDataMapper: ChangeRecordViewDataMapper,
21+
) : ChangeRecordActionsSubDelegate<ChangeRecordActionsMoveDelegate.Parent> {
22+
23+
private var parent: Parent? = null
24+
private var viewData: List<ViewHolderType> = emptyList()
25+
26+
override fun attach(parent: Parent) {
27+
this.parent = parent
28+
}
29+
30+
override fun getViewData(): List<ViewHolderType> {
31+
return viewData
32+
}
33+
34+
override suspend fun updateViewData() {
35+
viewData = loadViewData()
36+
parent?.update()
37+
}
38+
39+
suspend fun onMoveClickDelegate() {
40+
val params = parent?.getViewDataParams() ?: return
41+
val useMilitaryTime = prefsInteractor.getUseMilitaryTimeFormat()
42+
val firstDayOfWeek = prefsInteractor.getFirstDayOfWeek()
43+
val showSeconds = prefsInteractor.getShowSeconds()
44+
45+
router.navigate(
46+
DateTimeDialogParams(
47+
tag = MOVE_TIME_STARTED_TAG,
48+
timestamp = params.newTimeStarted,
49+
type = DateTimeDialogType.DATETIME(),
50+
useMilitaryTime = useMilitaryTime,
51+
firstDayOfWeek = firstDayOfWeek,
52+
showSeconds = showSeconds,
53+
),
54+
)
55+
}
56+
57+
private suspend fun loadViewData(): List<ViewHolderType> {
58+
val params = parent?.getViewDataParams()
59+
?: return emptyList()
60+
if (!params.isAvailable) return emptyList()
61+
val isDarkTheme = prefsInteractor.getDarkMode()
62+
63+
val result = mutableListOf<ViewHolderType>()
64+
result += HintViewData(
65+
text = resourceRepo.getString(R.string.change_record_move_hint),
66+
)
67+
result += changeRecordViewDataMapper.mapRecordActionButton(
68+
action = RecordQuickAction.MOVE,
69+
isEnabled = params.isButtonEnabled,
70+
isDarkTheme = isDarkTheme,
71+
)
72+
return result
73+
}
74+
75+
interface Parent {
76+
77+
fun getViewDataParams(): ViewDataParams?
78+
fun update()
79+
80+
data class ViewDataParams(
81+
val newTimeStarted: Long,
82+
val isAvailable: Boolean,
83+
val isButtonEnabled: Boolean,
84+
)
85+
}
86+
87+
companion object {
88+
const val MOVE_TIME_STARTED_TAG = "move_time_started_tag"
89+
}
90+
}

features/feature_change_record/src/main/java/com/example/util/simpletimetracker/feature_change_record/viewModel/ChangeRecordBaseViewModel.kt

+28-3
Original file line numberDiff line numberDiff line change
@@ -390,6 +390,16 @@ abstract class ChangeRecordBaseViewModel(
390390
onTimeSplitChanged()
391391
}
392392
}
393+
ChangeRecordActionsMoveDelegate.MOVE_TIME_STARTED_TAG -> {
394+
onRecordChangeButtonClick(
395+
onProceed = {
396+
val currentDuration = (newTimeEnded - newTimeStarted).coerceAtLeast(0)
397+
newTimeStarted = timestamp
398+
newTimeEnded = newTimeStarted + currentDuration
399+
onSaveClickDelegate()
400+
},
401+
)
402+
}
393403
}
394404
}
395405
}
@@ -508,13 +518,21 @@ abstract class ChangeRecordBaseViewModel(
508518
onTimeSplitChanged()
509519
}
510520

521+
private fun checkIfTypeSelected(): Boolean {
522+
return if (newTypeId == 0L) {
523+
showMessage(R.string.change_record_message_choose_type)
524+
false
525+
} else {
526+
true
527+
}
528+
}
529+
511530
private fun onRecordChangeButtonClick(
512531
onProceed: suspend () -> Unit,
513532
checkTypeSelected: Boolean = true,
514533
) {
515-
if (checkTypeSelected && newTypeId == 0L) {
516-
showMessage(R.string.change_record_message_choose_type)
517-
return
534+
if (checkTypeSelected) {
535+
if (!checkIfTypeSelected()) return
518536
}
519537
viewModelScope.launch {
520538
val canProceed = saveButtonEnabled.value.orFalse()
@@ -753,6 +771,9 @@ abstract class ChangeRecordBaseViewModel(
753771
duplicateParams = ChangeRecordActionsDelegate.Parent.ViewDataParams.DuplicateParams(
754772
isAvailable = isAdditionalActionsAvailable,
755773
),
774+
moveParams = ChangeRecordActionsDelegate.Parent.ViewDataParams.MoveParams(
775+
isAvailable = isAdditionalActionsAvailable,
776+
),
756777
continueParams = ChangeRecordActionsDelegate.Parent.ViewDataParams.ContinueParams(
757778
originalRecordId = originalRecordId,
758779
isAvailable = isAdditionalActionsAvailable,
@@ -781,6 +802,10 @@ abstract class ChangeRecordBaseViewModel(
781802
changeRecordActionsDelegate.updateViewData()
782803
}
783804

805+
override fun checkIfTypeSelected(): Boolean {
806+
return this@ChangeRecordBaseViewModel.checkIfTypeSelected()
807+
}
808+
784809
override fun onRecordChangeButtonClick(
785810
onProceed: suspend () -> Unit,
786811
checkTypeSelected: Boolean,

features/feature_dialogs/src/main/java/com/example/util/simpletimetracker/feature_dialogs/recordQuickActions/interactor/RecordQuickActionsInteractor.kt

+15
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,21 @@ class RecordQuickActionsInteractor @Inject constructor(
100100
}
101101
}
102102

103+
suspend fun move(
104+
params: Type,
105+
timestamp: Long,
106+
) {
107+
val recordId = (params as? Type.RecordTracked)?.id ?: return
108+
val record = recordInteractor.get(recordId) ?: return
109+
val currentDuration = record.duration
110+
record.copy(
111+
timeStarted = timestamp,
112+
timeEnded = timestamp + currentDuration
113+
).let {
114+
addRecordMediator.add(it)
115+
}
116+
}
117+
103118
private suspend fun changeRecord(
104119
old: Record,
105120
newTypeId: Long,

0 commit comments

Comments
 (0)