From 0703993823a00f45467a77b2e77dab02597c9dfc Mon Sep 17 00:00:00 2001 From: Evgenii Kozlov Date: Wed, 7 Aug 2024 17:28:52 +0200 Subject: [PATCH] DROID-2440 Multiplayer | Enhancement | Localize multiplayer errors (#1468) --- .../multiplayer/RequestJoinSpaceFragment.kt | 63 ++++--- .../ui/multiplayer/ShareSpaceFragment.kt | 33 +++- .../multiplayer/SpaceJoinRequestFragment.kt | 21 ++- .../core_models/multiplayer/Multiplayer.kt | 11 +- .../src/main/res/values-be-rBY/strings.xml | 2 +- .../src/main/res/values-de-rDE/strings.xml | 2 +- .../src/main/res/values-es-rES/strings.xml | 2 +- .../src/main/res/values-fr-rFR/strings.xml | 2 +- .../src/main/res/values-in-rID/strings.xml | 2 +- .../src/main/res/values-it-rIT/strings.xml | 2 +- .../src/main/res/values-nl-rNL/strings.xml | 2 +- .../src/main/res/values-no-rNO/strings.xml | 2 +- .../src/main/res/values-pt-rBR/strings.xml | 2 +- .../src/main/res/values-ru-rRU/strings.xml | 2 +- .../src/main/res/values-uk-rUA/strings.xml | 2 +- .../src/main/res/values-zh-rCN/strings.xml | 2 +- .../src/main/res/values-zh-rTW/strings.xml | 2 +- localization/src/main/res/values/strings.xml | 8 +- .../MiddlewareServiceImplementation.kt | 171 ++++++++++++++++-- .../multiplayer/RequestJoinSpaceViewModel.kt | 19 +- .../multiplayer/ShareSpaceViewModel.kt | 42 +++-- .../multiplayer/SpaceJoinRequestViewModel.kt | 14 +- 22 files changed, 321 insertions(+), 87 deletions(-) diff --git a/app/src/main/java/com/anytypeio/anytype/ui/multiplayer/RequestJoinSpaceFragment.kt b/app/src/main/java/com/anytypeio/anytype/ui/multiplayer/RequestJoinSpaceFragment.kt index 01ce2a1dc6..c473f6c97a 100644 --- a/app/src/main/java/com/anytypeio/anytype/ui/multiplayer/RequestJoinSpaceFragment.kt +++ b/app/src/main/java/com/anytypeio/anytype/ui/multiplayer/RequestJoinSpaceFragment.kt @@ -24,6 +24,7 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.anytypeio.anytype.R import com.anytypeio.anytype.core_models.Id import com.anytypeio.anytype.core_models.ext.EMPTY_STRING_VALUE +import com.anytypeio.anytype.core_models.multiplayer.MultiplayerError import com.anytypeio.anytype.core_ui.features.multiplayer.JoinSpaceScreen import com.anytypeio.anytype.core_ui.foundation.AlertConfig import com.anytypeio.anytype.core_ui.foundation.Announcement @@ -153,10 +154,27 @@ class RequestJoinSpaceFragment : BaseBottomSheetComposeFragment() { } ) } + is ErrorView.InviteNotFound -> { + GenericAlert( + config = AlertConfig.WithOneButton( + title = stringResource(R.string.multiplayer_error_invite_not_found), + firstButtonText = stringResource(id = R.string.button_okay), + firstButtonType = BUTTON_SECONDARY, + description = EMPTY_STRING_VALUE, + icon = AlertConfig.Icon( + gradient = GRADIENT_TYPE_BLUE, + icon = R.drawable.ic_alert_message + ) + ), + onFirstButtonClicked = { + dismiss() + } + ) + } is ErrorView.InvalidLink -> { GenericAlert( config = AlertConfig.WithOneButton( - title = stringResource(R.string.multiplayer_invite_link_this_link_does_not_seem_to_work), + title = stringResource(R.string.multiplayer_error_invite_bad_content), firstButtonText = stringResource(id = R.string.button_okay), firstButtonType = BUTTON_SECONDARY, description = EMPTY_STRING_VALUE, @@ -173,24 +191,7 @@ class RequestJoinSpaceFragment : BaseBottomSheetComposeFragment() { is ErrorView.SpaceDeleted -> { GenericAlert( config = AlertConfig.WithOneButton( - title = stringResource(R.string.multiplayer_invite_link_space_deleted), - firstButtonText = stringResource(id = R.string.button_okay), - firstButtonType = BUTTON_SECONDARY, - description = EMPTY_STRING_VALUE, - icon = AlertConfig.Icon( - gradient = GRADIENT_TYPE_BLUE, - icon = R.drawable.ic_alert_message - ) - ), - onFirstButtonClicked = { - dismiss() - } - ) - } - is ErrorView.SpaceNotFound -> { - GenericAlert( - config = AlertConfig.WithOneButton( - title = stringResource(R.string.multiplayer_invite_link_space_not_found), + title = stringResource(R.string.multiplayer_error_space_is_deleted), firstButtonText = stringResource(id = R.string.button_okay), firstButtonType = BUTTON_SECONDARY, description = EMPTY_STRING_VALUE, @@ -239,18 +240,34 @@ class RequestJoinSpaceFragment : BaseBottomSheetComposeFragment() { private fun proceedWithCommand(command: RequestJoinSpaceViewModel.Command) { when (command) { - RequestJoinSpaceViewModel.Command.Dismiss -> { + is RequestJoinSpaceViewModel.Command.Dismiss -> { dismiss() } - RequestJoinSpaceViewModel.Command.Toast.RequestSent -> { + is RequestJoinSpaceViewModel.Command.Toast.RequestSent -> { toast(getString(R.string.multiplayer_request_sent_toast)) } - RequestJoinSpaceViewModel.Command.Toast.SpaceDeleted -> { + is RequestJoinSpaceViewModel.Command.Toast.SpaceDeleted -> { toast(getString(R.string.multiplayer_error_space_deleted)) } - RequestJoinSpaceViewModel.Command.Toast.SpaceNotFound -> { + is RequestJoinSpaceViewModel.Command.Toast.SpaceNotFound -> { toast(getString(R.string.multiplayer_error_space_not_found)) } + is RequestJoinSpaceViewModel.Command.ShowGenericMultiplayerError -> { + when(command.error) { + is MultiplayerError.Generic.LimitReached -> { + toast(resources.getString(R.string.multiplayer_error_limit_reached)) + } + is MultiplayerError.Generic.NotShareable -> { + toast(resources.getString(R.string.multiplayer_error_not_shareable)) + } + is MultiplayerError.Generic.RequestFailed -> { + toast(resources.getString(R.string.multiplayer_error_request_failed)) + } + is MultiplayerError.Generic.SpaceIsDeleted -> { + toast(resources.getString(R.string.multiplayer_error_space_is_deleted)) + } + } + } } } diff --git a/app/src/main/java/com/anytypeio/anytype/ui/multiplayer/ShareSpaceFragment.kt b/app/src/main/java/com/anytypeio/anytype/ui/multiplayer/ShareSpaceFragment.kt index 266a0a27f3..284c52ce0c 100644 --- a/app/src/main/java/com/anytypeio/anytype/ui/multiplayer/ShareSpaceFragment.kt +++ b/app/src/main/java/com/anytypeio/anytype/ui/multiplayer/ShareSpaceFragment.kt @@ -17,6 +17,7 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.navigation.fragment.findNavController import com.anytypeio.anytype.R import com.anytypeio.anytype.analytics.base.EventsDictionary +import com.anytypeio.anytype.core_models.multiplayer.MultiplayerError import com.anytypeio.anytype.core_models.primitives.SpaceId import com.anytypeio.anytype.core_ui.features.multiplayer.ShareSpaceScreen import com.anytypeio.anytype.core_utils.ext.arg @@ -183,11 +184,35 @@ class ShareSpaceFragment : BaseBottomSheetComposeFragment() { val msg = getString(R.string.multiplayer_toast_permission_not_allowed) toast(msg) } - Command.ShowMembershipScreen -> { - findNavController().navigate(R.id.paymentsScreen) + is Command.ShowMembershipScreen -> { + runCatching { + findNavController().navigate(R.id.paymentsScreen) + }.onFailure { + Timber.e(it, "Error while navigation: $command") + } } - Command.ShowMembershipUpgradeScreen -> { - findNavController().navigate(R.id.membershipUpdateScreen) + is Command.ShowMembershipUpgradeScreen -> { + runCatching { + findNavController().navigate(R.id.membershipUpdateScreen) + }.onFailure { + Timber.e(it, "Error while navigation: $command") + } + } + is Command.ShowMultiplayerError -> { + when(command.error) { + is MultiplayerError.Generic.LimitReached -> { + toast(resources.getString(R.string.multiplayer_error_limit_reached)) + } + is MultiplayerError.Generic.NotShareable -> { + toast(resources.getString(R.string.multiplayer_error_not_shareable)) + } + is MultiplayerError.Generic.RequestFailed -> { + toast(resources.getString(R.string.multiplayer_error_request_failed)) + } + is MultiplayerError.Generic.SpaceIsDeleted -> { + toast(resources.getString(R.string.multiplayer_error_space_is_deleted)) + } + } } } } diff --git a/app/src/main/java/com/anytypeio/anytype/ui/multiplayer/SpaceJoinRequestFragment.kt b/app/src/main/java/com/anytypeio/anytype/ui/multiplayer/SpaceJoinRequestFragment.kt index e709f3ea7f..6c8e3673c1 100644 --- a/app/src/main/java/com/anytypeio/anytype/ui/multiplayer/SpaceJoinRequestFragment.kt +++ b/app/src/main/java/com/anytypeio/anytype/ui/multiplayer/SpaceJoinRequestFragment.kt @@ -14,6 +14,7 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.navigation.fragment.findNavController import com.anytypeio.anytype.R import com.anytypeio.anytype.core_models.Id +import com.anytypeio.anytype.core_models.multiplayer.MultiplayerError import com.anytypeio.anytype.core_models.primitives.SpaceId import com.anytypeio.anytype.core_ui.features.multiplayer.SpaceJoinRequestScreen import com.anytypeio.anytype.core_utils.ext.arg @@ -73,12 +74,28 @@ class SpaceJoinRequestFragment : BaseBottomSheetComposeFragment() { private fun proceedWithCommand(command: SpaceJoinRequestViewModel.Command) { Timber.d("proceedWithCommand: $command") when (command) { - SpaceJoinRequestViewModel.Command.NavigateToMembership -> { + is SpaceJoinRequestViewModel.Command.NavigateToMembership -> { findNavController().navigate(R.id.paymentsScreen) } - SpaceJoinRequestViewModel.Command.NavigateToMembershipUpdate -> { + is SpaceJoinRequestViewModel.Command.NavigateToMembershipUpdate -> { findNavController().navigate(R.id.membershipUpdateScreen) } + is SpaceJoinRequestViewModel.Command.ShowGenericMultiplayerError -> { + when(command.error) { + is MultiplayerError.Generic.LimitReached -> { + toast(resources.getString(R.string.multiplayer_error_limit_reached)) + } + is MultiplayerError.Generic.NotShareable -> { + toast(resources.getString(R.string.multiplayer_error_not_shareable)) + } + is MultiplayerError.Generic.RequestFailed -> { + toast(resources.getString(R.string.multiplayer_error_request_failed)) + } + is MultiplayerError.Generic.SpaceIsDeleted -> { + toast(resources.getString(R.string.multiplayer_error_space_is_deleted)) + } + } + } } } diff --git a/core-models/src/main/java/com/anytypeio/anytype/core_models/multiplayer/Multiplayer.kt b/core-models/src/main/java/com/anytypeio/anytype/core_models/multiplayer/Multiplayer.kt index ecd3afb0c2..60a8de41c3 100644 --- a/core-models/src/main/java/com/anytypeio/anytype/core_models/multiplayer/Multiplayer.kt +++ b/core-models/src/main/java/com/anytypeio/anytype/core_models/multiplayer/Multiplayer.kt @@ -55,9 +55,18 @@ enum class SpaceAccessType(val code: Int) { } sealed class SpaceInviteError : Exception() { - class SpaceNotFound : SpaceInviteError() class SpaceDeleted : SpaceInviteError() class InvalidInvite : SpaceInviteError() + class InvalidNotFound : SpaceInviteError() +} + +sealed class MultiplayerError : Exception() { + sealed class Generic : MultiplayerError() { + class NotShareable : Generic() + class SpaceIsDeleted : Generic() + class LimitReached : Generic() + class RequestFailed : Generic() + } } sealed class SpaceSyncUpdate { diff --git a/localization/src/main/res/values-be-rBY/strings.xml b/localization/src/main/res/values-be-rBY/strings.xml index 263b23541c..b75bf57cad 100644 --- a/localization/src/main/res/values-be-rBY/strings.xml +++ b/localization/src/main/res/values-be-rBY/strings.xml @@ -1247,7 +1247,7 @@ Вам трэба будзе зноў адправіць запыт на далучэнне Не адмяняць Здаецца, гэтая спасылка не працуе - Гэтая спасылка з запрашэннем больш не дзейнічае, таму што прастора была выдалена. + Гэтая спасылка з запрашэннем больш не дзейнічае, таму што прастора была выдалена. Гэта спасылка для запрашэння больш не дзейнічае, таму што прастора не знойдзена. Запыт адпраўлены diff --git a/localization/src/main/res/values-de-rDE/strings.xml b/localization/src/main/res/values-de-rDE/strings.xml index 90e2940a3e..1c71c2c4a7 100644 --- a/localization/src/main/res/values-de-rDE/strings.xml +++ b/localization/src/main/res/values-de-rDE/strings.xml @@ -1235,7 +1235,7 @@ Du wirst eine neue Beitrittsanfrage senden müssen Nicht verwerfen Der Link scheint nicht zu funktionieren - Dieser Einladungslink ist nicht mehr gültig, da der Raum gelöscht wurde. + Dieser Einladungslink ist nicht mehr gültig, da der Raum gelöscht wurde. Dieser Einladungslink ist nicht mehr gültig, da der Raum gelöscht wurde. Anfrage gesendet diff --git a/localization/src/main/res/values-es-rES/strings.xml b/localization/src/main/res/values-es-rES/strings.xml index 8918778154..be8b2fb941 100644 --- a/localization/src/main/res/values-es-rES/strings.xml +++ b/localization/src/main/res/values-es-rES/strings.xml @@ -1235,7 +1235,7 @@ Tendrás que volver a solicitar el acceso. No cancelar Este enlace no parece funcionar - Este enlace de invitación ya no es válido porque el espacio se ha eliminado. + Este enlace de invitación ya no es válido porque el espacio se ha eliminado. Este enlace de invitación ya no es válido porque el espacio no se encuentra. Solicitud enviada diff --git a/localization/src/main/res/values-fr-rFR/strings.xml b/localization/src/main/res/values-fr-rFR/strings.xml index a29d270e4e..89606c9427 100644 --- a/localization/src/main/res/values-fr-rFR/strings.xml +++ b/localization/src/main/res/values-fr-rFR/strings.xml @@ -1235,7 +1235,7 @@ Vous devrez envoyer à nouveau la demande d\'accès Ne pas annuler Ce lien ne semble pas fonctionner - Ce lien d\'invitation n\'est plus valide car l\'espace a été supprimé. + Ce lien d\'invitation n\'est plus valide car l\'espace a été supprimé. Ce lien d\'invitation n\'est plus valide car l\'espace n\'a pas été trouvé. Demande envoyée diff --git a/localization/src/main/res/values-in-rID/strings.xml b/localization/src/main/res/values-in-rID/strings.xml index 653917bbd6..0f5322bd79 100644 --- a/localization/src/main/res/values-in-rID/strings.xml +++ b/localization/src/main/res/values-in-rID/strings.xml @@ -1229,7 +1229,7 @@ Kamu akan perlu mengirimkan permintaan bergabung lagi Jangan batalkan Sepertinya tautan ini tidak bisa digunakan - Tautan undangan ini tidak berlaku karena ruangnya telah dihapus. + Tautan undangan ini tidak berlaku karena ruangnya telah dihapus. Tautan undangan ini tidak berlaku karena ruangnya tidak ditemukan. Permintaan terkirim diff --git a/localization/src/main/res/values-it-rIT/strings.xml b/localization/src/main/res/values-it-rIT/strings.xml index 8e7ed6bb62..abdb9c8c0c 100644 --- a/localization/src/main/res/values-it-rIT/strings.xml +++ b/localization/src/main/res/values-it-rIT/strings.xml @@ -1236,7 +1236,7 @@ Dovrai inviare nuovamente la richiesta di partecipazione Non annullare Questo link sembra non funzionare - Questo link di invito non è più valido perché lo spazio è stato eliminato. + Questo link di invito non è più valido perché lo spazio è stato eliminato. Questo link di invito non è più valido perché lo spazio non è stato trovato. Richiesta inviata diff --git a/localization/src/main/res/values-nl-rNL/strings.xml b/localization/src/main/res/values-nl-rNL/strings.xml index ac10be105c..73961d3929 100644 --- a/localization/src/main/res/values-nl-rNL/strings.xml +++ b/localization/src/main/res/values-nl-rNL/strings.xml @@ -1235,7 +1235,7 @@ Je zult het deelnameverzoek opnieuw moeten sturen Annuleer niet Deze koppeling lijkt niet te werken - Deze uitnodigingskoppeling is niet langer geldig omdat de ruimte is verwijderd. + Deze uitnodigingskoppeling is niet langer geldig omdat de ruimte is verwijderd. Deze uitnodigingskoppeling is niet langer geldig omdat de ruimte niet werd gevonden. Verzoek verzonden diff --git a/localization/src/main/res/values-no-rNO/strings.xml b/localization/src/main/res/values-no-rNO/strings.xml index 5aecc12667..62a5dddf12 100644 --- a/localization/src/main/res/values-no-rNO/strings.xml +++ b/localization/src/main/res/values-no-rNO/strings.xml @@ -1235,7 +1235,7 @@ You will have to send join request again Do not cancel This link does not seem to work - This invite link is no longer valid because the space has been deleted. + This invite link is no longer valid because the space has been deleted. This invite link is no longer valid because the space was not found. Forespørsel sendt diff --git a/localization/src/main/res/values-pt-rBR/strings.xml b/localization/src/main/res/values-pt-rBR/strings.xml index 4342ad83e5..82da3678af 100644 --- a/localization/src/main/res/values-pt-rBR/strings.xml +++ b/localization/src/main/res/values-pt-rBR/strings.xml @@ -1235,7 +1235,7 @@ You will have to send join request again Do not cancel This link does not seem to work - This invite link is no longer valid because the space has been deleted. + This invite link is no longer valid because the space has been deleted. This invite link is no longer valid because the space was not found. Solicitação enviada diff --git a/localization/src/main/res/values-ru-rRU/strings.xml b/localization/src/main/res/values-ru-rRU/strings.xml index 9bf70dddc1..e7bf20fff1 100644 --- a/localization/src/main/res/values-ru-rRU/strings.xml +++ b/localization/src/main/res/values-ru-rRU/strings.xml @@ -1247,7 +1247,7 @@ You will have to send join request again Do not cancel This link does not seem to work - This invite link is no longer valid because the space has been deleted. + This invite link is no longer valid because the space has been deleted. This invite link is no longer valid because the space was not found. Запрос отправлен diff --git a/localization/src/main/res/values-uk-rUA/strings.xml b/localization/src/main/res/values-uk-rUA/strings.xml index db031844e7..facb7455b6 100644 --- a/localization/src/main/res/values-uk-rUA/strings.xml +++ b/localization/src/main/res/values-uk-rUA/strings.xml @@ -1247,7 +1247,7 @@ You will have to send join request again Do not cancel This link does not seem to work - This invite link is no longer valid because the space has been deleted. + This invite link is no longer valid because the space has been deleted. This invite link is no longer valid because the space was not found. Request sent diff --git a/localization/src/main/res/values-zh-rCN/strings.xml b/localization/src/main/res/values-zh-rCN/strings.xml index 771a900bad..5c45c176c7 100644 --- a/localization/src/main/res/values-zh-rCN/strings.xml +++ b/localization/src/main/res/values-zh-rCN/strings.xml @@ -1229,7 +1229,7 @@ 您将需要再次发送加入请求 不要取消 这个链接似乎无法工作 - 这个邀请链接不再有效,因为空间已被删除。 + 这个邀请链接不再有效,因为空间已被删除。 这个邀请链接不再有效,因为找不到空间。 已发送申请 diff --git a/localization/src/main/res/values-zh-rTW/strings.xml b/localization/src/main/res/values-zh-rTW/strings.xml index 2110008579..b8d885e652 100644 --- a/localization/src/main/res/values-zh-rTW/strings.xml +++ b/localization/src/main/res/values-zh-rTW/strings.xml @@ -1229,7 +1229,7 @@ 您將需要再次發送加入請求 不要取消 這個連結似乎不起作用 - 此邀請連結不再生效,因為空間已被刪除。 + 此邀請連結不再生效,因為空間已被刪除。 此邀請連結無效,找不到此空間。 已送出請求 diff --git a/localization/src/main/res/values/strings.xml b/localization/src/main/res/values/strings.xml index 8f05812816..f14c0e4e51 100644 --- a/localization/src/main/res/values/strings.xml +++ b/localization/src/main/res/values/strings.xml @@ -1435,8 +1435,14 @@ You will have to send join request again Do not cancel + The invitation does not exist. Please ensure that your devices are synchronized. + The invitation link could not be parsed. It may contain errors in the format or invalid data. + It looks like the space has been deleted. Please ensure that your devices are synchronized. + Limit reached for this space. Please upgrade your membership or contact support for assistance. + It looks like the space is no longer shared. Please ensure that your devices are synchronized. + Oops! The request failed. Please check your Internet connection and try again. + This link does not seem to work - This invite link is no longer valid because the space has been deleted. This invite link is no longer valid because the space was not found. Request sent diff --git a/middleware/src/main/java/com/anytypeio/anytype/middleware/service/MiddlewareServiceImplementation.kt b/middleware/src/main/java/com/anytypeio/anytype/middleware/service/MiddlewareServiceImplementation.kt index 7851aa2c7e..4fdbec050a 100644 --- a/middleware/src/main/java/com/anytypeio/anytype/middleware/service/MiddlewareServiceImplementation.kt +++ b/middleware/src/main/java/com/anytypeio/anytype/middleware/service/MiddlewareServiceImplementation.kt @@ -3,9 +3,8 @@ package com.anytypeio.anytype.middleware.service import anytype.Rpc import com.anytypeio.anytype.core_models.exceptions.AccountIsDeletedException import com.anytypeio.anytype.core_models.exceptions.LoginException -import com.anytypeio.anytype.core_models.exceptions.MigrationNeededException import com.anytypeio.anytype.core_models.exceptions.NeedToUpdateApplicationException -import com.anytypeio.anytype.core_models.exceptions.SpaceLimitReachedException +import com.anytypeio.anytype.core_models.multiplayer.MultiplayerError import com.anytypeio.anytype.core_models.multiplayer.SpaceInviteError import com.anytypeio.anytype.core_utils.tools.FeatureToggles import com.anytypeio.anytype.data.auth.exception.AnytypeNeedsUpgradeException @@ -1791,7 +1790,21 @@ class MiddlewareServiceImplementation @Inject constructor( val response = Rpc.Space.InviteGenerate.Response.ADAPTER.decode(encoded) val error = response.error if (error != null && error.code != Rpc.Space.InviteGenerate.Response.Error.Code.NULL) { - throw Exception(error.description) + when(error.code) { + Rpc.Space.InviteGenerate.Response.Error.Code.NOT_SHAREABLE -> { + throw MultiplayerError.Generic.NotShareable() + } + Rpc.Space.InviteGenerate.Response.Error.Code.SPACE_IS_DELETED -> { + throw MultiplayerError.Generic.SpaceIsDeleted() + } + Rpc.Space.InviteGenerate.Response.Error.Code.LIMIT_REACHED -> { + throw MultiplayerError.Generic.LimitReached() + } + Rpc.Space.InviteGenerate.Response.Error.Code.REQUEST_FAILED -> { + throw MultiplayerError.Generic.RequestFailed() + } + else -> throw Exception(error.description) + } } else { return response } @@ -1817,7 +1830,21 @@ class MiddlewareServiceImplementation @Inject constructor( val response = Rpc.Space.InviteRevoke.Response.ADAPTER.decode(encoded) val error = response.error if (error != null && error.code != Rpc.Space.InviteRevoke.Response.Error.Code.NULL) { - throw Exception(error.description) + when(error.code) { + Rpc.Space.InviteRevoke.Response.Error.Code.NOT_SHAREABLE -> { + throw MultiplayerError.Generic.NotShareable() + } + Rpc.Space.InviteRevoke.Response.Error.Code.SPACE_IS_DELETED -> { + throw MultiplayerError.Generic.SpaceIsDeleted() + } + Rpc.Space.InviteRevoke.Response.Error.Code.LIMIT_REACHED -> { + throw MultiplayerError.Generic.LimitReached() + } + Rpc.Space.InviteRevoke.Response.Error.Code.REQUEST_FAILED -> { + throw MultiplayerError.Generic.RequestFailed() + } + else -> throw Exception(error.description) + } } else { return response } @@ -1830,7 +1857,7 @@ class MiddlewareServiceImplementation @Inject constructor( if (error != null && error.code != Rpc.Space.InviteView.Response.Error.Code.NULL) { when(error.code) { Rpc.Space.InviteView.Response.Error.Code.INVITE_NOT_FOUND -> { - throw SpaceInviteError.InvalidInvite() + throw SpaceInviteError.InvalidNotFound() } Rpc.Space.InviteView.Response.Error.Code.INVITE_BAD_CONTENT -> { throw SpaceInviteError.InvalidInvite() @@ -1852,7 +1879,21 @@ class MiddlewareServiceImplementation @Inject constructor( val response = Rpc.Space.Join.Response.ADAPTER.decode(encoded) val error = response.error if (error != null && error.code != Rpc.Space.Join.Response.Error.Code.NULL) { - throw Exception(error.description) + when(error.code) { + Rpc.Space.Join.Response.Error.Code.NOT_SHAREABLE -> { + throw MultiplayerError.Generic.NotShareable() + } + Rpc.Space.Join.Response.Error.Code.SPACE_IS_DELETED -> { + throw MultiplayerError.Generic.SpaceIsDeleted() + } + Rpc.Space.Join.Response.Error.Code.LIMIT_REACHED -> { + throw MultiplayerError.Generic.LimitReached() + } + Rpc.Space.Join.Response.Error.Code.REQUEST_FAILED -> { + throw MultiplayerError.Generic.RequestFailed() + } + else -> throw Exception(error.description) + } } else { return response } @@ -1863,7 +1904,21 @@ class MiddlewareServiceImplementation @Inject constructor( val response = Rpc.Space.JoinCancel.Response.ADAPTER.decode(encoded) val error = response.error if (error != null && error.code != Rpc.Space.JoinCancel.Response.Error.Code.NULL) { - throw Exception(error.description) + when(error.code) { + Rpc.Space.JoinCancel.Response.Error.Code.NOT_SHAREABLE -> { + throw MultiplayerError.Generic.NotShareable() + } + Rpc.Space.JoinCancel.Response.Error.Code.SPACE_IS_DELETED -> { + throw MultiplayerError.Generic.SpaceIsDeleted() + } + Rpc.Space.JoinCancel.Response.Error.Code.LIMIT_REACHED -> { + throw MultiplayerError.Generic.LimitReached() + } + Rpc.Space.JoinCancel.Response.Error.Code.REQUEST_FAILED -> { + throw MultiplayerError.Generic.RequestFailed() + } + else -> throw Exception(error.description) + } } else { return response } @@ -1874,7 +1929,21 @@ class MiddlewareServiceImplementation @Inject constructor( val response = Rpc.Space.LeaveApprove.Response.ADAPTER.decode(encoded) val error = response.error if (error != null && error.code != Rpc.Space.LeaveApprove.Response.Error.Code.NULL) { - throw Exception(error.description) + when(error.code) { + Rpc.Space.LeaveApprove.Response.Error.Code.NOT_SHAREABLE -> { + throw MultiplayerError.Generic.NotShareable() + } + Rpc.Space.LeaveApprove.Response.Error.Code.SPACE_IS_DELETED -> { + throw MultiplayerError.Generic.SpaceIsDeleted() + } + Rpc.Space.LeaveApprove.Response.Error.Code.LIMIT_REACHED -> { + throw MultiplayerError.Generic.LimitReached() + } + Rpc.Space.LeaveApprove.Response.Error.Code.REQUEST_FAILED -> { + throw MultiplayerError.Generic.RequestFailed() + } + else -> throw Exception(error.description) + } } else { return response } @@ -1886,12 +1955,16 @@ class MiddlewareServiceImplementation @Inject constructor( val error = response.error if (error != null && error.code != Rpc.Space.MakeShareable.Response.Error.Code.NULL) { when(error.code) { + Rpc.Space.MakeShareable.Response.Error.Code.SPACE_IS_DELETED -> { + throw MultiplayerError.Generic.SpaceIsDeleted() + } Rpc.Space.MakeShareable.Response.Error.Code.LIMIT_REACHED -> { - throw SpaceLimitReachedException() + throw MultiplayerError.Generic.LimitReached() } - else -> { - throw Exception(error.description) + Rpc.Space.MakeShareable.Response.Error.Code.REQUEST_FAILED -> { + throw MultiplayerError.Generic.RequestFailed() } + else -> throw Exception(error.description) } } else { return response @@ -1905,7 +1978,21 @@ class MiddlewareServiceImplementation @Inject constructor( val response = Rpc.Space.ParticipantPermissionsChange.Response.ADAPTER.decode(encoded) val error = response.error if (error != null && error.code != Rpc.Space.ParticipantPermissionsChange.Response.Error.Code.NULL) { - throw Exception(error.description) + when(error.code) { + Rpc.Space.ParticipantPermissionsChange.Response.Error.Code.NOT_SHAREABLE -> { + throw MultiplayerError.Generic.NotShareable() + } + Rpc.Space.ParticipantPermissionsChange.Response.Error.Code.SPACE_IS_DELETED -> { + throw MultiplayerError.Generic.SpaceIsDeleted() + } + Rpc.Space.ParticipantPermissionsChange.Response.Error.Code.LIMIT_REACHED -> { + throw MultiplayerError.Generic.LimitReached() + } + Rpc.Space.ParticipantPermissionsChange.Response.Error.Code.REQUEST_FAILED -> { + throw MultiplayerError.Generic.RequestFailed() + } + else -> throw Exception(error.description) + } } else { return response } @@ -1919,6 +2006,21 @@ class MiddlewareServiceImplementation @Inject constructor( val error = response.error if (error != null && error.code != Rpc.Space.ParticipantRemove.Response.Error.Code.NULL) { throw Exception(error.description) + when(error.code) { + Rpc.Space.ParticipantRemove.Response.Error.Code.NOT_SHAREABLE -> { + throw MultiplayerError.Generic.NotShareable() + } + Rpc.Space.ParticipantRemove.Response.Error.Code.SPACE_IS_DELETED -> { + throw MultiplayerError.Generic.SpaceIsDeleted() + } + Rpc.Space.ParticipantRemove.Response.Error.Code.LIMIT_REACHED -> { + throw MultiplayerError.Generic.LimitReached() + } + Rpc.Space.ParticipantRemove.Response.Error.Code.REQUEST_FAILED -> { + throw MultiplayerError.Generic.RequestFailed() + } + else -> throw Exception(error.description) + } } else { return response } @@ -1931,7 +2033,21 @@ class MiddlewareServiceImplementation @Inject constructor( val response = Rpc.Space.RequestApprove.Response.ADAPTER.decode(encoded) val error = response.error if (error != null && error.code != Rpc.Space.RequestApprove.Response.Error.Code.NULL) { - throw Exception(error.description) + when(error.code) { + Rpc.Space.RequestApprove.Response.Error.Code.NOT_SHAREABLE -> { + throw MultiplayerError.Generic.NotShareable() + } + Rpc.Space.RequestApprove.Response.Error.Code.SPACE_IS_DELETED -> { + throw MultiplayerError.Generic.SpaceIsDeleted() + } + Rpc.Space.RequestApprove.Response.Error.Code.LIMIT_REACHED -> { + throw MultiplayerError.Generic.LimitReached() + } + Rpc.Space.RequestApprove.Response.Error.Code.REQUEST_FAILED -> { + throw MultiplayerError.Generic.RequestFailed() + } + else -> throw Exception(error.description) + } } else { return response } @@ -1944,7 +2060,21 @@ class MiddlewareServiceImplementation @Inject constructor( val response = Rpc.Space.RequestDecline.Response.ADAPTER.decode(encoded) val error = response.error if (error != null && error.code != Rpc.Space.RequestDecline.Response.Error.Code.NULL) { - throw Exception(error.description) + when(error.code) { + Rpc.Space.RequestDecline.Response.Error.Code.NOT_SHAREABLE -> { + throw MultiplayerError.Generic.NotShareable() + } + Rpc.Space.RequestDecline.Response.Error.Code.SPACE_IS_DELETED -> { + throw MultiplayerError.Generic.SpaceIsDeleted() + } + Rpc.Space.RequestDecline.Response.Error.Code.LIMIT_REACHED -> { + throw MultiplayerError.Generic.LimitReached() + } + Rpc.Space.RequestDecline.Response.Error.Code.REQUEST_FAILED -> { + throw MultiplayerError.Generic.RequestFailed() + } + else -> throw Exception(error.description) + } } else { return response } @@ -1957,7 +2087,18 @@ class MiddlewareServiceImplementation @Inject constructor( val response = Rpc.Space.StopSharing.Response.ADAPTER.decode(encoded) val error = response.error if (error != null && error.code != Rpc.Space.StopSharing.Response.Error.Code.NULL) { - throw Exception(error.description) + when(error.code) { + Rpc.Space.StopSharing.Response.Error.Code.SPACE_IS_DELETED -> { + throw MultiplayerError.Generic.SpaceIsDeleted() + } + Rpc.Space.StopSharing.Response.Error.Code.LIMIT_REACHED -> { + throw MultiplayerError.Generic.LimitReached() + } + Rpc.Space.StopSharing.Response.Error.Code.REQUEST_FAILED -> { + throw MultiplayerError.Generic.RequestFailed() + } + else -> throw Exception(error.description) + } } else { return response } diff --git a/presentation/src/main/java/com/anytypeio/anytype/presentation/multiplayer/RequestJoinSpaceViewModel.kt b/presentation/src/main/java/com/anytypeio/anytype/presentation/multiplayer/RequestJoinSpaceViewModel.kt index b5bac036c3..b0e7034459 100644 --- a/presentation/src/main/java/com/anytypeio/anytype/presentation/multiplayer/RequestJoinSpaceViewModel.kt +++ b/presentation/src/main/java/com/anytypeio/anytype/presentation/multiplayer/RequestJoinSpaceViewModel.kt @@ -7,6 +7,7 @@ import com.anytypeio.anytype.analytics.base.Analytics import com.anytypeio.anytype.analytics.base.EventsDictionary.screenInviteRequest import com.anytypeio.anytype.analytics.base.EventsDictionary.screenRequestSent import com.anytypeio.anytype.analytics.base.sendEvent +import com.anytypeio.anytype.core_models.multiplayer.MultiplayerError import com.anytypeio.anytype.core_models.multiplayer.SpaceInviteError import com.anytypeio.anytype.core_models.multiplayer.SpaceInviteView import com.anytypeio.anytype.core_models.primitives.SpaceId @@ -90,16 +91,16 @@ class RequestJoinSpaceViewModel( ErrorView.InvalidLink ) } + is SpaceInviteError.InvalidNotFound -> { + state.value = TypedViewState.Error( + ErrorView.InviteNotFound + ) + } is SpaceInviteError.SpaceDeleted -> { state.value = TypedViewState.Error( ErrorView.SpaceDeleted ) } - is SpaceInviteError.SpaceNotFound -> { - state.value = TypedViewState.Error( - ErrorView.SpaceNotFound - ) - } } } Timber.e(e, "Error while getting space invite view") @@ -132,7 +133,10 @@ class RequestJoinSpaceViewModel( ) ).fold( onFailure = { e -> - Timber.e(e, "Error while sending space join request").also { + Timber.e(e, "Error while sending space join request") + if (e is MultiplayerError.Generic) { + commands.emit(Command.ShowGenericMultiplayerError(e)) + } else { sendToast(e.msg()) } }, @@ -213,13 +217,14 @@ class RequestJoinSpaceViewModel( data object SpaceNotFound : Toast() data object SpaceDeleted : Toast() } + data class ShowGenericMultiplayerError(val error: MultiplayerError.Generic) : Command() data object Dismiss: Command() } sealed class ErrorView { data object InvalidLink : ErrorView() + data object InviteNotFound : ErrorView() data object SpaceDeleted : ErrorView() - data object SpaceNotFound : ErrorView() data class AlreadySpaceMember(val space: SpaceId) : ErrorView() data object RequestAlreadySent: ErrorView() } diff --git a/presentation/src/main/java/com/anytypeio/anytype/presentation/multiplayer/ShareSpaceViewModel.kt b/presentation/src/main/java/com/anytypeio/anytype/presentation/multiplayer/ShareSpaceViewModel.kt index 667e81ddb1..49dfcee729 100644 --- a/presentation/src/main/java/com/anytypeio/anytype/presentation/multiplayer/ShareSpaceViewModel.kt +++ b/presentation/src/main/java/com/anytypeio/anytype/presentation/multiplayer/ShareSpaceViewModel.kt @@ -23,6 +23,7 @@ import com.anytypeio.anytype.core_models.Id import com.anytypeio.anytype.core_models.ObjectWrapper import com.anytypeio.anytype.core_models.ext.isPossibleToUpgradeNumberOfSpaceMembers import com.anytypeio.anytype.core_models.membership.TierId +import com.anytypeio.anytype.core_models.multiplayer.MultiplayerError import com.anytypeio.anytype.core_models.multiplayer.ParticipantStatus import com.anytypeio.anytype.core_models.multiplayer.SpaceAccessType import com.anytypeio.anytype.core_models.multiplayer.SpaceMemberPermissions @@ -204,6 +205,7 @@ class ShareSpaceViewModel( }, onFailure = { Timber.e(it, "Error while making space shareable") + proceedWithMultiplayerError(it) } ) } @@ -215,6 +217,7 @@ class ShareSpaceViewModel( }, onFailure = { Timber.e(it, "Error while generating invite link") + proceedWithMultiplayerError(it) } ) } @@ -278,9 +281,8 @@ class ShareSpaceViewModel( ) ).fold( onFailure = { e -> - Timber.e(e, "Error while approving unjoin request").also { - sendToast(e.msg()) - } + Timber.e(e, "Error while approving leave request") + proceedWithMultiplayerError(e) }, onSuccess = { analytics.sendEvent(eventName = EventsDictionary.approveLeaveRequest) @@ -311,9 +313,8 @@ class ShareSpaceViewModel( ) ).fold( onFailure = { e -> - Timber.e(e, "Error while changing member permissions").also { - sendToast(e.msg()) - } + Timber.e(e, "Error while changing member permissions") + proceedWithMultiplayerError(e) }, onSuccess = { Timber.d("Successfully updated space member permissions") @@ -350,9 +351,8 @@ class ShareSpaceViewModel( ) ).fold( onFailure = { e -> - Timber.e(e, "Error while changing member permissions").also { - sendToast(e.msg()) - } + Timber.e(e, "Error while changing member permissions") + proceedWithMultiplayerError(e) }, onSuccess = { Timber.d("Successfully updated space member permissions") @@ -394,9 +394,8 @@ class ShareSpaceViewModel( ) ).fold( onFailure = { e -> - Timber.e(e, "Error while removing space member").also { - sendToast(e.msg()) - } + Timber.e(e, "Error while removing space member") + proceedWithMultiplayerError(e) }, onSuccess = { Timber.d("Successfully removed space member") @@ -430,9 +429,8 @@ class ShareSpaceViewModel( analytics.sendEvent(eventName = stopSpaceShare) }, onFailure = { e -> - Timber.e(e, "Error while sharing space").also { - sendToast(e.msg()) - } + Timber.e(e, "Error while sharing space") + proceedWithMultiplayerError(e) } ) } else { @@ -485,9 +483,8 @@ class ShareSpaceViewModel( analytics.sendEvent(eventName = EventsDictionary.revokeShareLink) }, onFailure = { e -> - Timber.e(e, "Error while revoking space invite link").also { - sendToast(e.msg()) - } + Timber.e(e, "Error while revoking space invite link") + proceedWithMultiplayerError(e) } ) } else { @@ -512,6 +509,14 @@ class ShareSpaceViewModel( } } + private suspend fun proceedWithMultiplayerError(e: Throwable) { + if (e is MultiplayerError.Generic) { + commands.emit(Command.ShowMultiplayerError(e)) + } else { + sendToast(e.msg()) + } + } + override fun onCleared() { viewModelScope.launch { container.unsubscribe( @@ -576,6 +581,7 @@ class ShareSpaceViewModel( data class ShareQrCode(val link: String) : Command() data class ViewJoinRequest(val space: SpaceId, val member: Id) : Command() data class ShowRemoveMemberWarning(val identity: Id, val name: String): Command() + data class ShowMultiplayerError(val error: MultiplayerError.Generic) : Command() data object ShowHowToShareSpace: Command() data object ShowStopSharingWarning: Command() data object ShowDeleteLinkWarning: Command() diff --git a/presentation/src/main/java/com/anytypeio/anytype/presentation/multiplayer/SpaceJoinRequestViewModel.kt b/presentation/src/main/java/com/anytypeio/anytype/presentation/multiplayer/SpaceJoinRequestViewModel.kt index feb0919d5c..44ee275b41 100644 --- a/presentation/src/main/java/com/anytypeio/anytype/presentation/multiplayer/SpaceJoinRequestViewModel.kt +++ b/presentation/src/main/java/com/anytypeio/anytype/presentation/multiplayer/SpaceJoinRequestViewModel.kt @@ -14,6 +14,8 @@ import com.anytypeio.anytype.core_models.ObjectWrapper import com.anytypeio.anytype.core_models.ext.isPossibleToUpgradeNumberOfSpaceMembers import com.anytypeio.anytype.core_models.membership.MembershipConstants.BUILDER_ID import com.anytypeio.anytype.core_models.membership.MembershipConstants.EXPLORER_ID +import com.anytypeio.anytype.core_models.membership.TierId +import com.anytypeio.anytype.core_models.multiplayer.MultiplayerError import com.anytypeio.anytype.core_models.multiplayer.SpaceMemberPermissions import com.anytypeio.anytype.core_models.primitives.SpaceId import com.anytypeio.anytype.core_utils.ext.msg @@ -28,7 +30,6 @@ import com.anytypeio.anytype.domain.`object`.canAddWriters import com.anytypeio.anytype.domain.search.SearchObjects import com.anytypeio.anytype.presentation.common.BaseViewModel import com.anytypeio.anytype.presentation.extension.sendAnalyticsApproveInvite -import com.anytypeio.anytype.core_models.membership.TierId import com.anytypeio.anytype.presentation.membership.provider.MembershipProvider import com.anytypeio.anytype.presentation.objects.SpaceMemberIconView import com.anytypeio.anytype.presentation.objects.toSpaceMembers @@ -346,7 +347,10 @@ class SpaceJoinRequestViewModel( isDismissed.value = true }, onFailure = { e -> - Timber.e(e, "Error while rejecting join-space request").also { + Timber.e(e, "Error while rejecting join-space request") + if (e is MultiplayerError.Generic) { + _commands.emit(Command.ShowGenericMultiplayerError(e)) + } else { sendToast(e.msg()) } } @@ -369,7 +373,10 @@ class SpaceJoinRequestViewModel( isDismissed.value = true }, onFailure = { e -> - Timber.e(e, "Error while approving join-space request").also { + Timber.e(e, "Error while approving join-space request") + if (e is MultiplayerError.Generic) { + _commands.emit(Command.ShowGenericMultiplayerError(e)) + } else { sendToast(e.msg()) } } @@ -477,6 +484,7 @@ class SpaceJoinRequestViewModel( sealed class Command { data object NavigateToMembership : Command() data object NavigateToMembershipUpdate : Command() + data class ShowGenericMultiplayerError(val error: MultiplayerError.Generic) : Command() } }