fix: refresh drawer after failed load and use rtl-safe drawer close

This commit is contained in:
2026-03-18 09:30:45 -04:00
parent eeffb3de49
commit 3188fc472a
3 changed files with 36 additions and 3 deletions

View File

@@ -2,7 +2,6 @@ package space.hackenslacker.kanbn4droid.app
import android.content.Intent import android.content.Intent
import android.os.Bundle import android.os.Bundle
import android.view.Gravity
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.widget.ArrayAdapter import android.widget.ArrayAdapter
@@ -249,7 +248,7 @@ class BoardsActivity : AppCompatActivity() {
selectedWorkspace == state.drawer.activeWorkspaceId && selectedWorkspace == state.drawer.activeWorkspaceId &&
state.drawer.errorCode == DrawerDataErrorCode.NONE state.drawer.errorCode == DrawerDataErrorCode.NONE
) { ) {
drawerLayout.closeDrawer(Gravity.START) drawerLayout.closeDrawer(GravityCompat.START)
} }
pendingWorkspaceSelectionId = null pendingWorkspaceSelectionId = null
} }

View File

@@ -39,6 +39,7 @@ class BoardsViewModel(
val events: SharedFlow<BoardsUiEvent> = _events.asSharedFlow() val events: SharedFlow<BoardsUiEvent> = _events.asSharedFlow()
private var lastDrawerLoadAtMillis: Long? = null private var lastDrawerLoadAtMillis: Long? = null
private var hadDrawerLoadFailureSinceLastSuccess: Boolean = false
fun loadBoards() { fun loadBoards() {
fetchBoards(initial = true) fetchBoards(initial = true)
@@ -49,6 +50,10 @@ class BoardsViewModel(
} }
fun loadDrawerDataIfStale() { fun loadDrawerDataIfStale() {
if (hadDrawerLoadFailureSinceLastSuccess) {
fetchDrawerData()
return
}
val now = nowProvider() val now = nowProvider()
val isStale = lastDrawerLoadAtMillis?.let { now - it >= DRAWER_STALE_MS } ?: true val isStale = lastDrawerLoadAtMillis?.let { now - it >= DRAWER_STALE_MS } ?: true
if (!isStale) { if (!isStale) {
@@ -258,7 +263,12 @@ class BoardsViewModel(
) )
} }
if (result.errorCode == DrawerDataErrorCode.NONE) {
lastDrawerLoadAtMillis = nowProvider() lastDrawerLoadAtMillis = nowProvider()
hadDrawerLoadFailureSinceLastSuccess = false
} else {
hadDrawerLoadFailureSinceLastSuccess = true
}
if (result.errorCode == DrawerDataErrorCode.UNAUTHORIZED) { if (result.errorCode == DrawerDataErrorCode.UNAUTHORIZED) {
_events.emit(BoardsUiEvent.ForceSignOut) _events.emit(BoardsUiEvent.ForceSignOut)

View File

@@ -302,6 +302,30 @@ class BoardsViewModelTest {
assertEquals(2, api.getCurrentUserCalls) assertEquals(2, api.getCurrentUserCalls)
} }
@Test
fun loadDrawerDataIfStaleRefetchesImmediatelyAfterFailedLoad() = runTest {
val api = FakeBoardsApiClient().apply {
usersMeResults.addLast(BoardsApiResult.Failure("Cannot reach server. Check your connection and URL."))
usersMeResults.addLast(BoardsApiResult.Success(DrawerProfile(displayName = "Alice", email = null)))
workspacesResults.addLast(BoardsApiResult.Failure("Cannot reach server. Check your connection and URL."))
workspacesResults.addLast(BoardsApiResult.Success(listOf(WorkspaceSummary("ws-1", "Main"))))
}
val viewModel = newViewModel(apiClient = api, nowProvider = { 1_000L })
viewModel.loadDrawerData()
advanceUntilIdle()
assertEquals(DrawerDataErrorCode.NETWORK, viewModel.uiState.value.drawer.errorCode)
assertEquals(1, api.listWorkspacesCalls)
assertEquals(1, api.getCurrentUserCalls)
viewModel.loadDrawerDataIfStale()
advanceUntilIdle()
assertEquals(DrawerDataErrorCode.NONE, viewModel.uiState.value.drawer.errorCode)
assertEquals(2, api.listWorkspacesCalls)
assertEquals(2, api.getCurrentUserCalls)
}
@Test @Test
fun loadDrawerDataFallbackWorkspacePersistsFirstAndTriggersBoardsRefresh() = runTest { fun loadDrawerDataFallbackWorkspacePersistsFirstAndTriggersBoardsRefresh() = runTest {
val api = FakeBoardsApiClient().apply { val api = FakeBoardsApiClient().apply {