chore: Update plugins and libraries.

AGP 8.9.1
Gradle 8.13
Dagger/Hilt 2.53.1
Jacoco to Cobertura 1.3.2
Room 2.7.2
Store 5.0.0
This commit is contained in:
Mateusz Armatys
2025-09-15 14:47:55 +02:00
parent c10115b0e1
commit a44b79c533
47 changed files with 166 additions and 156 deletions
+1 -1
View File
@@ -69,7 +69,7 @@ dependencies {
project(Module.kotlinUtil),
project(Module.data),
`coroutines-core`,
store4
store5
)
testImplementation(
@@ -19,10 +19,6 @@
package me.proton.core.auth.data.repository
import androidx.work.WorkManager
import com.dropbox.android.external.store4.Fetcher
import com.dropbox.android.external.store4.SourceOfTruth
import com.dropbox.android.external.store4.StoreBuilder
import com.dropbox.android.external.store4.StoreRequest
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.map
@@ -38,6 +34,10 @@ import me.proton.core.data.arch.buildProtonStore
import me.proton.core.domain.entity.UserId
import me.proton.core.util.kotlin.CoroutineScopeProvider
import me.proton.core.util.kotlin.coroutine.result
import org.mobilenativefoundation.store.store5.Fetcher
import org.mobilenativefoundation.store.store5.SourceOfTruth
import org.mobilenativefoundation.store.store5.StoreBuilder
import org.mobilenativefoundation.store.store5.StoreReadRequest
import javax.inject.Inject
class AuthDeviceRepositoryImpl @Inject constructor(
@@ -122,12 +122,12 @@ class AuthDeviceRepositoryImpl @Inject constructor(
}
override fun observeByUserId(userId: UserId, refresh: Boolean): Flow<List<AuthDevice>> =
store.stream(StoreRequest.cached(userId, refresh = refresh))
store.stream(StoreReadRequest.cached(userId, refresh = refresh))
.map { it.dataOrNull().orEmpty() }
.distinctUntilChanged()
override fun observeByDeviceId(userId: UserId, deviceId: AuthDeviceId, refresh: Boolean): Flow<AuthDevice?> =
store.stream(StoreRequest.cached(userId, refresh))
store.stream(StoreReadRequest.cached(userId, refresh))
.map { it.dataOrNull().orEmpty() }
.map { devices -> devices.firstOrNull { it.deviceId == deviceId } }
.distinctUntilChanged()
@@ -18,10 +18,6 @@
package me.proton.core.auth.data.repository
import com.dropbox.android.external.store4.Fetcher
import com.dropbox.android.external.store4.SourceOfTruth
import com.dropbox.android.external.store4.StoreBuilder
import com.dropbox.android.external.store4.StoreRequest
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
import me.proton.core.auth.domain.entity.MemberDevice
@@ -31,6 +27,10 @@ import me.proton.core.auth.domain.repository.MemberDeviceRepository
import me.proton.core.data.arch.buildProtonStore
import me.proton.core.domain.entity.UserId
import me.proton.core.util.kotlin.CoroutineScopeProvider
import org.mobilenativefoundation.store.store5.Fetcher
import org.mobilenativefoundation.store.store5.SourceOfTruth
import org.mobilenativefoundation.store.store5.StoreBuilder
import org.mobilenativefoundation.store.store5.StoreReadRequest
import javax.inject.Inject
class MemberDeviceRepositoryImpl @Inject constructor(
@@ -56,11 +56,11 @@ class MemberDeviceRepositoryImpl @Inject constructor(
if (refresh) store.fresh(userId) else store.get(userId)
override fun observeByMemberId(userId: UserId, memberId: UserId, refresh: Boolean): Flow<List<MemberDevice>> =
store.stream(StoreRequest.cached(userId, refresh))
store.stream(StoreReadRequest.cached(userId, refresh))
.map { it.dataOrNull().orEmpty() }
.map { memberDevices -> memberDevices.filter { it.memberId == memberId } }
override fun observeByUserId(userId: UserId, refresh: Boolean): Flow<List<MemberDevice>> =
store.stream(StoreRequest.cached(userId, refresh))
store.stream(StoreReadRequest.cached(userId, refresh))
.map { it.dataOrNull().orEmpty() }
}
+1 -1
View File
@@ -59,7 +59,7 @@ dependencies {
project(Module.userData),
`coroutines-core`,
store4,
store5,
)
kaptTest(`room-compiler`)
@@ -18,10 +18,6 @@
package me.proton.core.contact.data.repository
import com.dropbox.android.external.store4.Fetcher
import com.dropbox.android.external.store4.SourceOfTruth
import com.dropbox.android.external.store4.StoreBuilder
import com.dropbox.android.external.store4.StoreRequest
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
import me.proton.core.contact.domain.entity.Contact
@@ -39,6 +35,10 @@ import me.proton.core.domain.arch.DataResult
import me.proton.core.domain.arch.mapSuccess
import me.proton.core.domain.entity.UserId
import me.proton.core.util.kotlin.CoroutineScopeProvider
import org.mobilenativefoundation.store.store5.Fetcher
import org.mobilenativefoundation.store.store5.SourceOfTruth
import org.mobilenativefoundation.store.store5.StoreBuilder
import org.mobilenativefoundation.store.store5.StoreReadRequest
import javax.inject.Inject
import javax.inject.Singleton
@@ -97,7 +97,7 @@ class ContactRepositoryImpl @Inject constructor(
refresh: Boolean
): Flow<DataResult<ContactWithCards>> {
val key = ContactStoreKey(userId, contactId)
return contactWithCardsStore.stream(StoreRequest.cached(key, refresh)).map { it.toDataResult() }
return contactWithCardsStore.stream(StoreReadRequest.cached(key, refresh)).map { it.toDataResult() }
}
override suspend fun getContactWithCards(
@@ -110,7 +110,7 @@ class ContactRepositoryImpl @Inject constructor(
}
override fun observeAllContacts(userId: UserId, refresh: Boolean): Flow<DataResult<List<Contact>>> {
return contactsStore.stream(StoreRequest.cached(userId, refresh)).map { it.toDataResult() }
return contactsStore.stream(StoreReadRequest.cached(userId, refresh)).map { it.toDataResult() }
}
override suspend fun getAllContacts(userId: UserId, refresh: Boolean): List<Contact> {
+1 -2
View File
@@ -16,7 +16,6 @@
* along with ProtonCore. If not, see <https://www.gnu.org/licenses/>.
*/
import studio.forface.easygradle.dsl.*
import studio.forface.easygradle.dsl.android.*
plugins {
protonAndroidLibrary
@@ -43,7 +42,7 @@ dependencies {
project(Module.networkDomain),
`androidx-core`,
`coroutines-core`,
store4
store5
)
implementation(
@@ -18,11 +18,11 @@
package me.proton.core.data.arch
import com.dropbox.android.external.store4.Store
import com.dropbox.android.external.store4.StoreBuilder
import com.dropbox.android.external.store4.fresh
import com.dropbox.android.external.store4.get
import me.proton.core.util.kotlin.CoroutineScopeProvider
import org.mobilenativefoundation.store.store5.Store
import org.mobilenativefoundation.store.store5.StoreBuilder
import org.mobilenativefoundation.store.store5.impl.extensions.fresh
import org.mobilenativefoundation.store.store5.impl.extensions.get
import kotlin.coroutines.cancellation.CancellationException
private suspend fun <T> catchWithStackTrace(block: suspend () -> T): T {
@@ -18,31 +18,31 @@
package me.proton.core.data.arch
import com.dropbox.android.external.store4.ResponseOrigin
import com.dropbox.android.external.store4.StoreResponse
import me.proton.core.domain.arch.DataResult
import me.proton.core.domain.arch.ResponseSource
import me.proton.core.util.kotlin.exhaustive
import org.mobilenativefoundation.store.store5.StoreReadResponse
import org.mobilenativefoundation.store.store5.StoreReadResponseOrigin
fun <T> StoreResponse<T>.toDataResult(): DataResult<T> = when (this) {
is StoreResponse.Data ->
fun <T> StoreReadResponse<T>.toDataResult(): DataResult<T> = when (this) {
is StoreReadResponse.Data ->
when (origin) {
ResponseOrigin.Fetcher -> DataResult.Success(ResponseSource.Remote, value)
ResponseOrigin.Cache,
ResponseOrigin.SourceOfTruth -> DataResult.Success(ResponseSource.Local, value)
is StoreReadResponseOrigin.Fetcher -> DataResult.Success(ResponseSource.Remote, value)
is StoreReadResponseOrigin.Cache,
is StoreReadResponseOrigin.SourceOfTruth -> DataResult.Success(ResponseSource.Local, value)
}
is StoreResponse.Error -> {
val cause = (this as? StoreResponse.Error.Exception)?.error
is StoreReadResponse.Error -> {
val cause = (this as? StoreReadResponse.Error.Exception)?.error
when (origin) {
ResponseOrigin.Fetcher -> DataResult.Error.Remote(errorMessageOrNull(), cause)
ResponseOrigin.Cache -> DataResult.Error.Local(errorMessageOrNull(), cause)
ResponseOrigin.SourceOfTruth -> DataResult.Error.Local(errorMessageOrNull(), cause)
is StoreReadResponseOrigin.Fetcher -> DataResult.Error.Remote(errorMessageOrNull(), cause)
is StoreReadResponseOrigin.Cache -> DataResult.Error.Local(errorMessageOrNull(), cause)
is StoreReadResponseOrigin.SourceOfTruth -> DataResult.Error.Local(errorMessageOrNull(), cause)
}
}
is StoreResponse.Loading -> when (origin) {
ResponseOrigin.Fetcher -> DataResult.Processing(ResponseSource.Remote)
ResponseOrigin.Cache,
ResponseOrigin.SourceOfTruth -> DataResult.Processing(ResponseSource.Local)
is StoreReadResponse.Loading -> when (origin) {
is StoreReadResponseOrigin.Fetcher -> DataResult.Processing(ResponseSource.Remote)
is StoreReadResponseOrigin.Cache,
is StoreReadResponseOrigin.SourceOfTruth -> DataResult.Processing(ResponseSource.Local)
}
is StoreResponse.NoNewData -> DataResult.Processing(ResponseSource.Remote)
is StoreReadResponse.NoNewData -> DataResult.Processing(ResponseSource.Remote)
}.exhaustive
@@ -18,10 +18,6 @@
package me.proton.core.data.arch
import com.dropbox.android.external.store4.Fetcher
import com.dropbox.android.external.store4.FetcherResult
import com.dropbox.android.external.store4.SourceOfTruth
import com.dropbox.android.external.store4.StoreBuilder
import io.mockk.coEvery
import io.mockk.mockk
import kotlinx.coroutines.Dispatchers
@@ -33,6 +29,10 @@ import kotlinx.coroutines.test.runTest
import kotlinx.coroutines.test.setMain
import me.proton.core.test.kotlin.TestCoroutineScopeProvider
import me.proton.core.test.kotlin.TestDispatcherProvider
import org.mobilenativefoundation.store.store5.Fetcher
import org.mobilenativefoundation.store.store5.FetcherResult
import org.mobilenativefoundation.store.store5.SourceOfTruth
import org.mobilenativefoundation.store.store5.StoreBuilder
import kotlin.test.AfterTest
import kotlin.test.BeforeTest
import kotlin.test.Test
@@ -18,11 +18,11 @@
package me.proton.core.data.arch
import com.dropbox.android.external.store4.ResponseOrigin
import com.dropbox.android.external.store4.StoreResponse
import io.mockk.mockk
import me.proton.core.domain.arch.DataResult
import me.proton.core.domain.arch.ResponseSource
import org.mobilenativefoundation.store.store5.StoreReadResponse
import org.mobilenativefoundation.store.store5.StoreReadResponseOrigin
import kotlin.test.Test
import kotlin.test.assertEquals
@@ -31,15 +31,15 @@ class StoreResponseMapperKtTest {
fun toSuccessDataResult() {
assertEquals(
DataResult.Success(ResponseSource.Local, "body"),
StoreResponse.Data("body", ResponseOrigin.Cache).toDataResult()
StoreReadResponse.Data("body", StoreReadResponseOrigin.Cache).toDataResult()
)
assertEquals(
DataResult.Success(ResponseSource.Remote, "body"),
StoreResponse.Data("body", ResponseOrigin.Fetcher).toDataResult()
StoreReadResponse.Data("body", StoreReadResponseOrigin.Fetcher()).toDataResult()
)
assertEquals(
DataResult.Success(ResponseSource.Local, "body"),
StoreResponse.Data("body", ResponseOrigin.SourceOfTruth).toDataResult()
StoreReadResponse.Data("body", StoreReadResponseOrigin.SourceOfTruth).toDataResult()
)
}
@@ -48,17 +48,17 @@ class StoreResponseMapperKtTest {
val cause = Throwable("cause")
assertEquals(
DataResult.Error.Local("cause", cause),
StoreResponse.Error.Exception(cause, ResponseOrigin.Cache).toDataResult()
StoreReadResponse.Error.Exception(cause, StoreReadResponseOrigin.Cache).toDataResult()
)
assertEquals(
DataResult.Error.Remote("msg", null),
StoreResponse.Error.Message("msg", ResponseOrigin.Fetcher).toDataResult()
StoreReadResponse.Error.Message("msg", StoreReadResponseOrigin.Fetcher()).toDataResult()
)
assertEquals(
DataResult.Error.Local("msg", null),
StoreResponse.Error.Message("msg", ResponseOrigin.SourceOfTruth).toDataResult()
StoreReadResponse.Error.Message("msg", StoreReadResponseOrigin.SourceOfTruth).toDataResult()
)
}
@@ -66,22 +66,22 @@ class StoreResponseMapperKtTest {
fun toProcessingDataResult() {
assertEquals(
DataResult.Processing(ResponseSource.Local),
StoreResponse.Loading(ResponseOrigin.Cache).toDataResult()
StoreReadResponse.Loading(StoreReadResponseOrigin.Cache).toDataResult()
)
assertEquals(
DataResult.Processing(ResponseSource.Local),
StoreResponse.Loading(ResponseOrigin.SourceOfTruth).toDataResult()
StoreReadResponse.Loading(StoreReadResponseOrigin.SourceOfTruth).toDataResult()
)
assertEquals(
DataResult.Processing(ResponseSource.Remote),
StoreResponse.Loading(ResponseOrigin.Fetcher).toDataResult()
StoreReadResponse.Loading(StoreReadResponseOrigin.Fetcher()).toDataResult()
)
assertEquals(
DataResult.Processing(ResponseSource.Remote),
StoreResponse.NoNewData(mockk()).toDataResult()
StoreReadResponse.NoNewData(mockk()).toDataResult()
)
}
}
+1 -1
View File
@@ -67,7 +67,7 @@ dependencies {
retrofit,
`room-ktx`,
`serialization-core`,
store4
store5
)
testImplementation(
@@ -18,10 +18,6 @@
package me.proton.core.featureflag.data.repository
import com.dropbox.android.external.store4.Fetcher
import com.dropbox.android.external.store4.SourceOfTruth
import com.dropbox.android.external.store4.StoreBuilder
import com.dropbox.android.external.store4.StoreRequest
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.first
@@ -45,6 +41,10 @@ import me.proton.core.observability.domain.ObservabilityContext
import me.proton.core.observability.domain.ObservabilityManager
import me.proton.core.observability.domain.metrics.FeatureFlagAwaitTotal
import me.proton.core.util.kotlin.CoroutineScopeProvider
import org.mobilenativefoundation.store.store5.Fetcher
import org.mobilenativefoundation.store.store5.SourceOfTruth
import org.mobilenativefoundation.store.store5.StoreBuilder
import org.mobilenativefoundation.store.store5.StoreReadRequest
import javax.inject.Inject
import javax.inject.Singleton
@@ -138,7 +138,7 @@ public class FeatureFlagRepositoryImpl @Inject internal constructor(
featureIds: Set<FeatureId>,
refresh: Boolean
): Flow<List<FeatureFlag>> = StoreKey(userId = userId, featureIds = featureIds).let { key ->
store.stream(StoreRequest.cached(key, refresh))
store.stream(StoreReadRequest.cached(key, refresh))
.map { it.dataOrNull().orEmpty().filterNot { flag -> flag.scope == Scope.Unknown } }
}
@@ -298,6 +298,7 @@ class FeatureFlagRepositoryImplTest : CoroutinesTest by UnconfinedCoroutinesTest
mutableDbFlow.emit(listOf(enabledFeatureEntity))
val expected = enabledFeature
assertNull(awaitItem())
assertEquals(expected, awaitItem())
}
}
@@ -326,6 +327,7 @@ class FeatureFlagRepositoryImplTest : CoroutinesTest by UnconfinedCoroutinesTest
mutableDbFlow.emit(listOf(enabledFeatureEntity, disabledFeatureEntity))
val expected = listOf(enabledFeature, disabledFeature)
assertEquals(emptyList(), awaitItem())
assertEquals(expected, awaitItem())
}
coVerify(Ordering.ORDERED) {
@@ -372,6 +374,7 @@ class FeatureFlagRepositoryImplTest : CoroutinesTest by UnconfinedCoroutinesTest
// Unknown flag is filtered out.
val expected = listOf(enabledFeature)
assertEquals(emptyList(), awaitItem())
assertEquals(expected, awaitItem())
}
coVerify(Ordering.ORDERED) {
+3 -3
View File
@@ -1,8 +1,8 @@
[versions]
androidGradle = "8.7.3"
androidGradle = "8.9.1"
arturboschDetektGradle = "1.23.5"
benManesVersions = "0.44.0"
daggerHiltAndroid = "2.49"
daggerHiltAndroid = "2.53.1"
dependencyAnalysis = "2.4.2"
detekt = "1.23.5"
easyGradle = "2.8"
@@ -12,7 +12,7 @@ kotlinDokka = "1.9.10"
kotlinCoroutines = "1.8.0"
kotlinSerialization = "1.6.3"
kotlinx-kover = "0.8.2"
jacoco-to-cobertura = "1.2.0"
jacoco-to-cobertura = "1.3.2"
vanniktechPublish = "0.33.0"
paparazzi = "1.3.4"
Binary file not shown.
+3 -3
View File
@@ -1,3 +1,3 @@
# Gradle 8.9
# Updated on Thu Jan 23 17:59:28 CET 2025
498495120a03b9a6ab5d155f5de3c8f0d986a449153702fb80fc80e134484f17 gradle-wrapper.jar
# Gradle 8.13
# Updated on Mon Sep 15 14:27:06 CEST 2025
81a82aaea5abcc8ff68b3dfcb58b3c3c429378efd98e7433460610fecd7ae45f gradle-wrapper.jar
+2 -3
View File
@@ -1,8 +1,7 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip
# https://gradle.org/release-checksums
distributionSha256Sum=d725d707bfabd4dfdc958c624003b3c80accc03f7037b5122c4b1d0ef15cecab
distributionUrl=https\://services.gradle.org/distributions/gradle-8.13-bin.zip
distributionSha256Sum=20f1b1176237254a6fc204d8434196fa11a4cfb387567519c61556e8710aed78
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
Vendored
+2 -3
View File
@@ -86,8 +86,7 @@ done
# shellcheck disable=SC2034
APP_BASE_NAME=${0##*/}
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s
' "$PWD" ) || exit
APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD=maximum
@@ -206,7 +205,7 @@ fi
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Collect all arguments for the java command:
# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
# and any embedded shellness will be escaped.
# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
# treated as '${Hostname}' itself on the command line.
+1 -1
View File
@@ -59,7 +59,7 @@ dependencies {
project(Module.authDomain),
`coroutines-core`,
`room-ktx`,
store4
store5
)
androidTestImplementation(
@@ -18,9 +18,6 @@
package me.proton.core.key.data.repository
import com.dropbox.android.external.store4.Fetcher
import com.dropbox.android.external.store4.SourceOfTruth
import com.dropbox.android.external.store4.StoreBuilder
import kotlinx.coroutines.flow.map
import me.proton.core.data.arch.buildProtonStore
import me.proton.core.domain.entity.SessionUserId
@@ -33,6 +30,9 @@ import me.proton.core.key.domain.repository.KeySaltRepository
import me.proton.core.network.data.ApiProvider
import me.proton.core.util.kotlin.CoroutineScopeProvider
import me.proton.core.util.kotlin.takeIfNotEmpty
import org.mobilenativefoundation.store.store5.Fetcher
import org.mobilenativefoundation.store.store5.SourceOfTruth
import org.mobilenativefoundation.store.store5.StoreBuilder
import javax.inject.Inject
class KeySaltRepositoryImpl @Inject constructor(
@@ -62,5 +62,5 @@ class KeySaltRepositoryImpl @Inject constructor(
override suspend fun clear(userId: UserId) = store.clear(userId)
override suspend fun clearAll() = store.clearAll()
override suspend fun clearAll() = store.clear()
}
@@ -18,9 +18,6 @@
package me.proton.core.key.data.repository
import com.dropbox.android.external.store4.Fetcher
import com.dropbox.android.external.store4.SourceOfTruth
import com.dropbox.android.external.store4.StoreBuilder
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
import me.proton.core.data.arch.buildProtonStore
@@ -38,12 +35,15 @@ import me.proton.core.key.domain.entity.key.PublicAddress
import me.proton.core.key.domain.entity.key.PublicAddressInfo
import me.proton.core.key.domain.entity.key.PublicSignedKeyList
import me.proton.core.key.domain.repository.PublicAddressRepository
import me.proton.core.key.domain.repository.Source
import me.proton.core.key.domain.repository.PublicAddressVerifier
import me.proton.core.key.domain.repository.Source
import me.proton.core.network.data.ApiProvider
import me.proton.core.network.domain.CacheOverride
import me.proton.core.util.kotlin.CoroutineScopeProvider
import me.proton.core.util.kotlin.toInt
import org.mobilenativefoundation.store.store5.Fetcher
import org.mobilenativefoundation.store.store5.SourceOfTruth
import org.mobilenativefoundation.store.store5.StoreBuilder
import java.util.Optional
import javax.inject.Inject
@@ -189,7 +189,7 @@ class PublicAddressRepositoryImpl @Inject constructor(
}.valueOrThrow
override suspend fun clearAll() {
publicAddressInfoStore.clearAll()
store.clearAll()
publicAddressInfoStore.clear()
store.clear()
}
}
@@ -244,7 +244,6 @@ class PublicAddressRepositoryImplTest {
coEvery { keyApi.getAllActivePublicKeys(any(), any(), any()) } returns testResponse
coEvery { publicAddressInfoWithKeysDao.findWithKeysByEmail(testEmail) } returns flowOf(
null,
testResponse.toPublicAddressInfo(testEmail).toEntity()
)
coJustRun { publicAddressInfoDao.deleteByEmail(testEmail) }
+1 -1
View File
@@ -66,7 +66,7 @@ dependencies {
// Other
`android-work-runtime`,
store4,
store5,
)
kaptTest(`room-compiler`)
@@ -20,10 +20,6 @@ package me.proton.core.label.data.repository
import androidx.work.ExistingWorkPolicy
import androidx.work.WorkManager
import com.dropbox.android.external.store4.Fetcher
import com.dropbox.android.external.store4.SourceOfTruth
import com.dropbox.android.external.store4.StoreBuilder
import com.dropbox.android.external.store4.StoreRequest
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
import me.proton.core.data.arch.ProtonStore
@@ -43,6 +39,10 @@ import me.proton.core.label.domain.repository.LabelLocalDataSource
import me.proton.core.label.domain.repository.LabelRemoteDataSource
import me.proton.core.label.domain.repository.LabelRepository
import me.proton.core.util.kotlin.CoroutineScopeProvider
import org.mobilenativefoundation.store.store5.Fetcher
import org.mobilenativefoundation.store.store5.SourceOfTruth
import org.mobilenativefoundation.store.store5.StoreBuilder
import org.mobilenativefoundation.store.store5.StoreReadRequest
import javax.inject.Inject
import javax.inject.Singleton
@@ -74,7 +74,7 @@ class LabelRepositoryImpl @Inject constructor(
override fun observeLabels(userId: UserId, type: LabelType, refresh: Boolean): Flow<DataResult<List<Label>>> =
StoreKey(userId = userId, type = type).let { key ->
store.stream(StoreRequest.cached(key, refresh)).map { it.toDataResult() }
store.stream(StoreReadRequest.cached(key, refresh)).map { it.toDataResult() }
}
override suspend fun getLabels(userId: UserId, type: LabelType, refresh: Boolean): List<Label> =
+1 -1
View File
@@ -68,7 +68,7 @@ dependencies {
// Other
`room-ktx`,
store4
store5
)
testImplementation(
@@ -18,10 +18,6 @@
package me.proton.core.mailsettings.data.repository
import com.dropbox.android.external.store4.Fetcher
import com.dropbox.android.external.store4.SourceOfTruth
import com.dropbox.android.external.store4.StoreBuilder
import com.dropbox.android.external.store4.StoreRequest
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
import me.proton.core.data.arch.buildProtonStore
@@ -54,6 +50,10 @@ import me.proton.core.mailsettings.domain.repository.MailSettingsRepository
import me.proton.core.network.data.ApiProvider
import me.proton.core.util.kotlin.CoroutineScopeProvider
import me.proton.core.util.kotlin.toInt
import org.mobilenativefoundation.store.store5.Fetcher
import org.mobilenativefoundation.store.store5.SourceOfTruth
import org.mobilenativefoundation.store.store5.StoreBuilder
import org.mobilenativefoundation.store.store5.StoreReadRequest
import javax.inject.Inject
@Suppress("TooManyFunctions", "ComplexInterface")
@@ -104,7 +104,7 @@ class MailSettingsRepositoryImpl @Inject constructor(
}
override fun getMailSettingsFlow(userId: UserId, refresh: Boolean) =
store.stream(StoreRequest.cached(userId, refresh = refresh)).map { it.toDataResult() }
store.stream(StoreReadRequest.cached(userId, refresh = refresh)).map { it.toDataResult() }
override suspend fun getMailSettings(userId: UserId, refresh: Boolean) =
if (refresh) store.fresh(userId) else store.get(userId)
@@ -63,6 +63,6 @@ enum class ClientIdType(val value: String) {
companion object {
val map = values().associateBy { it.value }
fun getByValue(value: String) = map[value.toLowerCase(Locale.ROOT)] ?: COOKIE
fun getByValue(value: String) = map[value.lowercase(Locale.ROOT)] ?: COOKIE
}
}
+1 -1
View File
@@ -60,7 +60,7 @@ dependencies {
`room-ktx`,
`serialization-core`,
`serialization-json`,
store4
store5
)
testImplementation(
@@ -18,16 +18,9 @@
package me.proton.core.notification.data.repository
import com.dropbox.android.external.store4.Fetcher
import com.dropbox.android.external.store4.FetcherResult
import com.dropbox.android.external.store4.SourceOfTruth
import com.dropbox.android.external.store4.Store
import com.dropbox.android.external.store4.StoreBuilder
import com.dropbox.android.external.store4.StoreRequest
import com.dropbox.android.external.store4.fresh
import com.dropbox.android.external.store4.get
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.mapNotNull
import me.proton.core.data.arch.ProtonStore
import me.proton.core.data.arch.buildProtonStore
import me.proton.core.domain.entity.UserId
import me.proton.core.notification.domain.entity.Notification
@@ -35,6 +28,14 @@ import me.proton.core.notification.domain.entity.NotificationId
import me.proton.core.notification.domain.repository.NotificationLocalDataSource
import me.proton.core.notification.domain.repository.NotificationRepository
import me.proton.core.util.kotlin.CoroutineScopeProvider
import org.mobilenativefoundation.store.store5.Fetcher
import org.mobilenativefoundation.store.store5.FetcherResult
import org.mobilenativefoundation.store.store5.SourceOfTruth
import org.mobilenativefoundation.store.store5.Store
import org.mobilenativefoundation.store.store5.StoreBuilder
import org.mobilenativefoundation.store.store5.StoreReadRequest
import org.mobilenativefoundation.store.store5.impl.extensions.fresh
import org.mobilenativefoundation.store.store5.impl.extensions.get
import javax.inject.Inject
import javax.inject.Singleton
@@ -72,7 +73,7 @@ public class NotificationRepositoryImpl @Inject constructor(
if (refresh) store.fresh(userId) else store.get(userId)
override fun observeAllNotificationsByUser(userId: UserId, refresh: Boolean): Flow<List<Notification>> =
store.stream(StoreRequest.cached(userId, refresh)).mapNotNull { it.dataOrNull() }
store.stream(StoreReadRequest.cached(userId, refresh)).mapNotNull { it.dataOrNull() }
override suspend fun deleteAllNotificationsByUser(userId: UserId) {
localDataSource.deleteAllNotificationsByUser(userId)
+2 -2
View File
@@ -155,8 +155,8 @@ public val DependencyHandler.`lint-tests`: Any
get() = lint("tests")
public val DependencyHandler.`okHttp-logging`: Any
get() = squareup("okhttp3", module = "logging-interceptor") version `okHttp version`
public val DependencyHandler.store4: Any
get() = dependency("org.mobilenativefoundation.store", module = "store4") version `store4 version`
public val DependencyHandler.store5: Any
get() = dependency("org.mobilenativefoundation.store", module = "store5") version `store5 version`
public val DependencyHandler.cache4k: Any
get() = dependency("io.github.reactivecircus.cache4k", module = "cache4k") version `cache4k version`
public val DependencyHandler.`lifecycle-common`: Any
@@ -67,7 +67,7 @@ internal fun initVersions(libs: VersionCatalog) {
`material version` = "1.7.0"
`android-paging version` = "3.1.0"
`android-work version` = "2.8.1"
`android-room version` = "2.6.1"
`android-room version` = "2.7.2"
`android-test version` = "1.5.0"
`robolectric version` = "4.14.1"
@@ -121,7 +121,7 @@ public const val `leakCanary version`: String = "2.14"
public const val `miniDns version`: String = "1.0.4"
public const val `okHttp version`: String = "4.12.0"
public const val `certificate-transparency version`: String = "2.5.71"
public const val `store4 version`: String = "4.0.7"
public const val `store5 version`: String = "5.0.0"
public const val `cache4k version`: String = "0.13.0"
public const val `lifecycle-extensions version`: String = "2.2.0" // Released: Jan 00, 2020
public const val `lottie version`: String = "4.1.0"
Binary file not shown.
+1 -1
View File
@@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.13-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
+5 -2
View File
@@ -15,6 +15,8 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#
# SPDX-License-Identifier: Apache-2.0
#
##############################################################################
#
@@ -55,7 +57,7 @@
# Darwin, MinGW, and NonStop.
#
# (3) This script is generated from the Groovy template
# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# within the Gradle project.
#
# You can find Gradle at https://github.com/gradle/gradle/.
@@ -84,7 +86,8 @@ done
# shellcheck disable=SC2034
APP_BASE_NAME=${0##*/}
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit
APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s
' "$PWD" ) || exit
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD=maximum
+2
View File
@@ -13,6 +13,8 @@
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@rem SPDX-License-Identifier: Apache-2.0
@rem
@if "%DEBUG%"=="" @echo off
@rem ##########################################################################
+1 -1
View File
@@ -59,7 +59,7 @@ dependencies {
retrofit,
`room-ktx`,
`serialization-core`,
store4,
store5,
`android-work-runtime`,
)
@@ -20,13 +20,6 @@ package me.proton.core.push.data.repository
import androidx.work.ExistingWorkPolicy
import androidx.work.WorkManager
import com.dropbox.android.external.store4.Fetcher
import com.dropbox.android.external.store4.SourceOfTruth
import com.dropbox.android.external.store4.Store
import com.dropbox.android.external.store4.StoreBuilder
import com.dropbox.android.external.store4.StoreRequest
import com.dropbox.android.external.store4.fresh
import com.dropbox.android.external.store4.get
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.mapNotNull
@@ -41,6 +34,13 @@ import me.proton.core.push.domain.local.PushLocalDataSource
import me.proton.core.push.domain.remote.PushRemoteDataSource
import me.proton.core.push.domain.repository.PushRepository
import me.proton.core.util.kotlin.CoroutineScopeProvider
import org.mobilenativefoundation.store.store5.Fetcher
import org.mobilenativefoundation.store.store5.SourceOfTruth
import org.mobilenativefoundation.store.store5.Store
import org.mobilenativefoundation.store.store5.StoreBuilder
import org.mobilenativefoundation.store.store5.StoreReadRequest
import org.mobilenativefoundation.store.store5.impl.extensions.fresh
import org.mobilenativefoundation.store.store5.impl.extensions.get
import javax.inject.Inject
import javax.inject.Singleton
@@ -87,7 +87,7 @@ public class PushRepositoryImpl @Inject constructor(
override fun observeAllPushes(userId: UserId, type: PushObjectType, refresh: Boolean): Flow<List<Push>> {
val storeKey = StoreKey(userId, type)
return pushStore.stream(StoreRequest.cached(storeKey, refresh)).mapNotNull { it.dataOrNull() }
return pushStore.stream(StoreReadRequest.cached(storeKey, refresh)).mapNotNull { it.dataOrNull() }
}
override fun markAsStale(userId: UserId, type: PushObjectType) {
Binary file not shown.
+1 -1
View File
@@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.13-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
+5 -2
View File
@@ -15,6 +15,8 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#
# SPDX-License-Identifier: Apache-2.0
#
##############################################################################
#
@@ -55,7 +57,7 @@
# Darwin, MinGW, and NonStop.
#
# (3) This script is generated from the Groovy template
# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# within the Gradle project.
#
# You can find Gradle at https://github.com/gradle/gradle/.
@@ -84,7 +86,8 @@ done
# shellcheck disable=SC2034
APP_BASE_NAME=${0##*/}
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit
APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s
' "$PWD" ) || exit
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD=maximum
+2
View File
@@ -13,6 +13,8 @@
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@rem SPDX-License-Identifier: Apache-2.0
@rem
@if "%DEBUG%"=="" @echo off
@rem ##########################################################################
+1 -1
View File
@@ -70,7 +70,7 @@ dependencies {
cache4k,
datastorePreferences,
`room-ktx`,
store4
store5
)
testImplementation(
@@ -18,10 +18,6 @@
package me.proton.core.usersettings.data.repository
import com.dropbox.android.external.store4.Fetcher
import com.dropbox.android.external.store4.SourceOfTruth
import com.dropbox.android.external.store4.StoreBuilder
import com.dropbox.android.external.store4.StoreRequest
import io.github.reactivecircus.cache4k.Cache
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
@@ -43,6 +39,10 @@ import me.proton.core.usersettings.domain.entity.OrganizationSettings
import me.proton.core.usersettings.domain.entity.OrganizationSignature
import me.proton.core.usersettings.domain.repository.OrganizationRepository
import me.proton.core.util.kotlin.CoroutineScopeProvider
import org.mobilenativefoundation.store.store5.Fetcher
import org.mobilenativefoundation.store.store5.SourceOfTruth
import org.mobilenativefoundation.store.store5.StoreBuilder
import org.mobilenativefoundation.store.store5.StoreReadRequest
import javax.inject.Inject
import kotlin.time.Duration.Companion.hours
@@ -107,7 +107,7 @@ class OrganizationRepositoryImpl @Inject constructor(
sessionUserId: SessionUserId,
refresh: Boolean
): Flow<DataResult<Organization>> =
storeOrganization.stream(StoreRequest.cached(sessionUserId, refresh)).map { it.toDataResult() }
storeOrganization.stream(StoreReadRequest.cached(sessionUserId, refresh)).map { it.toDataResult() }
override suspend fun getOrganization(sessionUserId: SessionUserId, refresh: Boolean): Organization =
if (refresh) storeOrganization.fresh(sessionUserId) else storeOrganization.get(sessionUserId)
@@ -129,7 +129,7 @@ class OrganizationRepositoryImpl @Inject constructor(
sessionUserId: SessionUserId,
refresh: Boolean
): Flow<DataResult<OrganizationKeys>> =
storeOrganizationKeys.stream(StoreRequest.cached(sessionUserId, refresh)).map { it.toDataResult() }
storeOrganizationKeys.stream(StoreReadRequest.cached(sessionUserId, refresh)).map { it.toDataResult() }
override suspend fun getOrganizationKeys(sessionUserId: SessionUserId, refresh: Boolean) =
if (refresh) storeOrganizationKeys.fresh(sessionUserId) else storeOrganizationKeys.get(sessionUserId)
@@ -20,10 +20,6 @@ package me.proton.core.usersettings.data.repository
import androidx.work.ExistingWorkPolicy
import androidx.work.WorkManager
import com.dropbox.android.external.store4.Fetcher
import com.dropbox.android.external.store4.SourceOfTruth
import com.dropbox.android.external.store4.StoreBuilder
import com.dropbox.android.external.store4.StoreRequest
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
import me.proton.core.auth.domain.usecase.ValidateServerProof
@@ -46,6 +42,10 @@ import me.proton.core.usersettings.domain.repository.UserSettingsLocalDataSource
import me.proton.core.usersettings.domain.repository.UserSettingsRemoteDataSource
import me.proton.core.usersettings.domain.repository.UserSettingsRepository
import me.proton.core.util.kotlin.CoroutineScopeProvider
import org.mobilenativefoundation.store.store5.Fetcher
import org.mobilenativefoundation.store.store5.SourceOfTruth
import org.mobilenativefoundation.store.store5.StoreBuilder
import org.mobilenativefoundation.store.store5.StoreReadRequest
import javax.inject.Inject
class UserSettingsRepositoryImpl @Inject constructor(
@@ -76,7 +76,7 @@ class UserSettingsRepositoryImpl @Inject constructor(
}
override fun getUserSettingsFlow(sessionUserId: SessionUserId, refresh: Boolean): Flow<DataResult<UserSettings>> {
return store.stream(StoreRequest.cached(sessionUserId, refresh = refresh)).map { it.toDataResult() }
return store.stream(StoreReadRequest.cached(sessionUserId, refresh = refresh)).map { it.toDataResult() }
}
override suspend fun getUserSettings(sessionUserId: SessionUserId, refresh: Boolean) =
+1 -1
View File
@@ -72,7 +72,7 @@ dependencies {
// Other
`room-ktx`,
store4,
store5,
cache4k
)
@@ -18,11 +18,6 @@
package me.proton.core.user.data.repository
import com.dropbox.android.external.store4.ExperimentalStoreApi
import com.dropbox.android.external.store4.Fetcher
import com.dropbox.android.external.store4.SourceOfTruth
import com.dropbox.android.external.store4.StoreBuilder
import com.dropbox.android.external.store4.StoreRequest
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.map
@@ -45,6 +40,11 @@ import me.proton.core.user.domain.repository.UserAddressRemoteDataSource
import me.proton.core.user.domain.repository.UserAddressRepository
import me.proton.core.user.domain.repository.UserRepository
import me.proton.core.util.kotlin.CoroutineScopeProvider
import org.mobilenativefoundation.store.store5.ExperimentalStoreApi
import org.mobilenativefoundation.store.store5.Fetcher
import org.mobilenativefoundation.store.store5.SourceOfTruth
import org.mobilenativefoundation.store.store5.StoreBuilder
import org.mobilenativefoundation.store.store5.StoreReadRequest
import javax.inject.Inject
import javax.inject.Singleton
@@ -87,7 +87,7 @@ class UserAddressRepositoryImpl @Inject constructor(
@OptIn(ExperimentalStoreApi::class)
private suspend fun invalidateMemCache(userId: UserId? = null): Unit =
if (userId != null) store.clear(userId) else store.clearAll()
if (userId != null) store.clear(userId) else store.clear()
private suspend fun List<UserAddressKey>.updateIsActive(userId: UserId): List<UserAddressKey> =
userRepository.getUser(userId).useKeysAs(context) { userContext ->
@@ -163,7 +163,7 @@ class UserAddressRepositoryImpl @Inject constructor(
deleteAll(userId)
override fun observeAddresses(sessionUserId: SessionUserId, refresh: Boolean): Flow<List<UserAddress>> =
store.stream(StoreRequest.cached(sessionUserId, refresh = refresh))
store.stream(StoreReadRequest.cached(sessionUserId, refresh = refresh))
.map { it.dataOrNull().orEmpty() }
.distinctUntilChanged()
@@ -19,10 +19,6 @@
package me.proton.core.user.data.repository
import android.content.Context
import com.dropbox.android.external.store4.Fetcher
import com.dropbox.android.external.store4.SourceOfTruth
import com.dropbox.android.external.store4.StoreBuilder
import com.dropbox.android.external.store4.StoreRequest
import dagger.hilt.android.qualifiers.ApplicationContext
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.distinctUntilChanged
@@ -60,6 +56,10 @@ import me.proton.core.user.domain.repository.UserRemoteDataSource
import me.proton.core.user.domain.repository.UserRepository
import me.proton.core.util.kotlin.CoroutineScopeProvider
import me.proton.core.util.kotlin.coroutine.result
import org.mobilenativefoundation.store.store5.Fetcher
import org.mobilenativefoundation.store.store5.SourceOfTruth
import org.mobilenativefoundation.store.store5.StoreBuilder
import org.mobilenativefoundation.store.store5.StoreReadRequest
import javax.inject.Inject
import javax.inject.Singleton
@@ -116,7 +116,7 @@ class UserRepositoryImpl @Inject constructor(
}
override fun observeUser(sessionUserId: SessionUserId, refresh: Boolean): Flow<User?> =
store.stream(StoreRequest.cached(sessionUserId, refresh = refresh))
store.stream(StoreReadRequest.cached(sessionUserId, refresh = refresh))
.map { it.dataOrNull() }
.distinctUntilChanged()