diff --git a/app/src/main/java/com/anod/appwatcher/watchlist/WatchListPage.kt b/app/src/main/java/com/anod/appwatcher/watchlist/WatchListPage.kt index af8e2b7e..dcff9625 100644 --- a/app/src/main/java/com/anod/appwatcher/watchlist/WatchListPage.kt +++ b/app/src/main/java/com/anod/appwatcher/watchlist/WatchListPage.kt @@ -15,10 +15,12 @@ import androidx.compose.foundation.horizontalScroll import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.IntrinsicSize import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.WindowInsets import androidx.compose.foundation.layout.asPaddingValues import androidx.compose.foundation.layout.defaultMinSize +import androidx.compose.foundation.layout.fillMaxHeight import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height @@ -233,7 +235,11 @@ fun WatchListSectionItem( appIconLoader = appIconLoader ) - is SectionItem.Recent -> RecentItem(onEvent = onEvent, recentApps = recentlyInstalledApps) + is SectionItem.Recent -> RecentItem( + onEvent = onEvent, + recentApps = recentlyInstalledApps, + appIconLoader = appIconLoader + ) is SectionItem.Empty -> EmptyItem(onEvent = onEvent) } } @@ -478,6 +484,7 @@ private fun RecentItemRow( modifier = Modifier .defaultMinSize(minHeight = 96.dp) .fillMaxWidth() + .height(IntrinsicSize.Max) .padding(start = 6.dp, end = 8.dp) .horizontalScroll(scrollState) ) { @@ -513,6 +520,7 @@ private fun RecentItemAppCard( ) { Card( modifier = Modifier + .fillMaxHeight() .defaultMinSize(minHeight = 116.dp) .width(96.dp) .padding(start = 2.dp, end = 2.dp, top = 2.dp, bottom = 2.dp) diff --git a/app/src/test/java/com/anod/appwatcher/watchlist/RecentlyInstalledCardsTest.kt b/app/src/test/java/com/anod/appwatcher/watchlist/RecentlyInstalledCardsTest.kt new file mode 100644 index 00000000..463bd5f2 --- /dev/null +++ b/app/src/test/java/com/anod/appwatcher/watchlist/RecentlyInstalledCardsTest.kt @@ -0,0 +1,80 @@ +package com.anod.appwatcher.watchlist + +import android.content.Context +import androidx.compose.material3.MaterialTheme +import androidx.compose.ui.test.hasClickAction +import androidx.compose.ui.test.junit4.v2.createComposeRule +import androidx.compose.ui.test.onNodeWithText +import androidx.compose.ui.unit.sp +import androidx.test.core.app.ApplicationProvider +import coil3.ImageLoader +import com.anod.appwatcher.compose.AppTheme +import com.anod.appwatcher.database.entities.App +import com.anod.appwatcher.utils.AppIconLoader +import kotlinx.collections.immutable.persistentListOf +import org.junit.Assert.assertEquals +import org.junit.Assert.assertTrue +import org.junit.Rule +import org.junit.Test +import org.junit.runner.RunWith +import org.robolectric.RobolectricTestRunner +import org.robolectric.annotation.Config + +@RunWith(RobolectricTestRunner::class) +@Config(sdk = [36], qualifiers = "w411dp-h891dp") +class RecentlyInstalledCardsTest { + + @get:Rule + val compose = createComposeRule() + + @Test + fun cardsHaveEqualHeightWhenTitlesUseDifferentLineCounts() { + val context = ApplicationProvider.getApplicationContext() + val appIconLoader = AppIconLoader.Simple(context, ImageLoader.Builder(context).build()) + val apps = persistentListOf( + createApp(rowId = 1, packageName = "eden", title = "Eden"), + createApp(rowId = 2, packageName = "adaptive", title = "Simply\nAdaptive App") + ) + + compose.setContent { + AppTheme(updateSystemBars = false) { + MaterialTheme( + typography = MaterialTheme.typography.copy( + bodyMedium = MaterialTheme.typography.bodyMedium.copy(lineHeight = 28.sp) + ) + ) { + WatchListSectionItem( + item = SectionItem.Recent, + index = 0, + onEvent = {}, + appIconLoader = appIconLoader, + recentlyInstalledApps = apps + ) + } + } + } + compose.waitForIdle() + + val cardHeights = compose + .onAllNodes(hasClickAction(), useUnmergedTree = true) + .fetchSemanticsNodes() + .map { it.boundsInRoot.height } + val titleHeights = apps.map { + compose.onNodeWithText(it.title, useUnmergedTree = true).fetchSemanticsNode().boundsInRoot.height + } + + assertEquals(2, cardHeights.size) + assertTrue(titleHeights.last() > titleHeights.first()) + assertEquals(cardHeights.first(), cardHeights.last(), 0f) + } + + private fun createApp(rowId: Int, packageName: String, title: String): App = App.fromLocalPackage( + rowId = rowId, + packageName = packageName, + uploadTime = 0, + versionCode = 1, + versionName = "1", + appTitle = title, + launchComponent = null + ) +} \ No newline at end of file