From fe0c0e3f8ff71e19d8cab4a234606f3101bcec09 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9F=D1=8B=D1=82=D0=BA=D0=BE=D0=B2=20=D0=A0=D0=BE=D0=BC?= =?UTF-8?q?=D0=B0=D0=BD?= Date: Sun, 17 May 2026 19:39:21 +0300 Subject: [PATCH] =?UTF-8?q?=D0=98=D1=81=D0=BF=D1=80=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=D0=BE=20=D0=B5=D1=89=D1=91=20=D0=BD=D0=B5=D1=81?= =?UTF-8?q?=D0=BA=D0=BE=D0=BB=D1=8C=D0=BA=D0=BE=20deprecated=20=D0=BF?= =?UTF-8?q?=D1=80=D0=B5=D0=B4=D1=83=D0=BF=D1=80=D0=B5=D0=B6=D0=B4=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D0=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../repository/YandexDiskRepository.kt | 5 +- .../storage/twofa/TwoFaTokensScreen.kt | 47 ++++++++++++------- 2 files changed, 30 insertions(+), 22 deletions(-) diff --git a/domain-vault/src/main/java/com/github/nullptroma/wallenc/infrastructure/network/yandexdisk/repository/YandexDiskRepository.kt b/domain-vault/src/main/java/com/github/nullptroma/wallenc/infrastructure/network/yandexdisk/repository/YandexDiskRepository.kt index c26cae8..2cc5199 100644 --- a/domain-vault/src/main/java/com/github/nullptroma/wallenc/infrastructure/network/yandexdisk/repository/YandexDiskRepository.kt +++ b/domain-vault/src/main/java/com/github/nullptroma/wallenc/infrastructure/network/yandexdisk/repository/YandexDiskRepository.kt @@ -190,10 +190,7 @@ class YandexDiskRepository( when { resp.isSuccessful -> { val body = resp.body - val stream = body?.byteStream() ?: run { - resp.close() - throw IOException("Download failed: missing body") - } + val stream = body.byteStream() return@withContext object : FilterInputStream(stream) { override fun close() { `in`.use { diff --git a/ui/src/main/java/com/github/nullptroma/wallenc/ui/screens/main/screens/storage/twofa/TwoFaTokensScreen.kt b/ui/src/main/java/com/github/nullptroma/wallenc/ui/screens/main/screens/storage/twofa/TwoFaTokensScreen.kt index 4090279..84f0d63 100644 --- a/ui/src/main/java/com/github/nullptroma/wallenc/ui/screens/main/screens/storage/twofa/TwoFaTokensScreen.kt +++ b/ui/src/main/java/com/github/nullptroma/wallenc/ui/screens/main/screens/storage/twofa/TwoFaTokensScreen.kt @@ -1,22 +1,27 @@ package com.github.nullptroma.wallenc.ui.screens.main.screens.storage.twofa import android.Manifest +import android.content.ClipData import android.content.pm.PackageManager +import androidx.activity.compose.rememberLauncherForActivityResult +import androidx.activity.result.contract.ActivityResultContracts +import androidx.compose.foundation.background import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.WindowInsets -import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxHeight +import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.heightIn +import androidx.compose.foundation.layout.offset import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size -import androidx.compose.foundation.rememberScrollState -import androidx.compose.foundation.verticalScroll import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items +import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.verticalScroll import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Add import androidx.compose.material.icons.filled.ContentCopy @@ -28,7 +33,10 @@ import androidx.compose.material3.AlertDialog import androidx.compose.material3.Card import androidx.compose.material3.CardDefaults import androidx.compose.material3.CircularProgressIndicator +import androidx.compose.material3.DropdownMenu import androidx.compose.material3.DropdownMenuItem +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.ExposedDropdownMenuAnchorType import androidx.compose.material3.ExposedDropdownMenuBox import androidx.compose.material3.ExposedDropdownMenuDefaults import androidx.compose.material3.FloatingActionButton @@ -41,7 +49,6 @@ import androidx.compose.material3.Scaffold import androidx.compose.material3.Slider import androidx.compose.material3.Text import androidx.compose.material3.TextButton -import androidx.compose.material3.DropdownMenu import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue @@ -50,27 +57,24 @@ import androidx.compose.runtime.mutableIntStateOf import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.produceState import androidx.compose.runtime.remember +import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.setValue import androidx.compose.runtime.snapshotFlow +import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.alpha -import androidx.compose.ui.Alignment +import androidx.compose.ui.graphics.Color import androidx.compose.ui.layout.onSizeChanged +import androidx.compose.ui.platform.LocalClipboard import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalDensity +import androidx.compose.ui.platform.toClipEntry import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.font.FontFamily -import androidx.compose.ui.text.AnnotatedString import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.unit.IntOffset import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp -import androidx.activity.compose.rememberLauncherForActivityResult -import androidx.activity.result.contract.ActivityResultContracts -import androidx.compose.foundation.background -import androidx.compose.foundation.layout.offset -import androidx.compose.material3.ExperimentalMaterial3Api -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.platform.LocalClipboard import androidx.core.content.ContextCompat import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle @@ -81,8 +85,8 @@ import com.github.nullptroma.wallenc.usecases.TwoFaCodeState import com.github.nullptroma.wallenc.usecases.buildTwoFaCodeState import kotlinx.coroutines.delay import kotlinx.coroutines.flow.collectLatest +import kotlinx.coroutines.launch import kotlin.math.roundToInt -import androidx.compose.ui.unit.IntOffset @Composable fun TwoFaTokensScreen( @@ -91,6 +95,7 @@ fun TwoFaTokensScreen( ) { val uiState by viewModel.state.collectAsStateWithLifecycle() val clipboard = LocalClipboard.current + val scope = rememberCoroutineScope() val nowMillis by produceState(initialValue = System.currentTimeMillis()) { while (true) { value = System.currentTimeMillis() @@ -231,7 +236,10 @@ fun TwoFaTokensScreen( Card( onClick = { codeState?.let { - clipboard.setText(AnnotatedString(it.code)) + scope.launch { + val clipData = ClipData.newPlainText(it.code, it.code) + clipboard.setClipEntry(clipData.toClipEntry()) + } } }, enabled = codeState != null, @@ -413,14 +421,17 @@ private fun TwoFaTokenEditDialog( expanded = algorithmExpanded, onExpandedChange = { if (!isBusy) algorithmExpanded = !algorithmExpanded }, ) { + val fillMaxWidth = Modifier + .fillMaxWidth() OutlinedTextField( value = algorithmValue, onValueChange = {}, readOnly = true, enabled = !isBusy, - modifier = Modifier - .fillMaxWidth() - .menuAnchor(), + modifier = fillMaxWidth.menuAnchor( + type = ExposedDropdownMenuAnchorType.PrimaryNotEditable, + enabled = !isBusy, + ), trailingIcon = { ExposedDropdownMenuDefaults.TrailingIcon(expanded = algorithmExpanded) },