Skip to content

Commit

Permalink
feat: Custom server no network dialog #WPB-11627 (#3543)
Browse files Browse the repository at this point in the history
  • Loading branch information
m-zagorski authored Dec 16, 2024
1 parent d37cf33 commit a9a85be
Show file tree
Hide file tree
Showing 8 changed files with 63 additions and 49 deletions.
18 changes: 8 additions & 10 deletions app/src/main/kotlin/com/wire/android/ui/WireActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -517,16 +517,14 @@ class WireActivity : AppCompatActivity() {
)
CustomBackendDialog(
viewModel.globalAppState,
viewModel::dismissCustomBackendDialog
) {
viewModel.customBackendDialogProceedButtonClicked {
navigate(
NavigationCommand(
WelcomeScreenDestination
)
)
}
}
viewModel::dismissCustomBackendDialog,
onConfirm = {
viewModel.customBackendDialogProceedButtonClicked {
navigate(NavigationCommand(WelcomeScreenDestination))
}
},
onTryAgain = viewModel::onCustomServerConfig
)
MaxAccountDialog(
shouldShow = viewModel.globalAppState.maxAccountDialog,
onConfirm = {
Expand Down
13 changes: 8 additions & 5 deletions app/src/main/kotlin/com/wire/android/ui/WireActivityDialogs.kt
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,8 @@ import com.wire.android.ui.common.button.WireButtonState
import com.wire.android.ui.common.button.WireSecondaryButton
import com.wire.android.ui.common.dialogs.CustomServerDetailsDialog
import com.wire.android.ui.common.dialogs.CustomServerDetailsDialogState
import com.wire.android.ui.common.dialogs.CustomServerInvalidJsonDialog
import com.wire.android.ui.common.dialogs.CustomServerInvalidJsonDialogState
import com.wire.android.ui.common.dialogs.CustomServerNoNetworkDialog
import com.wire.android.ui.common.dialogs.CustomServerNoNetworkDialogState
import com.wire.android.ui.common.dialogs.MaxAccountAllowedDialogContent
import com.wire.android.ui.common.dimensions
import com.wire.android.ui.common.wireDialogPropertiesBuilder
Expand Down Expand Up @@ -244,7 +244,8 @@ fun JoinConversationDialog(
fun CustomBackendDialog(
globalAppState: GlobalAppState,
onDismiss: () -> Unit,
onConfirm: () -> Unit
onConfirm: () -> Unit,
onTryAgain: (String) -> Unit
) {
when (globalAppState.customBackendDialog) {
is CustomServerDetailsDialogState -> {
Expand All @@ -255,8 +256,9 @@ fun CustomBackendDialog(
)
}

is CustomServerInvalidJsonDialogState -> {
CustomServerInvalidJsonDialog(
is CustomServerNoNetworkDialogState -> {
CustomServerNoNetworkDialog(
onTryAgain = { onTryAgain(globalAppState.customBackendDialog.customServerUrl) },
onDismiss = onDismiss
)
}
Expand Down Expand Up @@ -581,6 +583,7 @@ fun PreviewCustomBackendDialog() {
)
),
{},
{},
{}
)
}
Expand Down
21 changes: 12 additions & 9 deletions app/src/main/kotlin/com/wire/android/ui/WireActivityViewModel.kt
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ import com.wire.android.services.ServicesManager
import com.wire.android.ui.authentication.devices.model.displayName
import com.wire.android.ui.common.dialogs.CustomServerDetailsDialogState
import com.wire.android.ui.common.dialogs.CustomServerDialogState
import com.wire.android.ui.common.dialogs.CustomServerInvalidJsonDialogState
import com.wire.android.ui.common.dialogs.CustomServerNoNetworkDialogState
import com.wire.android.ui.joinConversation.JoinConversationViaCodeState
import com.wire.android.ui.theme.ThemeOption
import com.wire.android.util.CurrentScreen
Expand Down Expand Up @@ -320,7 +320,7 @@ class WireActivityViewModel @Inject constructor(
when (val result = deepLinkProcessor.get().invoke(intent?.data, isSharingIntent)) {
DeepLinkResult.AuthorizationNeeded -> onAuthorizationNeeded()
is DeepLinkResult.SSOLogin -> onSSOLogin(result)
is DeepLinkResult.CustomServerConfig -> onCustomServerConfig(result)
is DeepLinkResult.CustomServerConfig -> onCustomServerConfig(result.url)
is DeepLinkResult.Failure.OngoingCall -> onCannotLoginDuringACall()
is DeepLinkResult.Failure.Unknown -> appLogger.e("unknown deeplink failure")
is DeepLinkResult.JoinConversation -> onConversationInviteDeepLink(
Expand Down Expand Up @@ -429,13 +429,16 @@ class WireActivityViewModel @Inject constructor(
}
}

private suspend fun onCustomServerConfig(result: DeepLinkResult.CustomServerConfig) {
val customBackendDialogData = loadServerConfig(result.url)?.let { serverLinks ->
CustomServerDetailsDialogState(serverLinks = serverLinks)
} ?: CustomServerInvalidJsonDialogState
globalAppState = globalAppState.copy(
customBackendDialog = customBackendDialogData
)
fun onCustomServerConfig(customServerUrl: String) {
viewModelScope.launch(dispatchers.io()) {
val customBackendDialogData = loadServerConfig(customServerUrl)
?.let { serverLinks -> CustomServerDetailsDialogState(serverLinks = serverLinks) }
?: CustomServerNoNetworkDialogState(customServerUrl)

globalAppState = globalAppState.copy(
customBackendDialog = customBackendDialogData
)
}
}

private suspend fun onConversationInviteDeepLink(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,29 +28,40 @@ import com.wire.android.ui.theme.WireTheme
import com.wire.android.util.ui.PreviewMultipleThemes

@Composable
internal fun CustomServerInvalidJsonDialog(
internal fun CustomServerNoNetworkDialog(
onTryAgain: () -> Unit,
onDismiss: () -> Unit
) {
WireDialog(
title = stringResource(R.string.custom_backend_invalid_deeplink_data_title),
text = stringResource(R.string.custom_backend_invalid_deeplink_data_body),
title = stringResource(R.string.custom_backend_error_title),
text = stringResource(R.string.custom_backend_error_no_internet_connection_body),
onDismiss = onDismiss,
buttonsHorizontalAlignment = false,
optionButton1Properties = WireDialogButtonProperties(
onClick = onDismiss,
text = stringResource(id = R.string.label_ok),
onClick = {
onTryAgain()
onDismiss()
},
text = stringResource(id = R.string.custom_backend_error_no_internet_connection_try_again),
type = WireDialogButtonType.Primary,
state =
WireButtonState.Default
state = WireButtonState.Default
),
optionButton2Properties = WireDialogButtonProperties(
onClick = onDismiss,
text = stringResource(id = R.string.label_cancel),
type = WireDialogButtonType.Secondary,
state = WireButtonState.Default
)
)
}

data object CustomServerInvalidJsonDialogState : CustomServerDialogState()
data class CustomServerNoNetworkDialogState(val customServerUrl: String) : CustomServerDialogState()

@PreviewMultipleThemes
@Composable
fun PreviewCustomServerInvalidJsonDialog() = WireTheme {
CustomServerInvalidJsonDialog(
onDismiss = { }
fun PreviewCustomServerNoNetworkDialog() = WireTheme {
CustomServerNoNetworkDialog(
onTryAgain = {},
onDismiss = {}
)
}
3 changes: 1 addition & 2 deletions app/src/main/res/values-hu/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1133,8 +1133,7 @@ Ez a beállítás az összes beszélgetésre érvényes ezen az eszközön.</str
<string name="custom_backend_dialog_body_backend_accounts">Fiókok URL:</string>
<string name="custom_backend_dialog_body_backend_website">Honlap URL:</string>
<string name="custom_backend_dialog_body_backend_websocket">Kiszolgáló WSURL:</string>
<string name="custom_backend_invalid_deeplink_data_title">Hiba történt</string>
<string name="custom_backend_invalid_deeplink_data_body">A saját kiszolgálóra történő átirányítás nem volt lehetséges, mivel a JSON fájl érvénytelen beállítást tartalmazott.\n\nLépjen kapcsolatba a rendszergazdával, vagy ellenőrizze a mélylinket, ami ide vezette.</string>
<string name="custom_backend_error_title">Hiba történt</string>
<string name="label_fetching_your_messages">Új üzenetek lekérdezése</string>
<string name="label_text_copied">Szöveg a vágólapra másolva</string>
<string name="label_logs_option_title">Naplók</string>
Expand Down
3 changes: 1 addition & 2 deletions app/src/main/res/values-ru/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1171,8 +1171,7 @@
<string name="custom_backend_dialog_body_backend_accounts">URL аккаунта:</string>
<string name="custom_backend_dialog_body_backend_website">URL веб-сайта:</string>
<string name="custom_backend_dialog_body_backend_websocket">WSURL бэкэнда:</string>
<string name="custom_backend_invalid_deeplink_data_title">Произошла ошибка</string>
<string name="custom_backend_invalid_deeplink_data_body">Перенаправление на локальный бэкэнд было неудачным, поскольку в JSON-файле была неверная конфигурация.\n\nСвяжитесь с администратором или проверьте ссылку, которая привела вас сюда.</string>
<string name="custom_backend_error_title">Произошла ошибка</string>
<string name="label_fetching_your_messages">Получение новых сообщений</string>
<string name="label_text_copied">Текст скопирован в буфер обмена</string>
<string name="label_logs_option_title">Журналы</string>
Expand Down
5 changes: 3 additions & 2 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1183,8 +1183,9 @@ In group conversations, the group admin can overwrite this setting.</string>
<string name="custom_backend_dialog_body_backend_accounts">Accounts URL:</string>
<string name="custom_backend_dialog_body_backend_website">Website URL:</string>
<string name="custom_backend_dialog_body_backend_websocket">Backend WSURL:</string>
<string name="custom_backend_invalid_deeplink_data_title">An error occurred</string>
<string name="custom_backend_invalid_deeplink_data_body">Redirecting to an on-premises backend was not possible, as there was an invalid configuration in the JSON file.\n\nContact your admin or check the deeplink that brought you here.</string>
<string name="custom_backend_error_title">An error occurred</string>
<string name="custom_backend_error_no_internet_connection_body">Redirecting to an on-premises backend was not possible, you don’t seem to be connected to the internet.\n\nEstablish an internet connection and try again.</string>
<string name="custom_backend_error_no_internet_connection_try_again">Try again</string>
<string name="label_fetching_your_messages">Receiving new messages</string>
<string name="label_text_copied">Text copied to clipboard</string>
<string name="label_logs_option_title">Logs</string>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ import com.wire.android.framework.TestUser
import com.wire.android.migration.MigrationManager
import com.wire.android.services.ServicesManager
import com.wire.android.ui.common.dialogs.CustomServerDetailsDialogState
import com.wire.android.ui.common.dialogs.CustomServerInvalidJsonDialogState
import com.wire.android.ui.common.dialogs.CustomServerNoNetworkDialogState
import com.wire.android.ui.common.topappbar.CommonTopAppBarViewModelTest
import com.wire.android.ui.joinConversation.JoinConversationViaCodeState
import com.wire.android.ui.theme.ThemeOption
Expand Down Expand Up @@ -141,39 +141,39 @@ class WireActivityViewModelTest {
}

@Test
fun `given Intent with malformed ServerConfig json, when currentSessions is present, then initialAppState is LOGGED_IN and customBackEndInvalidJson dialog is shown`() =
fun `given intent with correct ServerConfig json, when no network is present, then initialAppState is LOGGED_IN and no network dialog is shown`() =
runTest {
val result = DeepLinkResult.CustomServerConfig("url")
val (arrangement, viewModel) = Arrangement()
.withSomeCurrentSession()
.withDeepLinkResult(result)
.withMalformedServerJson()
.withNoNetworkConnectionWhenGettingServerConfig()
.withNoOngoingCall()
.arrange()

viewModel.handleDeepLink(mockedIntent(), {}, {}, arrangement.onDeepLinkResult, {}, {}, {}, {})

assertEquals(InitialAppState.LOGGED_IN, viewModel.initialAppState())
verify(exactly = 0) { arrangement.onDeepLinkResult(any()) }
assertInstanceOf(CustomServerInvalidJsonDialogState::class.java, viewModel.globalAppState.customBackendDialog)
assertInstanceOf(CustomServerNoNetworkDialogState::class.java, viewModel.globalAppState.customBackendDialog)
}

@Test
fun `given Intent with malformed ServerConfig json, when currentSessions is present, then initialAppState is NOT_LOGGED_IN and customBackEndInvalidJson dialog is shown`() =
fun `given Intent with malformed ServerConfig json, when currentSessions is absent, then initialAppState is NOT_LOGGED_IN and no network dialog is shown`() =
runTest {
val result = DeepLinkResult.CustomServerConfig("url")
val (arrangement, viewModel) = Arrangement()
.withNoCurrentSession()
.withDeepLinkResult(result)
.withMalformedServerJson()
.withNoNetworkConnectionWhenGettingServerConfig()
.withNoOngoingCall()
.arrange()

viewModel.handleDeepLink(mockedIntent(), {}, {}, arrangement.onDeepLinkResult, {}, {}, {}, {})

assertEquals(InitialAppState.NOT_LOGGED_IN, viewModel.initialAppState())
verify(exactly = 0) { arrangement.onDeepLinkResult(any()) }
assertInstanceOf(CustomServerInvalidJsonDialogState::class.java, viewModel.globalAppState.customBackendDialog)
assertInstanceOf(CustomServerNoNetworkDialogState::class.java, viewModel.globalAppState.customBackendDialog)
}

@Test
Expand Down Expand Up @@ -919,7 +919,7 @@ class WireActivityViewModelTest {
coEvery { coreLogic.getSessionScope(TEST_ACCOUNT_INFO.userId).observeIfE2EIRequiredDuringLogin() } returns flowOf(false)
}

fun withMalformedServerJson() = apply {
fun withNoNetworkConnectionWhenGettingServerConfig() = apply {
coEvery { getServerConfigUseCase(any()) } returns
GetServerConfigResult.Failure.Generic(NetworkFailure.NoNetworkConnection(null))
}
Expand Down

0 comments on commit a9a85be

Please sign in to comment.