package com.suno.android.common_ui.components.aura import android.graphics.Shader import android.os.Build import androidx.annotation.RequiresApi import androidx.compose.runtime.Composable import androidx.compose.runtime.remember import androidx.compose.ui.geometry.Size import androidx.compose.ui.graphics.Brush import androidx.compose.ui.graphics.ImageBitmap import androidx.compose.ui.graphics.ImageShader import androidx.compose.ui.graphics.ShaderBrush import androidx.compose.ui.res.imageResource class AuraBrush( val brush: Brush, ) { fun update( time: Float, enabledScalar: Float, ) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { (brush as? AuraShaderBrush)?.update(time, enabledScalar) } } } @Composable fun rememberAuraBrush( style: AuraStyle = AuraStyle(), ): AuraBrush { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU) { val bitmap = ImageBitmap.imageResource(com.suno.android.common_ui.R.drawable.launch_splash_auk) return remember { AuraBrush(ShaderBrush(ImageShader(bitmap))) } } return remember { AuraBrush(AuraShaderBrush(style)) } } @RequiresApi(Build.VERSION_CODES.TIRAMISU) private class AuraShaderBrush( val style: AuraStyle, ) : ShaderBrush() { private var shader: AuraShader? = null private var cachedUpdate: Pair? = null override fun createShader( size: Size, ): Shader = (shader ?: AuraShader(style)).apply { setResolution(size) }.also { shader -> this.shader = shader cachedUpdate?.let { update(it.first, it.second) cachedUpdate = null } } fun update( time: Float, enabledScalar: Float, ): Unit? { if (shader == null) { cachedUpdate = time to enabledScalar } return shader?.update(time, enabledScalar) } }