diff --git a/app/android/build.gradle.kts b/app/android/build.gradle.kts index 10edc72..68ec6ec 100644 --- a/app/android/build.gradle.kts +++ b/app/android/build.gradle.kts @@ -166,9 +166,4 @@ dependencies { implementation(project(":app:shared")) implementation(project(":utils:shared")) - - testImplementation("junit:junit:4.13.2") - testImplementation(libs.androidx.compose.material3) - testImplementation("androidx.graphics:graphics-shapes:1.0.1") - testImplementation("org.robolectric:robolectric:4.14.1") } \ No newline at end of file diff --git a/app/android/src/main/AndroidManifest.xml b/app/android/src/main/AndroidManifest.xml index d21ec15..a9c2985 100644 --- a/app/android/src/main/AndroidManifest.xml +++ b/app/android/src/main/AndroidManifest.xml @@ -22,6 +22,9 @@ + iosTarget.binaries.framework { baseName = "ComposeApp" diff --git a/app/shared/src/androidMain/kotlin/ru/fromchat/api/FcmRegistration.android.kt b/app/shared/src/androidMain/kotlin/ru/fromchat/api/FcmRegistration.android.kt index a192856..c4aef63 100644 --- a/app/shared/src/androidMain/kotlin/ru/fromchat/api/FcmRegistration.android.kt +++ b/app/shared/src/androidMain/kotlin/ru/fromchat/api/FcmRegistration.android.kt @@ -1,6 +1,7 @@ package ru.fromchat.api import com.google.android.gms.tasks.Task +import com.google.firebase.installations.FirebaseInstallations import com.google.firebase.messaging.FirebaseMessaging import com.pr0gramm3r101.utils.settings.settings import kotlinx.coroutines.Dispatchers @@ -13,17 +14,25 @@ import kotlin.coroutines.resumeWithException private const val PENDING_FCM_TOKEN_KEY = "pending_fcm_token" private const val CURRENT_FCM_TOKEN_KEY = "current_fcm_token" -private suspend fun fetchCurrentFcmToken(): String? = suspendCancellableCoroutine { cont -> - FirebaseMessaging.getInstance().token - .addOnCompleteListener { task: Task -> - if (task.isSuccessful) { - cont.resume(task.result) - } else { - cont.resumeWithException( - task.exception ?: IllegalStateException("Failed to fetch FCM token") - ) - } +private suspend fun Task.awaitResult(): T = suspendCancellableCoroutine { cont -> + addOnCompleteListener { task -> + if (task.isSuccessful) { + cont.resume(task.result) + } else { + cont.resumeWithException( + task.exception ?: IllegalStateException("Firebase task failed"), + ) } + } +} + +/** Registers with FCM and returns the Firebase Installation ID used for targeting. */ +private suspend fun fetchCurrentFcmToken(): String? = runCatching { + FirebaseMessaging.getInstance().register().awaitResult() + FirebaseInstallations.getInstance().id.awaitResult() +}.getOrElse { e -> + Logger.e("FcmReg", "Failed to fetch FCM installation id: ${e.message}", e) + null } private suspend fun postFcmToken(token: String): Boolean { diff --git a/app/shared/src/androidMain/kotlin/ru/fromchat/api/crypto/dm/PlatformAesGcmStreamDecrypt.android.kt b/app/shared/src/androidMain/kotlin/ru/fromchat/api/crypto/dm/PlatformAesGcmStreamDecrypt.android.kt index caa99c3..5c28097 100644 --- a/app/shared/src/androidMain/kotlin/ru/fromchat/api/crypto/dm/PlatformAesGcmStreamDecrypt.android.kt +++ b/app/shared/src/androidMain/kotlin/ru/fromchat/api/crypto/dm/PlatformAesGcmStreamDecrypt.android.kt @@ -40,7 +40,7 @@ internal actual suspend fun platformAesGcmStreamDecryptMekFile( outputFile.delete() } - val cipher = GCMBlockCipher.newInstance(AESEngine()) + val cipher = GCMBlockCipher.newInstance(AESEngine.newInstance()) cipher.init(false, AEADParameters(KeyParameter(key), 128, iv)) val inBuf = ByteArray(FILE_DECRYPT_BUFFER_BYTES) diff --git a/app/shared/src/commonMain/kotlin/ru/fromchat/api/local/db/store/MessageCacheStore.kt b/app/shared/src/commonMain/kotlin/ru/fromchat/api/local/db/store/MessageCacheStore.kt index 2b2ad6d..e1cf54d 100644 --- a/app/shared/src/commonMain/kotlin/ru/fromchat/api/local/db/store/MessageCacheStore.kt +++ b/app/shared/src/commonMain/kotlin/ru/fromchat/api/local/db/store/MessageCacheStore.kt @@ -386,7 +386,7 @@ object MessageCacheStore { if (product in 0.92f..1.08f && kotlin.math.abs(decodedAspect - serverAspect) > 0.15f) { resolved = resolved.copy( fileAspectRatios = listOf(decodedAspect), - fileDimensions = thumbDims?.let { listOf(it.first to it.second) } ?: resolved.fileDimensions, + fileDimensions = listOf(thumbDims.first to thumbDims.second), ) } } diff --git a/app/shared/src/commonMain/kotlin/ru/fromchat/ui/chat/ChatScreen.kt b/app/shared/src/commonMain/kotlin/ru/fromchat/ui/chat/ChatScreen.kt index 4600562..53fd231 100644 --- a/app/shared/src/commonMain/kotlin/ru/fromchat/ui/chat/ChatScreen.kt +++ b/app/shared/src/commonMain/kotlin/ru/fromchat/ui/chat/ChatScreen.kt @@ -1189,7 +1189,7 @@ fun ChatScreen( .getOrNull(panelState.messages.lastIndex - 1) previous != null && messageListKey(previous) == listKey && - classifyEnterMode(previous, newest!!) == + classifyEnterMode(previous, newest) == EnterMode.ExtendGroup } val showTimestamp = when { diff --git a/app/shared/src/commonMain/kotlin/ru/fromchat/ui/chat/components/ChatFileAttachmentTile.kt b/app/shared/src/commonMain/kotlin/ru/fromchat/ui/chat/components/ChatFileAttachmentTile.kt index c6bf504..7d3b940 100644 --- a/app/shared/src/commonMain/kotlin/ru/fromchat/ui/chat/components/ChatFileAttachmentTile.kt +++ b/app/shared/src/commonMain/kotlin/ru/fromchat/ui/chat/components/ChatFileAttachmentTile.kt @@ -136,7 +136,7 @@ fun ChatFileAttachmentTile( } } } - downloadPaused && canDownload -> file?.let { downloadFile -> + downloadPaused && file != null && canDownload -> { { AttachmentDownloadNotifier.beginDownload( messageId = messageId, @@ -148,7 +148,7 @@ fun ChatFileAttachmentTile( val ok = downloadAttachmentToCache( messageId = messageId, fileIndex = fileIndex, - file = downloadFile, + file = file, dmEnvelope = dmEnvelope, currentUserId = currentUserId, clientMessageId = clientMessageId, @@ -166,7 +166,7 @@ fun ChatFileAttachmentTile( } } } - canDownload && !isDownloading && !downloadPaused -> file?.let { downloadFile -> + file != null && canDownload && !isDownloading && !downloadPaused -> { { AttachmentDownloadNotifier.beginDownload( messageId = messageId, @@ -178,7 +178,7 @@ fun ChatFileAttachmentTile( val ok = downloadAttachmentToCache( messageId = messageId, fileIndex = fileIndex, - file = downloadFile, + file = file, dmEnvelope = dmEnvelope, currentUserId = currentUserId, clientMessageId = clientMessageId, diff --git a/app/shared/src/commonMain/kotlin/ru/fromchat/ui/main/chats/ChatListShared.kt b/app/shared/src/commonMain/kotlin/ru/fromchat/ui/main/chats/ChatListShared.kt index 678eb8d..924b2b2 100644 --- a/app/shared/src/commonMain/kotlin/ru/fromchat/ui/main/chats/ChatListShared.kt +++ b/app/shared/src/commonMain/kotlin/ru/fromchat/ui/main/chats/ChatListShared.kt @@ -938,13 +938,13 @@ internal fun DmConversationRowContent( val avatarUrl = if (isPeerDeleted) null else cached?.profilePicture val peerTitle = when { isPeerDeleted -> deletedUserDisplayNameForUi() - !cached?.displayName.isNullOrBlank() -> cached.displayName!!.trim() + !cached?.displayName.isNullOrBlank() -> cached.displayName.trim() conversation.displayName.isNotBlank() -> conversation.displayName else -> cached?.visibleUsername(currentUserId).orEmpty() } val avatarInitialsLabel = when { isPeerDeleted -> deletedUserDisplayNameForUi() - !cached?.displayName.isNullOrBlank() -> cached.displayName!!.trim() + !cached?.displayName.isNullOrBlank() -> cached.displayName.trim() conversation.displayName.isNotBlank() -> conversation.displayName else -> "" } diff --git a/app/shared/src/commonMain/kotlin/ru/fromchat/ui/main/chats/ChatsTab.kt b/app/shared/src/commonMain/kotlin/ru/fromchat/ui/main/chats/ChatsTab.kt index 9e3db6b..f9ff83a 100644 --- a/app/shared/src/commonMain/kotlin/ru/fromchat/ui/main/chats/ChatsTab.kt +++ b/app/shared/src/commonMain/kotlin/ru/fromchat/ui/main/chats/ChatsTab.kt @@ -90,15 +90,14 @@ import androidx.compose.ui.input.pointer.pointerInput import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.layout.onGloballyPositioned import androidx.compose.ui.layout.positionInRoot -import androidx.compose.ui.platform.LocalClipboardManager import androidx.compose.ui.platform.LocalDensity -import androidx.compose.ui.text.AnnotatedString import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.IntOffset import androidx.compose.ui.unit.IntSize import androidx.compose.ui.unit.dp import coil3.compose.AsyncImage +import com.pr0gramm3r101.utils.supportClipboardManagerImpl import kotlinx.coroutines.coroutineScope import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.first @@ -529,7 +528,7 @@ fun ChatsTab( animatedVisibilityScope: AnimatedVisibilityScope? = null, ) { val navController = LocalNavController.current - val clipboardManager = LocalClipboardManager.current + val clipboard = supportClipboardManagerImpl val haptic = rememberHapticFeedback() val scope = rememberCoroutineScope() val connectionStatus by ConnectionStateStore.status.collectAsState() @@ -1092,7 +1091,9 @@ fun ChatsTab( chatContextMenuOverlay.onLink = { when (contextMenuState.target) { ChatContextMenuTarget.Public -> { - publicChatLink?.let { clipboardManager.setText(AnnotatedString(it)) } + publicChatLink?.let { link -> + scope.launch { clipboard.setText(link) } + } } ChatContextMenuTarget.Dm -> { val link = contextMenuState.otherUserId?.let { userId -> @@ -1100,7 +1101,7 @@ fun ChatsTab( val username = cached?.visibleUsername(ApiClient.user?.id) ?: cached?.username username?.let { "https://fromchat.ru/@$it" } ?: "https://fromchat.ru/?u=$userId" } - link?.let { clipboardManager.setText(AnnotatedString(it)) } + link?.let { scope.launch { clipboard.setText(it) } } } } } diff --git a/app/shared/src/commonMain/kotlin/ru/fromchat/ui/profile/ProfileScreen.kt b/app/shared/src/commonMain/kotlin/ru/fromchat/ui/profile/ProfileScreen.kt index 68f7a3e..a57b03f 100644 --- a/app/shared/src/commonMain/kotlin/ru/fromchat/ui/profile/ProfileScreen.kt +++ b/app/shared/src/commonMain/kotlin/ru/fromchat/ui/profile/ProfileScreen.kt @@ -105,10 +105,7 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.geometry.Rect import androidx.compose.ui.layout.onGloballyPositioned import androidx.compose.ui.layout.positionInRoot -import androidx.compose.ui.platform.ClipboardManager -import androidx.compose.ui.platform.LocalClipboardManager import androidx.compose.ui.platform.LocalDensity -import androidx.compose.ui.text.AnnotatedString import androidx.compose.ui.unit.dp import com.pr0gramm3r101.components.Category import com.pr0gramm3r101.components.ContextMenuPressable @@ -267,7 +264,6 @@ fun ProfileScreen( onOpenSettings: () -> Unit = {}, showBackButton: Boolean = false, ) { - val clipboardManager: ClipboardManager = LocalClipboardManager.current val clipboard = supportClipboardManagerImpl val navController = LocalNavController.current val scope = rememberCoroutineScope() @@ -377,7 +373,7 @@ fun ProfileScreen( ApiClient.applyOwnProfile(refreshed) state = latestUi.copy(profile = refreshed, error = null) } catch (_: Exception) { - ownUserId?.let { ProfileCache.get(it) }?.let { cached -> + ownUserId.let { ProfileCache.get(it) }?.let { cached -> state = latestUi.copy(profile = cached) } } @@ -609,7 +605,7 @@ fun ProfileScreen( ProfileAction( label = labelLink, icon = Icons.Filled.Link, - onClick = { clipboardManager.setText(AnnotatedString(profileLink.orEmpty())) }, + onClick = { scope.launch { clipboard.setText(profileLink.orEmpty()) } }, ), ProfileAction( label = labelSettings, @@ -654,7 +650,7 @@ fun ProfileScreen( ProfileAction( label = labelLink, icon = Icons.Filled.Link, - onClick = { clipboardManager.setText(AnnotatedString(profileLink.orEmpty())) }, + onClick = { scope.launch { clipboard.setText(profileLink.orEmpty()) } }, ) ) if (ServerConfig.callsEnabled) { @@ -831,7 +827,6 @@ fun ProfileScreen( labelCopy = labelCopy, labelEdit = labelEdit, detailsBringIntoView = detailsBringIntoView, - clipboardManager = clipboardManager, clipboard = clipboard, navController = navController, scope = scope, @@ -880,7 +875,6 @@ fun PublicChatProfileScreen( initialDisplayName: String? = null, showBackButton: Boolean = false, ) { - val clipboardManager = LocalClipboardManager.current val clipboard = supportClipboardManagerImpl val scope = rememberCoroutineScope() val snackbarHostState = remember { SnackbarHostState() } @@ -962,7 +956,7 @@ fun PublicChatProfileScreen( ProfileAction( label = labelLink, icon = Icons.Filled.Link, - onClick = { clipboardManager.setText(AnnotatedString(profileLink.orEmpty())) }, + onClick = { scope.launch { clipboard.setText(profileLink.orEmpty()) } }, ), ProfileAction( label = labelSearch, @@ -1003,15 +997,15 @@ fun PublicChatProfileScreen( when { useSharedAvatar && displayName.isNotBlank() -> { item { - with(sharedTransitionScope!!) { + with(sharedTransitionScope) { Avatar( profilePictureUrl = null, displayName = displayName, modifier = Modifier .padding(top = profileAvatarTop) .sharedElement( - rememberSharedContentState(key = sharedAvatarKey!!), - animatedVisibilityScope = animatedVisibilityScope!!, + rememberSharedContentState(key = sharedAvatarKey), + animatedVisibilityScope = animatedVisibilityScope, ) .size(104.dp), ) @@ -1320,7 +1314,6 @@ private fun ProfileLoadedBody( labelCopy: String, labelEdit: String, detailsBringIntoView: BringIntoViewRequester, - clipboardManager: ClipboardManager, clipboard: SupportClipboardManager, navController: NavController, scope: CoroutineScope, @@ -1349,7 +1342,7 @@ private fun ProfileLoadedBody( onContextMenuOpen = openContextMenuHaptic, contextMenu = { item(Icons.Rounded.ContentCopy, labelCopy) { - clipboardManager.setText(AnnotatedString(displayName)) + scope.launch { clipboard.setText(displayName) } } if (isOwnProfile) { item(Icons.Rounded.Edit, labelEdit) { @@ -1453,9 +1446,9 @@ private fun ProfileLoadedBody( }, contextMenu = { item(Icons.Rounded.ContentCopy, labelCopy) { - clipboardManager.setText( - AnnotatedString(usernameForLinks.orEmpty()), - ) + scope.launch { + clipboard.setText(usernameForLinks.orEmpty()) + } } if (isOwnProfile) { item(Icons.Rounded.Edit, labelEdit) { @@ -1491,7 +1484,7 @@ private fun ProfileLoadedBody( }, contextMenu = { item(Icons.Rounded.ContentCopy, labelCopy) { - clipboardManager.setText(AnnotatedString(memberSinceText)) + scope.launch { clipboard.setText(memberSinceText) } } }, ) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 442bf60..63cc85e 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,52 +1,53 @@ [versions] -agp = "9.1.1" +agp = "9.3.0" androidx-activityCompose = "1.13.0" androidx-appcompat = "1.7.1" -androidx-core-ktx = "1.18.0" -androidx-exifinterface = "1.3.7" -coilCompose = "3.4.0" -compose-multiplatform = "1.10.3" +androidx-core-ktx = "1.19.0" +androidx-exifinterface = "1.4.2" +coilCompose = "3.5.0" +compose-multiplatform = "1.11.1" #noinspection NewerVersionAvailable constraintlayout = "0.6.1-shaded" coreSplashscreen = "1.2.0" -firebaseMessaging = "25.0.2" -googleServices = "4.4.4" +firebaseMessaging = "25.1.1" +googleServices = "4.5.0" haze = "1.7.2" -kotlin = "2.3.21" +junit = "4.13.2" +kotlin = "2.4.10" adaptiveAndroid = "1.2.0" biometric = "1.4.0-alpha07" gson = "2.14.0" -kotlinxIoBytestring = "0.9.0" +kotlinxIoBytestring = "0.9.1" kotlinxCoroutinesCore = "1.11.0" -kotlinxIoCore = "0.9.0" +kotlinxIoCore = "0.9.1" multiplatformCryptoLibsodiumBindings = "0.9.5" multiplatformSettings = "1.3.0" -serialization = "2.3.21" +serialization = "2.4.10" serialization-json = "1.11.0" -material = "1.13.0" +material = "1.14.0" activityKtx = "1.13.0" navigationCompose = "2.9.2" datastore = "1.2.1" security-crypto = "1.1.0" -ktor = "3.4.3" +ktor = "3.5.1" slf4j = "1.7.36" kotlinxDatetime = "0.8.0" -lifecycleRuntimeKtx = "2.10.0" -composeBom = "2026.05.00" +lifecycleRuntimeKtx = "2.11.0" +composeBom = "2026.06.01" composeMaterialIconsExtended = "1.7.3" composeMaterial3 = "1.10.0-alpha05" -composeComponents = "1.10.3" +composeComponents = "1.11.1" playServicesBase = "18.10.0" tweetnaclJava = "1.1.3" androidxWork = "2.11.2" cryptography-kotlin = "0.6.0" krypto = "4.0.10" sqldelight = "2.3.2" -livekitAndroid = "2.25.2" -livekitAndroidComposeComponents = "2.3.0" -markdownRendererM3 = "0.41.0" -bouncycastle = "1.79" -webkit = "1.14.0" +livekitAndroid = "2.27.0" +livekitAndroidComposeComponents = "2.4.0" +markdownRendererM3 = "0.43.0" +bouncycastle = "1.85" +webkit = "1.16.0" [libraries] androidx-core-splashscreen = { module = "androidx.core:core-splashscreen", version.ref = "coreSplashscreen" } @@ -66,6 +67,7 @@ haze-materials = { module = "dev.chrisbanes.haze:haze-materials", version.ref = jetbrains-kotlinx-coroutines-core = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "kotlinxCoroutinesCore" } jetbrains-kotlinx-io-bytestring = { module = "org.jetbrains.kotlinx:kotlinx-io-bytestring", version.ref = "kotlinxIoBytestring" } androidx-adaptive-android = { group = "androidx.compose.material3.adaptive", name = "adaptive-android", version.ref = "adaptiveAndroid" } +junit = { module = "junit:junit", version.ref = "junit" } kotlin-stdlib = { group = "org.jetbrains.kotlin", name = "kotlin-stdlib", version.ref = "kotlin" } biometric = { module = "androidx.biometric:biometric", version.ref = "biometric" } gson = { module = "com.google.code.gson:gson", version.ref = "gson" } @@ -87,7 +89,6 @@ ktor-client-serialization-kotlinx-json = { module = "io.ktor:ktor-serialization- ktor-client-websockets = { module = "io.ktor:ktor-client-websockets", version.ref = "ktor" } ktor-client-logging = { module = "io.ktor:ktor-client-logging", version.ref = "ktor" } ktor-client-okhttp = { module = "io.ktor:ktor-client-okhttp", version.ref = "ktor" } -ktor-client-cio = { module = "io.ktor:ktor-client-cio", version.ref = "ktor" } ktor-client-darwin = { module = "io.ktor:ktor-client-darwin", version.ref = "ktor" } slf4j-android = { module = "org.slf4j:slf4j-android", version.ref = "slf4j" } kotlinx-datetime = { module = "org.jetbrains.kotlinx:kotlinx-datetime", version.ref = "kotlinxDatetime" } @@ -104,7 +105,6 @@ compose-foundation = { module = "org.jetbrains.compose.foundation:foundation", v compose-material3 = { module = "org.jetbrains.compose.material3:material3", version.ref = "composeMaterial3" } compose-ui = { module = "org.jetbrains.compose.ui:ui", version.ref = "compose-multiplatform" } compose-components-resources = { module = "org.jetbrains.compose.components:components-resources", version.ref = "composeComponents" } -compose-ui-tooling-preview = { module = "org.jetbrains.compose.ui:ui-tooling-preview", version.ref = "compose-multiplatform" } compose-materialIconsExtended = { module = "org.jetbrains.compose.material:material-icons-extended", version.ref = "composeMaterialIconsExtended" } tweetnacl-java = { module = "org.purejava:tweetnacl-java", version.ref = "tweetnaclJava" } krypto = { module = "com.soywiz.korlibs.krypto:krypto", version.ref = "krypto" } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index b52fb7e..078785f 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,9 +1,6 @@ +#Tue Jul 21 20:27:03 MSK 2026 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-9.5.0-bin.zip -networkTimeout=10000 -retries=0 -retryBackOffMs=500 -validateDistributionUrl=true +distributionUrl=https\://services.gradle.org/distributions/gradle-9.6.1-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/utils/shared/build.gradle.kts b/utils/shared/build.gradle.kts index aff24d4..83a7f43 100644 --- a/utils/shared/build.gradle.kts +++ b/utils/shared/build.gradle.kts @@ -18,8 +18,7 @@ kotlin { listOf( iosArm64(), - iosSimulatorArm64(), - iosX64(), + iosSimulatorArm64() ).forEach { it.binaries.framework { baseName = "shared" diff --git a/utils/shared/src/androidMain/kotlin/com/pr0gramm3r101/utils/ClipboardSupport.android.kt b/utils/shared/src/androidMain/kotlin/com/pr0gramm3r101/utils/ClipboardSupport.android.kt index f4097b3..372ad14 100644 --- a/utils/shared/src/androidMain/kotlin/com/pr0gramm3r101/utils/ClipboardSupport.android.kt +++ b/utils/shared/src/androidMain/kotlin/com/pr0gramm3r101/utils/ClipboardSupport.android.kt @@ -17,7 +17,7 @@ actual fun Clipboard.toSupport(): SupportClipboardManager { override suspend fun getText(): String? { val entry = clipboard.getClipEntry() ?: return null - return entry.clipData?.getItemAt(0)?.text?.toString() + return entry.clipData.getItemAt(0)?.text?.toString() } override fun setTextListener(listener: (String) -> Unit) { diff --git a/utils/shared/src/androidMain/kotlin/com/pr0gramm3r101/utils/settings/AndroidSecureSettings.kt b/utils/shared/src/androidMain/kotlin/com/pr0gramm3r101/utils/settings/AndroidSecureSettings.kt index 602bea1..a0d4c56 100644 --- a/utils/shared/src/androidMain/kotlin/com/pr0gramm3r101/utils/settings/AndroidSecureSettings.kt +++ b/utils/shared/src/androidMain/kotlin/com/pr0gramm3r101/utils/settings/AndroidSecureSettings.kt @@ -1,3 +1,5 @@ +@file:Suppress("DEPRECATION") + package com.pr0gramm3r101.utils.settings import androidx.core.content.edit @@ -7,6 +9,12 @@ import com.pr0gramm3r101.utils.UtilsLibrary.context import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext +/** + * Secure prefs via EncryptedSharedPreferences. + * + * These APIs are deprecated in favor of DataStore + Tink (`datastore-tink`, DataStore 1.3+). + * Kept until that stack is stable enough to migrate auth/identity keys without risk. + */ class AndroidSecureSettings : Settings { private val masterKey by lazy { MasterKey.Builder(context) @@ -80,4 +88,3 @@ class AndroidSecureSettings : Settings { encryptedPrefs.contains(key) } } -