Skip to content

Commit

Permalink
UI: Refactor SavedTripsScreen with LaunchedEffect and add LoadSavedTr…
Browse files Browse the repository at this point in the history
…ips event (#260)

### TL;DR

Added a LoadSavedTrips event and improved the SavedTrips screen initialization.

### What changed?

- Added a new `LoadSavedTrips` event to `SavedTripUiEvent` sealed interface.
- Replaced the `isActive` state flow in `SavedTripsViewModel` with a direct call to `loadSavedTrips()` using `LaunchedEffect` in `SavedTripsDestination`.
- Removed the `ANR_TIMEOUT` constant and related code from `SavedTripsViewModel`.
- Added a spacer at the bottom of the `TimeTableScreen` to improve layout.

### Why make this change?

This change simplifies the initialization process for the SavedTrips screen by using a more direct approach to load saved trips. It removes unnecessary complexity related to the `isActive` state flow and improves the overall user experience by ensuring saved trips are loaded immediately upon screen entry. The added spacer in the TimeTable screen enhances the layout and prevents content from being obscured by system bars or other UI elements.


https://github.com/user-attachments/assets/c664863c-3096-446e-87fe-28a7e2c5a066
  • Loading branch information
ksharma-xyz authored Oct 26, 2024
1 parent 34adc73 commit 949ae6f
Show file tree
Hide file tree
Showing 4 changed files with 17 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package xyz.ksharma.krail.trip.planner.ui.state.savedtrip
import xyz.ksharma.krail.trip.planner.ui.state.timetable.Trip

sealed interface SavedTripUiEvent {
data object LoadSavedTrips : SavedTripUiEvent
data class SavedTripClicked(val trip: Trip) : SavedTripUiEvent
data class DeleteSavedTrip(val trip: Trip) : SavedTripUiEvent
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import xyz.ksharma.krail.trip.planner.ui.navigation.SavedTripsRoute
import xyz.ksharma.krail.trip.planner.ui.navigation.SearchStopFieldType
import xyz.ksharma.krail.trip.planner.ui.navigation.SearchStopRoute
import xyz.ksharma.krail.trip.planner.ui.navigation.TimeTableRoute
import xyz.ksharma.krail.trip.planner.ui.state.savedtrip.SavedTripUiEvent
import xyz.ksharma.krail.trip.planner.ui.state.searchstop.model.StopItem
import xyz.ksharma.krail.trip.planner.ui.state.searchstop.model.StopItem.Companion.fromJsonString

Expand All @@ -29,8 +30,9 @@ internal fun NavGraphBuilder.savedTripsDestination(navController: NavHostControl
val toArg: String? =
backStackEntry.savedStateHandle.get<String>(SearchStopFieldType.TO.key)

// Subscribe to the isActive state flow to Load Trips only once at the start.
val isActive by viewModel.isActive.collectAsStateWithLifecycle()
LaunchedEffect(Unit) {
viewModel.onEvent(SavedTripUiEvent.LoadSavedTrips)
}

// Cannot use 'rememberSaveable' here because StopItem is not Parcelable.
// But it's saved in backStackEntry.savedStateHandle as json, so it's able to
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,7 @@ import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.collections.immutable.toImmutableList
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.onStart
import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
import timber.log.Timber
Expand All @@ -21,7 +18,6 @@ import xyz.ksharma.krail.trip.planner.ui.state.savedtrip.SavedTripUiEvent
import xyz.ksharma.krail.trip.planner.ui.state.savedtrip.SavedTripsState
import xyz.ksharma.krail.trip.planner.ui.state.timetable.Trip
import javax.inject.Inject
import kotlin.time.Duration.Companion.seconds

@HiltViewModel
class SavedTripsViewModel @Inject constructor(
Expand All @@ -34,15 +30,6 @@ class SavedTripsViewModel @Inject constructor(
private val _uiState: MutableStateFlow<SavedTripsState> = MutableStateFlow(SavedTripsState())
val uiState: StateFlow<SavedTripsState> = _uiState

private val _isActive: MutableStateFlow<Boolean> = MutableStateFlow(false)
val isActive: StateFlow<Boolean> = _isActive.onStart {
loadSavedTrips()
}.stateIn(
scope = viewModelScope,
started = SharingStarted.WhileSubscribed(ANR_TIMEOUT.inWholeMilliseconds),
initialValue = true,
)

private fun loadSavedTrips() {
viewModelScope.launch(context = ioDispatcher) {
val trips = sandook.keys().mapNotNull { key ->
Expand All @@ -61,6 +48,7 @@ class SavedTripsViewModel @Inject constructor(
when (event) {
is SavedTripUiEvent.DeleteSavedTrip -> onDeleteSavedTrip(event.trip)
is SavedTripUiEvent.SavedTripClicked -> onSavedTripClicked(event.trip)
SavedTripUiEvent.LoadSavedTrips -> loadSavedTrips()
}
}

Expand All @@ -79,8 +67,4 @@ class SavedTripsViewModel @Inject constructor(
private fun updateUiState(block: SavedTripsState.() -> SavedTripsState) {
_uiState.update(block)
}

companion object {
private val ANR_TIMEOUT = 5.seconds
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,11 @@ import androidx.compose.animation.animateContentSize
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.systemBarsPadding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.runtime.Composable
Expand Down Expand Up @@ -91,6 +94,14 @@ fun TimeTableScreen(
Text("No data found")
}
}

item {
Spacer(
modifier = Modifier
.height(96.dp)
.systemBarsPadding(),
)
}
}
}

Expand Down

0 comments on commit 949ae6f

Please sign in to comment.