Improve new convo error messages

This commit is contained in:
Andrew 2024-03-27 12:22:53 +10:30
parent 006c50e38d
commit e25b90b229
6 changed files with 25 additions and 27 deletions

View File

@ -46,7 +46,7 @@ class NewConversationFragment : BottomSheetDialogFragment(), NewConversationDele
val bottomSheetDialog = it as BottomSheetDialog val bottomSheetDialog = it as BottomSheetDialog
val parentLayout = val parentLayout =
bottomSheetDialog.findViewById<View>(com.google.android.material.R.id.design_bottom_sheet) bottomSheetDialog.findViewById<View>(com.google.android.material.R.id.design_bottom_sheet)
parentLayout?.let { it -> parentLayout?.let {
val behaviour = BottomSheetBehavior.from(it) val behaviour = BottomSheetBehavior.from(it)
val layoutParams = it.layoutParams val layoutParams = it.layoutParams
layoutParams.height = defaultPeekHeight layoutParams.height = defaultPeekHeight

View File

@ -60,8 +60,12 @@ class NewMessageFragment : Fragment() {
} }
private fun createPrivateChatIfPossible(onsNameOrPublicKey: String) { private fun createPrivateChatIfPossible(onsNameOrPublicKey: String) {
if (PublicKeyValidation.isValid(onsNameOrPublicKey)) { if (PublicKeyValidation.isValid(onsNameOrPublicKey, isPrefixRequired = false)) {
createPrivateChat(onsNameOrPublicKey) if (PublicKeyValidation.hasValidPrefix(onsNameOrPublicKey)) {
createPrivateChat(onsNameOrPublicKey)
} else {
Toast.makeText(requireContext(), R.string.accountIdErrorInvalid, Toast.LENGTH_SHORT).show()
}
} else { } else {
// This could be an ONS name // This could be an ONS name
showLoader() showLoader()
@ -70,9 +74,9 @@ class NewMessageFragment : Fragment() {
createPrivateChat(hexEncodedPublicKey) createPrivateChat(hexEncodedPublicKey)
}.failUi { exception -> }.failUi { exception ->
hideLoader() hideLoader()
var message = getString(R.string.fragment_enter_public_key_error_message) val message = when (exception) {
exception.localizedMessage?.let { is SnodeAPI.Error.Generic -> "We couldnt recognize this ONS. Please check and try again."
message = it else -> exception.localizedMessage ?: getString(R.string.fragment_enter_public_key_error_message)
} }
Toast.makeText(requireContext(), message, Toast.LENGTH_SHORT).show() Toast.makeText(requireContext(), message, Toast.LENGTH_SHORT).show()
} }
@ -81,12 +85,11 @@ class NewMessageFragment : Fragment() {
private fun createPrivateChat(hexEncodedPublicKey: String) { private fun createPrivateChat(hexEncodedPublicKey: String) {
val recipient = Recipient.from(requireContext(), Address.fromSerialized(hexEncodedPublicKey), false) val recipient = Recipient.from(requireContext(), Address.fromSerialized(hexEncodedPublicKey), false)
val intent = Intent(requireContext(), ConversationActivityV2::class.java) Intent(requireContext(), ConversationActivityV2::class.java).apply {
intent.putExtra(ConversationActivityV2.ADDRESS, recipient.address) putExtra(ConversationActivityV2.ADDRESS, recipient.address)
intent.setDataAndType(requireActivity().intent.data, requireActivity().intent.type) setDataAndType(requireActivity().intent.data, requireActivity().intent.type)
val existingThread = DatabaseComponent.get(requireContext()).threadDatabase().getThreadIdIfExistsFor(recipient) putExtra(ConversationActivityV2.THREAD_ID, DatabaseComponent.get(requireContext()).threadDatabase().getThreadIdIfExistsFor(recipient))
intent.putExtra(ConversationActivityV2.THREAD_ID, existingThread) }.let(requireContext()::startActivity)
requireContext().startActivity(intent)
delegate.onDialogClosePressed() delegate.onDialogClosePressed()
} }

View File

@ -1081,4 +1081,5 @@
<string name="activity_link_load_account">Load Account</string> <string name="activity_link_load_account">Load Account</string>
<string name="activity_link_camera_permission_permanently_denied_configure_in_settings">Camera Permission permanently denied. Configure in settings.</string> <string name="activity_link_camera_permission_permanently_denied_configure_in_settings">Camera Permission permanently denied. Configure in settings.</string>
<string name="activity_link_enter_your_recovery_password_to_load_your_account_if_you_haven_t_saved_it_you_can_find_it_in_your_app_settings">Enter your recovery password to load your account. If you haven\'t saved it, you can find it in your app settings.</string> <string name="activity_link_enter_your_recovery_password_to_load_your_account_if_you_haven_t_saved_it_you_can_find_it_in_your_app_settings">Enter your recovery password to load your account. If you haven\'t saved it, you can find it in your app settings.</string>
<string name="accountIdErrorInvalid">This Account ID is invalid. Please check and try again.</string>
</resources> </resources>

View File

@ -91,7 +91,7 @@ object SnodeAPI {
const val useTestnet = false const val useTestnet = false
// Error // Error
internal sealed class Error(val description: String) : Exception(description) { sealed class Error(val description: String) : Exception(description) {
object Generic : Error("An error occurred.") object Generic : Error("An error occurred.")
object ClockOutOfSync : Error("Your clock is out of sync with the Service Node network.") object ClockOutOfSync : Error("Your clock is out of sync with the Service Node network.")
object NoKeyPair : Error("Missing user key pair.") object NoKeyPair : Error("Missing user key pair.")

View File

@ -1,7 +1,7 @@
package org.session.libsignal.utilities package org.session.libsignal.utilities
enum class IdPrefix(val value: String) { enum class IdPrefix(val value: String) {
STANDARD("05"), BLINDED("15"), UN_BLINDED("00"), BLINDEDV2("25"); STANDARD("05"), BLINDED("15"), UN_BLINDED("00"), BLINDEDV2("25"), GROUP("03");
fun isBlinded() = value == BLINDED.value || value == BLINDEDV2.value fun isBlinded() = value == BLINDED.value || value == BLINDEDV2.value
@ -11,6 +11,7 @@ enum class IdPrefix(val value: String) {
BLINDED.value -> BLINDED BLINDED.value -> BLINDED
BLINDEDV2.value -> BLINDEDV2 BLINDEDV2.value -> BLINDEDV2
UN_BLINDED.value -> UN_BLINDED UN_BLINDED.value -> UN_BLINDED
GROUP.value -> GROUP
else -> null else -> null
} }
} }

View File

@ -1,18 +1,11 @@
package org.session.libsignal.utilities package org.session.libsignal.utilities
object PublicKeyValidation { object PublicKeyValidation {
private val HEX_CHARACTERS = "0123456789ABCDEF".toSet()
private val INVALID_PREFIXES = setOf(IdPrefix.GROUP, IdPrefix.BLINDED, IdPrefix.BLINDEDV2)
@JvmStatic fun isValid(candidate: String, isPrefixRequired: Boolean = true): Boolean = hasValidLength(candidate) && isValidHexEncoding(candidate) && (!isPrefixRequired || IdPrefix.fromValue(candidate) != null)
fun isValid(candidate: String): Boolean { fun hasValidPrefix(candidate: String) = IdPrefix.fromValue(candidate) !in INVALID_PREFIXES
return isValid(candidate, 66, true) private fun hasValidLength(candidate: String) = candidate.length == 66
} private fun isValidHexEncoding(candidate: String) = HEX_CHARACTERS.containsAll(candidate.uppercase().toSet())
@JvmStatic
fun isValid(candidate: String, expectedLength: Int, isPrefixRequired: Boolean): Boolean {
val hexCharacters = "0123456789ABCDEF".toSet()
val isValidHexEncoding = hexCharacters.containsAll(candidate.uppercase().toSet())
val hasValidLength = candidate.length == expectedLength
val hasValidPrefix = if (isPrefixRequired) IdPrefix.fromValue(candidate) != null else true
return isValidHexEncoding && hasValidLength && hasValidPrefix
}
} }