diff --git a/android/app/build.gradle.kts b/android/app/build.gradle.kts index 350ec8f3..925813b7 100644 --- a/android/app/build.gradle.kts +++ b/android/app/build.gradle.kts @@ -90,6 +90,7 @@ android { ksp { arg("room.generateKotlin", "true") + arg("skipPrivatePreviews", "true") } emerge { @@ -117,8 +118,8 @@ sentry { } distribution { - //enabled = providers.environmentVariable("GITHUB_ACTIONS").isPresent - //updateSdkVariants.add("beta") + enabled = providers.environmentVariable("GITHUB_ACTIONS").isPresent + updateSdkVariants.add("beta") } vcsInfo { @@ -178,4 +179,8 @@ dependencies { debugImplementation(libs.androidx.ui.tooling) debugImplementation(libs.androidx.ui.test.manifest) + debugImplementation(libs.showkase) + implementation(libs.showkase.annotation) + kspDebug(libs.showkase.processor) + } diff --git a/android/app/src/debug/java/com/emergetools/hackernews/ShowkaseLauncher.kt b/android/app/src/debug/java/com/emergetools/hackernews/ShowkaseLauncher.kt new file mode 100644 index 00000000..686bd59c --- /dev/null +++ b/android/app/src/debug/java/com/emergetools/hackernews/ShowkaseLauncher.kt @@ -0,0 +1,12 @@ +package com.emergetools.hackernews + +import android.content.Context +import com.airbnb.android.showkase.models.Showkase + +object ShowkaseLauncher { + fun launch(context: Context) { + context.startActivity(Showkase.getBrowserIntent(context)) + } + + const val isAvailable = true +} diff --git a/android/app/src/debug/java/com/emergetools/hackernews/ShowkaseRootModule.kt b/android/app/src/debug/java/com/emergetools/hackernews/ShowkaseRootModule.kt new file mode 100644 index 00000000..135024ca --- /dev/null +++ b/android/app/src/debug/java/com/emergetools/hackernews/ShowkaseRootModule.kt @@ -0,0 +1,7 @@ +package com.emergetools.hackernews + +import com.airbnb.android.showkase.annotation.ShowkaseRoot +import com.airbnb.android.showkase.annotation.ShowkaseRootModule + +@ShowkaseRoot +class HackerNewsShowkaseRoot : ShowkaseRootModule diff --git a/android/app/src/main/java/com/emergetools/hackernews/features/settings/SettingsScreen.kt b/android/app/src/main/java/com/emergetools/hackernews/features/settings/SettingsScreen.kt index 3c05ca13..826b637f 100644 --- a/android/app/src/main/java/com/emergetools/hackernews/features/settings/SettingsScreen.kt +++ b/android/app/src/main/java/com/emergetools/hackernews/features/settings/SettingsScreen.kt @@ -15,6 +15,7 @@ import androidx.compose.foundation.verticalScroll import androidx.compose.material.icons.Icons import androidx.compose.material.icons.rounded.Lock import androidx.compose.material.icons.rounded.Warning +import androidx.compose.ui.platform.LocalContext import androidx.compose.material3.Icon import androidx.compose.material3.MaterialTheme import androidx.compose.material3.NavigationBar @@ -34,6 +35,7 @@ import androidx.compose.ui.tooling.preview.Devices import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import com.emergetools.hackernews.R +import com.emergetools.hackernews.ShowkaseLauncher import com.emergetools.hackernews.features.settings.components.BuiltByCard import com.emergetools.hackernews.features.settings.components.LoginCard import com.emergetools.hackernews.features.settings.components.SettingsCard @@ -182,6 +184,24 @@ fun SettingsScreen( ) { navigation(SettingsNavigation.GoToSettingsLink("https://www.emergetools.com/HackerNewsPrivacyPolicy.html")) } + if (ShowkaseLauncher.isAvailable) { + Spacer(modifier = Modifier.height(8.dp)) + SettingsSectionLabel("Developer") + val context = LocalContext.current + SettingsCard( + leadingIcon = { + Icon( + modifier = Modifier.width(12.dp), + painter = painterResource(R.drawable.ic_settings), + tint = MaterialTheme.colorScheme.primary, + contentDescription = "Component Browser" + ) + }, + label = "Component Browser" + ) { + ShowkaseLauncher.launch(context) + } + } } } } diff --git a/android/app/src/release/java/com/emergetools/hackernews/ShowkaseLauncher.kt b/android/app/src/release/java/com/emergetools/hackernews/ShowkaseLauncher.kt new file mode 100644 index 00000000..fc93de01 --- /dev/null +++ b/android/app/src/release/java/com/emergetools/hackernews/ShowkaseLauncher.kt @@ -0,0 +1,11 @@ +package com.emergetools.hackernews + +import android.content.Context + +object ShowkaseLauncher { + fun launch(context: Context) { + // No-op in release builds + } + + const val isAvailable = false +} diff --git a/android/gradle/libs.versions.toml b/android/gradle/libs.versions.toml index df218585..a32b4fc2 100644 --- a/android/gradle/libs.versions.toml +++ b/android/gradle/libs.versions.toml @@ -29,6 +29,7 @@ composeBom = "2025.09.00" uiTestJunit4Android = "1.10.0" uiautomator = "2.3.0" benchmarkMacroJunit4 = "1.4.1" +showkase = "1.0.5" [libraries] androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" } @@ -75,6 +76,10 @@ androidx-ui-test-junit4-android = { group = "androidx.compose.ui", name = "ui-te androidx-uiautomator = { group = "androidx.test.uiautomator", name = "uiautomator", version.ref = "uiautomator" } androidx-benchmark-macro-junit4 = { group = "androidx.benchmark", name = "benchmark-macro-junit4", version.ref = "benchmarkMacroJunit4" } +showkase = { group = "com.airbnb.android", name = "showkase", version.ref = "showkase" } +showkase-annotation = { group = "com.airbnb.android", name = "showkase-annotation", version.ref = "showkase" } +showkase-processor = { group = "com.airbnb.android", name = "showkase-processor", version.ref = "showkase" } + [plugins] android-application = { id = "com.android.application", version.ref = "agp" } kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }