diff --git a/app-android/build.gradle.kts b/app-android/build.gradle.kts
index 287a18875..3438a8617 100644
--- a/app-android/build.gradle.kts
+++ b/app-android/build.gradle.kts
@@ -113,4 +113,5 @@ dependencies {
implementation(libs.firebaseDynamicLinks)
debugImplementation(projects.core.testingManifest)
testImplementation(projects.core.testing)
+ testImplementation(libs.composablePreviewScanner)
}
diff --git a/app-android/src/main/res/values-night/splash_theme.xml b/app-android/src/main/res/values-night/splash_theme.xml
index 503d3f9e3..35fafb677 100644
--- a/app-android/src/main/res/values-night/splash_theme.xml
+++ b/app-android/src/main/res/values-night/splash_theme.xml
@@ -5,7 +5,6 @@
- @drawable/splash_icon
- @android:color/black
- 5000
- - @style/Theme.App
- @drawable/splash_branding_image
diff --git a/app-android/src/main/res/values/splash_theme.xml b/app-android/src/main/res/values/splash_theme.xml
index 280cf5162..dc3334cee 100644
--- a/app-android/src/main/res/values/splash_theme.xml
+++ b/app-android/src/main/res/values/splash_theme.xml
@@ -5,7 +5,6 @@
- @drawable/splash_icon
- @android:color/white
- 5000
- - @style/Theme.App
- @drawable/splash_branding_image
diff --git a/app-android/src/test/java/io/github/droidkaigi/confsched/PreviewTest.kt b/app-android/src/test/java/io/github/droidkaigi/confsched/PreviewTest.kt
index 2242c5e31..8c184a4fe 100644
--- a/app-android/src/test/java/io/github/droidkaigi/confsched/PreviewTest.kt
+++ b/app-android/src/test/java/io/github/droidkaigi/confsched/PreviewTest.kt
@@ -1,143 +1,50 @@
package io.github.droidkaigi.confsched
import android.content.res.Configuration
-import android.os.LocaleList
-import androidx.compose.runtime.Composable
-import androidx.compose.runtime.CompositionLocalProvider
-import androidx.compose.ui.platform.LocalConfiguration
-import com.airbnb.android.showkase.models.Showkase
-import com.airbnb.android.showkase.models.ShowkaseBrowserComponent
import com.github.takahirom.roborazzi.DEFAULT_ROBORAZZI_OUTPUT_DIR_PATH
import com.github.takahirom.roborazzi.captureRoboImage
-import io.github.droidkaigi.confsched.designsystem.preview.MultiLanguagePreviewDefinition
-import io.github.droidkaigi.confsched.designsystem.preview.MultiThemePreviewDefinition
-import io.github.droidkaigi.confsched.designsystem.preview.ShowkaseMultiplePreviewsWorkaround
import org.junit.Test
import org.junit.runner.RunWith
import org.robolectric.ParameterizedRobolectricTestRunner
-import java.util.Locale
+import org.robolectric.RuntimeEnvironment
+import sergio.sastre.composable.preview.scanner.android.AndroidComposablePreviewScanner
+import sergio.sastre.composable.preview.scanner.android.AndroidPreviewInfo
+import sergio.sastre.composable.preview.scanner.core.preview.ComposablePreview
@RunWith(ParameterizedRobolectricTestRunner::class)
class PreviewTest(
- val showkaseBrowserComponent: ShowkaseBrowserComponent,
+ private val preview: ComposablePreview,
) {
+ object RobolectricPreviewInfosApplier {
+ fun applyFor(preview: ComposablePreview) {
+ val uiMode =
+ when (preview.previewInfo.uiMode and Configuration.UI_MODE_NIGHT_MASK == Configuration.UI_MODE_NIGHT_YES) {
+ true -> "+night"
+ false -> "+notnight"
+ }
+ RuntimeEnvironment.setQualifiers(uiMode)
+ }
+ }
@Test
fun previewScreenshot() {
val filePath =
- DEFAULT_ROBORAZZI_OUTPUT_DIR_PATH + "/" + showkaseBrowserComponent.componentKey + ".png"
+ DEFAULT_ROBORAZZI_OUTPUT_DIR_PATH + "/" + preview.methodName + ".png"
+ RobolectricPreviewInfosApplier.applyFor(preview)
captureRoboImage(
- filePath,
+ filePath = filePath,
) {
- ProvidesPreviewValues(group = showkaseBrowserComponent.group, componentKey = showkaseBrowserComponent.componentKey) {
- showkaseBrowserComponent.component()
- }
- }
- }
-
- @Suppress("TestFunctionName")
- @ShowkaseMultiplePreviewsWorkaround
- @Composable
- private fun ProvidesPreviewValues(group: String, componentKey: String, content: @Composable () -> Unit) {
- val appliers = arrayListOf<(Configuration) -> Unit>()
-
- if (isCustomGroup(group = group)) {
- val previewValue = extractPreviewValues(group = group, componentKey)
-
- when (group) {
- MultiLanguagePreviewDefinition.Group -> {
- appliers += { c ->
- c.setLocales(newLocales(baseLocales = c.locales, previewValue = previewValue))
- }
- }
- MultiThemePreviewDefinition.Group -> {
- appliers += { c ->
- c.uiMode = newUiMode(baseUiMode = c.uiMode, previewValue = previewValue)
- }
- }
- }
- }
-
- val newConfiguration = appliers.fold(LocalConfiguration.current) { c, a -> c.apply(a) }
-
- CompositionLocalProvider(LocalConfiguration provides newConfiguration) {
- // Notify locale changes to lang() through the following invocation.
- LocaleList.setDefault(LocalConfiguration.current.locales)
-
- content()
- }
- }
-
- /**
- * Depends on the naming rule from Showkase.
- * We must not include "_${group}_" in an original preview function name.
- */
- @ShowkaseMultiplePreviewsWorkaround
- private fun extractPreviewValues(group: String, componentKey: String): String {
- val components = componentKey.split("_")
-
- // _${group_ is expected here
- val groupIndex = requireNotNull(components.indexOf(group).takeIf { it > 0 }) {
- "Failed to extract a preview value for $group: $group is not found in $components"
- }
-
- val modifiedPreviewName = requireNotNull(components.getOrNull(groupIndex + 1)) {
- "Failed to extract a preview value for $group: $components is unexpectedly aligned"
- }
-
- // ${preview_name}_${preview_value}_${...others}
- val match = requireNotNull(Regex("\\w+-([\\w-]+)-[_\\w]+").matchEntire(modifiedPreviewName)) {
- "Failed to extract a preview value for $group: no value was found in $modifiedPreviewName"
- }
-
- return requireNotNull(match.groupValues.getOrNull(1)) {
- "Failed to extract a preview value for $group: this may be a development issue"
+ preview()
}
}
- @ShowkaseMultiplePreviewsWorkaround
- private fun newLocales(baseLocales: LocaleList, previewValue: String): LocaleList {
- val locale = when (previewValue) {
- MultiLanguagePreviewDefinition.English.Name -> {
- MultiLanguagePreviewDefinition.English.Locale
- }
- MultiLanguagePreviewDefinition.Japanese.Name -> {
- MultiLanguagePreviewDefinition.Japanese.Locale
- }
- else -> return baseLocales
- }
-
- return LocaleList(Locale.getAvailableLocales().first { it.toString() == locale })
- }
-
- @ShowkaseMultiplePreviewsWorkaround
- private fun newUiMode(baseUiMode: Int, previewValue: String): Int {
- val nightMode = when (previewValue) {
- // FIXME
-// MultiThemePreviewDefinition.DarkMode.Name -> {
-// MultiThemePreviewDefinition.DarkMode.UiMode
-// }
-// MultiThemePreviewDefinition.LightMode.Name -> {
-// MultiThemePreviewDefinition.LightMode.UiMode
-// }
- else -> baseUiMode
- }
-
- val currentNightMode = baseUiMode and Configuration.UI_MODE_NIGHT_MASK
- return baseUiMode xor currentNightMode or nightMode
- }
-
companion object {
- fun isCustomGroup(group: String): Boolean {
- return group != "Default Group"
- }
-
@ParameterizedRobolectricTestRunner.Parameters
@JvmStatic
- fun components(): Iterable> {
- return Showkase.getMetadata().componentList.map { showkaseBrowserComponent ->
- arrayOf(showkaseBrowserComponent)
- }
+ fun components(): List> {
+ return AndroidComposablePreviewScanner()
+ .scanPackageTrees("io.github.droidkaigi.confsched")
+ .getPreviews()
}
}
}
diff --git a/app-android/src/test/java/io/github/droidkaigi/confsched/ShowkaseRootModule.kt b/app-android/src/test/java/io/github/droidkaigi/confsched/ShowkaseRootModule.kt
deleted file mode 100644
index a7373b1d7..000000000
--- a/app-android/src/test/java/io/github/droidkaigi/confsched/ShowkaseRootModule.kt
+++ /dev/null
@@ -1,7 +0,0 @@
-package io.github.droidkaigi.confsched
-
-import com.airbnb.android.showkase.annotation.ShowkaseRoot
-import com.airbnb.android.showkase.annotation.ShowkaseRootModule
-
-@ShowkaseRoot
-class ShowkaseRootModule : ShowkaseRootModule
diff --git a/build-logic/build.gradle.kts b/build-logic/build.gradle.kts
index dad835a5b..5e3769751 100644
--- a/build-logic/build.gradle.kts
+++ b/build-logic/build.gradle.kts
@@ -95,10 +95,6 @@ gradlePlugin {
id = "droidkaigi.primitive.kmp.android.hilt"
implementationClass = "io.github.droidkaigi.confsched.primitive.KmpAndroidHiltPlugin"
}
- register("kotlinMppAndroidShowkase") {
- id = "droidkaigi.primitive.kmp.android.showkase"
- implementationClass = "io.github.droidkaigi.confsched.primitive.KmpAndroidShowkasePlugin"
- }
register("kotlinMppKotlinSerialization") {
id = "droidkaigi.primitive.kmp.serialization"
implementationClass = "io.github.droidkaigi.confsched.primitive.KotlinSerializationPlugin"
diff --git a/build-logic/src/main/kotlin/io/github/droidkaigi/confsched/primitive/AndroidRoborazziPlugin.kt b/build-logic/src/main/kotlin/io/github/droidkaigi/confsched/primitive/AndroidRoborazziPlugin.kt
index c90d48f06..b100fcb4d 100644
--- a/build-logic/src/main/kotlin/io/github/droidkaigi/confsched/primitive/AndroidRoborazziPlugin.kt
+++ b/build-logic/src/main/kotlin/io/github/droidkaigi/confsched/primitive/AndroidRoborazziPlugin.kt
@@ -31,9 +31,6 @@ class AndroidRoborazziPlugin : Plugin {
testImplementation(libs.library("androidxTestExtJunit"))
testImplementation(libs.library("roborazzi"))
testImplementation(libs.library("roborazziCompose"))
- // For preview screenshot tests
- implementation(libs.library("showkaseRuntime"))
- ksp(libs.library("showkaseProcessor"))
}
}
}
diff --git a/build-logic/src/main/kotlin/io/github/droidkaigi/confsched/primitive/KmpAndroidShowkasePlugin.kt b/build-logic/src/main/kotlin/io/github/droidkaigi/confsched/primitive/KmpAndroidShowkasePlugin.kt
deleted file mode 100644
index 9b8350af9..000000000
--- a/build-logic/src/main/kotlin/io/github/droidkaigi/confsched/primitive/KmpAndroidShowkasePlugin.kt
+++ /dev/null
@@ -1,26 +0,0 @@
-package io.github.droidkaigi.confsched.primitive
-
-import org.gradle.api.Plugin
-import org.gradle.api.Project
-import org.gradle.kotlin.dsl.dependencies
-
-@Suppress("unused")
-class KmpAndroidShowkasePlugin : Plugin {
- override fun apply(target: Project) {
- with(target) {
- with(pluginManager) {
- apply(libs.plugin("kspGradlePlugin").pluginId)
- }
- kotlin {
- sourceSets.getByName("androidMain") {
- dependencies {
- implementation(libs.library("showkaseRuntime"))
- }
- }
- }
- dependencies {
- add("kspAndroid", libs.library("showkaseProcessor"))
- }
- }
- }
-}
diff --git a/build-logic/src/main/kotlin/io/github/droidkaigi/confsched/primitive/KmpRoborazziPlugin.kt b/build-logic/src/main/kotlin/io/github/droidkaigi/confsched/primitive/KmpRoborazziPlugin.kt
index 31cda28d2..a23810f7c 100644
--- a/build-logic/src/main/kotlin/io/github/droidkaigi/confsched/primitive/KmpRoborazziPlugin.kt
+++ b/build-logic/src/main/kotlin/io/github/droidkaigi/confsched/primitive/KmpRoborazziPlugin.kt
@@ -31,18 +31,7 @@ class KmpRoborazziPlugin : Plugin {
kotlin {
if (plugins.hasPlugin("com.android.library")) {
sourceSets.getByName("androidUnitTest") {
- val kspConfiguration = configurations["kspAndroid"]
- kspConfiguration.dependencies.add(
- libs.library("showkaseProcessor").let {
- DefaultExternalModuleDependency(
- it.module.group,
- it.module.name,
- it.versionConstraint.requiredVersion
- )
- }
- )
dependencies {
- implementation(libs.library("showkaseRuntime"))
implementation(libs.library("androidxTestEspressoEspressoCore"))
implementation(libs.library("junit"))
implementation(libs.library("robolectric"))
diff --git a/build-logic/src/main/kotlin/io/github/droidkaigi/confsched/primitive/KoverEntryPointPlugin.kt b/build-logic/src/main/kotlin/io/github/droidkaigi/confsched/primitive/KoverEntryPointPlugin.kt
index e46daf49e..cdcb975a8 100644
--- a/build-logic/src/main/kotlin/io/github/droidkaigi/confsched/primitive/KoverEntryPointPlugin.kt
+++ b/build-logic/src/main/kotlin/io/github/droidkaigi/confsched/primitive/KoverEntryPointPlugin.kt
@@ -21,7 +21,6 @@ class KoverEntryPointPlugin : Plugin {
filters {
excludes {
packages(
- "com.airbnb.android.showkase",
"dagger.hilt.*",
"hilt_aggregated_deps",
)
diff --git a/core/designsystem/build.gradle.kts b/core/designsystem/build.gradle.kts
index 4d51defd2..5d5cac859 100644
--- a/core/designsystem/build.gradle.kts
+++ b/core/designsystem/build.gradle.kts
@@ -5,7 +5,6 @@ plugins {
id("droidkaigi.primitive.kmp.compose")
id("droidkaigi.primitive.kmp.android.hilt")
id("droidkaigi.primitive.detekt")
- id("droidkaigi.primitive.kmp.android.showkase")
}
android.namespace = "io.github.droidkaigi.confsched.core.designsystem"
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
index cde74e533..20e2e2b9d 100644
--- a/gradle/libs.versions.toml
+++ b/gradle/libs.versions.toml
@@ -29,7 +29,6 @@ ktlint = "0.49.1"
kotlinxSerialization = "1.6.3"
ktor = "2.3.10"
roborazzi = "1.20.0"
-showkase = "1.0.0-beta18"
ksp = "1.9.24-1.0.20"
firebaseBom = "33.1.0"
multiplatformFirebase = "1.8.1"
@@ -45,6 +44,7 @@ molecule = "1.4.1"
kover = "0.7.6"
androidxLifecycleProcess = "2.8.2"
skie = "0.8.2"
+composablePreviewScanner = "0.1.1"
[libraries]
androidGradlePlugin = { group = "com.android.tools.build", name = "gradle", version.ref = "androidGradlePlugin" }
@@ -168,8 +168,7 @@ roborazzi = { module = "io.github.takahirom.roborazzi:roborazzi", version.ref =
roborazziCompose = { module = "io.github.takahirom.roborazzi:roborazzi-compose", version.ref = "roborazzi" }
roborazziIos = { module = "io.github.takahirom.roborazzi:roborazzi-compose-ios", version.ref = "roborazzi" }
roborazziRule = { module = "io.github.takahirom.roborazzi:roborazzi-junit-rule", version.ref = "roborazzi" }
-showkaseRuntime = { group = "com.airbnb.android", name = "showkase", version.ref = "showkase" }
-showkaseProcessor = { group = "com.airbnb.android", name = "showkase-processor", version.ref = "showkase" }
+composablePreviewScanner = { module = "com.github.sergio-sastre.ComposablePreviewScanner:android", version.ref = "composablePreviewScanner" }
[plugins]
androidGradlePlugin = { id = "com.android.application", version.ref = "androidGradlePlugin" }
diff --git a/settings.gradle.kts b/settings.gradle.kts
index ad3779140..5196bcff9 100644
--- a/settings.gradle.kts
+++ b/settings.gradle.kts
@@ -15,6 +15,7 @@ dependencyResolutionManagement {
maven {
url = uri("https://maven.pkg.jetbrains.space/public/p/compose/dev/")
}
+ maven { url = uri("https://jitpack.io") }
}
}
rootProject.name = "conference-app-2024"