Element config (#4471)

* Add handy extension "VariantDimension.buildConfigFieldStr"

* Update configuration for MapTiler.

* Update configuration for Sentry.

* Build AnalyticsConfig depending on analytics configuration.

* Configure analytics policy url.

* Add handy extension "VariantDimension.buildConfigFieldBoolean"

* Configure legal urls.

* Add a way to disable rageshake / reporting bugs.

* Update screenshots

* Quality

* Fix test

* Use `ifBlank` extension

* Add missing configuration for PostHog

* Update configuration for Rageshake.

* Add build log.

* Disable crash detection if rageshake feature is not available.
Disabled twice.

* Hide link to analytics policy if the link is missing.

* Fix test when run in enterprise context.

* Use RageshakeFeatureAvailability where appropriate.

* Rename file.

* Move some classes to their correct module.

* Update screenshots

---------

Co-authored-by: ElementBot <android@element.io>
This commit is contained in:
Benoit Marty 2025-03-27 11:25:04 +01:00 committed by GitHub
parent c6b99c853c
commit 3c1deff79c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
95 changed files with 613 additions and 273 deletions

View file

@ -10,7 +10,9 @@ package io.element.android.features.onboarding.impl
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.produceState
import androidx.compose.runtime.remember
import io.element.android.appconfig.OnBoardingConfig
import io.element.android.features.rageshake.api.RageshakeFeatureAvailability
import io.element.android.libraries.architecture.Presenter
import io.element.android.libraries.core.meta.BuildMeta
import io.element.android.libraries.featureflag.api.FeatureFlagService
@ -24,16 +26,19 @@ import javax.inject.Inject
class OnBoardingPresenter @Inject constructor(
private val buildMeta: BuildMeta,
private val featureFlagService: FeatureFlagService,
private val rageshakeFeatureAvailability: RageshakeFeatureAvailability,
) : Presenter<OnBoardingState> {
@Composable
override fun present(): OnBoardingState {
val canLoginWithQrCode by produceState(initialValue = false) {
value = featureFlagService.isFeatureEnabled(FeatureFlags.QrCodeLogin)
}
val canReportBug = remember { rageshakeFeatureAvailability.isAvailable() }
return OnBoardingState(
productionApplicationName = buildMeta.productionApplicationName,
canLoginWithQrCode = canLoginWithQrCode,
canCreateAccount = OnBoardingConfig.CAN_CREATE_ACCOUNT,
canReportBug = canReportBug,
)
}
}

View file

@ -11,4 +11,5 @@ data class OnBoardingState(
val productionApplicationName: String,
val canLoginWithQrCode: Boolean,
val canCreateAccount: Boolean,
val canReportBug: Boolean,
)

View file

@ -16,15 +16,18 @@ open class OnBoardingStateProvider : PreviewParameterProvider<OnBoardingState> {
anOnBoardingState(canLoginWithQrCode = true),
anOnBoardingState(canCreateAccount = true),
anOnBoardingState(canLoginWithQrCode = true, canCreateAccount = true),
anOnBoardingState(canLoginWithQrCode = true, canCreateAccount = true, canReportBug = true),
)
}
fun anOnBoardingState(
productionApplicationName: String = "Element",
canLoginWithQrCode: Boolean = false,
canCreateAccount: Boolean = false
canCreateAccount: Boolean = false,
canReportBug: Boolean = false,
) = OnBoardingState(
productionApplicationName = productionApplicationName,
canLoginWithQrCode = canLoginWithQrCode,
canCreateAccount = canCreateAccount
canCreateAccount = canCreateAccount,
canReportBug = canReportBug,
)

View file

@ -144,8 +144,8 @@ private fun OnBoardingButtons(
text = stringResource(id = signInButtonStringRes),
onClick = onSignIn,
modifier = Modifier
.fillMaxWidth()
.testTag(TestTags.onBoardingSignIn)
.fillMaxWidth()
.testTag(TestTags.onBoardingSignIn)
)
if (state.canCreateAccount) {
TextButton(
@ -155,15 +155,17 @@ private fun OnBoardingButtons(
.fillMaxWidth()
)
}
// Add a report problem text button. Use a Text since we need a special theme here.
Text(
modifier = Modifier
if (state.canReportBug) {
// Add a report problem text button. Use a Text since we need a special theme here.
Text(
modifier = Modifier
.padding(16.dp)
.clickable(onClick = onReportProblem),
text = stringResource(id = CommonStrings.common_report_a_problem),
style = ElementTheme.typography.fontBodySmRegular,
color = ElementTheme.colors.textSecondary,
)
text = stringResource(id = CommonStrings.common_report_a_problem),
style = ElementTheme.typography.fontBodySmRegular,
color = ElementTheme.colors.textSecondary,
)
}
}
}

View file

@ -16,6 +16,7 @@ import io.element.android.libraries.featureflag.api.FeatureFlags
import io.element.android.libraries.featureflag.test.FakeFeatureFlagService
import io.element.android.libraries.matrix.test.core.aBuildMeta
import io.element.android.tests.testutils.WarmUpRule
import io.element.android.tests.testutils.test
import kotlinx.coroutines.test.runTest
import org.junit.Rule
import org.junit.Test
@ -38,6 +39,7 @@ class OnBoardingPresenterTest {
val presenter = OnBoardingPresenter(
buildMeta = buildMeta,
featureFlagService = featureFlagService,
rageshakeFeatureAvailability = { true },
)
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
@ -46,7 +48,21 @@ class OnBoardingPresenterTest {
assertThat(initialState.canLoginWithQrCode).isFalse()
assertThat(initialState.productionApplicationName).isEqualTo("B")
assertThat(initialState.canCreateAccount).isEqualTo(OnBoardingConfig.CAN_CREATE_ACCOUNT)
assertThat(initialState.canReportBug).isTrue()
assertThat(awaitItem().canLoginWithQrCode).isTrue()
}
}
@Test
fun `present - rageshake not available`() = runTest {
val presenter = OnBoardingPresenter(
buildMeta = aBuildMeta(),
featureFlagService = FakeFeatureFlagService(),
rageshakeFeatureAvailability = { false },
)
presenter.test {
skipItems(1)
assertThat(awaitItem().canReportBug).isFalse()
}
}
}

View file

@ -10,6 +10,7 @@ package io.element.android.features.onboarding.impl
import androidx.activity.ComponentActivity
import androidx.compose.ui.test.junit4.AndroidComposeTestRule
import androidx.compose.ui.test.junit4.createAndroidComposeRule
import androidx.compose.ui.test.onNodeWithText
import androidx.test.ext.junit.runners.AndroidJUnit4
import io.element.android.libraries.ui.strings.CommonStrings
import io.element.android.tests.testutils.EnsureNeverCalled
@ -76,13 +77,28 @@ class OnboardingViewTest {
fun `clicking on report a problem calls the sign in callback`() {
ensureCalledOnce { callback ->
rule.setOnboardingView(
state = anOnBoardingState(),
state = anOnBoardingState(
canReportBug = true,
),
onReportProblem = callback,
)
val text = rule.activity.getString(CommonStrings.common_report_a_problem)
rule.onNodeWithText(text).assertExists()
rule.clickOn(CommonStrings.common_report_a_problem)
}
}
@Test
fun `cannot report a problem when the feature is disabled`() {
rule.setOnboardingView(
state = anOnBoardingState(
canReportBug = false,
),
)
val text = rule.activity.getString(CommonStrings.common_report_a_problem)
rule.onNodeWithText(text).assertDoesNotExist()
}
private fun <R : TestRule> AndroidComposeTestRule<R, ComponentActivity>.setOnboardingView(
state: OnBoardingState,
onSignInWithQrCode: () -> Unit = EnsureNeverCalled(),