Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asSharedFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch

@HiltViewModel
Expand Down Expand Up @@ -93,17 +94,21 @@ class ProcedureViewModel @Inject constructor(

val currentState = _uiState.value
if (currentState is UiState.Success) {
_uiState.value = currentState.copy(
data = currentState.data.copy(worries = worriesToUse)
)
_uiState.update { state ->
(state as? UiState.Success)?.copy(
data = state.data.copy(worries = worriesToUse)
) ?: state
}
} else {
_uiState.value = UiState.Success(
ProcedureUiState(
worries = worriesToUse,
startDay = startDateArg,
screenHeightDp = latestScreenHeightDp
_uiState.update {
UiState.Success(
ProcedureUiState(
worries = worriesToUse,
startDay = startDateArg,
screenHeightDp = latestScreenHeightDp
)
)
)
}
}
}
.onLogFailure { }
Expand Down Expand Up @@ -269,21 +274,21 @@ class ProcedureViewModel @Inject constructor(
}

fun onNextClick() {
var queryToFetch: ProceduresQuery? = null
val current = currentStateOrNull() ?: return

_uiState.updateSuccess { current ->
if (!current.isNextEnabled) return@updateSuccess current
if (!current.isNextEnabled) return

if (current.flow == ProcedureFlow.Entry) {
val selected = current.existenceSelectedIndex ?: return@updateSuccess current
val nextFlow = if (selected == 1) ProcedureFlow.NoTreat else ProcedureFlow.Treat
val nextStep = if (nextFlow == ProcedureFlow.NoTreat) {
ProcedureStep.Category
} else {
ProcedureStep.RecoverySchedule
}
if (current.flow == ProcedureFlow.Entry) {
val selected = current.existenceSelectedIndex ?: return
val nextFlow = if (selected == 1) ProcedureFlow.NoTreat else ProcedureFlow.Treat
val nextStep = if (nextFlow == ProcedureFlow.NoTreat) {
ProcedureStep.Category
} else {
ProcedureStep.RecoverySchedule
}

return@updateSuccess current.copy(
_uiState.updateSuccess {
it.copy(
flow = nextFlow,
step = nextStep,
selectedWorryId = null,
Expand All @@ -297,60 +302,117 @@ class ProcedureViewModel @Inject constructor(
procedureDowntimeMap = emptyMap()
)
}
return
}

if (current.step == ProcedureStep.Filtering ||
current.step == ProcedureStep.FilteringWithSearch
) {
val nextStep = current.nextStep()
if (current.step == ProcedureStep.Filtering ||
current.step == ProcedureStep.FilteringWithSearch
) {
val nextStep = current.nextStep()

val updatedProcedureItems = current.procedureItems.map { item ->
if (item.id in current.selectedProcedureCardIds) {
item.copy(displayMode = ProcedureCardDisplayMode.Selectable)
} else {
item
}
}.toImmutableList()
val updatedProcedureItems = current.procedureItems.map { item ->
if (item.id in current.selectedProcedureCardIds) {
item.copy(displayMode = ProcedureCardDisplayMode.Selectable)
} else {
item.copy(displayMode = ProcedureCardDisplayMode.Basic)
}
}.toImmutableList()

val updatedSelectedItems = current.selectedProcedureItems.map { item ->
if (item.id in current.selectedProcedureCardIds) {
item.copy(displayMode = ProcedureCardDisplayMode.Selectable)
} else {
item
}
}.toImmutableList()
val updatedSelectedItems = current.selectedProcedureItems.map { item ->
if (item.id in current.selectedProcedureCardIds) {
item.copy(displayMode = ProcedureCardDisplayMode.Selectable)
} else {
item.copy(displayMode = ProcedureCardDisplayMode.Basic)
}
}.toImmutableList()

return@updateSuccess current.copy(
_uiState.updateSuccess {
it.copy(
step = nextStep,
procedureItems = updatedProcedureItems,
selectedProcedureItems = updatedSelectedItems
)
}
return
}

val nextStep = current.nextStep()
val nextStep = current.nextStep()

if (current.flow == ProcedureFlow.NoTreat &&
current.step == ProcedureStep.RecoverySchedule
) {
queryToFetch = ProceduresQuery(
if (current.flow == ProcedureFlow.NoTreat &&
current.step == ProcedureStep.RecoverySchedule
) {
_uiState.update { UiState.Loading }

viewModelScope.launch {
procedureRepository.getProcedures(
keyword = null,
worryId = current.selectedWorryId
)
).onSuccess { response ->
val items = response.procedures
.map { it.toUiModel() }
.toPersistentList()

_uiState.update {
UiState.Success(
current.copy(
step = nextStep,
procedureItems = items
)
)
}
}.onLogFailure {
_uiState.update { UiState.Success(current) }
}
}
return
}

if (current.flow == ProcedureFlow.Treat &&
current.step == ProcedureStep.RecoverySchedule
) {
_uiState.update { UiState.Loading }

if (current.flow == ProcedureFlow.Treat &&
current.step == ProcedureStep.RecoverySchedule
) {
viewModelScope.launch {
val keyword = current.searchQuery.trim().takeIf { it.isNotEmpty() }
queryToFetch = ProceduresQuery(
procedureRepository.getProcedures(
keyword = keyword,
worryId = null
)
}
).onSuccess { response ->
val normalizedKeyword = keyword?.trim().takeIf { !it.isNullOrEmpty() }
val filteredProcedures = if (normalizedKeyword == null) {
response.procedures
} else {
response.procedures.filter { procedure ->
procedure.name.contains(normalizedKeyword, ignoreCase = true) ||
(
procedure.category?.contains(
normalizedKeyword,
ignoreCase = true
) == true
)
}
}

current.copy(step = nextStep)
val items = filteredProcedures
.map { it.toUiModel() }
.toPersistentList()

_uiState.update {
UiState.Success(
current.copy(
step = nextStep,
procedureItems = items
)
)
}
}.onLogFailure {
_uiState.update { UiState.Success(current) }
}
}
return
}

queryToFetch?.let { fetchProcedures(keyword = it.keyword, worryId = it.worryId) }
_uiState.updateSuccess { it.copy(step = nextStep) }
}

fun onBackClick() {
Expand Down Expand Up @@ -499,11 +561,6 @@ class ProcedureViewModel @Inject constructor(
}
}

private data class ProceduresQuery(
val keyword: String?,
val worryId: Long?
)

private fun ProcedureModel.toUiModel(): ProcedureCardItemUiModel =
ProcedureCardItemUiModel(
id = this.id,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
package com.cherrish.android.presentation.main

import androidx.activity.compose.BackHandler
import androidx.activity.compose.LocalActivity
import androidx.compose.animation.EnterTransition
import androidx.compose.animation.ExitTransition
import androidx.compose.material3.Scaffold
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableLongStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.navigation.compose.NavHost
import com.cherrish.android.data.repository.ChallengeMissionProgressRepository
Expand All @@ -31,6 +36,8 @@ fun MainScreen(
val currentTab by appState.currentTab.collectAsStateWithLifecycle()
val coroutineScope = rememberCoroutineScope()

HandleBackPressToExit()

CompositionLocalProvider(LocalCalendarEventBus provides appState.calendarEventBus) {
Scaffold(
bottomBar = {
Expand Down Expand Up @@ -115,3 +122,19 @@ fun MainScreen(
}
}
}

@Composable
private fun HandleBackPressToExit(
enabled: Boolean = true,
backPressInterval: Long = 2000L
) {
val context = LocalActivity.current
var backPressedTime by remember { mutableLongStateOf(0L) }

BackHandler(enabled = enabled) {
if (System.currentTimeMillis() - backPressedTime <= backPressInterval) {
context?.finish()
}
backPressedTime = System.currentTimeMillis()
}
}