Плавный прогрессбар 2fa
This commit is contained in:
@@ -55,6 +55,7 @@ import androidx.compose.runtime.mutableIntStateOf
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.produceState
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.withFrameMillis
|
||||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.runtime.snapshotFlow
|
||||
@@ -83,7 +84,8 @@ import com.github.nullptroma.wallenc.ui.elements.WallencScreenContentPadding
|
||||
import com.github.nullptroma.wallenc.ui.elements.WallencScreenScaffold
|
||||
import com.github.nullptroma.wallenc.usecases.TwoFaCodeState
|
||||
import com.github.nullptroma.wallenc.usecases.buildTwoFaCodeState
|
||||
import kotlinx.coroutines.delay
|
||||
import com.github.nullptroma.wallenc.usecases.totpPeriodProgress
|
||||
import com.github.nullptroma.wallenc.usecases.totpSecondsUntilRefresh
|
||||
import kotlinx.coroutines.flow.collectLatest
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlin.math.roundToInt
|
||||
@@ -98,8 +100,9 @@ fun TwoFaTokensScreen(
|
||||
val scope = rememberCoroutineScope()
|
||||
val nowMillis by produceState(initialValue = System.currentTimeMillis()) {
|
||||
while (true) {
|
||||
value = System.currentTimeMillis()
|
||||
delay(1000)
|
||||
withFrameMillis { frameTimeMillis ->
|
||||
value = frameTimeMillis
|
||||
}
|
||||
}
|
||||
}
|
||||
var editingToken by remember { mutableStateOf<TwoFaTokenRecord?>(null) }
|
||||
@@ -160,12 +163,13 @@ fun TwoFaTokensScreen(
|
||||
}
|
||||
}
|
||||
}
|
||||
val codeProgress = if (codeState == null) 0f else {
|
||||
val period = item.periodSeconds.coerceAtLeast(1)
|
||||
val elapsed = (period - codeState.secondsUntilRefresh)
|
||||
.coerceAtLeast(0)
|
||||
.coerceAtMost(period)
|
||||
elapsed.toFloat() / period.toFloat()
|
||||
val codeProgress = if (codeState == null) {
|
||||
0f
|
||||
} else {
|
||||
totpPeriodProgress(nowMillis, item.periodSeconds)
|
||||
}
|
||||
val secondsUntilRefresh = codeState?.let {
|
||||
totpSecondsUntilRefresh(nowMillis, item.periodSeconds)
|
||||
}
|
||||
Row(
|
||||
modifier = Modifier
|
||||
@@ -183,10 +187,10 @@ fun TwoFaTokensScreen(
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
)
|
||||
Text(
|
||||
text = if (codeState != null) {
|
||||
text = if (secondsUntilRefresh != null) {
|
||||
stringResource(
|
||||
R.string.two_fa_code_refresh_seconds,
|
||||
codeState.secondsUntilRefresh,
|
||||
secondsUntilRefresh,
|
||||
)
|
||||
} else {
|
||||
stringResource(R.string.two_fa_code_invalid_secret)
|
||||
@@ -562,7 +566,9 @@ private fun TwoFaTokenEditDialog(
|
||||
|
||||
@Composable
|
||||
private fun rememberTwoFaCode(token: TwoFaTokenRecord, nowMillis: Long): TwoFaCodeState? {
|
||||
return remember(token, nowMillis) {
|
||||
val period = token.periodSeconds.coerceAtLeast(1)
|
||||
val periodSlot = nowMillis / 1000L / period
|
||||
return remember(token, periodSlot) {
|
||||
buildTwoFaCodeState(token, nowMillis)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user