diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 270f2128ef..437f62de86 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -68,7 +68,7 @@ material = "1.13.0" mockk = "1.14.7" paparazzi = "1.3.5" proton-core = "36.2.0" -proton-rust-core = "0.161.8" +proton-rust-core = "0.161.9" robolectric = "4.15.1" # 4.16.0 requires Java 21 kotlinpoet-ksp = "2.2.0" leakcanary = "2.14" diff --git a/mail-conversation/data/src/main/kotlin/ch/protonmail/android/mailconversation/data/local/RustConversationsQueryImpl.kt b/mail-conversation/data/src/main/kotlin/ch/protonmail/android/mailconversation/data/local/RustConversationsQueryImpl.kt index 6ff5b02356..520378fd6c 100644 --- a/mail-conversation/data/src/main/kotlin/ch/protonmail/android/mailconversation/data/local/RustConversationsQueryImpl.kt +++ b/mail-conversation/data/src/main/kotlin/ch/protonmail/android/mailconversation/data/local/RustConversationsQueryImpl.kt @@ -323,7 +323,7 @@ class RustConversationsQueryImpl @Inject constructor( fun ConversationScrollerUpdate.List.toScrollerUpdate(): ScrollerUpdate = when (val listResult = this.v1) { - is ConversationScrollerListUpdate.Append -> ScrollerUpdate.Append(listResult.v1) + is ConversationScrollerListUpdate.Append -> ScrollerUpdate.Append(listResult.items) is ConversationScrollerListUpdate.ReplaceFrom -> ScrollerUpdate.ReplaceFrom( listResult.idx.toInt(), listResult.items @@ -334,7 +334,7 @@ fun ConversationScrollerUpdate.List.toScrollerUpdate(): ScrollerUpdate ScrollerUpdate.None + is ConversationScrollerListUpdate.None -> ScrollerUpdate.None is ConversationScrollerListUpdate.ReplaceRange -> ScrollerUpdate.ReplaceRange( listResult.from.toInt(), listResult.to.toInt(), diff --git a/mail-conversation/data/src/test/kotlin/ch/protonmail/android/mailconversation/data/local/RustConversationsQueryImplTest.kt b/mail-conversation/data/src/test/kotlin/ch/protonmail/android/mailconversation/data/local/RustConversationsQueryImplTest.kt index 63dece2d5d..e7e0b59878 100644 --- a/mail-conversation/data/src/test/kotlin/ch/protonmail/android/mailconversation/data/local/RustConversationsQueryImplTest.kt +++ b/mail-conversation/data/src/test/kotlin/ch/protonmail/android/mailconversation/data/local/RustConversationsQueryImplTest.kt @@ -89,7 +89,10 @@ class RustConversationsQueryImplTest { delay(100) // Simulate callback delay compared to nextPage invocation callbackSlot.captured.onUpdate( ConversationScrollerUpdate.List( - ConversationScrollerListUpdate.Append(expectedConversations) + ConversationScrollerListUpdate.Append( + items = expectedConversations, + scrollerId = DefaultScrollerId + ) ) ) } @@ -128,7 +131,10 @@ class RustConversationsQueryImplTest { delay(100) // Simulate callback delay compared to nextPage invocation callbackSlot.captured.onUpdate( ConversationScrollerUpdate.List( - ConversationScrollerListUpdate.Append(expectedConversations) + ConversationScrollerListUpdate.Append( + items = expectedConversations, + scrollerId = DefaultScrollerId + ) ) ) } @@ -168,8 +174,9 @@ class RustConversationsQueryImplTest { callbackSlot.captured.onUpdate( ConversationScrollerUpdate.List( ConversationScrollerListUpdate.ReplaceFrom( - 0uL, - expectedConversations + idx = 0uL, + items = expectedConversations, + scrollerId = DefaultScrollerId ) ) ) @@ -217,7 +224,8 @@ class RustConversationsQueryImplTest { callbackSlot.captured.onUpdate( ConversationScrollerUpdate.List( ConversationScrollerListUpdate.Append( - expectedPage + items = expectedPage, + scrollerId = DefaultScrollerId ) ) ) @@ -266,7 +274,8 @@ class RustConversationsQueryImplTest { callbackSlot.captured.onUpdate( ConversationScrollerUpdate.List( ConversationScrollerListUpdate.Append( - firstPage + items = firstPage, + scrollerId = DefaultScrollerId ) ) ) @@ -316,7 +325,8 @@ class RustConversationsQueryImplTest { callbackSlot.captured.onUpdate( ConversationScrollerUpdate.List( ConversationScrollerListUpdate.Append( - firstPage + items = firstPage, + scrollerId = DefaultScrollerId ) ) ) @@ -363,7 +373,8 @@ class RustConversationsQueryImplTest { callbackSlot.captured.onUpdate( ConversationScrollerUpdate.List( ConversationScrollerListUpdate.Append( - firstPage + items = firstPage, + scrollerId = DefaultScrollerId ) ) ) @@ -412,7 +423,8 @@ class RustConversationsQueryImplTest { callbackSlot.captured.onUpdate( ConversationScrollerUpdate.List( ConversationScrollerListUpdate.Append( - firstPage + items = firstPage, + scrollerId = DefaultScrollerId ) ) ) @@ -438,7 +450,13 @@ class RustConversationsQueryImplTest { // When rustConversationsQuery.getConversations(userId, pageKey) callbackSlot.captured.onUpdate( - ConversationScrollerUpdate.List(ConversationScrollerListUpdate.ReplaceBefore(2uL, firstPage)) + ConversationScrollerUpdate.List( + ConversationScrollerListUpdate.ReplaceBefore( + idx = 2uL, + items = firstPage, + scrollerId = DefaultScrollerId + ) + ) ) // Then @@ -462,7 +480,8 @@ class RustConversationsQueryImplTest { callbackSlot.captured.onUpdate( ConversationScrollerUpdate.List( ConversationScrollerListUpdate.Append( - firstPage + items = firstPage, + scrollerId = DefaultScrollerId ) ) ) @@ -490,8 +509,9 @@ class RustConversationsQueryImplTest { callbackSlot.captured.onUpdate( ConversationScrollerUpdate.List( ConversationScrollerListUpdate.ReplaceFrom( - 2uL, - firstPage + idx = 2uL, + items = firstPage, + scrollerId = DefaultScrollerId ) ) ) @@ -516,13 +536,18 @@ class RustConversationsQueryImplTest { val paginator = mockk { coEvery { nextPage() } answers { CoroutineScope(mainDispatcherRule.testDispatcher).launch { - callbackSlot.captured.onUpdate(ConversationScrollerUpdate.List(ConversationScrollerListUpdate.None)) + callbackSlot.captured.onUpdate( + ConversationScrollerUpdate.List( + ConversationScrollerListUpdate.None(DefaultScrollerId) + ) + ) delay(NONE_FOLLOWUP_GRACE_MS - 100) callbackSlot.captured.onUpdate( ConversationScrollerUpdate.List( ConversationScrollerListUpdate.ReplaceBefore( - 0uL, - expectedFollowUp + idx = 0uL, + items = expectedFollowUp, + scrollerId = DefaultScrollerId ) ) ) @@ -562,13 +587,18 @@ class RustConversationsQueryImplTest { val paginator = mockk { coEvery { nextPage() } answers { CoroutineScope(mainDispatcherRule.testDispatcher).launch { - callbackSlot.captured.onUpdate(ConversationScrollerUpdate.List(ConversationScrollerListUpdate.None)) + callbackSlot.captured.onUpdate( + ConversationScrollerUpdate.List( + ConversationScrollerListUpdate.None(DefaultScrollerId) + ) + ) delay(NONE_FOLLOWUP_GRACE_MS + 100) callbackSlot.captured.onUpdate( ConversationScrollerUpdate.List( ConversationScrollerListUpdate.ReplaceBefore( - 0uL, - listOf(LocalConversationTestData.OctConversation) + idx = 0uL, + items = listOf(LocalConversationTestData.OctConversation), + scrollerId = DefaultScrollerId ) ) ) @@ -611,12 +641,17 @@ class RustConversationsQueryImplTest { val paginator = mockk { coEvery { nextPage() } answers { CoroutineScope(mainDispatcherRule.testDispatcher).launch { - callbackSlot.captured.onUpdate(ConversationScrollerUpdate.List(ConversationScrollerListUpdate.None)) + callbackSlot.captured.onUpdate( + ConversationScrollerUpdate.List( + ConversationScrollerListUpdate.None(DefaultScrollerId) + ) + ) delay(NONE_FOLLOWUP_GRACE_MS + 100) callbackSlot.captured.onUpdate( ConversationScrollerUpdate.List( ConversationScrollerListUpdate.Append( - lateItems + items = lateItems, + scrollerId = DefaultScrollerId ) ) ) @@ -645,4 +680,9 @@ class RustConversationsQueryImplTest { testScheduler.advanceUntilIdle() coVerify(exactly = 1) { invalidationRepository.submit(PageInvalidationEvent.ConversationsInvalidated) } } + + companion object { + + private const val DefaultScrollerId = "scroller-id" + } } diff --git a/mail-message/data/src/main/kotlin/ch/protonmail/android/mailmessage/data/local/RustMessageListQueryImpl.kt b/mail-message/data/src/main/kotlin/ch/protonmail/android/mailmessage/data/local/RustMessageListQueryImpl.kt index 2b12e2401f..1ef720254c 100644 --- a/mail-message/data/src/main/kotlin/ch/protonmail/android/mailmessage/data/local/RustMessageListQueryImpl.kt +++ b/mail-message/data/src/main/kotlin/ch/protonmail/android/mailmessage/data/local/RustMessageListQueryImpl.kt @@ -311,10 +311,10 @@ class RustMessageListQueryImpl @Inject constructor( fun MessageScrollerUpdate.List.toScrollerUpdate(): ScrollerUpdate = when (val listResult = this.v1) { - is MessageScrollerListUpdate.Append -> Append(listResult.v1) + is MessageScrollerListUpdate.Append -> Append(listResult.items) is MessageScrollerListUpdate.ReplaceFrom -> ReplaceFrom(listResult.idx.toInt(), listResult.items) is MessageScrollerListUpdate.ReplaceBefore -> ReplaceBefore(listResult.idx.toInt(), listResult.items) - MessageScrollerListUpdate.None -> ScrollerUpdate.None + is MessageScrollerListUpdate.None -> ScrollerUpdate.None is MessageScrollerListUpdate.ReplaceRange -> ReplaceRange( listResult.from.toInt(), listResult.to.toInt(), diff --git a/mail-message/data/src/test/kotlin/ch/protonmail/android/mailmessage/data/local/RustMessageListQueryImplTest.kt b/mail-message/data/src/test/kotlin/ch/protonmail/android/mailmessage/data/local/RustMessageListQueryImplTest.kt index dd775cf63a..c2919563d8 100644 --- a/mail-message/data/src/test/kotlin/ch/protonmail/android/mailmessage/data/local/RustMessageListQueryImplTest.kt +++ b/mail-message/data/src/test/kotlin/ch/protonmail/android/mailmessage/data/local/RustMessageListQueryImplTest.kt @@ -94,7 +94,14 @@ class RustMessageListQueryImplTest { showSpamTrash: Boolean = false ): MessagePaginatorWrapper = mockk { coEvery { nextPage() } answers { - callback.captured.onUpdate(MessageScrollerUpdate.List(MessageScrollerListUpdate.Append(items))) + callback.captured.onUpdate( + MessageScrollerUpdate.List( + MessageScrollerListUpdate.Append( + items = items, + scrollerId = DefaultScrollerId + ) + ) + ) Unit.right() } coEvery { destroy() } just Runs @@ -110,7 +117,13 @@ class RustMessageListQueryImplTest { showSpamTrash: Boolean = false ): MessagePaginatorWrapper = mockk { coEvery { reload() } answers { - callback.captured.onUpdate(MessageScrollerUpdate.List(MessageScrollerListUpdate.ReplaceFrom(idx, items))) + callback.captured.onUpdate( + MessageScrollerUpdate.List( + MessageScrollerListUpdate.ReplaceFrom( + idx = idx, items = items, scrollerId = DefaultScrollerId + ) + ) + ) Unit.right() } coEvery { destroy() } just Runs @@ -398,7 +411,13 @@ class RustMessageListQueryImplTest { rustMessageListQuery.getMessages(userId, pageKey) // Then - callback.captured.onUpdate(MessageScrollerUpdate.List(MessageScrollerListUpdate.ReplaceBefore(1u, emptyList()))) + callback.captured.onUpdate( + MessageScrollerUpdate.List( + MessageScrollerListUpdate.ReplaceBefore( + idx = 1u, items = emptyList(), scrollerId = DefaultScrollerId + ) + ) + ) advanceUntilIdle() coVerify { invalidationRepository.submit(PageInvalidationEvent.MessagesInvalidated) } @@ -414,10 +433,18 @@ class RustMessageListQueryImplTest { val paginator = mockk { coEvery { nextPage() } answers { CoroutineScope(mainDispatcherRule.testDispatcher).launch { - callback.captured.onUpdate(MessageScrollerUpdate.List(MessageScrollerListUpdate.None)) + callback.captured.onUpdate( + MessageScrollerUpdate.List( + MessageScrollerListUpdate.None(DefaultScrollerId) + ) + ) delay(NONE_FOLLOWUP_GRACE_MS - 100) callback.captured.onUpdate( - MessageScrollerUpdate.List(MessageScrollerListUpdate.ReplaceBefore(0u, expectedFollowUp)) + MessageScrollerUpdate.List( + MessageScrollerListUpdate.ReplaceBefore( + idx = 0u, items = expectedFollowUp, scrollerId = DefaultScrollerId + ) + ) ) } Unit.right() @@ -451,13 +478,20 @@ class RustMessageListQueryImplTest { val paginator = mockk { coEvery { nextPage() } answers { CoroutineScope(mainDispatcherRule.testDispatcher).launch { - callback.captured.onUpdate(MessageScrollerUpdate.List(MessageScrollerListUpdate.None)) + callback.captured.onUpdate( + MessageScrollerUpdate.List( + MessageScrollerListUpdate.None(DefaultScrollerId) + ) + ) delay(NONE_FOLLOWUP_GRACE_MS + 100) callback.captured.onUpdate( MessageScrollerUpdate.List( MessageScrollerListUpdate.ReplaceBefore( - 0u, - listOf(LocalMessageTestData.OctWeatherForecast) + idx = 0u, + items = listOf( + LocalMessageTestData.OctWeatherForecast + ), + scrollerId = DefaultScrollerId ) ) ) @@ -484,4 +518,9 @@ class RustMessageListQueryImplTest { // Then assertEquals(emptyList().right(), actual) } + + companion object { + + private const val DefaultScrollerId = "scroller-id" + } }