From 1f7231bd09c7b80708fd0a38fd0551b12e2c959f Mon Sep 17 00:00:00 2001 From: CHARLES BOND Date: Tue, 25 Jun 2024 01:07:39 +0900 Subject: [PATCH 1/4] UI adjustments to list (incomplete). --- .../confsched/model/TimetableRoom.kt | 55 ++++++++ .../sessions/section/TimetableList.kt | 129 ++++++++++++++++-- 2 files changed, 172 insertions(+), 12 deletions(-) diff --git a/core/model/src/commonMain/kotlin/io/github/droidkaigi/confsched/model/TimetableRoom.kt b/core/model/src/commonMain/kotlin/io/github/droidkaigi/confsched/model/TimetableRoom.kt index e8bc4b127..fc206bdfb 100644 --- a/core/model/src/commonMain/kotlin/io/github/droidkaigi/confsched/model/TimetableRoom.kt +++ b/core/model/src/commonMain/kotlin/io/github/droidkaigi/confsched/model/TimetableRoom.kt @@ -1,5 +1,10 @@ package io.github.droidkaigi.confsched.model +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.Star +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.vector.ImageVector + @Immutable data class TimetableRooms(val rooms: List) @@ -15,6 +20,56 @@ data class TimetableRoom( } return sort.compareTo(other.sort) } + + fun getColor(): Color { + return when(name.enTitle) { + "Chipmunk" -> { + Color(0xFFFF974B) + } + "Dolphin" -> { + Color(0xFFBB85FF) + } + "Bumblebee" -> { + Color(0xFFDDD33C) + } + "Arctic Fox" -> { + Color(0xFF45E761) + } + else -> { + Color.White + } + } + } + + fun getShape(): Shapes { + return when(name.enTitle) { + "Arctic Fox" -> { + Shapes.SQUARE + } + "Bumblebee" -> { + Shapes.CIRCLE + } + "Chipmunk" -> { + Shapes.SHARP_DIAMOND + } + "Dolphin" -> { + Shapes.DIAMOND + } + else -> { + Shapes.SQUARE + } + } + } + + enum class Shapes { + SQUARE, + CIRCLE, + SHARP_DIAMOND, + DIAMOND + } + + + } val TimetableRoom.nameAndFloor: String diff --git a/feature/sessions/src/commonMain/kotlin/io/github/droidkaigi/confsched/sessions/section/TimetableList.kt b/feature/sessions/src/commonMain/kotlin/io/github/droidkaigi/confsched/sessions/section/TimetableList.kt index 12e8df34b..ea8d54824 100644 --- a/feature/sessions/src/commonMain/kotlin/io/github/droidkaigi/confsched/sessions/section/TimetableList.kt +++ b/feature/sessions/src/commonMain/kotlin/io/github/droidkaigi/confsched/sessions/section/TimetableList.kt @@ -1,6 +1,11 @@ package io.github.droidkaigi.confsched.sessions.section +import androidx.compose.foundation.BorderStroke +import androidx.compose.foundation.background +import androidx.compose.foundation.border import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer @@ -8,14 +13,32 @@ import androidx.compose.foundation.layout.padding import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.LazyListState import androidx.compose.foundation.lazy.items -import androidx.compose.material3.Button +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.Circle +import androidx.compose.material.icons.filled.Diamond +import androidx.compose.material.icons.filled.Favorite +import androidx.compose.material.icons.filled.Square +import androidx.compose.material.icons.filled.Star +import androidx.compose.material.icons.filled.Thermostat +import androidx.compose.material.icons.outlined.FavoriteBorder +import androidx.compose.material3.Icon import androidx.compose.material3.Text +import androidx.compose.material3.TextButton import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.platform.testTag +import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import io.github.droidkaigi.confsched.model.Timetable import io.github.droidkaigi.confsched.model.TimetableItem +import io.github.droidkaigi.confsched.model.TimetableRoom.Shapes.CIRCLE +import io.github.droidkaigi.confsched.model.TimetableRoom.Shapes.DIAMOND +import io.github.droidkaigi.confsched.model.TimetableRoom.Shapes.SHARP_DIAMOND +import io.github.droidkaigi.confsched.model.TimetableRoom.Shapes.SQUARE import io.github.droidkaigi.confsched.sessions.TimetableListItemBookmarkIconTestTag import io.github.droidkaigi.confsched.sessions.TimetableListItemTestTag import kotlinx.collections.immutable.PersistentMap @@ -43,24 +66,106 @@ fun TimetableList( ) { items(uiState.timetable.timetableItems, key = { it.id.value }) { timetableItem -> val isBookmarked = uiState.timetable.bookmarks.contains(timetableItem.id) - Row { + val roomName = timetableItem.room.name.currentLangTitle + + //TODO: Replace with the real icons. Probably need to embed them. + val roomIcon = when (timetableItem.room.getShape()) { + SQUARE -> { Icons.Filled.Square } + CIRCLE -> { Icons.Filled.Circle } + DIAMOND -> {Icons.Filled.Thermostat } + SHARP_DIAMOND -> {Icons.Filled.Diamond } + else -> { Icons.Filled.Star } + } + val roomColor = timetableItem.room.getColor() + + Column( + modifier = Modifier.border(border= BorderStroke(width=1.dp,color=Color.White)) + .clip(RoundedCornerShape(5.dp)) + .padding(15.dp)) { + Row { + TagView(tagText=roomName, icon = roomIcon, tagColor=roomColor) + Spacer(modifier = Modifier.padding(3.dp)) + TagView(tagText="JA", tagColor=Color.White) + Spacer(modifier = Modifier.padding(3.dp)) + TagView(tagText="EN", tagColor=Color.White) + Spacer(modifier = Modifier.weight(1f)) + TextButton( + onClick = { onBookmarkClick(timetableItem, true) }, + modifier = Modifier.testTag(TimetableListItemBookmarkIconTestTag) + ) { + if (isBookmarked) { + Icon( + Icons.Filled.Favorite, + contentDescription = "Bookmarked", + tint = Color.Green + ) + } else { + Icon( + Icons.Outlined.FavoriteBorder, + contentDescription = "Not Bookmarked", + tint = Color.White + ) + } + } + } Text( text = timetableItem.title.currentLangTitle, modifier = Modifier - .padding(horizontal = 16.dp) .testTag(TimetableListItemTestTag) .clickable { onTimetableItemClick(timetableItem) }, ) - Spacer(modifier = Modifier.weight(1f)) - Button( - modifier = Modifier.testTag(TimetableListItemBookmarkIconTestTag), - onClick = { onBookmarkClick(timetableItem, true) }, - ) { - Text( - text = "Bookmark $isBookmarked", - ) - } } } } } + +@Composable +fun TagView (tagText: String, icon: ImageVector?=null, tagColor: Color) { + Row(modifier = Modifier + .border(border = BorderStroke(width = 1.dp, color = tagColor)) + .clip(RoundedCornerShape(15.dp)) + .padding(5.dp)) { + icon?.let { ico -> + Icon(ico, "", tint=tagColor) + } + Spacer(modifier = Modifier.padding(3.dp)) + Text( + color = tagColor, + text = tagText, + modifier = Modifier.padding(end=5.dp) + ) + } +} + +//@Composable +//fun testItem() { +// val isBookmarked = false +// Row { +// Text( +// text = "Placeholder",//timetableItem.title.currentLangTitle, +// modifier = Modifier +// .padding(horizontal = 16.dp) +// //.testTag(TimetableListItemTestTag) +// //.clickable { onTimetableItemClick(timetableItem) }, +// ) +// Spacer(modifier = Modifier.weight(1f)) +// TextButton( +// onClick = {} +// //onClick = { onBookmarkClick(timetableItem, true) }//, +// //modifier = Modifier.testTag(TimetableListItemBookmarkIconTestTag) +// ) { +// if (isBookmarked) { +// Icon(Icons.Filled.Favorite, contentDescription = "Bookmarked", tint= Color.Green) +// } else { +// Icon(Icons.Outlined.FavoriteBorder, contentDescription = "Not Bookmarked", tint= Color.White) +// } +// } +// } +//} +// +//@Preview @Composable +//fun previewItem() { +// testItem() +//} + + From 349a101bb6a203607af6ddb7a7323bab7120c786 Mon Sep 17 00:00:00 2001 From: CHARLES BOND Date: Tue, 25 Jun 2024 23:05:08 +0900 Subject: [PATCH 2/4] Added initial list cell formatting. Basically functional. Missing: Time sorting, correct shapes for room names, correct room names (data issue), warning data (canceled events), Favorite is misaligned. Also: Overall top bar, title, etc is still missing. --- .../sessions/section/TimetableList.kt | 54 ++++++++++++++++--- 1 file changed, 46 insertions(+), 8 deletions(-) diff --git a/feature/sessions/src/commonMain/kotlin/io/github/droidkaigi/confsched/sessions/section/TimetableList.kt b/feature/sessions/src/commonMain/kotlin/io/github/droidkaigi/confsched/sessions/section/TimetableList.kt index ea8d54824..7c7d023f1 100644 --- a/feature/sessions/src/commonMain/kotlin/io/github/droidkaigi/confsched/sessions/section/TimetableList.kt +++ b/feature/sessions/src/commonMain/kotlin/io/github/droidkaigi/confsched/sessions/section/TimetableList.kt @@ -1,18 +1,23 @@ package io.github.droidkaigi.confsched.sessions.section import androidx.compose.foundation.BorderStroke +import androidx.compose.foundation.Image import androidx.compose.foundation.background import androidx.compose.foundation.border import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.width import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.LazyListState import androidx.compose.foundation.lazy.items +import androidx.compose.foundation.shape.CircleShape import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Circle @@ -26,6 +31,8 @@ import androidx.compose.material3.Icon import androidx.compose.material3.Text import androidx.compose.material3.TextButton import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Alignment.Companion import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.graphics.Color @@ -33,6 +40,8 @@ import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.platform.testTag import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import com.seiko.imageloader.rememberImagePainter import io.github.droidkaigi.confsched.model.Timetable import io.github.droidkaigi.confsched.model.TimetableItem import io.github.droidkaigi.confsched.model.TimetableRoom.Shapes.CIRCLE @@ -62,6 +71,7 @@ fun TimetableList( LazyColumn( modifier = modifier.testTag(TimetableListTestTag), state = scrollState, + verticalArrangement = Arrangement.spacedBy(10.dp), contentPadding = contentPadding, ) { items(uiState.timetable.timetableItems, key = { it.id.value }) { timetableItem -> @@ -79,15 +89,17 @@ fun TimetableList( val roomColor = timetableItem.room.getColor() Column( - modifier = Modifier.border(border= BorderStroke(width=1.dp,color=Color.White)) - .clip(RoundedCornerShape(5.dp)) - .padding(15.dp)) { + modifier = Modifier + .border(border= BorderStroke(width=1.dp,color=Color.White), shape = RoundedCornerShape(5.dp)) + .padding(15.dp) + ) { Row { TagView(tagText=roomName, icon = roomIcon, tagColor=roomColor) Spacer(modifier = Modifier.padding(3.dp)) - TagView(tagText="JA", tagColor=Color.White) - Spacer(modifier = Modifier.padding(3.dp)) - TagView(tagText="EN", tagColor=Color.White) + timetableItem.language.labels.forEach { label -> + TagView(tagText=label, tagColor=Color.White) + Spacer(modifier = Modifier.padding(3.dp)) + } Spacer(modifier = Modifier.weight(1f)) TextButton( onClick = { onBookmarkClick(timetableItem, true) }, @@ -97,23 +109,49 @@ fun TimetableList( Icon( Icons.Filled.Favorite, contentDescription = "Bookmarked", - tint = Color.Green + tint = Color.Green, ) } else { Icon( Icons.Outlined.FavoriteBorder, contentDescription = "Not Bookmarked", - tint = Color.White + tint = Color.White, ) } } } Text( text = timetableItem.title.currentLangTitle, + fontSize = 24.sp, modifier = Modifier .testTag(TimetableListItemTestTag) + .padding(bottom=5.dp) .clickable { onTimetableItemClick(timetableItem) }, ) + timetableItem.speakers.forEach { speaker -> + Row { + //TODO: This style of image loading was included by default but it seems slow + val painter = rememberImagePainter(speaker.iconUrl) + Image( + painter = painter, + modifier = Modifier + .width(32.dp) + .height(32.dp) + .clip(CircleShape), + contentDescription = "image", + ) + Text( + text = speaker.name, + fontSize = 24.sp, + modifier = Modifier + .testTag(TimetableListItemTestTag) + .padding(5.dp) + .align(Alignment.CenterVertically) + ) + } + } + //TODO: There is no data for the warning string right now. (Should go here) + } } } From 7c110b55e330f97ab34e8be442b5a51e1f06fe1f Mon Sep 17 00:00:00 2001 From: takahirom Date: Wed, 26 Jun 2024 09:49:07 +0900 Subject: [PATCH 3/4] Fix format --- .../confsched/model/TimetableRoom.kt | 12 +- .../sessions/section/TimetableList.kt | 108 ++++++++---------- 2 files changed, 50 insertions(+), 70 deletions(-) diff --git a/core/model/src/commonMain/kotlin/io/github/droidkaigi/confsched/model/TimetableRoom.kt b/core/model/src/commonMain/kotlin/io/github/droidkaigi/confsched/model/TimetableRoom.kt index fc206bdfb..48919271b 100644 --- a/core/model/src/commonMain/kotlin/io/github/droidkaigi/confsched/model/TimetableRoom.kt +++ b/core/model/src/commonMain/kotlin/io/github/droidkaigi/confsched/model/TimetableRoom.kt @@ -1,9 +1,6 @@ package io.github.droidkaigi.confsched.model -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.Star import androidx.compose.ui.graphics.Color -import androidx.compose.ui.graphics.vector.ImageVector @Immutable data class TimetableRooms(val rooms: List) @@ -22,7 +19,7 @@ data class TimetableRoom( } fun getColor(): Color { - return when(name.enTitle) { + return when (name.enTitle) { "Chipmunk" -> { Color(0xFFFF974B) } @@ -42,7 +39,7 @@ data class TimetableRoom( } fun getShape(): Shapes { - return when(name.enTitle) { + return when (name.enTitle) { "Arctic Fox" -> { Shapes.SQUARE } @@ -65,11 +62,8 @@ data class TimetableRoom( SQUARE, CIRCLE, SHARP_DIAMOND, - DIAMOND + DIAMOND, } - - - } val TimetableRoom.nameAndFloor: String diff --git a/feature/sessions/src/commonMain/kotlin/io/github/droidkaigi/confsched/sessions/section/TimetableList.kt b/feature/sessions/src/commonMain/kotlin/io/github/droidkaigi/confsched/sessions/section/TimetableList.kt index 7c7d023f1..1ecc04771 100644 --- a/feature/sessions/src/commonMain/kotlin/io/github/droidkaigi/confsched/sessions/section/TimetableList.kt +++ b/feature/sessions/src/commonMain/kotlin/io/github/droidkaigi/confsched/sessions/section/TimetableList.kt @@ -2,11 +2,9 @@ package io.github.droidkaigi.confsched.sessions.section import androidx.compose.foundation.BorderStroke import androidx.compose.foundation.Image -import androidx.compose.foundation.background import androidx.compose.foundation.border import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.Row @@ -32,13 +30,11 @@ import androidx.compose.material3.Text import androidx.compose.material3.TextButton import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment -import androidx.compose.ui.Alignment.Companion import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.platform.testTag -import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import com.seiko.imageloader.rememberImagePainter @@ -78,32 +74,49 @@ fun TimetableList( val isBookmarked = uiState.timetable.bookmarks.contains(timetableItem.id) val roomName = timetableItem.room.name.currentLangTitle - //TODO: Replace with the real icons. Probably need to embed them. + // TODO: Replace with the real icons. Probably need to embed them. val roomIcon = when (timetableItem.room.getShape()) { - SQUARE -> { Icons.Filled.Square } - CIRCLE -> { Icons.Filled.Circle } - DIAMOND -> {Icons.Filled.Thermostat } - SHARP_DIAMOND -> {Icons.Filled.Diamond } - else -> { Icons.Filled.Star } + SQUARE -> { + Icons.Filled.Square + } + + CIRCLE -> { + Icons.Filled.Circle + } + + DIAMOND -> { + Icons.Filled.Thermostat + } + + SHARP_DIAMOND -> { + Icons.Filled.Diamond + } + + else -> { + Icons.Filled.Star + } } val roomColor = timetableItem.room.getColor() Column( modifier = Modifier - .border(border= BorderStroke(width=1.dp,color=Color.White), shape = RoundedCornerShape(5.dp)) - .padding(15.dp) - ) { + .border( + border = BorderStroke(width = 1.dp, color = Color.White), + shape = RoundedCornerShape(5.dp), + ) + .padding(15.dp), + ) { Row { - TagView(tagText=roomName, icon = roomIcon, tagColor=roomColor) + TagView(tagText = roomName, icon = roomIcon, tagColor = roomColor) Spacer(modifier = Modifier.padding(3.dp)) timetableItem.language.labels.forEach { label -> - TagView(tagText=label, tagColor=Color.White) + TagView(tagText = label, tagColor = Color.White) Spacer(modifier = Modifier.padding(3.dp)) } Spacer(modifier = Modifier.weight(1f)) TextButton( onClick = { onBookmarkClick(timetableItem, true) }, - modifier = Modifier.testTag(TimetableListItemBookmarkIconTestTag) + modifier = Modifier.testTag(TimetableListItemBookmarkIconTestTag), ) { if (isBookmarked) { Icon( @@ -125,12 +138,12 @@ fun TimetableList( fontSize = 24.sp, modifier = Modifier .testTag(TimetableListItemTestTag) - .padding(bottom=5.dp) + .padding(bottom = 5.dp) .clickable { onTimetableItemClick(timetableItem) }, ) timetableItem.speakers.forEach { speaker -> Row { - //TODO: This style of image loading was included by default but it seems slow + // TODO: This style of image loading was included by default but it seems slow val painter = rememberImagePainter(speaker.iconUrl) Image( painter = painter, @@ -146,64 +159,37 @@ fun TimetableList( modifier = Modifier .testTag(TimetableListItemTestTag) .padding(5.dp) - .align(Alignment.CenterVertically) + .align(Alignment.CenterVertically), ) } } - //TODO: There is no data for the warning string right now. (Should go here) - + // TODO: There is no data for the warning string right now. (Should go here) } } } } @Composable -fun TagView (tagText: String, icon: ImageVector?=null, tagColor: Color) { - Row(modifier = Modifier - .border(border = BorderStroke(width = 1.dp, color = tagColor)) - .clip(RoundedCornerShape(15.dp)) - .padding(5.dp)) { +fun TagView( + tagText: String, + tagColor: Color, + modifier: Modifier = Modifier, + icon: ImageVector? = null, +) { + Row( + modifier = modifier + .border(border = BorderStroke(width = 1.dp, color = tagColor)) + .clip(RoundedCornerShape(15.dp)) + .padding(5.dp), + ) { icon?.let { ico -> - Icon(ico, "", tint=tagColor) + Icon(ico, "", tint = tagColor) } Spacer(modifier = Modifier.padding(3.dp)) Text( color = tagColor, text = tagText, - modifier = Modifier.padding(end=5.dp) + modifier = Modifier.padding(end = 5.dp), ) } } - -//@Composable -//fun testItem() { -// val isBookmarked = false -// Row { -// Text( -// text = "Placeholder",//timetableItem.title.currentLangTitle, -// modifier = Modifier -// .padding(horizontal = 16.dp) -// //.testTag(TimetableListItemTestTag) -// //.clickable { onTimetableItemClick(timetableItem) }, -// ) -// Spacer(modifier = Modifier.weight(1f)) -// TextButton( -// onClick = {} -// //onClick = { onBookmarkClick(timetableItem, true) }//, -// //modifier = Modifier.testTag(TimetableListItemBookmarkIconTestTag) -// ) { -// if (isBookmarked) { -// Icon(Icons.Filled.Favorite, contentDescription = "Bookmarked", tint= Color.Green) -// } else { -// Icon(Icons.Outlined.FavoriteBorder, contentDescription = "Not Bookmarked", tint= Color.White) -// } -// } -// } -//} -// -//@Preview @Composable -//fun previewItem() { -// testItem() -//} - - From ca12096ad18108ad67e9e7a06847566c941239f6 Mon Sep 17 00:00:00 2001 From: takahirom Date: Wed, 26 Jun 2024 10:46:25 +0900 Subject: [PATCH 4/4] Fix image loading in test --- core/testing/build.gradle.kts | 1 + .../confsched/testing/RobotTestRule.kt | 17 +++++++++++++++++ core/ui/build.gradle.kts | 2 +- .../droidkaigi/confsched/ui/ImagePainter.kt | 5 +++-- .../confsched/sessions/section/TimetableList.kt | 4 ++-- gradle/libs.versions.toml | 5 +++-- 6 files changed, 27 insertions(+), 7 deletions(-) diff --git a/core/testing/build.gradle.kts b/core/testing/build.gradle.kts index c03967267..a268a81e0 100644 --- a/core/testing/build.gradle.kts +++ b/core/testing/build.gradle.kts @@ -18,6 +18,7 @@ dependencies { implementation(libs.daggerHiltAndroidTesting) implementation(libs.roborazzi) implementation(libs.kermit) + implementation(libs.coilTest) api(projects.core.testingManifest) api(libs.composeNavigation) api(libs.roborazziRule) diff --git a/core/testing/src/main/java/io/github/droidkaigi/confsched/testing/RobotTestRule.kt b/core/testing/src/main/java/io/github/droidkaigi/confsched/testing/RobotTestRule.kt index 99e46b5ec..7c1d24986 100644 --- a/core/testing/src/main/java/io/github/droidkaigi/confsched/testing/RobotTestRule.kt +++ b/core/testing/src/main/java/io/github/droidkaigi/confsched/testing/RobotTestRule.kt @@ -1,6 +1,7 @@ package io.github.droidkaigi.confsched.testing import android.content.Intent +import android.graphics.drawable.ColorDrawable import android.os.Bundle import androidx.activity.ComponentActivity import androidx.compose.runtime.Composable @@ -12,6 +13,10 @@ import androidx.test.core.app.ApplicationProvider import androidx.test.ext.junit.rules.ActivityScenarioRule import co.touchlab.kermit.CommonWriter import co.touchlab.kermit.Logger +import coil3.ImageLoader +import coil3.SingletonImageLoader +import coil3.test.FakeImageLoaderEngine +import coil3.test.default import com.github.takahirom.roborazzi.RoborazziOptions import com.github.takahirom.roborazzi.RoborazziOptions.CompareOptions import com.github.takahirom.roborazzi.RoborazziOptions.PixelBitConfig @@ -108,6 +113,18 @@ class RobotTestRule( ), ), ) + .around(object : TestWatcher() { + override fun starting(description: Description?) { + super.starting(description) + val engine = FakeImageLoaderEngine.Builder() + .default(ColorDrawable(android.graphics.Color.BLUE)) + .build() + val imageLoader = ImageLoader.Builder(ApplicationProvider.getApplicationContext()) + .components { add(engine) } + .build() + SingletonImageLoader.setUnsafe(imageLoader) + } + }) .around(composeTestRule) .apply(base, description) } diff --git a/core/ui/build.gradle.kts b/core/ui/build.gradle.kts index e7f3ebe7b..39953d332 100644 --- a/core/ui/build.gradle.kts +++ b/core/ui/build.gradle.kts @@ -17,7 +17,7 @@ kotlin { implementation(projects.core.data) implementation(libs.kermit) api(projects.core.common) - api(libs.composeImageLoader) + api(libs.coil) api(libs.kotlinxDatetime) implementation(libs.moleculeRuntime) implementation(libs.coreBundle) diff --git a/core/ui/src/commonMain/kotlin/io/github/droidkaigi/confsched/ui/ImagePainter.kt b/core/ui/src/commonMain/kotlin/io/github/droidkaigi/confsched/ui/ImagePainter.kt index 40433ee72..6813d3287 100644 --- a/core/ui/src/commonMain/kotlin/io/github/droidkaigi/confsched/ui/ImagePainter.kt +++ b/core/ui/src/commonMain/kotlin/io/github/droidkaigi/confsched/ui/ImagePainter.kt @@ -2,9 +2,10 @@ package io.github.droidkaigi.confsched.ui import androidx.compose.runtime.Composable import androidx.compose.ui.graphics.painter.Painter -import com.seiko.imageloader.rememberImagePainter @Composable fun rememberAsyncImagePainter(url: String): Painter { - return rememberImagePainter(url = url) + return coil3.compose.rememberAsyncImagePainter( + model = url, + ) } diff --git a/feature/sessions/src/commonMain/kotlin/io/github/droidkaigi/confsched/sessions/section/TimetableList.kt b/feature/sessions/src/commonMain/kotlin/io/github/droidkaigi/confsched/sessions/section/TimetableList.kt index 1ecc04771..c4a26f775 100644 --- a/feature/sessions/src/commonMain/kotlin/io/github/droidkaigi/confsched/sessions/section/TimetableList.kt +++ b/feature/sessions/src/commonMain/kotlin/io/github/droidkaigi/confsched/sessions/section/TimetableList.kt @@ -37,7 +37,6 @@ import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.platform.testTag import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp -import com.seiko.imageloader.rememberImagePainter import io.github.droidkaigi.confsched.model.Timetable import io.github.droidkaigi.confsched.model.TimetableItem import io.github.droidkaigi.confsched.model.TimetableRoom.Shapes.CIRCLE @@ -46,6 +45,7 @@ import io.github.droidkaigi.confsched.model.TimetableRoom.Shapes.SHARP_DIAMOND import io.github.droidkaigi.confsched.model.TimetableRoom.Shapes.SQUARE import io.github.droidkaigi.confsched.sessions.TimetableListItemBookmarkIconTestTag import io.github.droidkaigi.confsched.sessions.TimetableListItemTestTag +import io.github.droidkaigi.confsched.ui.rememberAsyncImagePainter import kotlinx.collections.immutable.PersistentMap const val TimetableListTestTag = "TimetableList" @@ -144,7 +144,7 @@ fun TimetableList( timetableItem.speakers.forEach { speaker -> Row { // TODO: This style of image loading was included by default but it seems slow - val painter = rememberImagePainter(speaker.iconUrl) + val painter = rememberAsyncImagePainter(speaker.iconUrl) Image( painter = painter, modifier = Modifier diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 20e2e2b9d..8981e64d2 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -45,6 +45,7 @@ kover = "0.7.6" androidxLifecycleProcess = "2.8.2" skie = "0.8.2" composablePreviewScanner = "0.1.1" +coil = "3.0.0-alpha06" [libraries] androidGradlePlugin = { group = "com.android.tools.build", name = "gradle", version.ref = "androidGradlePlugin" } @@ -107,8 +108,8 @@ composeNavigation = { module = "org.jetbrains.androidx.navigation:navigation-com coreBundle = { module = "org.jetbrains.androidx.core:core-bundle", version = "1.0.0-alpha01" } composeHiltNavigtation = { module = "androidx.hilt:hilt-navigation-compose", version.ref = "composeHiltNavigatiaon" } composeLintCheck = { module = "com.slack.lint.compose:compose-lint-checks", version = "1.3.1" } -composeCoil = { module = "io.coil-kt:coil-compose", version = "2.4.0" } -composeImageLoader = { module = "io.github.qdsfdhvh:image-loader", version = "1.6.7" } +coil = { module = "io.coil-kt.coil3:coil-compose", version.ref = "coil" } +coilTest = { module = "io.coil-kt.coil3:coil-test", version.ref = "coil" } composeShimmer = { module = "com.valentinilk.shimmer:compose-shimmer", version = "1.0.5" } rin = { module = "io.github.takahirom.rin:rin", version.ref = "rin" } lottieCompose = { module = "com.airbnb.android:lottie-compose", version.ref = "lottie" }