mirror of
https://github.com/Novaloop-AG/element-x-android.git
synced 2026-10-31 16:22:49 +00:00
Merge pull request #7678 from element-hq/feature/bma/removeShowkase
Remove Showkase and its in-app component browser
This commit is contained in:
Generated
-1
@@ -16,7 +16,6 @@
|
||||
<w>posthog</w>
|
||||
<w>rageshake</w>
|
||||
<w>securebackup</w>
|
||||
<w>showkase</w>
|
||||
<w>snackbar</w>
|
||||
<w>spdx</w>
|
||||
<w>swipeable</w>
|
||||
|
||||
@@ -358,7 +358,8 @@ Some dependency, mainly because they are not shared can be declared in `build.gr
|
||||
We have 3 tests frameworks in place, and this should be sufficient to guarantee a good code coverage and limit regressions hopefully:
|
||||
|
||||
- Maestro to test the global usage of the application. See the related [documentation](../.maestro/README.md).
|
||||
- Combination of [Showkase](https://github.com/airbnb/Showkase) and [Paparazzi](https://github.com/cashapp/paparazzi), to test UI pixel perfect. To add test,
|
||||
- Combination of [Paparazzi](https://github.com/cashapp/paparazzi) and
|
||||
[ComposablePreviewScanner](https://github.com/sergio-sastre/ComposablePreviewScanner), to test UI pixel perfect. To add test,
|
||||
just add `@Preview` for the composable you are adding. See the related [documentation](screenshot_testing.md) and see in the template the
|
||||
file [TemplateView.kt](../features/template/src/main/kotlin/io/element/android/features/template/TemplateView.kt). We create PreviewParam classes to provide
|
||||
different states. See for instance the
|
||||
@@ -449,9 +450,8 @@ number at the bottom 7 times. After tapping, a new "Developer options" entry wil
|
||||
at the bottom of the list.
|
||||
|
||||
The developer options include feature flags, notification/push history, Element call
|
||||
customization, Rust SDK log levels, per-feature tracing toggles, Showkase to debug UI
|
||||
components, rageshake controls, app crash controls, cache details/controls, persistent
|
||||
storage maintenance tasks.
|
||||
customization, Rust SDK log levels, per-feature tracing toggles, rageshake controls, app
|
||||
crash controls, cache details/controls, persistent storage maintenance tasks.
|
||||
|
||||
Keywords: Developer settings, developer mode
|
||||
|
||||
|
||||
@@ -94,7 +94,6 @@ dependencies {
|
||||
implementation(libs.androidx.datastore.preferences)
|
||||
implementation(libs.serialization.json)
|
||||
api(projects.features.preferences.api)
|
||||
implementation(libs.showkase)
|
||||
|
||||
implementation(platform(libs.network.okhttp.bom))
|
||||
implementation(libs.network.okhttp)
|
||||
|
||||
-10
@@ -8,10 +8,8 @@
|
||||
|
||||
package io.element.android.features.preferences.impl.developer
|
||||
|
||||
import androidx.activity.compose.LocalActivity
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import com.airbnb.android.showkase.models.Showkase
|
||||
import com.bumble.appyx.core.modality.BuildContext
|
||||
import com.bumble.appyx.core.node.Node
|
||||
import com.bumble.appyx.core.plugin.Plugin
|
||||
@@ -20,7 +18,6 @@ import dev.zacsweers.metro.AssistedInject
|
||||
import io.element.android.annotations.ContributesNode
|
||||
import io.element.android.features.preferences.api.ExtraDeveloperOptionsRenderer
|
||||
import io.element.android.libraries.architecture.callback
|
||||
import io.element.android.libraries.designsystem.showkase.getBrowserIntent
|
||||
import io.element.android.libraries.di.SessionScope
|
||||
|
||||
@ContributesNode(SessionScope::class)
|
||||
@@ -47,17 +44,10 @@ class DeveloperSettingsNode(
|
||||
|
||||
@Composable
|
||||
override fun View(modifier: Modifier) {
|
||||
val activity = requireNotNull(LocalActivity.current)
|
||||
fun openShowkase() {
|
||||
val intent = Showkase.getBrowserIntent(activity)
|
||||
activity.startActivity(intent)
|
||||
}
|
||||
|
||||
val state = presenter.present()
|
||||
DeveloperSettingsView(
|
||||
state = state,
|
||||
modifier = modifier,
|
||||
onOpenShowkase = ::openShowkase,
|
||||
onPushHistoryClick = callback::navigateToPushHistory,
|
||||
onBackClick = callback::onDone,
|
||||
extraOptions = { extraDeveloperOptionsRenderer.Render(Modifier) },
|
||||
|
||||
-3
@@ -44,7 +44,6 @@ import io.mhssn.colorpicker.ColorPickerType
|
||||
@Composable
|
||||
fun DeveloperSettingsView(
|
||||
state: DeveloperSettingsState,
|
||||
onOpenShowkase: () -> Unit,
|
||||
onPushHistoryClick: () -> Unit,
|
||||
onBackClick: () -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
@@ -84,7 +83,6 @@ fun DeveloperSettingsView(
|
||||
// Note: this is OK to hardcode strings in this debug screen.
|
||||
AppDeveloperSettingsView(
|
||||
state = state.appDeveloperSettingsState,
|
||||
onOpenShowkase = onOpenShowkase,
|
||||
)
|
||||
SessionCategory(deviceId = state.deviceId)
|
||||
NotificationCategory(
|
||||
@@ -255,7 +253,6 @@ internal fun DeveloperSettingsViewPreview(
|
||||
) = ElementPreview {
|
||||
DeveloperSettingsView(
|
||||
state = state,
|
||||
onOpenShowkase = {},
|
||||
onPushHistoryClick = {},
|
||||
onBackClick = {},
|
||||
)
|
||||
|
||||
-10
@@ -7,10 +7,8 @@
|
||||
|
||||
package io.element.android.features.preferences.impl.developer.appsettings
|
||||
|
||||
import androidx.activity.compose.LocalActivity
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import com.airbnb.android.showkase.models.Showkase
|
||||
import com.bumble.appyx.core.modality.BuildContext
|
||||
import com.bumble.appyx.core.node.Node
|
||||
import com.bumble.appyx.core.plugin.Plugin
|
||||
@@ -21,7 +19,6 @@ import io.element.android.annotations.ContributesNode
|
||||
import io.element.android.features.preferences.api.ExtraDeveloperOptionsRenderer
|
||||
import io.element.android.features.preferences.api.PreferencesEntryPoint
|
||||
import io.element.android.libraries.architecture.callback
|
||||
import io.element.android.libraries.designsystem.showkase.getBrowserIntent
|
||||
|
||||
@ContributesNode(AppScope::class)
|
||||
@AssistedInject
|
||||
@@ -35,17 +32,10 @@ class AppDeveloperSettingsNode(
|
||||
|
||||
@Composable
|
||||
override fun View(modifier: Modifier) {
|
||||
val activity = requireNotNull(LocalActivity.current)
|
||||
fun openShowkase() {
|
||||
val intent = Showkase.getBrowserIntent(activity)
|
||||
activity.startActivity(intent)
|
||||
}
|
||||
|
||||
val state = presenter.present()
|
||||
AppDeveloperSettingsPage(
|
||||
state = state,
|
||||
modifier = modifier,
|
||||
onOpenShowkase = ::openShowkase,
|
||||
onBackClick = callback::onDone,
|
||||
extraOptions = { extraDeveloperOptionsRenderer.Render(Modifier) },
|
||||
)
|
||||
|
||||
-3
@@ -21,7 +21,6 @@ import io.element.android.libraries.designsystem.preview.PreviewsDayNight
|
||||
@Composable
|
||||
fun AppDeveloperSettingsPage(
|
||||
state: AppDeveloperSettingsState,
|
||||
onOpenShowkase: () -> Unit,
|
||||
onBackClick: () -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
extraOptions: @Composable () -> Unit = {},
|
||||
@@ -38,7 +37,6 @@ fun AppDeveloperSettingsPage(
|
||||
) {
|
||||
AppDeveloperSettingsView(
|
||||
state = state,
|
||||
onOpenShowkase = onOpenShowkase,
|
||||
modifier = Modifier.padding(top = 8.dp)
|
||||
)
|
||||
extraOptions()
|
||||
@@ -50,7 +48,6 @@ fun AppDeveloperSettingsPage(
|
||||
internal fun AppDeveloperSettingsPagePreview() = ElementPreview {
|
||||
AppDeveloperSettingsPage(
|
||||
state = anAppDeveloperSettingsState(),
|
||||
onOpenShowkase = {},
|
||||
onBackClick = {},
|
||||
)
|
||||
}
|
||||
|
||||
-10
@@ -42,7 +42,6 @@ import kotlinx.collections.immutable.toImmutableList
|
||||
@Composable
|
||||
fun AppDeveloperSettingsView(
|
||||
state: AppDeveloperSettingsState,
|
||||
onOpenShowkase: () -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
Column(
|
||||
@@ -82,14 +81,6 @@ fun AppDeveloperSettingsView(
|
||||
)
|
||||
}
|
||||
}
|
||||
PreferenceCategory(title = "Showkase") {
|
||||
ListItem(
|
||||
content = {
|
||||
Text("Open Showkase browser")
|
||||
},
|
||||
onClick = onOpenShowkase
|
||||
)
|
||||
}
|
||||
RageshakePreferencesView(
|
||||
state = state.rageshakeState,
|
||||
)
|
||||
@@ -186,6 +177,5 @@ internal fun AppDeveloperSettingsViewPreview(
|
||||
) = ElementPreview {
|
||||
AppDeveloperSettingsView(
|
||||
state = state,
|
||||
onOpenShowkase = {},
|
||||
)
|
||||
}
|
||||
|
||||
-17
@@ -70,21 +70,6 @@ class DeveloperSettingsViewTest : RobolectricTest() {
|
||||
eventsRecorder.assertSingle(DeveloperSettingsEvent.OpenPushRules)
|
||||
}
|
||||
|
||||
@Config(qualifiers = "h2000dp")
|
||||
@Test
|
||||
fun `clicking on open showkase invokes the expected callback`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<DeveloperSettingsEvent>(expectEvents = false)
|
||||
ensureCalledOnce {
|
||||
setDeveloperSettingsView(
|
||||
state = aDeveloperSettingsState(
|
||||
eventSink = eventsRecorder
|
||||
),
|
||||
onOpenShowkase = it
|
||||
)
|
||||
onNodeWithText("Open Showkase browser").performClick()
|
||||
}
|
||||
}
|
||||
|
||||
@Config(qualifiers = "h2400dp")
|
||||
@Test
|
||||
fun `clicking on clear cache emits the expected event`() = runAndroidComposeUiTest {
|
||||
@@ -101,14 +86,12 @@ class DeveloperSettingsViewTest : RobolectricTest() {
|
||||
|
||||
private fun AndroidComposeUiTest<ComponentActivity>.setDeveloperSettingsView(
|
||||
state: DeveloperSettingsState,
|
||||
onOpenShowkase: () -> Unit = EnsureNeverCalled(),
|
||||
onPushHistoryClick: () -> Unit = EnsureNeverCalled(),
|
||||
onBackClick: () -> Unit = EnsureNeverCalled()
|
||||
) {
|
||||
setContent {
|
||||
DeveloperSettingsView(
|
||||
state = state,
|
||||
onOpenShowkase = onOpenShowkase,
|
||||
onPushHistoryClick = onPushHistoryClick,
|
||||
onBackClick = onBackClick,
|
||||
)
|
||||
|
||||
-17
@@ -64,21 +64,6 @@ class AppDeveloperSettingsPageTest : RobolectricTest() {
|
||||
eventsRecorder.assertSingle(AppDeveloperSettingsEvent.SetCustomElementCallBaseUrl("https://call.element.dev"))
|
||||
}
|
||||
|
||||
@Config(qualifiers = "h2000dp")
|
||||
@Test
|
||||
fun `clicking on open showkase invokes the expected callback`() = runAndroidComposeUiTest {
|
||||
val eventsRecorder = EventsRecorder<AppDeveloperSettingsEvent>(expectEvents = false)
|
||||
ensureCalledOnce {
|
||||
setAppDeveloperSettingsView(
|
||||
state = anAppDeveloperSettingsState(
|
||||
eventSink = eventsRecorder
|
||||
),
|
||||
onOpenShowkase = it
|
||||
)
|
||||
onNodeWithText("Open Showkase browser").performClick()
|
||||
}
|
||||
}
|
||||
|
||||
@Config(qualifiers = "h1024dp")
|
||||
@Test
|
||||
fun `clicking on log level emits the expected event`() = runAndroidComposeUiTest {
|
||||
@@ -96,13 +81,11 @@ class AppDeveloperSettingsPageTest : RobolectricTest() {
|
||||
|
||||
private fun AndroidComposeUiTest<ComponentActivity>.setAppDeveloperSettingsView(
|
||||
state: AppDeveloperSettingsState,
|
||||
onOpenShowkase: () -> Unit = EnsureNeverCalled(),
|
||||
onBackClick: () -> Unit = EnsureNeverCalled(),
|
||||
) {
|
||||
setContent {
|
||||
AppDeveloperSettingsPage(
|
||||
state = state,
|
||||
onOpenShowkase = onOpenShowkase,
|
||||
onBackClick = onBackClick,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -40,8 +40,6 @@ serialization_json = "1.11.0"
|
||||
|
||||
#other
|
||||
coil = "3.6.1"
|
||||
# Rollback to 1.0.4, 1.0.5 has this issue: https://github.com/airbnb/Showkase/issues/420
|
||||
showkase = "1.0.5"
|
||||
# There is some custom logic in `RootFlowNode` that may break because it reuses some Appyx internal APIs.
|
||||
# When upgrading this version, check state restoration still works fine.
|
||||
appyx = "1.7.1"
|
||||
@@ -198,8 +196,6 @@ coil_test = { module = "io.coil-kt.coil3:coil-test", version.ref = "coil" }
|
||||
datetime = { module = "org.jetbrains.kotlinx:kotlinx-datetime", version.ref = "datetime" }
|
||||
serialization_json = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json", version.ref = "serialization_json" }
|
||||
kotlinx_collections_immutable = "org.jetbrains.kotlinx:kotlinx-collections-immutable:0.5.2"
|
||||
showkase = { module = "com.airbnb.android:showkase", version.ref = "showkase" }
|
||||
showkase_processor = { module = "com.airbnb.android:showkase-processor", version.ref = "showkase" }
|
||||
jsoup = "org.jsoup:jsoup:1.23.2"
|
||||
appyx_core = { module = "com.bumble.appyx:core", version.ref = "appyx" }
|
||||
molecule-runtime = "app.cash.molecule:molecule-runtime:2.2.0"
|
||||
|
||||
@@ -22,7 +22,6 @@ android {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation(libs.showkase)
|
||||
testCommonDependencies(libs)
|
||||
testImplementation(libs.test.roborazzi)
|
||||
testImplementation(libs.test.roborazzi.compose)
|
||||
|
||||
-15
@@ -1,15 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2025 Element Creations Ltd.
|
||||
* Copyright 2025 New Vector Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
|
||||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
package io.element.android.compound.showkase
|
||||
|
||||
import com.airbnb.android.showkase.annotation.ShowkaseRoot
|
||||
import com.airbnb.android.showkase.annotation.ShowkaseRootModule
|
||||
|
||||
@ShowkaseRoot
|
||||
class CompoundShowkaseRootModule : ShowkaseRootModule
|
||||
+1
-17
@@ -16,19 +16,15 @@ import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.text.style.LineHeightStyle
|
||||
import androidx.compose.ui.unit.em
|
||||
import androidx.compose.ui.unit.sp
|
||||
import com.airbnb.android.showkase.annotation.ShowkaseTypography
|
||||
import io.element.android.compound.tokens.generated.TypographyTokens
|
||||
|
||||
// 32px (Material) vs 34px, it's the closest one
|
||||
@ShowkaseTypography(name = "M3 Headline Large", group = "Compound")
|
||||
internal val compoundHeadingXlRegular = TypographyTokens.fontHeadingXlRegular
|
||||
|
||||
// both are 28px
|
||||
@ShowkaseTypography(name = "M3 Headline Medium", group = "Compound")
|
||||
internal val compoundHeadingLgRegular = TypographyTokens.fontHeadingLgRegular
|
||||
|
||||
// These are the default M3 values, but we're setting them manually so an update in M3 doesn't break our designs
|
||||
@ShowkaseTypography(name = "M3 Headline Small", group = "Compound")
|
||||
internal val defaultHeadlineSmall = TextStyle(
|
||||
fontFamily = FontFamily.Default,
|
||||
fontWeight = FontWeight.Normal,
|
||||
@@ -40,39 +36,27 @@ internal val defaultHeadlineSmall = TextStyle(
|
||||
)
|
||||
|
||||
// 22px (Material) vs 20px, it's the closest one
|
||||
@ShowkaseTypography(name = "M3 Title Large", group = "Compound")
|
||||
internal val compoundHeadingMdRegular = TypographyTokens.fontHeadingMdRegular
|
||||
|
||||
// 16px both
|
||||
@ShowkaseTypography(name = "M3 Title Medium", group = "Compound")
|
||||
internal val compoundBodyLgMedium = TypographyTokens.fontBodyLgMedium
|
||||
|
||||
// 14px both
|
||||
@ShowkaseTypography(name = "M3 Title Small", group = "Compound")
|
||||
internal val compoundBodyMdMedium = TypographyTokens.fontBodyMdMedium
|
||||
|
||||
// 16px both
|
||||
@ShowkaseTypography(name = "M3 Body Large", group = "Compound")
|
||||
internal val compoundBodyLgRegular = TypographyTokens.fontBodyLgRegular
|
||||
|
||||
// 14px both
|
||||
@ShowkaseTypography(name = "M3 Body Medium", group = "Compound")
|
||||
internal val compoundBodyMdRegular = TypographyTokens.fontBodyMdRegular
|
||||
|
||||
// 12px both
|
||||
@ShowkaseTypography(name = "M3 Body Small", group = "Compound")
|
||||
internal val compoundBodySmRegular = TypographyTokens.fontBodySmRegular
|
||||
|
||||
// 14px both, Title Small uses the same token so we have to declare it twice
|
||||
@ShowkaseTypography(name = "M3 Label Large", group = "Compound")
|
||||
internal val compoundBodyMdMedium_LabelLarge = TypographyTokens.fontBodyMdMedium
|
||||
|
||||
// 12px both
|
||||
@ShowkaseTypography(name = "M3 Label Medium", group = "Compound")
|
||||
internal val compoundBodySmMedium = TypographyTokens.fontBodySmMedium
|
||||
|
||||
// 11px both
|
||||
@ShowkaseTypography(name = "M3 Label Small", group = "Compound")
|
||||
internal val compoundBodyXsMedium = TypographyTokens.fontBodyXsMedium
|
||||
|
||||
internal val compoundTypography = Typography(
|
||||
@@ -88,7 +72,7 @@ internal val compoundTypography = Typography(
|
||||
bodyLarge = compoundBodyLgRegular,
|
||||
bodyMedium = compoundBodyMdRegular,
|
||||
bodySmall = compoundBodySmRegular,
|
||||
labelLarge = compoundBodyMdMedium_LabelLarge,
|
||||
labelLarge = compoundBodyMdMedium,
|
||||
labelMedium = compoundBodySmMedium,
|
||||
labelSmall = compoundBodyXsMedium,
|
||||
)
|
||||
|
||||
@@ -10,7 +10,6 @@ import extension.testCommonDependencies
|
||||
|
||||
plugins {
|
||||
id("io.element.android-compose-library")
|
||||
alias(libs.plugins.ksp)
|
||||
id("kotlin-parcelize")
|
||||
}
|
||||
|
||||
@@ -20,12 +19,6 @@ android {
|
||||
buildFeatures {
|
||||
buildConfig = true
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
getByName("release") {
|
||||
consumerProguardFiles("consumer-rules.keep")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
@@ -43,8 +36,5 @@ dependencies {
|
||||
implementation(projects.libraries.testtags)
|
||||
implementation(projects.libraries.uiStrings)
|
||||
|
||||
ksp(libs.showkase.processor)
|
||||
implementation(libs.showkase)
|
||||
|
||||
testCommonDependencies(libs)
|
||||
}
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
# Showkase generates this class, and Showkase's ShowkaseBrowserActivity loads it reflectively with
|
||||
# Class.forName(...).getDeclaredConstructor().newInstance(), so its constructor must be kept too.
|
||||
-keep class io.element.android.libraries.designsystem.showkase.DesignSystemShowkaseRootModuleCodegen {
|
||||
<init>();
|
||||
}
|
||||
+2
-2
@@ -14,8 +14,8 @@ import androidx.compose.ui.platform.LocalDensity
|
||||
import androidx.compose.ui.unit.Density
|
||||
|
||||
/**
|
||||
* Showkase does not take into account the `fontScale` parameter of the Preview annotation, so alter the
|
||||
* LocalDensity in the CompositionLocalProvider.
|
||||
* Render the content at the given font scale, by altering the `LocalDensity` in the
|
||||
* CompositionLocalProvider. Useful to preview a Composable at several font scales.
|
||||
*/
|
||||
@Composable
|
||||
fun WithFontScale(fontScale: Float, content: @Composable () -> Unit) {
|
||||
|
||||
-15
@@ -1,15 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2025 Element Creations Ltd.
|
||||
* Copyright 2022-2025 New Vector Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
|
||||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
package io.element.android.libraries.designsystem.showkase
|
||||
|
||||
import com.airbnb.android.showkase.annotation.ShowkaseRoot
|
||||
import com.airbnb.android.showkase.annotation.ShowkaseRootModule
|
||||
|
||||
@ShowkaseRoot
|
||||
class DesignSystemShowkaseRootModule : ShowkaseRootModule
|
||||
@@ -107,13 +107,8 @@ fun Project.setupKover() {
|
||||
// Exclude generated classes.
|
||||
"*_Module",
|
||||
"*_AssistedFactory",
|
||||
"com.airbnb.android.showkase*",
|
||||
"io.element.android.libraries.designsystem.showkase.*",
|
||||
"*ComposableSingletons$*",
|
||||
"*BuildConfig",
|
||||
// Generated by Showkase
|
||||
"*Ioelementandroid*PreviewKt$*",
|
||||
"*Ioelementandroid*PreviewKt",
|
||||
// Other
|
||||
// We do not cover Nodes (normally covered by maestro, but code coverage is not computed with maestro)
|
||||
"*Node",
|
||||
|
||||
@@ -40,8 +40,6 @@ dependencies {
|
||||
)
|
||||
}
|
||||
|
||||
implementation(libs.showkase)
|
||||
|
||||
// TODO There is a Resources.NotFoundException maybe due to the mipmap, even if we have
|
||||
// `testOptions { unitTests.isIncludeAndroidResources = true }` in the app build.gradle.kts file
|
||||
// implementation(projects.app)
|
||||
|
||||
Reference in New Issue
Block a user