Handle network errors gracefully during contacts refresh on new message and new call screens.

This commit is contained in:
jeffrey-signal
2025-11-26 10:26:45 -05:00
parent 38bc2b950f
commit 8e2f2b8d1a
4 changed files with 66 additions and 6 deletions

View File

@@ -231,6 +231,13 @@ private fun UserMessagesHost(
)
onDismiss(userMessage)
}
is UserMessage.ContactsRefreshFailed -> LaunchedEffect(userMessage) {
snackbarHostState.showSnackbar(
message = context.getString(R.string.ContactSelectionListFragment_error_retrieving_contacts_check_your_network_connection)
)
onDismiss(userMessage)
}
}
}

View File

@@ -25,6 +25,7 @@ import org.thoughtcrime.securesms.recipients.Recipient
import org.thoughtcrime.securesms.recipients.RecipientId
import org.thoughtcrime.securesms.recipients.RecipientRepository
import org.thoughtcrime.securesms.recipients.ui.RecipientSelection
import org.whispersystems.signalservice.api.NetworkResult
class NewCallViewModel : ViewModel() {
companion object {
@@ -115,12 +116,33 @@ class NewCallViewModel : ViewModel() {
viewModelScope.launch {
internalUiState.update { it.copy(isRefreshingContacts = true) }
withContext(Dispatchers.IO) {
val result = withContext(Dispatchers.IO) {
NetworkResult.fromFetch {
ContactDiscovery.refreshAll(AppDependencies.application, true)
}
}
when (result) {
is NetworkResult.Success -> {
internalUiState.update { it.copy(isRefreshingContacts = false) }
}
is NetworkResult.NetworkError, is NetworkResult.StatusCodeError -> {
Log.w(TAG, "Encountered network error while refreshing contacts.", result.getCause())
internalUiState.update {
it.copy(
isRefreshingContacts = false,
userMessage = UserMessage.ContactsRefreshFailed
)
}
}
is NetworkResult.ApplicationError -> {
Log.e(TAG, "Encountered unexpected error while refreshing contacts.", result.throwable)
throw result.throwable
}
}
}
}
fun clearUserMessage() {
@@ -139,6 +161,7 @@ data class NewCallUiState(
sealed interface UserMessage {
data object UserAlreadyInAnotherCall : UserMessage
data class RecipientLookupFailed(val failure: RecipientRepository.LookupResult.Failure) : UserMessage
data object ContactsRefreshFailed : UserMessage
}
sealed interface CallType {

View File

@@ -364,6 +364,13 @@ private fun UserMessagesHost(
onDismiss(userMessage)
}
is UserMessage.Info.ContactsRefreshFailed -> LaunchedEffect(userMessage) {
snackbarHostState.showSnackbar(
message = context.getString(R.string.ContactSelectionListFragment_error_retrieving_contacts_check_your_network_connection)
)
onDismiss(userMessage)
}
is UserMessage.Prompt.ConfirmRemoveRecipient -> Dialogs.SimpleAlertDialog(
title = stringResource(R.string.NewConversationActivity__remove_s, userMessage.recipient.getShortDisplayName(context)),
body = stringResource(R.string.NewConversationActivity__you_wont_see_this_person),

View File

@@ -27,6 +27,7 @@ import org.thoughtcrime.securesms.recipients.Recipient
import org.thoughtcrime.securesms.recipients.RecipientId
import org.thoughtcrime.securesms.recipients.RecipientRepository
import org.thoughtcrime.securesms.recipients.ui.RecipientSelection
import org.whispersystems.signalservice.api.NetworkResult
class NewConversationViewModel : ViewModel() {
companion object {
@@ -143,12 +144,33 @@ class NewConversationViewModel : ViewModel() {
viewModelScope.launch {
internalUiState.update { it.copy(isRefreshingContacts = true) }
withContext(Dispatchers.IO) {
val result = withContext(Dispatchers.IO) {
NetworkResult.fromFetch {
ContactDiscovery.refreshAll(AppDependencies.application, true)
}
}
when (result) {
is NetworkResult.Success -> {
internalUiState.update { it.copy(isRefreshingContacts = false) }
}
is NetworkResult.NetworkError, is NetworkResult.StatusCodeError -> {
Log.w(TAG, "Encountered network error while refreshing contacts.", result.getCause())
internalUiState.update {
it.copy(
isRefreshingContacts = false,
userMessage = Info.ContactsRefreshFailed
)
}
}
is NetworkResult.ApplicationError -> {
Log.e(TAG, "Encountered unexpected error while refreshing contacts.", result.throwable)
throw result.throwable
}
}
}
}
fun clearUserMessage() {
@@ -171,6 +193,7 @@ data class NewConversationUiState(
data class RecipientBlocked(val recipient: Recipient) : Info
data class RecipientLookupFailed(val failure: RecipientRepository.LookupResult.Failure) : Info
data object UserAlreadyInAnotherCall : Info
data object ContactsRefreshFailed : Info
}
sealed interface Prompt : UserMessage {