package com.suno.android.common_ui.components.billing import androidx.compose.foundation.Canvas import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.geometry.Offset import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.drawscope.Stroke import androidx.compose.ui.text.drawText import androidx.compose.ui.text.rememberTextMeasurer import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import com.suno.android.common_ui.theme.ExtendedTheme import com.suno.android.common_ui.theme.NavBarSelection import com.suno.android.common_ui.theme.SunoTheme @Composable fun BillingCreditsCircle( modifier: Modifier = Modifier, percentageRemaining: Float, numerator: String, denominator: String, ) { val textMeasurer = rememberTextMeasurer() val firstTextStyle = ExtendedTheme.typography.categoryHeadline.copy( color = Color.White, ) val firstTextLayoutResult = textMeasurer.measure( text = numerator, style = firstTextStyle, ) val secondTextStyle = ExtendedTheme.typography.smallBody.copy( color = Color.White, ) val secondTextLayoutResult = textMeasurer.measure( text = denominator, style = secondTextStyle, ) Canvas(modifier = modifier) { drawCircle( color = NavBarSelection.copy(alpha = 0.2f), radius = size.minDimension / 2f, style = Stroke(width = 2.dp.toPx()), ) drawArc( color = NavBarSelection, startAngle = 270f, sweepAngle = -(percentageRemaining * 360f), useCenter = false, style = Stroke(width = 2.dp.toPx()), size = androidx.compose.ui.geometry.Size(size.width, size.height), topLeft = Offset(0f, 0f), ) // Calculate center position val centerX = size.width / 2 val centerY = size.height / 2 this.drawText( textMeasurer = textMeasurer, text = numerator, style = firstTextStyle, topLeft = Offset( x = centerX - firstTextLayoutResult.size.width / 2, y = centerY - firstTextLayoutResult.size.height / 2, ), ) drawText( textMeasurer = textMeasurer, text = denominator, style = secondTextStyle, topLeft = Offset( x = centerX - secondTextLayoutResult.size.width / 2, y = centerY + firstTextLayoutResult.size.height / 2 + 2.dp.toPx(), ), ) } } @Preview( showSystemUi = true, showBackground = true, ) @Composable private fun BillingCreditsCircle_Preview() { SunoTheme { BillingCreditsCircle( modifier = Modifier .size(200.dp) .padding(5.dp), percentageRemaining = 0.1f, numerator = "100", denominator = "/200", ) } }