mirror of
https://github.com/fromchat-messenger/app.git
synced 2026-09-22 11:05:04 +03:00
Update dependencies, fix build warnings
Signed-off-by: denis0001-dev <denis0001.dev@ya.ru>
This commit is contained in:
@@ -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")
|
||||
}
|
||||
@@ -22,6 +22,9 @@
|
||||
<meta-data
|
||||
android:name="com.google.firebase.messaging.default_notification_icon"
|
||||
android:resource="@drawable/ic_stat_fromchat" />
|
||||
<meta-data
|
||||
android:name="firebase_messaging_installation_id_enabled"
|
||||
android:value="true" />
|
||||
<activity
|
||||
android:name=".MainActivity"
|
||||
android:exported="true"
|
||||
|
||||
@@ -9,8 +9,8 @@ import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.launch
|
||||
import ru.fromchat.Logger
|
||||
import ru.fromchat.api.ApiClient
|
||||
import ru.fromchat.notifications.NotificationHelper
|
||||
import ru.fromchat.api.uploadPendingFcmTokenIfAvailable
|
||||
import ru.fromchat.notifications.NotificationHelper
|
||||
|
||||
@OptIn(DelicateCoroutinesApi::class)
|
||||
class FromChatFirebaseMessagingService : FirebaseMessagingService() {
|
||||
@@ -65,18 +65,16 @@ class FromChatFirebaseMessagingService : FirebaseMessagingService() {
|
||||
}
|
||||
}
|
||||
|
||||
override fun onNewToken(token: String) {
|
||||
Logger.i("FromChatFCM", "onNewToken received (...${token.takeLast(8)})")
|
||||
override fun onRegistered(installationId: String) {
|
||||
Logger.i("FromChatFCM", "onRegistered received (...${installationId.takeLast(8)})")
|
||||
GlobalScope.launch(Dispatchers.IO) {
|
||||
try {
|
||||
settings.putString("pending_fcm_token", token)
|
||||
settings.putString("pending_fcm_token", installationId)
|
||||
uploadPendingFcmTokenIfAvailable()
|
||||
Logger.i("FromChatFCM", "FCM token queued or uploaded for this app instance")
|
||||
Logger.i("FromChatFCM", "FCM installation id queued or uploaded for this app instance")
|
||||
} catch (e: Exception) {
|
||||
Logger.e("FromChatFCM", "onNewToken upload error: ${e.message}", e)
|
||||
Logger.e("FromChatFCM", "onRegistered upload error: ${e.message}", e)
|
||||
}
|
||||
|
||||
super.onNewToken(token)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
@file:Suppress("TaskMissingDescription")
|
||||
|
||||
plugins {
|
||||
alias(libs.plugins.kotlin.multiplatform)
|
||||
alias(libs.plugins.compose.multiplatform)
|
||||
@@ -21,7 +23,6 @@ kotlin {
|
||||
listOf(
|
||||
iosArm64(),
|
||||
iosSimulatorArm64(),
|
||||
iosX64(),
|
||||
).forEach { iosTarget ->
|
||||
iosTarget.binaries.framework {
|
||||
baseName = "ComposeApp"
|
||||
|
||||
@@ -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,19 +14,27 @@ 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<String> ->
|
||||
private suspend fun <T> Task<T>.awaitResult(): T = suspendCancellableCoroutine { cont ->
|
||||
addOnCompleteListener { task ->
|
||||
if (task.isSuccessful) {
|
||||
cont.resume(task.result)
|
||||
} else {
|
||||
cont.resumeWithException(
|
||||
task.exception ?: IllegalStateException("Failed to fetch FCM token")
|
||||
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 {
|
||||
return runCatching {
|
||||
ApiClient.registerFcmToken(token)
|
||||
|
||||
+1
-1
@@ -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)
|
||||
|
||||
+1
-1
@@ -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),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
+4
-4
@@ -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,
|
||||
|
||||
@@ -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 -> ""
|
||||
}
|
||||
|
||||
@@ -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) } }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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) }
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
+23
-23
@@ -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" }
|
||||
|
||||
+2
-5
@@ -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
|
||||
|
||||
@@ -18,8 +18,7 @@ kotlin {
|
||||
|
||||
listOf(
|
||||
iosArm64(),
|
||||
iosSimulatorArm64(),
|
||||
iosX64(),
|
||||
iosSimulatorArm64()
|
||||
).forEach {
|
||||
it.binaries.framework {
|
||||
baseName = "shared"
|
||||
|
||||
+1
-1
@@ -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) {
|
||||
|
||||
+8
-1
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user