diff --git a/app/src/main/java/io/xxlabs/messenger/data/datatype/RequestStatus.kt b/app/src/main/java/io/xxlabs/messenger/data/datatype/RequestStatus.kt index 617601e34341ea387629bbd3cec3cb4c940ec06d..67d87288165fb10dae5457a82a3f7bf9f206749f 100644 --- a/app/src/main/java/io/xxlabs/messenger/data/datatype/RequestStatus.kt +++ b/app/src/main/java/io/xxlabs/messenger/data/datatype/RequestStatus.kt @@ -14,6 +14,7 @@ enum class RequestStatus(val value: Int) { SENDING(10), DELETING(11), HIDDEN(12), + RECEIVED(13), SEARCH(99); companion object { diff --git a/app/src/main/java/io/xxlabs/messenger/data/room/dao/RequestsDao.kt b/app/src/main/java/io/xxlabs/messenger/data/room/dao/RequestsDao.kt index add64887956a79f92de3186295ebcb409cbdae68..20b67752185ee27741d2a216f186fb6137e82797 100644 --- a/app/src/main/java/io/xxlabs/messenger/data/room/dao/RequestsDao.kt +++ b/app/src/main/java/io/xxlabs/messenger/data/room/dao/RequestsDao.kt @@ -21,6 +21,9 @@ interface RequestsDao { @Query("SELECT * FROM Requests WHERE requestId IN (SELECT userId FROM Contacts)") fun getContactRequests(): Flow<List<RequestData>> + @Query("SELECT * FROM Requests WHERE requestId IN (SELECT userId FROM Contacts)") + fun getContactRequestsOnce(): List<RequestData> + @Query("SELECT * FROM Requests WHERE requestId IN (SELECT groupId FROM Groups)") fun getGroupInvitations(): Flow<List<RequestData>> diff --git a/app/src/main/java/io/xxlabs/messenger/repository/client/ClientRepository.kt b/app/src/main/java/io/xxlabs/messenger/repository/client/ClientRepository.kt index 5d3d5c48905e602ac92ca6f627cfcdc43a754c38..89d818a7267c3aac12eb19ed2cbb08f6d66bc98f 100644 --- a/app/src/main/java/io/xxlabs/messenger/repository/client/ClientRepository.kt +++ b/app/src/main/java/io/xxlabs/messenger/repository/client/ClientRepository.kt @@ -829,6 +829,8 @@ class ClientRepository @Inject constructor( } Timber.v("[USER LOOKUP] Total execution time: ${Utils.getCurrentTimeStamp() - executionTime}") } + } else { + callback.invoke(null, "Failed to establish secure connection to network") } } diff --git a/app/src/main/java/io/xxlabs/messenger/requests/data/LocalRequestsDataSource.kt b/app/src/main/java/io/xxlabs/messenger/requests/data/LocalRequestsDataSource.kt index e30a49ec10a6e5ddb133b9a4b899f107f3f26074..b94bb691eba5b4aad49af1dc9e54d6d87a26b376 100644 --- a/app/src/main/java/io/xxlabs/messenger/requests/data/LocalRequestsDataSource.kt +++ b/app/src/main/java/io/xxlabs/messenger/requests/data/LocalRequestsDataSource.kt @@ -8,6 +8,7 @@ import kotlinx.coroutines.flow.Flow interface LocalRequestsDataSource { val unreadCount: Flow<Int> + suspend fun getContactRequestsOnce(): List<RequestData> suspend fun getContactRequests(): Flow<List<RequestData>> suspend fun getGroupInvitations(): Flow<List<RequestData>> suspend fun getRequest(requestId: ByteArray): RequestData? diff --git a/app/src/main/java/io/xxlabs/messenger/requests/data/RequestsDatabase.kt b/app/src/main/java/io/xxlabs/messenger/requests/data/RequestsDatabase.kt index 71643ddee64be1dc029ce403211557573d00ee28..47a36b5f2d9c5434b816f2b500c8223b11b7934c 100644 --- a/app/src/main/java/io/xxlabs/messenger/requests/data/RequestsDatabase.kt +++ b/app/src/main/java/io/xxlabs/messenger/requests/data/RequestsDatabase.kt @@ -52,6 +52,9 @@ class RequestsDatabase @Inject constructor( } } + override suspend fun getContactRequestsOnce(): List<RequestData> = + requestsDao.getContactRequestsOnce() + override suspend fun getContactRequests(): Flow<List<RequestData>> = requestsDao.getContactRequests() .stateIn(scope, SharingStarted.Eagerly, listOf()) diff --git a/app/src/main/java/io/xxlabs/messenger/requests/data/contact/ContactRequestRepository.kt b/app/src/main/java/io/xxlabs/messenger/requests/data/contact/ContactRequestRepository.kt index 8d48c35602042ef110197ce4c08be3eacd1403f4..caf0d00d4d8efd7c95dba7730585bc47abc860a1 100644 --- a/app/src/main/java/io/xxlabs/messenger/requests/data/contact/ContactRequestRepository.kt +++ b/app/src/main/java/io/xxlabs/messenger/requests/data/contact/ContactRequestRepository.kt @@ -10,6 +10,8 @@ import io.xxlabs.messenger.requests.bindings.VerificationResult import io.xxlabs.messenger.requests.data.LocalRequestsDataSource import io.xxlabs.messenger.requests.data.RequestDataSource import io.xxlabs.messenger.requests.model.ContactRequest +import io.xxlabs.messenger.support.appContext +import io.xxlabs.messenger.support.extensions.toast import io.xxlabs.messenger.support.util.value import kotlinx.coroutines.* import kotlinx.coroutines.flow.* @@ -121,13 +123,19 @@ class ContactRequestsRepository @Inject constructor( override fun failUnverifiedRequests() { scope.launch { - getRequests().cancellable().collect { requests -> - requests.filter { + localDataSource.getContactRequestsOnce().let { requestDataList -> + requestDataList.mapNotNull { requestData -> + val contactData = daoRepository + .getContactByUserId(requestData.requestId) + .value() + contactData?.let { + ContactRequestData(it, requestData.unread) + } + }.filter { it.requestStatus == VERIFYING }.forEach { update(it, VERIFICATION_FAIL) } - this.coroutineContext.job.cancel() } } } diff --git a/app/src/main/java/io/xxlabs/messenger/requests/ui/RequestsViewModel.kt b/app/src/main/java/io/xxlabs/messenger/requests/ui/RequestsViewModel.kt index c3234c566f0b253c87aaded741c178d48d333a85..85fe5942da16cc55f42ed5336f47be804209cca2 100644 --- a/app/src/main/java/io/xxlabs/messenger/requests/ui/RequestsViewModel.kt +++ b/app/src/main/java/io/xxlabs/messenger/requests/ui/RequestsViewModel.kt @@ -311,7 +311,7 @@ class RequestsViewModel @Inject constructor( private fun RequestItem.isIncoming(): Boolean { return when (request.requestStatus) { - VERIFYING, VERIFIED, VERIFICATION_FAIL -> true + RECEIVED, VERIFYING, VERIFIED, VERIFICATION_FAIL -> true else -> false } } @@ -345,6 +345,7 @@ class RequestsViewModel @Inject constructor( override fun onItemClicked(request: RequestItem) { when (request.request.requestStatus) { + RECEIVED -> retryVerification(request) VERIFYING -> showVerifyingInfo() VERIFIED, HIDDEN -> showDetails(request) ACCEPTED -> { @@ -378,6 +379,7 @@ class RequestsViewModel @Inject constructor( else actionQueue.add(request.id) when (request.request.requestStatus) { + RECEIVED -> retryVerification(request).also { actionQueue.remove(request.id) } VERIFYING -> showVerifyingInfo().also { actionQueue.remove(request.id) } SEND_FAIL, SENT -> resendRequest(request) VERIFICATION_FAIL -> retryVerification(request) diff --git a/app/src/main/java/io/xxlabs/messenger/ui/global/ContactsViewModel.kt b/app/src/main/java/io/xxlabs/messenger/ui/global/ContactsViewModel.kt index 5892a9d2b9e06c6ab4f689df3474cbb782370adb..08f141021cfe7eb13d03515090ef125bb3eacf81 100644 --- a/app/src/main/java/io/xxlabs/messenger/ui/global/ContactsViewModel.kt +++ b/app/src/main/java/io/xxlabs/messenger/ui/global/ContactsViewModel.kt @@ -27,7 +27,6 @@ import io.xxlabs.messenger.repository.client.ClientRepository import io.xxlabs.messenger.requests.data.contact.ContactRequestData import io.xxlabs.messenger.requests.data.contact.ContactRequestsRepository import io.xxlabs.messenger.requests.data.contact.RequestMigrator -import io.xxlabs.messenger.requests.data.group.InvitationMigrator import io.xxlabs.messenger.support.extensions.combineWith import io.xxlabs.messenger.support.extensions.toBase64String import io.xxlabs.messenger.support.isMockVersion @@ -77,6 +76,11 @@ class ContactsViewModel @Inject constructor( init { Timber.v("isAuthCallbackRegistered: ${isAuthCallbackRegistered()}") migrateOldRequests() + + // The app has presumably had a fresh launch. + // Fail requests that haven't verified yet, so they may be retried manually by user. + failVerifyingRequests() + if (BuildConfig.DEBUG) listContacts() } @@ -117,6 +121,10 @@ class ContactsViewModel @Inject constructor( } } + private fun failVerifyingRequests() { + requestsDataSource.failUnverifiedRequests() + } + private fun onRequestReceived(contact: ByteArray) { val id = getBindingsContactId(contact) Timber.v("Request received from: ${id.toBase64String()}") @@ -304,7 +312,7 @@ class ContactsViewModel @Inject constructor( marshaled = marshalledData, email = contactEmail, phone = contactPhone, - status = VERIFYING.value + status = RECEIVED.value ) subscriptions.add( @@ -382,11 +390,13 @@ class ContactsViewModel @Inject constructor( fun verifyNewRequest( contact: ContactData ) { - Timber.v("[RECEIVED REQUEST] Verifying Request ${contact.userId.toBase64String()}...") - if (contact.hasFacts()) { //UD Search - verifyContactViaSearch(contact) - } else { // UD Lookup - verifyContactViaLookup(contact) + updateContactStatus(contact.userId, VERIFYING) { + Timber.v("[RECEIVED REQUEST] Verifying Request ${contact.userId.toBase64String()}...") + if (contact.hasFacts()) { //UD Search + verifyContactViaSearch(contact) + } else { // UD Lookup + verifyContactViaLookup(contact) + } } } diff --git a/app/src/main/java/io/xxlabs/messenger/ui/global/NetworkViewModel.kt b/app/src/main/java/io/xxlabs/messenger/ui/global/NetworkViewModel.kt index f21b1dee7ae108ba45cdd03d9caadadf18d5ec2d..0b32da51779e892783997fcd2ea25fd10a55c59b 100644 --- a/app/src/main/java/io/xxlabs/messenger/ui/global/NetworkViewModel.kt +++ b/app/src/main/java/io/xxlabs/messenger/ui/global/NetworkViewModel.kt @@ -289,6 +289,7 @@ class NetworkViewModel @Inject constructor( Timber.v("[NETWORK VIEWMODEL] Network follower is NOT RUNNING") } .doOnError { err -> + requestsDataSource.failUnverifiedRequests() Timber.v("[NETWORK VIEWMODEL] Network follower ERROR - could not stop properly: ${err.localizedMessage}") } .subscribe()