diff --git a/.idea/gradle.xml b/.idea/gradle.xml
index e0717840c..98a1e5216 100644
--- a/.idea/gradle.xml
+++ b/.idea/gradle.xml
@@ -23,8 +23,6 @@
-
-
@@ -47,10 +45,15 @@
+
+
+
+
+
diff --git a/app/src/main/java/com/dede/android_eggs/util/LocalEventExt.kt b/app/src/main/java/com/dede/android_eggs/util/LocalEventExt.kt
new file mode 100644
index 000000000..61ac5ae55
--- /dev/null
+++ b/app/src/main/java/com/dede/android_eggs/util/LocalEventExt.kt
@@ -0,0 +1,28 @@
+package com.dede.android_eggs.util
+
+import android.content.BroadcastReceiver
+import android.content.Context
+import android.content.Intent
+import android.content.IntentFilter
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.DisposableEffect
+import androidx.compose.runtime.remember
+import androidx.compose.ui.platform.LocalContext
+
+@Composable
+fun LocalEvent.DisposableReceiver(action: String, eventCallback: EventCallback) {
+ val context = LocalContext.current
+ val receiver = remember { DisposedReceiver(eventCallback) }
+ DisposableEffect(action) {
+ context.localBroadcastManager.registerReceiver(receiver, IntentFilter(action))
+ onDispose {
+ context.localBroadcastManager.unregisterReceiver(receiver)
+ }
+ }
+}
+
+private class DisposedReceiver(val callback: EventCallback) : BroadcastReceiver() {
+ override fun onReceive(context: Context, intent: Intent) {
+ callback.invoke(intent)
+ }
+}
diff --git a/app/src/main/java/com/dede/android_eggs/views/main/compose/EasterEggLogo.kt b/app/src/main/java/com/dede/android_eggs/views/main/compose/EasterEggLogo.kt
index f9befa41b..2e99c3e7d 100644
--- a/app/src/main/java/com/dede/android_eggs/views/main/compose/EasterEggLogo.kt
+++ b/app/src/main/java/com/dede/android_eggs/views/main/compose/EasterEggLogo.kt
@@ -19,6 +19,7 @@ import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import com.dede.android_eggs.ui.drawables.AlterableAdaptiveIconDrawable
import com.dede.android_eggs.util.LocalEvent
+import com.dede.android_eggs.util.DisposableReceiver
import com.dede.android_eggs.views.main.util.EasterEggHelp
import com.dede.android_eggs.views.main.util.EasterEggLogoSensorMatrixConvert
import com.dede.android_eggs.views.settings.compose.basic.SettingPrefUtil
@@ -56,7 +57,7 @@ fun EasterEggLogo(
val drawable = remember(maskPath, res, context.theme) {
AlterableAdaptiveIconDrawable(context, res, maskPath)
}
- LocalEvent.receiver().register(IconShapePrefUtil.ACTION_CHANGED) {
+ LocalEvent.DisposableReceiver(IconShapePrefUtil.ACTION_CHANGED) {
val newMaskPath = it.getStringExtra(SettingPrefUtil.EXTRA_VALUE)
if (newMaskPath != null) {
drawable.setMaskPath(newMaskPath)
diff --git a/app/src/main/java/com/dede/android_eggs/views/placeholder/PlaceholderActivity.kt b/app/src/main/java/com/dede/android_eggs/views/placeholder/PlaceholderActivity.kt
deleted file mode 100644
index c9798f85b..000000000
--- a/app/src/main/java/com/dede/android_eggs/views/placeholder/PlaceholderActivity.kt
+++ /dev/null
@@ -1,110 +0,0 @@
-package com.dede.android_eggs.views.placeholder
-
-import android.os.Bundle
-import androidx.activity.compose.setContent
-import androidx.activity.enableEdgeToEdge
-import androidx.appcompat.app.AppCompatActivity
-import androidx.compose.animation.AnimatedVisibility
-import androidx.compose.animation.core.MutableTransitionState
-import androidx.compose.animation.core.tween
-import androidx.compose.animation.fadeIn
-import androidx.compose.animation.scaleIn
-import androidx.compose.foundation.layout.Box
-import androidx.compose.foundation.layout.fillMaxSize
-import androidx.compose.foundation.layout.imePadding
-import androidx.compose.foundation.layout.size
-import androidx.compose.material3.Scaffold
-import androidx.compose.runtime.Composable
-import androidx.compose.runtime.remember
-import androidx.compose.ui.Alignment
-import androidx.compose.ui.Modifier
-import androidx.compose.ui.res.stringResource
-import androidx.compose.ui.tooling.preview.Preview
-import androidx.compose.ui.unit.dp
-import com.dede.android_eggs.R
-import com.dede.android_eggs.util.LocalEvent
-import com.dede.android_eggs.util.ThemeUtils
-import com.dede.android_eggs.views.main.compose.EasterEggLogo
-import com.dede.android_eggs.views.settings.compose.prefs.DynamicColorPrefUtil
-import com.dede.android_eggs.views.settings.compose.prefs.ThemePrefUtil
-import com.dede.android_eggs.views.theme.AppTheme
-import com.dede.basic.isAdaptiveIconDrawable
-import com.dede.basic.provider.EasterEgg
-import dagger.hilt.android.AndroidEntryPoint
-import javax.inject.Inject
-import kotlin.random.Random
-
-// todo Move to embedding-splits module
-@AndroidEntryPoint
-class PlaceholderActivity : AppCompatActivity() {
-
- @Inject
- lateinit var pureEasterEggs: List<@JvmSuppressWildcards EasterEgg>
-
- private lateinit var iconRes: List
-
- override fun onCreate(savedInstanceState: Bundle?) {
- ThemeUtils.tryApplyOLEDTheme(this)
- enableEdgeToEdge()
- super.onCreate(savedInstanceState)
- iconRes = pureEasterEggs.filter { isAdaptiveIconDrawable(it.iconRes) }
- .map { it.iconRes }
-
- setContent {
- AppTheme {
- @Suppress("UnusedMaterial3ScaffoldPaddingParameter")
- Scaffold {
- Placeholder(randomRes())
- }
- }
- }
-
- with(LocalEvent.receiver(this)) {
- register(ThemePrefUtil.ACTION_NIGHT_MODE_CHANGED) {
- recreate()
- }
- register(DynamicColorPrefUtil.ACTION_DYNAMIC_COLOR_CHANGED) {
- recreate()
- }
- }
-
- }
-
- private fun randomRes(): Int {
- val array = iconRes
- val index = Random.nextInt(array.size)
- return array[index]
- }
-
-}
-
-@Composable
-fun Placeholder(res: Int) {
- Box(
- contentAlignment = Alignment.Center,
- modifier = Modifier
- .fillMaxSize()
- .imePadding()
- ) {
- AnimatedVisibility(
- visibleState = remember { MutableTransitionState(false) }
- .apply { targetState = true },
- enter = scaleIn(
- initialScale = 0.3f,
- animationSpec = tween(500, delayMillis = 100)
- ) + fadeIn(animationSpec = tween(500, delayMillis = 100)),
- ) {
- EasterEggLogo(
- modifier = Modifier.size(56.dp),
- res = res,
- contentDescription = stringResource(R.string.app_name),
- )
- }
- }
-}
-
-@Preview
-@Composable
-fun PreviewPlaceholder() {
- Placeholder(R.mipmap.ic_launcher_round)
-}
diff --git a/app/src/main/java/com/dede/android_eggs/views/settings/SettingsScreen.kt b/app/src/main/java/com/dede/android_eggs/views/settings/SettingsScreen.kt
index 44df78e16..655639710 100644
--- a/app/src/main/java/com/dede/android_eggs/views/settings/SettingsScreen.kt
+++ b/app/src/main/java/com/dede/android_eggs/views/settings/SettingsScreen.kt
@@ -46,6 +46,7 @@ import androidx.compose.ui.unit.TextUnitType
import androidx.compose.ui.unit.dp
import com.dede.android_eggs.BuildConfig
import com.dede.android_eggs.R
+import com.dede.android_eggs.util.DisposableReceiver
import com.dede.android_eggs.util.LocalEvent
import com.dede.android_eggs.util.SplitUtils
import com.dede.android_eggs.views.main.compose.DrawableImage
@@ -80,7 +81,7 @@ fun SettingsScreen(drawerState: DrawerState = rememberDrawerState(DrawerValue.Cl
closeDrawer()
}
- LocalEvent.receiver().register(action = SettingPrefUtil.ACTION_CLOSE_SETTING) {
+ LocalEvent.DisposableReceiver(SettingPrefUtil.ACTION_CLOSE_SETTING) {
closeDrawer()
}
diff --git a/basic/build.gradle.kts b/basic/build.gradle.kts
index f7258aed8..d148f61ef 100644
--- a/basic/build.gradle.kts
+++ b/basic/build.gradle.kts
@@ -15,4 +15,5 @@ dependencies {
implementation(libs.androidx.viewmodel)
implementation(libs.androidx.startup)
implementation(libs.androidx.activity)
+ implementation(libs.androidx.localbroadcastmanager)
}
\ No newline at end of file
diff --git a/app/src/main/java/com/dede/android_eggs/util/LocalEvent.kt b/basic/src/main/java/com/dede/android_eggs/util/LocalEvent.kt
similarity index 62%
rename from app/src/main/java/com/dede/android_eggs/util/LocalEvent.kt
rename to basic/src/main/java/com/dede/android_eggs/util/LocalEvent.kt
index 660fc007a..b959b78ce 100644
--- a/app/src/main/java/com/dede/android_eggs/util/LocalEvent.kt
+++ b/basic/src/main/java/com/dede/android_eggs/util/LocalEvent.kt
@@ -6,10 +6,6 @@ import android.content.Intent
import android.content.IntentFilter
import android.os.Bundle
import androidx.activity.ComponentActivity
-import androidx.compose.runtime.Composable
-import androidx.compose.runtime.DisposableEffect
-import androidx.compose.runtime.remember
-import androidx.compose.ui.platform.LocalContext
import androidx.fragment.app.Fragment
import androidx.lifecycle.DefaultLifecycleObserver
import androidx.lifecycle.LifecycleOwner
@@ -19,6 +15,9 @@ typealias EventCallback = (intent: Intent) -> Unit
object LocalEvent {
+ val Context.localBroadcastManager: LocalBroadcastManager
+ get() = LocalBroadcastManager.getInstance(this)
+
fun poster(context: Context): Poster {
return Poster(context)
}
@@ -27,32 +26,6 @@ object LocalEvent {
return Receiver(owner)
}
- @Composable
- fun receiver(): ComposeReceiver {
- val context = LocalContext.current
- return remember { ComposeReceiver(context) }
- }
-
- class ComposeReceiver(private val context: Context) {
-
- private class DisposedReceiver(val callback: EventCallback) : BroadcastReceiver() {
- override fun onReceive(context: Context, intent: Intent) {
- callback.invoke(intent)
- }
- }
-
- @Composable
- fun register(action: String, eventCallback: EventCallback) {
- DisposableEffect(key1 = action) {
- val receiver = DisposedReceiver(eventCallback)
- context.localBroadcastManager.registerReceiver(receiver, IntentFilter(action))
- onDispose {
- context.localBroadcastManager.unregisterReceiver(receiver)
- }
- }
- }
- }
-
class Receiver(private val owner: LifecycleOwner) {
private class LifecycleReceiver(val callback: EventCallback) :
@@ -91,6 +64,3 @@ private val LifecycleOwner.context: Context
is Fragment -> requireContext()
else -> throw IllegalArgumentException(this.toString())
}
-
-private val Context.localBroadcastManager: LocalBroadcastManager
- get() = LocalBroadcastManager.getInstance(this)
\ No newline at end of file
diff --git a/feature/embedding-splits/build.gradle.kts b/feature/embedding-splits/build.gradle.kts
index da740976d..3880253fd 100644
--- a/feature/embedding-splits/build.gradle.kts
+++ b/feature/embedding-splits/build.gradle.kts
@@ -14,7 +14,7 @@ dependencies {
implementation(libs.androidx.window)
implementation(libs.google.material)
implementation(libs.androidx.startup)
-
+ implementation(libs.androidx.shapes)
implementation(libs.androidx.compose.activity)
implementation(platform(libs.androidx.compose.bom))
implementation(libs.androidx.compose.ui)
diff --git a/feature/embedding-splits/src/main/AndroidManifest.xml b/feature/embedding-splits/src/main/AndroidManifest.xml
index 0a4f21ba2..ad79904e2 100644
--- a/feature/embedding-splits/src/main/AndroidManifest.xml
+++ b/feature/embedding-splits/src/main/AndroidManifest.xml
@@ -17,6 +17,8 @@
android:name="com.dede.android_eggs.embedding_splits.SplitInitializer"
android:value="androidx.startup" />
+
+
diff --git a/feature/embedding-splits/src/main/java/com/dede/android_eggs/embedding_splits/PlaceholderActivity.kt b/feature/embedding-splits/src/main/java/com/dede/android_eggs/embedding_splits/PlaceholderActivity.kt
new file mode 100644
index 000000000..2a9f3cc9f
--- /dev/null
+++ b/feature/embedding-splits/src/main/java/com/dede/android_eggs/embedding_splits/PlaceholderActivity.kt
@@ -0,0 +1,239 @@
+package com.dede.android_eggs.embedding_splits
+
+import android.os.Bundle
+import androidx.activity.compose.setContent
+import androidx.activity.enableEdgeToEdge
+import androidx.appcompat.app.AppCompatActivity
+import androidx.compose.animation.core.Animatable
+import androidx.compose.animation.core.AnimationVector1D
+import androidx.compose.animation.core.spring
+import androidx.compose.foundation.clickable
+import androidx.compose.foundation.interaction.MutableInteractionSource
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.aspectRatio
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.imePadding
+import androidx.compose.material3.MaterialTheme.colorScheme
+import androidx.compose.material3.Scaffold
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.derivedStateOf
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableIntStateOf
+import androidx.compose.runtime.remember
+import androidx.compose.runtime.rememberCoroutineScope
+import androidx.compose.runtime.setValue
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.draw.drawWithContent
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.graphics.Matrix
+import androidx.compose.ui.graphics.asComposePath
+import androidx.compose.ui.tooling.preview.Preview
+import androidx.graphics.shapes.CornerRounding
+import androidx.graphics.shapes.Morph
+import androidx.graphics.shapes.RoundedPolygon
+import androidx.graphics.shapes.circle
+import androidx.graphics.shapes.pill
+import androidx.graphics.shapes.pillStar
+import androidx.graphics.shapes.rectangle
+import androidx.graphics.shapes.star
+import androidx.graphics.shapes.toPath
+import com.dede.android_eggs.util.LocalEvent
+import com.dede.android_eggs.util.ThemeUtils
+import com.dede.android_eggs.views.settings.compose.prefs.DynamicColorPrefUtil
+import com.dede.android_eggs.views.settings.compose.prefs.ThemePrefUtil
+import com.dede.android_eggs.views.theme.AppTheme
+import kotlinx.coroutines.launch
+import kotlin.math.max
+
+/**
+ * Placeholder for embedding splits
+ */
+class PlaceholderActivity : AppCompatActivity() {
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ ThemeUtils.tryApplyOLEDTheme(this)
+ enableEdgeToEdge()
+ super.onCreate(savedInstanceState)
+
+ setContent {
+ AppTheme {
+ @Suppress("UnusedMaterial3ScaffoldPaddingParameter")
+ Scaffold {
+ Placeholder()
+ }
+ }
+ }
+
+ with(LocalEvent.receiver(this)) {
+ register(ThemePrefUtil.ACTION_NIGHT_MODE_CHANGED) {
+ recreate()
+ }
+ register(DynamicColorPrefUtil.ACTION_DYNAMIC_COLOR_CHANGED) {
+ recreate()
+ }
+ }
+
+ }
+
+ init {
+ shapes.shuffle()
+ }
+
+}
+
+internal val shapes = arrayOf(
+ // PillStar
+ RoundedPolygon.pillStar(
+ numVerticesPerRadius = 12,
+ width = 1f,
+ height = 1f,
+ rounding = CornerRounding(.3f),
+ innerRounding = CornerRounding(.3f)
+ ).rotated(45f),
+ // Pill
+ RoundedPolygon.pill(
+ width = 1f,
+ height = 0.8f,
+ ).rotated(45f),
+ // Triangle
+ RoundedPolygon(
+ numVertices = 3,
+ rounding = CornerRounding(0.2f)
+ ),
+ // Circle
+ RoundedPolygon.circle(
+ numVertices = 4,
+ ),
+ // Square
+ RoundedPolygon.rectangle(
+ width = 1f,
+ height = 1f,
+ rounding = CornerRounding(0.3f)
+ ),
+ // Scallop
+ RoundedPolygon.star(
+ numVerticesPerRadius = 12,
+ innerRadius = .828f,
+ rounding = CornerRounding(.32f),
+ innerRounding = CornerRounding(.32f)
+ ),
+ // Clover
+ RoundedPolygon.star(
+ numVerticesPerRadius = 4,
+ innerRadius = .352f,
+ rounding = CornerRounding(.32f),
+ innerRounding = CornerRounding(.32f)
+ ).rotated(45f),
+ // Hexagon
+ RoundedPolygon(
+ numVertices = 6,
+ rounding = CornerRounding(0.2f),
+ ),
+ // Triangle
+ RoundedPolygon(
+ vertices = floatArrayOf(
+ radialToCartesian(1f, 270f.toRadians()).x,
+ radialToCartesian(1f, 270f.toRadians()).y,
+ radialToCartesian(1f, 30f.toRadians()).x,
+ radialToCartesian(1f, 30f.toRadians()).y,
+ radialToCartesian(0.1f, 90f.toRadians()).x,
+ radialToCartesian(0.1f, 90f.toRadians()).y,
+ radialToCartesian(1f, 150f.toRadians()).x,
+ radialToCartesian(1f, 150f.toRadians()).y
+ ),
+ rounding = CornerRounding(0.2f),
+ centerX = 0f,
+ centerY = 0f
+ ),
+ // CornerSE
+ RoundedPolygon(
+ vertices = floatArrayOf(1f, 1f, -1f, 1f, -1f, -1f, 1f, -1f),
+ perVertexRounding = listOf(
+ CornerRounding(0.4f),
+ CornerRounding(1f),
+ CornerRounding(1f),
+ CornerRounding(1f)
+ ),
+ ),
+
+ )
+
+@Preview
+@Composable
+internal fun Placeholder() {
+ val progress = remember { Animatable(0f) }
+ var currShape by remember { mutableIntStateOf(-1) }
+ val morphed by remember {
+ derivedStateOf {
+ Morph(
+ shapes[max(currShape, 0) % shapes.size],
+ shapes[(currShape + 1) % shapes.size]
+ )
+ }
+ }
+
+ Box(
+ contentAlignment = Alignment.Center,
+ modifier = Modifier
+ .fillMaxSize()
+ .imePadding()
+ ) {
+ val scope = rememberCoroutineScope()
+ MorphComposable(
+ sizedMorph = morphed,
+ modifier = Modifier
+ .fillMaxSize(0.3f)
+ .clickable(
+ indication = null, // Eliminate the ripple effect.
+ interactionSource = remember { MutableInteractionSource() }
+ ) {
+ scope.launch {
+ currShape += 1
+ doAnimation(progress)
+ }
+ },
+ progress = progress.value,
+ )
+ }
+}
+
+
+@Composable
+private fun MorphComposable(
+ sizedMorph: Morph,
+ modifier: Modifier = Modifier,
+ color: Color = colorScheme.surfaceVariant,
+ progress: Float,
+) {
+ val matrix = remember { Matrix() }
+ Box(
+ modifier = modifier
+ .aspectRatio(1f)
+ .drawWithContent {
+ val path = sizedMorph
+ .toPath(progress = progress)
+ .asComposePath()
+
+ matrix.reset()
+ val bounds = path.getBounds()
+ val maxDimension = max(bounds.width, bounds.height)
+ matrix.scale(size.width / maxDimension, size.height / maxDimension)
+ matrix.translate(-bounds.left, -bounds.top)
+
+ path.transform(matrix)
+
+ drawPath(path, color)
+
+ drawContent()
+ },
+ )
+}
+
+private suspend fun doAnimation(progress: Animatable) {
+ progress.snapTo(0f)
+ progress.animateTo(
+ 1f,
+ animationSpec = spring(0.6f, 50f)
+ )
+}
diff --git a/feature/embedding-splits/src/main/java/com/dede/android_eggs/embedding_splits/Utilities.kt b/feature/embedding-splits/src/main/java/com/dede/android_eggs/embedding_splits/Utilities.kt
new file mode 100644
index 000000000..5eeed87c9
--- /dev/null
+++ b/feature/embedding-splits/src/main/java/com/dede/android_eggs/embedding_splits/Utilities.kt
@@ -0,0 +1,126 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.dede.android_eggs.embedding_splits
+
+import android.graphics.PointF
+import androidx.compose.ui.geometry.Offset
+import androidx.compose.ui.geometry.Rect
+import androidx.compose.ui.geometry.Size
+import androidx.compose.ui.graphics.Matrix
+import androidx.compose.ui.graphics.Outline
+import androidx.compose.ui.graphics.Shape
+import androidx.compose.ui.graphics.asComposePath
+import androidx.compose.ui.unit.Density
+import androidx.compose.ui.unit.LayoutDirection
+import androidx.core.graphics.plus
+import androidx.core.graphics.times
+import androidx.graphics.shapes.Morph
+import androidx.graphics.shapes.RoundedPolygon
+import androidx.graphics.shapes.TransformResult
+import androidx.graphics.shapes.toPath
+import kotlin.math.PI
+import kotlin.math.cos
+import kotlin.math.max
+import kotlin.math.sin
+
+internal fun Float.toRadians() = this * PI.toFloat() / 180f
+
+internal fun Offset.rotate90() = Offset(-y, x)
+
+internal fun directionVector(angleRadians: Float) = Offset(cos(angleRadians), sin(angleRadians))
+
+internal fun Offset.rotate(angleRadians: Float): Offset {
+ val vec = directionVector(angleRadians)
+ return vec * x + vec.rotate90() * y
+}
+
+internal val PointZero = PointF(0f, 0f)
+
+internal fun radialToCartesian(
+ radius: Float,
+ angleRadians: Float,
+ center: PointF = PointZero
+) = directionVectorPointF(angleRadians) * radius + center
+
+
+internal fun directionVectorPointF(angleRadians: Float) =
+ PointF(cos(angleRadians), sin(angleRadians))
+
+
+fun RoundedPolygon.rotated(rotate: Float): RoundedPolygon {
+ return this.transformed(Matrix().apply { rotateZ(rotate) })
+}
+
+/**
+ * Transforms a [RoundedPolygon] with the given [Matrix]
+ */
+fun RoundedPolygon.transformed(matrix: Matrix): RoundedPolygon =
+ transformed { x, y ->
+ val transformedPoint = matrix.map(Offset(x, y))
+ TransformResult(transformedPoint.x, transformedPoint.y)
+ }
+
+/**
+ * Calculates and returns the bounds of this [RoundedPolygon] as a [Rect]
+ */
+fun RoundedPolygon.getBounds() = calculateBounds().let { Rect(it[0], it[1], it[2], it[3]) }
+
+class MorphPolygonShape(
+ private val morph: Morph,
+ private val percentage: Float
+) : Shape {
+
+ private val matrix = Matrix()
+
+ override fun createOutline(
+ size: Size,
+ layoutDirection: LayoutDirection,
+ density: Density
+ ): Outline {
+ val path = morph.toPath(progress = percentage).asComposePath()
+
+ val bounds = path.getBounds()
+ val maxDimension = max(bounds.width, bounds.height)
+ matrix.scale(size.width / maxDimension, size.height / maxDimension)
+ matrix.translate(-bounds.left, -bounds.top)
+
+ path.transform(matrix)
+ return Outline.Generic(path)
+ }
+}
+
+
+class RoundedPolygonShape(
+ private val polygon: RoundedPolygon,
+ private val matrix: Matrix = Matrix()
+) : Shape {
+
+ override fun createOutline(
+ size: Size,
+ layoutDirection: LayoutDirection,
+ density: Density
+ ): Outline {
+ val bounds = polygon.getBounds()
+ val maxDimension = max(bounds.width, bounds.height)
+ matrix.scale(size.width / maxDimension, size.height / maxDimension)
+ matrix.translate(-bounds.left, -bounds.top)
+
+ val path = polygon.toPath().asComposePath()
+ path.transform(matrix)
+ return Outline.Generic(path)
+ }
+}
diff --git a/feature/embedding-splits/src/main/res/drawable/better_together_hero.xml b/feature/embedding-splits/src/main/res/drawable/better_together_hero.xml
deleted file mode 100644
index 4a73cfa21..000000000
--- a/feature/embedding-splits/src/main/res/drawable/better_together_hero.xml
+++ /dev/null
@@ -1,138 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/feature/embedding-splits/src/main/res/xml/split_configuration.xml b/feature/embedding-splits/src/main/res/xml/split_configuration.xml
index 5ab01cf1c..f6cd61c83 100644
--- a/feature/embedding-splits/src/main/res/xml/split_configuration.xml
+++ b/feature/embedding-splits/src/main/res/xml/split_configuration.xml
@@ -56,7 +56,7 @@