1package com.peachpasswords.ui.components23import androidx.compose.foundation.Canvas4import androidx.compose.foundation.layout.size5import androidx.compose.runtime.Composable6import androidx.compose.runtime.getValue7import androidx.compose.runtime.produceState8import androidx.compose.ui.Modifier9import androidx.compose.ui.geometry.Offset10import androidx.compose.ui.geometry.Size11import androidx.compose.ui.graphics.StrokeCap12import androidx.compose.ui.graphics.drawscope.Stroke13import androidx.compose.ui.unit.Dp14import androidx.compose.ui.unit.dp15import com.peachpasswords.ui.theme.LocalPeachAccent16import com.peachpasswords.ui.theme.peachColors17import com.peachpasswords.vault.TOTPGenerator18import kotlinx.coroutines.delay192021222324@Composable25fun TOTPRing(modifier: Modifier = Modifier, size: Dp = 28.dp) {26 val accent = LocalPeachAccent.current27 val progress by produceState(TOTPGenerator.periodProgress()) {28 while (true) { value = TOTPGenerator.periodProgress(); delay(100) }29 }30 val isHot = TOTPGenerator.remainingSeconds() <= 531 val track = peachColors.T332 val breach = peachColors.Breach3334 Canvas(modifier = modifier.size(size)) {35 val stroke = 2.dp.toPx()36 val radius = (this.size.minDimension - stroke) / 2f37 val center = Offset(this.size.width / 2f, this.size.height / 2f)38 drawCircle(color = track, radius = radius, style = Stroke(stroke))39 drawArc(40 color = if (isHot) breach else accent,41 startAngle = -90f,42 43 44 45 sweepAngle = 360f * (1f - progress),46 useCenter = false,47 style = Stroke(stroke, cap = StrokeCap.Round),48 topLeft = Offset(center.x - radius, center.y - radius),49 size = Size(radius * 2, radius * 2),50 )51 }52}