Skip to content

Commit

Permalink
add record quick actions
Browse files Browse the repository at this point in the history
  • Loading branch information
Razeeman committed Jul 6, 2024
1 parent e4bea8d commit 30f596e
Show file tree
Hide file tree
Showing 21 changed files with 945 additions and 42 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import com.example.util.simpletimetracker.feature_dialogs.dateTime.DateTimeDialo
import com.example.util.simpletimetracker.feature_dialogs.duration.view.DurationDialogFragment
import com.example.util.simpletimetracker.feature_dialogs.emojiSelection.view.EmojiSelectionDialogFragment
import com.example.util.simpletimetracker.feature_dialogs.helpDialog.HelpDialogFragment
import com.example.util.simpletimetracker.feature_dialogs.recordQuickActions.view.RecordQuickActionsDialogFragment
import com.example.util.simpletimetracker.feature_dialogs.recordTagSelection.RecordTagSelectionDialogFragment
import com.example.util.simpletimetracker.feature_dialogs.typesSelection.view.TypesSelectionDialogFragment
import com.example.util.simpletimetracker.feature_dialogs.standard.StandardDialogFragment
Expand All @@ -34,6 +35,7 @@ import com.example.util.simpletimetracker.navigation.params.screen.DurationDialo
import com.example.util.simpletimetracker.navigation.params.screen.EmojiSelectionDialogParams
import com.example.util.simpletimetracker.navigation.params.screen.HelpDialogParams
import com.example.util.simpletimetracker.navigation.params.screen.PomodoroSettingsParams
import com.example.util.simpletimetracker.navigation.params.screen.RecordQuickActionsParams
import com.example.util.simpletimetracker.navigation.params.screen.RecordTagSelectionParams
import com.example.util.simpletimetracker.navigation.params.screen.TypesSelectionDialogParams
import com.example.util.simpletimetracker.navigation.params.screen.RecordsFilterParams
Expand Down Expand Up @@ -257,4 +259,14 @@ class NavigationDialogMapModule {
BundleCreator.empty(),
)
}

@IntoMap
@Provides
@ScreenKey(RecordQuickActionsParams::class)
fun recordQuickActionsDialog(): NavigationData {
return NavigationData(
R.id.recordQuickActionsDialogFragment,
bundleCreatorDelegate(RecordQuickActionsDialogFragment::createBundle),
)
}
}
5 changes: 5 additions & 0 deletions app/src/main/res/navigation/nav_graph.xml
Original file line number Diff line number Diff line change
Expand Up @@ -300,4 +300,9 @@
android:name="com.example.util.simpletimetracker.feature_pomodoro.settings.view.PomodoroSettingsDialogFragment"
android:label="PomodoroSettingsFragment"
tools:layout="@layout/pomodoro_settings_fragment" />
<dialog
android:id="@+id/recordQuickActionsDialogFragment"
android:name="com.example.util.simpletimetracker.feature_dialogs.recordQuickActions.view.RecordQuickActionsDialogFragment"
android:label="RecordQuickActionsDialogFragment"
tools:layout="@layout/record_quick_actions_dialog_fragment" />
</navigation>
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package com.example.util.simpletimetracker.core.dialog

interface RecordQuickActionDialogListener {

fun onUpdate()
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ class HoldDetector(
class SingleTapDetector(
context: Context,
onSingleTap: (MotionEvent) -> Unit,
onLongPress: (MotionEvent) -> Unit = {},
) {

private val detector = GestureDetectorCompat(
Expand All @@ -47,6 +48,11 @@ class SingleTapDetector(
onSingleTap(e)
return super.onSingleTapUp(e)
}

override fun onLongPress(e: MotionEvent) {
onLongPress(e)
super.onLongPress(e)
}
},
)

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package com.example.util.simpletimetracker.domain.interactor

import com.example.util.simpletimetracker.domain.extension.orZero
import javax.inject.Inject

class RecordActionContinueMediator @Inject constructor(
private val runningRecordInteractor: RunningRecordInteractor,
private val addRunningRecordMediator: AddRunningRecordMediator,
private val removeRunningRecordMediator: RemoveRunningRecordMediator,
private val recordInteractor: RecordInteractor,
private val removeRecordMediator: RemoveRecordMediator,
) {

suspend fun execute(
recordId: Long?,
typeId: Long,
timeStarted: Long,
comment: String,
tagIds: List<Long>,
) {
// Remove current record if exist.
recordId?.let {
val oldTypeId = recordInteractor.get(it)?.typeId.orZero()
removeRecordMediator.remove(it, oldTypeId)
}
// Stop same type running record if exist (only one of the same type can run at once).
// Widgets will update on adding.
runningRecordInteractor.get(typeId)
?.let { removeRunningRecordMediator.removeWithRecordAdd(it, updateWidgets = false) }
// Add new running record.
addRunningRecordMediator.startTimer(
typeId = typeId,
timeStarted = timeStarted,
comment = comment,
tagIds = tagIds,
)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package com.example.util.simpletimetracker.domain.interactor

import com.example.util.simpletimetracker.domain.model.Record
import javax.inject.Inject

class RecordActionDuplicateMediator @Inject constructor(
private val addRecordMediator: AddRecordMediator,
) {

suspend fun execute(
typeId: Long,
timeStarted: Long,
timeEnded: Long,
comment: String,
tagIds: List<Long>,
) {
Record(
typeId = typeId,
timeStarted = timeStarted,
timeEnded = timeEnded,
comment = comment,
tagIds = tagIds,
).let {
addRecordMediator.add(it)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.example.util.simpletimetracker.domain.interactor

import com.example.util.simpletimetracker.domain.model.Record
import javax.inject.Inject

class RecordActionMergeMediator @Inject constructor(
private val addRecordMediator: AddRecordMediator,
) {

suspend fun execute(
prevRecord: Record?,
newTimeEnded: Long,
onMergeComplete: () -> Unit,
) {
// If merge would be available but only for untracked - add removal of current record
prevRecord?.copy(
timeEnded = newTimeEnded,
)?.let {
addRecordMediator.add(it)
onMergeComplete()
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package com.example.util.simpletimetracker.domain.interactor

import javax.inject.Inject

class RecordActionRepeatMediator @Inject constructor(
private val runningRecordInteractor: RunningRecordInteractor,
private val addRunningRecordMediator: AddRunningRecordMediator,
private val removeRunningRecordMediator: RemoveRunningRecordMediator,
) {

suspend fun execute(
typeId: Long,
comment: String,
tagIds: List<Long>,
) {
// Stop same type running record if exist (only one of the same type can run at once).
// Widgets will update on adding.
runningRecordInteractor.get(typeId)
?.let { removeRunningRecordMediator.removeWithRecordAdd(it, updateWidgets = false) }
// Add new running record.
addRunningRecordMediator.startTimer(
typeId = typeId,
comment = comment,
tagIds = tagIds,
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,13 @@ import androidx.core.view.ViewCompat
import com.example.util.simpletimetracker.feature_base_adapter.createRecyclerBindingAdapterDelegate
import com.example.util.simpletimetracker.feature_views.TransitionNames
import com.example.util.simpletimetracker.feature_views.extension.setOnClick
import com.example.util.simpletimetracker.feature_views.extension.setOnLongClick
import com.example.util.simpletimetracker.feature_base_adapter.databinding.ItemRecordLayoutBinding as Binding
import com.example.util.simpletimetracker.feature_base_adapter.record.RecordViewData as ViewData

fun createRecordAdapterDelegate(
onItemClick: ((ViewData, Pair<Any, String>) -> Unit),
onItemLongClick: ((ViewData, Pair<Any, String>) -> Unit) = { _, _ -> },
) = createRecyclerBindingAdapterDelegate<ViewData, Binding>(
Binding::inflate,
) { binding, item, _ ->
Expand All @@ -27,6 +29,7 @@ fun createRecordAdapterDelegate(
itemComment = item.comment

setOnClick { onItemClick(item, this to transitionName) }
setOnLongClick { onItemLongClick(item, this to transitionName) }
ViewCompat.setTransitionName(this, transitionName)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package com.example.util.simpletimetracker.feature_change_record.viewModel
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import com.example.util.simpletimetracker.core.extension.set
import com.example.util.simpletimetracker.domain.interactor.AddRecordMediator
import com.example.util.simpletimetracker.domain.interactor.RecordActionMergeMediator
import com.example.util.simpletimetracker.domain.model.Record
import com.example.util.simpletimetracker.feature_change_record.interactor.ChangeRecordViewDataInteractor
import com.example.util.simpletimetracker.feature_change_record.mapper.ChangeRecordViewDataMapper
Expand All @@ -16,7 +16,7 @@ interface ChangeRecordMergeDelegate {

class ChangeRecordMergeDelegateImpl @Inject constructor(
private val changeRecordViewDataInteractor: ChangeRecordViewDataInteractor,
private val addRecordMediator: AddRecordMediator,
private val recordActionMergeMediator: RecordActionMergeMediator,
private val changeRecordViewDataMapper: ChangeRecordViewDataMapper,
) : ChangeRecordMergeDelegate {

Expand All @@ -28,13 +28,11 @@ class ChangeRecordMergeDelegateImpl @Inject constructor(
newTimeEnded: Long,
onMergeComplete: () -> Unit,
) {
// If merge would be available but only for untracked - add removal of current record
prevRecord?.copy(
timeEnded = newTimeEnded,
)?.let {
addRecordMediator.add(it)
onMergeComplete()
}
recordActionMergeMediator.execute(
prevRecord = prevRecord,
newTimeEnded = newTimeEnded,
onMergeComplete = onMergeComplete,
)
}

private fun getChangedRecord(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import com.example.util.simpletimetracker.domain.UNTRACKED_ITEM_ID
import com.example.util.simpletimetracker.domain.extension.orZero
import com.example.util.simpletimetracker.domain.interactor.AddRecordMediator
import com.example.util.simpletimetracker.domain.interactor.AddRunningRecordMediator
import com.example.util.simpletimetracker.domain.interactor.RecordActionContinueMediator
import com.example.util.simpletimetracker.domain.interactor.RecordActionDuplicateMediator
import com.example.util.simpletimetracker.domain.interactor.FavouriteCommentInteractor
import com.example.util.simpletimetracker.domain.interactor.NotificationGoalTimeInteractor
import com.example.util.simpletimetracker.domain.interactor.NotificationTypeInteractor
Expand All @@ -20,6 +22,7 @@ import com.example.util.simpletimetracker.domain.interactor.RecordInteractor
import com.example.util.simpletimetracker.domain.interactor.RecordTypeToTagInteractor
import com.example.util.simpletimetracker.domain.interactor.RemoveRecordMediator
import com.example.util.simpletimetracker.domain.interactor.RemoveRunningRecordMediator
import com.example.util.simpletimetracker.domain.interactor.RecordActionRepeatMediator
import com.example.util.simpletimetracker.domain.interactor.RunningRecordInteractor
import com.example.util.simpletimetracker.domain.model.ChartFilterType
import com.example.util.simpletimetracker.domain.model.RangeLength
Expand Down Expand Up @@ -58,6 +61,9 @@ class ChangeRecordViewModel @Inject constructor(
private val notificationTypeInteractor: NotificationTypeInteractor,
private val timeMapper: TimeMapper,
private val statisticsDetailNavigationInteractor: StatisticsDetailNavigationInteractor,
private val recordActionDuplicateMediator: RecordActionDuplicateMediator,
private val recordActionRepeatMediator: RecordActionRepeatMediator,
private val recordActionContinueMediator: RecordActionContinueMediator,
) : ChangeRecordBaseViewModel(
router = router,
snackBarMessageNavigationInteractor = snackBarMessageNavigationInteractor,
Expand Down Expand Up @@ -151,17 +157,8 @@ class ChangeRecordViewModel @Inject constructor(
}

override suspend fun onContinueClickDelegate() {
// Remove current record if exist.
recordId?.let {
val typeId = recordInteractor.get(it)?.typeId.orZero()
removeRecordMediator.remove(it, typeId)
}
// Stop same type running record if exist (only one of the same type can run at once).
// Widgets will update on adding.
runningRecordInteractor.get(newTypeId)
?.let { removeRunningRecordMediator.removeWithRecordAdd(it, updateWidgets = false) }
// Add new running record.
addRunningRecordMediator.startTimer(
recordActionContinueMediator.execute(
recordId = recordId,
typeId = newTypeId,
timeStarted = newTimeStarted,
comment = newComment,
Expand All @@ -172,12 +169,7 @@ class ChangeRecordViewModel @Inject constructor(
}

override suspend fun onRepeatClickDelegate() {
// Stop same type running record if exist (only one of the same type can run at once).
// Widgets will update on adding.
runningRecordInteractor.get(newTypeId)
?.let { removeRunningRecordMediator.removeWithRecordAdd(it, updateWidgets = false) }
// Add new running record.
addRunningRecordMediator.startTimer(
recordActionRepeatMediator.execute(
typeId = newTypeId,
comment = newComment,
tagIds = newCategoryIds,
Expand All @@ -187,15 +179,13 @@ class ChangeRecordViewModel @Inject constructor(
}

override suspend fun onDuplicateClickDelegate() {
Record(
recordActionDuplicateMediator.execute(
typeId = newTypeId,
timeStarted = newTimeStarted,
timeEnded = newTimeEnded,
comment = newComment,
tagIds = newCategoryIds,
).let {
addRecordMediator.add(it)
}
tagIds = newCategoryIds
)
onSaveClickDelegate()
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package com.example.util.simpletimetracker.feature_dialogs.recordQuickActions.model

data class RecordQuickActionsState(
val buttons: List<Button>,
) {

sealed interface Button {
val wrapBefore: Boolean

data class Statistics(
override val wrapBefore: Boolean,
) : Button

data class Delete(
override val wrapBefore: Boolean,
) : Button

data class Continue(
override val wrapBefore: Boolean,
) : Button

data class Repeat(
override val wrapBefore: Boolean,
) : Button

data class Duplicate(
override val wrapBefore: Boolean,
) : Button

data class Merge(
override val wrapBefore: Boolean,
) : Button
}
}
Loading

0 comments on commit 30f596e

Please sign in to comment.