This commit is contained in:
ponzischeme89
2026-08-28 09:37:05 +12:00
parent 0b12c09deb
commit 3e89036f7b
3 changed files with 77 additions and 63 deletions
+1 -1
View File
@@ -38,7 +38,7 @@ val membyGatewayUrl: String = (project.findProperty("memby.gatewayUrl") as Strin
val membyDiagnosticLogLevel: String = (project.findProperty("memby.diagnosticLogLevel") as String?)
?.trim()?.uppercase()?.takeIf { it in setOf("INFO", "DEBUG", "TRACE") } ?: "INFO"
val defaultVersionName = "0.3.38"
val defaultVersionName = "0.3.39"
val membyVersionName: String =
(project.findProperty("memby.versionName") as String?)
?.trim()
@@ -11,6 +11,7 @@ import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clipToBounds
import androidx.compose.ui.draw.drawWithCache
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.ContentScale
@@ -52,26 +53,31 @@ internal fun MetadataHero(
item = item,
modifier = Modifier.fillMaxSize(),
)
// Both scrims in one cached draw pass. Inline Brush.*Gradient in a
// .background() allocates a new brush on every recomposition — and the
// hero recomposes on every focus change while a shelf is browsed.
Box(
Modifier.fillMaxSize().background(
Brush.horizontalGradient(
Modifier
.fillMaxSize()
.drawWithCache {
val horizontal = Brush.horizontalGradient(
0f to MembySurface,
0.30f to MembySurface,
0.48f to MembySurface.copy(alpha = 0.80f),
0.62f to MembySurface.copy(alpha = 0.40f),
0.78f to MembySurface.copy(alpha = 0.10f),
1f to Color.Transparent,
),
),
)
Box(
Modifier.fillMaxSize().background(
Brush.verticalGradient(
val vertical = Brush.verticalGradient(
0f to MembySurface.copy(alpha = 0.18f),
0.58f to Color.Transparent,
1f to MembySurface.copy(alpha = 0.20f),
),
),
)
onDrawBehind {
drawRect(horizontal)
drawRect(vertical)
}
},
)
MediaMetadataPanel(
item = item,
@@ -127,36 +133,38 @@ private fun MetadataHeroArtwork(
modifier = Modifier
.align(Alignment.CenterEnd)
.fillMaxWidth(MetadataHeroArtworkWidthFraction)
.fillMaxHeight(),
.fillMaxHeight()
// Scrims in one cached pass over the artwork. The slow pull-back that
// used to sit on the image is gone here: on Home the backdrop changes
// on every focus move, so the 10s animation never finished and its
// per-frame graphicsLayer kept the whole launcher redrawing while the
// viewer merely scrolled a shelf. The detail and pause heroes keep it.
.drawWithCache {
val horizontal = Brush.horizontalGradient(
0f to MembySurface.copy(alpha = 0.92f),
0.18f to MembySurface.copy(alpha = 0.76f),
0.42f to MembySurface.copy(alpha = 0.42f),
0.70f to MembySurface.copy(alpha = 0.12f),
1f to Color.Transparent,
)
val vertical = Brush.verticalGradient(
0f to MembySurface.copy(alpha = 0.16f),
0.56f to Color.Transparent,
1f to MembySurface.copy(alpha = 0.28f),
)
onDrawWithContent {
drawContent()
drawRect(horizontal)
drawRect(vertical)
}
},
) {
AsyncImage(
model = request,
contentDescription = null,
contentScale = ContentScale.Crop,
alignment = Alignment.CenterEnd,
modifier = Modifier
.fillMaxSize()
.cinematicBackdropPullBack(artwork),
)
Box(
Modifier.fillMaxSize().background(
Brush.horizontalGradient(
0f to MembySurface.copy(alpha = 0.92f),
0.18f to MembySurface.copy(alpha = 0.76f),
0.42f to MembySurface.copy(alpha = 0.42f),
0.70f to MembySurface.copy(alpha = 0.12f),
1f to Color.Transparent,
),
),
)
Box(
Modifier.fillMaxSize().background(
Brush.verticalGradient(
0f to MembySurface.copy(alpha = 0.16f),
0.56f to Color.Transparent,
1f to MembySurface.copy(alpha = 0.28f),
),
),
modifier = Modifier.fillMaxSize(),
)
}
}
@@ -27,6 +27,7 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.draw.clipToBounds
import androidx.compose.ui.draw.drawWithCache
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.ContentScale
@@ -105,7 +106,30 @@ fun BackdropLayer(item: BaseItem?, modifier: Modifier = Modifier) {
.build()
}
}
Box(modifier.background(MembySurface)) {
Box(
modifier
.background(MembySurface)
// Both scrims over the backdrop in one cached pass. Inline Brush.*Gradient
// in .background() allocates a fresh brush every recomposition, and this
// layer recomposes on every settled focus change while a shelf is browsed.
.drawWithCache {
val horizontal = Brush.horizontalGradient(
0f to MembySurface,
0.58f to MembySurface.copy(alpha = 0.89f),
1f to MembySurface.copy(alpha = 0.65f),
)
val vertical = Brush.verticalGradient(
0f to MembySurface.copy(alpha = 0.45f),
0.66f to MembySurface.copy(alpha = 0.84f),
1f to MembySurface,
)
onDrawWithContent {
drawContent()
drawRect(horizontal)
drawRect(vertical)
}
},
) {
if (request != null) {
AsyncImage(
model = request,
@@ -114,24 +138,6 @@ fun BackdropLayer(item: BaseItem?, modifier: Modifier = Modifier) {
modifier = Modifier.fillMaxSize(),
)
}
Box(
Modifier.fillMaxSize().background(
Brush.horizontalGradient(
0f to MembySurface,
0.58f to MembySurface.copy(alpha = 0.89f),
1f to MembySurface.copy(alpha = 0.65f),
),
),
)
Box(
Modifier.fillMaxSize().background(
Brush.verticalGradient(
0f to MembySurface.copy(alpha = 0.45f),
0.66f to MembySurface.copy(alpha = 0.84f),
1f to MembySurface,
),
),
)
}
}