From 1e9decf1f9dba35fddd68a74cd844d291138070d Mon Sep 17 00:00:00 2001 From: hue Date: Tue, 22 Oct 2024 18:36:27 -0400 Subject: [PATCH] Decouple loading state when inviting teammate --- .../repository/AppDataManagementRepository.kt | 4 +- .../selectincident/SelectIncidentDialog.kt | 54 ++++++++++++------- feature/organizationmanage/build.gradle.kts | 1 + .../InviteTeammateViewModel.kt | 19 +++++-- .../ui/InviteTeammateScreen.kt | 10 +++- 5 files changed, 61 insertions(+), 27 deletions(-) diff --git a/core/data/src/main/java/com/crisiscleanup/core/data/repository/AppDataManagementRepository.kt b/core/data/src/main/java/com/crisiscleanup/core/data/repository/AppDataManagementRepository.kt index bd19b67d..2bff7aee 100644 --- a/core/data/src/main/java/com/crisiscleanup/core/data/repository/AppDataManagementRepository.kt +++ b/core/data/src/main/java/com/crisiscleanup/core/data/repository/AppDataManagementRepository.kt @@ -153,6 +153,6 @@ class CrisisCleanupDataManagementRepository @Inject constructor( } private fun isAppDataCleared() = incidentsRepository.incidentCount == 0L && - worksiteChangeRepository.worksiteChangeCount == 0L && - worksiteSyncStatDao.getWorksiteSyncStatCount() == 0L + worksiteChangeRepository.worksiteChangeCount == 0L && + worksiteSyncStatDao.getWorksiteSyncStatCount() == 0L } diff --git a/core/selectincident/src/main/java/com/crisiscleanup/core/selectincident/SelectIncidentDialog.kt b/core/selectincident/src/main/java/com/crisiscleanup/core/selectincident/SelectIncidentDialog.kt index 13a4f27d..9a966fbe 100644 --- a/core/selectincident/src/main/java/com/crisiscleanup/core/selectincident/SelectIncidentDialog.kt +++ b/core/selectincident/src/main/java/com/crisiscleanup/core/selectincident/SelectIncidentDialog.kt @@ -111,29 +111,14 @@ fun SelectIncidentDialog( } else -> { - Column( + RefreshIncidentsView( + isLoadingIncidents, + onRefreshIncidents, // TODO Common dimensions Modifier.sizeIn(maxWidth = 300.dp) .then(listItemModifier), - verticalArrangement = Arrangement.spacedBy( - padding, - alignment = Alignment.CenterVertically, - ), - ) { - Text( - t("info.no_incidents_to_select"), - style = LocalFontStyles.current.header3, - ) - - Text(t("info.incident_load_error")) - - CrisisCleanupTextButton( - Modifier.align(Alignment.End), - enabled = !isLoadingIncidents, - text = t("actions.retry"), - onClick = onRefreshIncidents, - ) - } + padding, + ) } } } @@ -228,3 +213,32 @@ private fun ColumnScope.IncidentSelectContent( ) } } + +@Composable +fun RefreshIncidentsView( + isLoadingIncidents: Boolean, + onRefreshIncidents: () -> Unit, + modifier: Modifier = Modifier, + padding: Dp = 16.dp, +) { + val t = LocalAppTranslator.current + + Column( + modifier, + verticalArrangement = Arrangement.spacedBy(padding, Alignment.CenterVertically), + ) { + Text( + t("info.no_incidents_to_select"), + style = LocalFontStyles.current.header3, + ) + + Text(t("info.incident_load_error")) + + CrisisCleanupTextButton( + Modifier.align(Alignment.End), + enabled = !isLoadingIncidents, + text = t("actions.retry"), + onClick = onRefreshIncidents, + ) + } +} diff --git a/feature/organizationmanage/build.gradle.kts b/feature/organizationmanage/build.gradle.kts index efbdfb03..12ba9eba 100644 --- a/feature/organizationmanage/build.gradle.kts +++ b/feature/organizationmanage/build.gradle.kts @@ -12,4 +12,5 @@ dependencies { implementation(projects.core.data) implementation(projects.core.designsystem) implementation(projects.core.domain) + implementation(projects.core.selectincident) } \ No newline at end of file diff --git a/feature/organizationmanage/src/main/java/com/crisiscleanup/feature/organizationmanage/InviteTeammateViewModel.kt b/feature/organizationmanage/src/main/java/com/crisiscleanup/feature/organizationmanage/InviteTeammateViewModel.kt index 10da1193..4b3fabfd 100644 --- a/feature/organizationmanage/src/main/java/com/crisiscleanup/feature/organizationmanage/InviteTeammateViewModel.kt +++ b/feature/organizationmanage/src/main/java/com/crisiscleanup/feature/organizationmanage/InviteTeammateViewModel.kt @@ -17,6 +17,7 @@ import com.crisiscleanup.core.common.log.CrisisCleanupLoggers.Onboarding import com.crisiscleanup.core.common.log.Logger import com.crisiscleanup.core.common.network.CrisisCleanupDispatchers.IO import com.crisiscleanup.core.common.network.Dispatcher +import com.crisiscleanup.core.common.sync.SyncPuller import com.crisiscleanup.core.common.throttleLatest import com.crisiscleanup.core.data.IncidentSelectManager import com.crisiscleanup.core.data.IncidentSelector @@ -65,6 +66,7 @@ class InviteTeammateViewModel @Inject constructor( private val inputValidator: InputValidator, qrCodeGenerator: QrCodeGenerator, incidentSelectManager: IncidentSelectManager, + private val syncPuller: SyncPuller, private val translator: KeyResourceTranslator, @Dispatcher(IO) private val ioDispatcher: CoroutineDispatcher, @Logger(Onboarding) private val logger: AppLogger, @@ -353,14 +355,19 @@ class InviteTeammateViewModel @Inject constructor( val sendInviteErrorMessage = MutableStateFlow("") + val isLoadingIncidents = incidentsRepository.isLoading + .stateIn( + scope = viewModelScope, + initialValue = false, + started = SharingStarted.WhileSubscribed(), + ) val isLoading = combine( isValidatingAccount, affiliateOrganizationIds, - incidentsData, - ::Triple, + ::Pair, ) - .map { (b0, affiliateIds, incidents) -> - b0 || affiliateIds == null || incidents is IncidentsData.Loading + .map { (b0, affiliateIds) -> + b0 || affiliateIds == null } .stateIn( scope = viewModelScope, @@ -515,6 +522,10 @@ class InviteTeammateViewModel @Inject constructor( return "$inviteUrl?org-id=${invite.orgId}&user-id=$userId&invite-token=${invite.token}" } + fun refreshIncidents() { + syncPuller.appPull(true, cancelOngoing = false) + } + fun onSelectOrganization(organization: OrganizationIdName) { selectedOtherOrg.value = organization organizationNameQuery.value = organization.name diff --git a/feature/organizationmanage/src/main/java/com/crisiscleanup/feature/organizationmanage/ui/InviteTeammateScreen.kt b/feature/organizationmanage/src/main/java/com/crisiscleanup/feature/organizationmanage/ui/InviteTeammateScreen.kt index cbffd542..f5677a52 100644 --- a/feature/organizationmanage/src/main/java/com/crisiscleanup/feature/organizationmanage/ui/InviteTeammateScreen.kt +++ b/feature/organizationmanage/src/main/java/com/crisiscleanup/feature/organizationmanage/ui/InviteTeammateScreen.kt @@ -72,6 +72,7 @@ import com.crisiscleanup.core.designsystem.theme.primaryBlueColor import com.crisiscleanup.core.model.data.EmptyIncident import com.crisiscleanup.core.model.data.Incident import com.crisiscleanup.core.model.data.OrganizationIdName +import com.crisiscleanup.core.selectincident.RefreshIncidentsView import com.crisiscleanup.core.ui.rememberCloseKeyboard import com.crisiscleanup.core.ui.scrollFlingListener import com.crisiscleanup.feature.organizationmanage.InviteOrgState @@ -487,8 +488,8 @@ private fun DropdownOrganizationItems( @Composable private fun NewOrganizationInput( isEditable: Boolean, - viewModel: InviteTeammateViewModel = hiltViewModel(), onEndOfInput: () -> Unit = {}, + viewModel: InviteTeammateViewModel = hiltViewModel(), ) { val t = LocalAppTranslator.current @@ -580,6 +581,13 @@ private fun NewOrganizationInput( } } } + } else { + val isLoadingIncidents by viewModel.isLoadingIncidents.collectAsStateWithLifecycle() + RefreshIncidentsView( + isLoadingIncidents, + viewModel::refreshIncidents, + listItemModifier, + ) } }