mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-04-29 05:04:54 +01:00
Always perform CDSI lookups when starting new chats.
This commit is contained in:
committed by
Alex Hart
parent
184c1b67cc
commit
2e4ac7ede1
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright 2024 Signal Messenger, LLC
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
package org.thoughtcrime.securesms.recipients
|
||||
|
||||
import android.content.Context
|
||||
import androidx.annotation.WorkerThread
|
||||
import org.signal.core.util.logging.Log
|
||||
import org.thoughtcrime.securesms.contacts.sync.ContactDiscovery
|
||||
import org.thoughtcrime.securesms.database.SignalDatabase
|
||||
import org.thoughtcrime.securesms.phonenumbers.NumberUtil
|
||||
import org.thoughtcrime.securesms.phonenumbers.PhoneNumberFormatter
|
||||
import java.io.IOException
|
||||
|
||||
/**
|
||||
* We operate on recipients many places, but sometimes we find ourselves performing the same recipient-related operations in several locations.
|
||||
* This is meant to be a place to put those common operations.
|
||||
*/
|
||||
object RecipientRepository {
|
||||
|
||||
private val TAG = Log.tag(RecipientRepository::class.java)
|
||||
|
||||
/**
|
||||
* Attempts to lookup a potentially-new recipient by their e164.
|
||||
* We will check locally first for a potential match, but may end up hitting the network.
|
||||
* This will not create a new recipient if we could not find it in the CDSI directory.
|
||||
*/
|
||||
@WorkerThread
|
||||
@JvmStatic
|
||||
fun lookupNewE164(context: Context, inputE164: String): LookupResult {
|
||||
val e164 = PhoneNumberFormatter.get(context).format(inputE164)
|
||||
|
||||
if (!NumberUtil.isVisuallyValidNumber(e164)) {
|
||||
return LookupResult.InvalidEntry
|
||||
}
|
||||
|
||||
val matchingFullRecipientId = SignalDatabase.recipients.getByE164IfRegisteredAndDiscoverable(e164)
|
||||
if (matchingFullRecipientId != null) {
|
||||
Log.i(TAG, "Already have a full, discoverable recipient for $e164. $matchingFullRecipientId")
|
||||
return LookupResult.Success(matchingFullRecipientId)
|
||||
}
|
||||
|
||||
Log.i(TAG, "Need to lookup up $e164 with CDSI.")
|
||||
|
||||
return try {
|
||||
val result = ContactDiscovery.lookupE164(e164)
|
||||
if (result == null) {
|
||||
LookupResult.NotFound()
|
||||
} else {
|
||||
LookupResult.Success(result.recipientId)
|
||||
}
|
||||
} catch (e: IOException) {
|
||||
return LookupResult.NetworkError
|
||||
}
|
||||
}
|
||||
|
||||
sealed interface LookupResult {
|
||||
data class Success(val recipientId: RecipientId) : LookupResult
|
||||
object InvalidEntry : LookupResult
|
||||
data class NotFound(val recipientId: RecipientId = RecipientId.UNKNOWN) : LookupResult
|
||||
object NetworkError : LookupResult
|
||||
}
|
||||
}
|
||||
@@ -84,7 +84,6 @@ import org.thoughtcrime.securesms.components.settings.app.usernamelinks.main.Use
|
||||
import org.thoughtcrime.securesms.invites.InviteActions
|
||||
import org.thoughtcrime.securesms.permissions.compose.Permissions
|
||||
import org.thoughtcrime.securesms.phonenumbers.PhoneNumberVisualTransformation
|
||||
import org.thoughtcrime.securesms.recipients.Recipient
|
||||
import org.thoughtcrime.securesms.recipients.RecipientId
|
||||
import org.thoughtcrime.securesms.registration.util.CountryPrefix
|
||||
import org.thoughtcrime.securesms.util.viewModel
|
||||
@@ -161,6 +160,7 @@ class FindByActivity : PassphraseRequiredActivity() {
|
||||
|
||||
FindByResult.InvalidEntry -> navController.navigate("invalid-entry")
|
||||
is FindByResult.NotFound -> navController.navigate("not-found/${result.recipientId.toLong()}")
|
||||
is FindByResult.NetworkError -> navController.navigate("network-error")
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -220,6 +220,16 @@ class FindByActivity : PassphraseRequiredActivity() {
|
||||
)
|
||||
}
|
||||
|
||||
dialog(
|
||||
route = "network-error"
|
||||
) {
|
||||
Dialogs.SimpleMessageDialog(
|
||||
message = getString(R.string.FindByActivity__network_error_dialog),
|
||||
dismiss = getString(android.R.string.ok),
|
||||
onDismiss = { navController.popBackStack() }
|
||||
)
|
||||
}
|
||||
|
||||
dialog(
|
||||
route = "not-found/{recipientId}",
|
||||
arguments = listOf(navArgument("recipientId") { type = NavType.LongType })
|
||||
@@ -260,15 +270,10 @@ class FindByActivity : PassphraseRequiredActivity() {
|
||||
dismiss = dismiss,
|
||||
onConfirm = {
|
||||
if (state.mode == FindByMode.PHONE_NUMBER) {
|
||||
val recipientId = navBackStackEntry.arguments?.getLong("recipientId")?.takeIf { it > 0 }?.let { RecipientId.from(it) } ?: RecipientId.UNKNOWN
|
||||
if (recipientId != RecipientId.UNKNOWN) {
|
||||
InviteActions.inviteUserToSignal(
|
||||
context,
|
||||
Recipient.resolved(recipientId),
|
||||
null,
|
||||
this@FindByActivity::startActivity
|
||||
)
|
||||
}
|
||||
InviteActions.inviteUserToSignal(
|
||||
context,
|
||||
this@FindByActivity::startActivity
|
||||
)
|
||||
}
|
||||
},
|
||||
onDismiss = { navController.popBackStack() }
|
||||
@@ -429,6 +434,10 @@ private fun Content(
|
||||
}
|
||||
}
|
||||
|
||||
if (state.isLookupInProgress) {
|
||||
Dialogs.IndeterminateProgressDialog()
|
||||
}
|
||||
|
||||
LaunchedEffect(Unit) {
|
||||
focusRequester.requestFocus()
|
||||
}
|
||||
|
||||
@@ -11,4 +11,5 @@ sealed interface FindByResult {
|
||||
data class Success(val recipientId: RecipientId) : FindByResult
|
||||
object InvalidEntry : FindByResult
|
||||
data class NotFound(val recipientId: RecipientId = RecipientId.UNKNOWN) : FindByResult
|
||||
object NetworkError : FindByResult
|
||||
}
|
||||
|
||||
@@ -14,14 +14,11 @@ import androidx.lifecycle.viewModelScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.async
|
||||
import org.signal.core.util.concurrent.safeBlockingGet
|
||||
import org.thoughtcrime.securesms.contacts.sync.ContactDiscovery
|
||||
import org.thoughtcrime.securesms.phonenumbers.NumberUtil
|
||||
import org.thoughtcrime.securesms.profiles.manage.UsernameRepository
|
||||
import org.thoughtcrime.securesms.recipients.Recipient
|
||||
import org.thoughtcrime.securesms.recipients.RecipientRepository
|
||||
import org.thoughtcrime.securesms.registration.util.CountryPrefix
|
||||
import org.thoughtcrime.securesms.util.UsernameUtil
|
||||
import org.whispersystems.signalservice.api.util.PhoneNumberFormatter
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
class FindByViewModel(
|
||||
mode: FindByMode
|
||||
@@ -86,40 +83,13 @@ class FindByViewModel(
|
||||
val countryCode = stateSnapshot.selectedCountryPrefix.digits
|
||||
val nationalNumber = stateSnapshot.userEntry.removePrefix(countryCode.toString())
|
||||
|
||||
val e164 = "$countryCode$nationalNumber"
|
||||
val e164 = "+$countryCode$nationalNumber"
|
||||
|
||||
if (!NumberUtil.isVisuallyValidNumber(e164)) {
|
||||
return FindByResult.InvalidEntry
|
||||
}
|
||||
|
||||
val recipient = try {
|
||||
Recipient.external(context, e164)
|
||||
} catch (e: Exception) {
|
||||
return FindByResult.InvalidEntry
|
||||
}
|
||||
|
||||
return if (!recipient.isRegistered || !recipient.hasServiceId()) {
|
||||
try {
|
||||
ContactDiscovery.refresh(context, recipient, false, TimeUnit.SECONDS.toMillis(10))
|
||||
val resolved = Recipient.resolved(recipient.id)
|
||||
if (!resolved.isRegistered) {
|
||||
if (PhoneNumberFormatter.isValidNumber(nationalNumber, countryCode.toString())) {
|
||||
FindByResult.NotFound(recipient.id)
|
||||
} else {
|
||||
FindByResult.InvalidEntry
|
||||
}
|
||||
} else {
|
||||
FindByResult.Success(recipient.id)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
if (PhoneNumberFormatter.isValidNumber(nationalNumber, countryCode.toString())) {
|
||||
FindByResult.NotFound(recipient.id)
|
||||
} else {
|
||||
FindByResult.InvalidEntry
|
||||
}
|
||||
}
|
||||
} else {
|
||||
FindByResult.Success(recipient.id)
|
||||
return when (val result = RecipientRepository.lookupNewE164(context, e164)) {
|
||||
RecipientRepository.LookupResult.InvalidEntry -> FindByResult.InvalidEntry
|
||||
RecipientRepository.LookupResult.NetworkError -> FindByResult.NetworkError
|
||||
is RecipientRepository.LookupResult.NotFound -> FindByResult.NotFound(result.recipientId)
|
||||
is RecipientRepository.LookupResult.Success -> FindByResult.Success(result.recipientId)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user