Move deviceId, gitBranch and gitSha to the developer screens.

This commit is contained in:
Benoit Marty
2026-07-17 17:37:57 +02:00
committed by Benoit Marty
parent 98c686dd5b
commit 4dffd7ddef
17 changed files with 98 additions and 45 deletions
@@ -31,6 +31,7 @@ import io.element.android.libraries.architecture.Presenter
import io.element.android.libraries.architecture.runCatchingUpdatingState import io.element.android.libraries.architecture.runCatchingUpdatingState
import io.element.android.libraries.core.data.ByteUnit import io.element.android.libraries.core.data.ByteUnit
import io.element.android.libraries.matrix.api.analytics.GetDatabaseSizesUseCase import io.element.android.libraries.matrix.api.analytics.GetDatabaseSizesUseCase
import io.element.android.libraries.matrix.api.core.DeviceId
import io.element.android.libraries.matrix.api.core.SessionId import io.element.android.libraries.matrix.api.core.SessionId
import kotlinx.collections.immutable.ImmutableMap import kotlinx.collections.immutable.ImmutableMap
import kotlinx.collections.immutable.toImmutableMap import kotlinx.collections.immutable.toImmutableMap
@@ -41,6 +42,7 @@ import kotlinx.coroutines.launch
class DeveloperSettingsPresenter( class DeveloperSettingsPresenter(
private val appDeveloperSettingsPresenter: Presenter<AppDeveloperSettingsState>, private val appDeveloperSettingsPresenter: Presenter<AppDeveloperSettingsState>,
private val sessionId: SessionId, private val sessionId: SessionId,
private val deviceId: DeviceId,
private val computeCacheSizeUseCase: ComputeCacheSizeUseCase, private val computeCacheSizeUseCase: ComputeCacheSizeUseCase,
private val clearCacheUseCase: ClearCacheUseCase, private val clearCacheUseCase: ClearCacheUseCase,
private val enterpriseService: EnterpriseService, private val enterpriseService: EnterpriseService,
@@ -117,6 +119,7 @@ class DeveloperSettingsPresenter(
markAllRoomsAsReadAction = markAllRoomsAsReadAction.value, markAllRoomsAsReadAction = markAllRoomsAsReadAction.value,
isEnterpriseBuild = enterpriseService.isEnterpriseBuild, isEnterpriseBuild = enterpriseService.isEnterpriseBuild,
showColorPicker = showColorPicker, showColorPicker = showColorPicker,
deviceId = deviceId,
eventSink = ::handleEvent, eventSink = ::handleEvent,
) )
} }
@@ -11,6 +11,7 @@ package io.element.android.features.preferences.impl.developer
import io.element.android.features.preferences.impl.developer.appsettings.AppDeveloperSettingsState import io.element.android.features.preferences.impl.developer.appsettings.AppDeveloperSettingsState
import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.architecture.AsyncAction
import io.element.android.libraries.architecture.AsyncData import io.element.android.libraries.architecture.AsyncData
import io.element.android.libraries.matrix.api.core.DeviceId
import kotlinx.collections.immutable.ImmutableMap import kotlinx.collections.immutable.ImmutableMap
data class DeveloperSettingsState( data class DeveloperSettingsState(
@@ -21,6 +22,7 @@ data class DeveloperSettingsState(
val markAllRoomsAsReadAction: AsyncAction<Unit>, val markAllRoomsAsReadAction: AsyncAction<Unit>,
val isEnterpriseBuild: Boolean, val isEnterpriseBuild: Boolean,
val showColorPicker: Boolean, val showColorPicker: Boolean,
val deviceId: DeviceId,
val eventSink: (DeveloperSettingsEvents) -> Unit val eventSink: (DeveloperSettingsEvents) -> Unit
) { ) {
val showLoader = clearCacheAction is AsyncAction.Loading || markAllRoomsAsReadAction is AsyncAction.Loading val showLoader = clearCacheAction is AsyncAction.Loading || markAllRoomsAsReadAction is AsyncAction.Loading
@@ -13,6 +13,7 @@ import io.element.android.features.preferences.impl.developer.appsettings.AppDev
import io.element.android.features.preferences.impl.developer.appsettings.anAppDeveloperSettingsState import io.element.android.features.preferences.impl.developer.appsettings.anAppDeveloperSettingsState
import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.architecture.AsyncAction
import io.element.android.libraries.architecture.AsyncData import io.element.android.libraries.architecture.AsyncData
import io.element.android.libraries.matrix.api.core.DeviceId
import kotlinx.collections.immutable.persistentMapOf import kotlinx.collections.immutable.persistentMapOf
open class DeveloperSettingsStateProvider : PreviewParameterProvider<DeveloperSettingsState> { open class DeveloperSettingsStateProvider : PreviewParameterProvider<DeveloperSettingsState> {
@@ -40,6 +41,7 @@ fun aDeveloperSettingsState(
markAllRoomsAsReadAction: AsyncAction<Unit> = AsyncAction.Uninitialized, markAllRoomsAsReadAction: AsyncAction<Unit> = AsyncAction.Uninitialized,
isEnterpriseBuild: Boolean = false, isEnterpriseBuild: Boolean = false,
showColorPicker: Boolean = false, showColorPicker: Boolean = false,
deviceId: DeviceId = DeviceId("ILAKNDNASDLK"),
eventSink: (DeveloperSettingsEvents) -> Unit = {}, eventSink: (DeveloperSettingsEvents) -> Unit = {},
) = DeveloperSettingsState( ) = DeveloperSettingsState(
appDeveloperSettingsState = appDeveloperSettingsState, appDeveloperSettingsState = appDeveloperSettingsState,
@@ -49,5 +51,6 @@ fun aDeveloperSettingsState(
markAllRoomsAsReadAction = markAllRoomsAsReadAction, markAllRoomsAsReadAction = markAllRoomsAsReadAction,
isEnterpriseBuild = isEnterpriseBuild, isEnterpriseBuild = isEnterpriseBuild,
showColorPicker = showColorPicker, showColorPicker = showColorPicker,
deviceId = deviceId,
eventSink = eventSink, eventSink = eventSink,
) )
@@ -15,12 +15,14 @@ import androidx.compose.foundation.progressSemantics
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.ExperimentalComposeUiApi import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import io.element.android.compound.theme.ElementTheme import io.element.android.compound.theme.ElementTheme
import io.element.android.features.preferences.impl.R import io.element.android.features.preferences.impl.R
import io.element.android.features.preferences.impl.developer.appsettings.AppDeveloperSettingsView import io.element.android.features.preferences.impl.developer.appsettings.AppDeveloperSettingsView
import io.element.android.libraries.androidutils.system.copyToClipboard
import io.element.android.libraries.designsystem.components.ProgressDialog import io.element.android.libraries.designsystem.components.ProgressDialog
import io.element.android.libraries.designsystem.components.dialogs.ConfirmationDialog import io.element.android.libraries.designsystem.components.dialogs.ConfirmationDialog
import io.element.android.libraries.designsystem.components.list.ListItemContent import io.element.android.libraries.designsystem.components.list.ListItemContent
@@ -31,6 +33,7 @@ import io.element.android.libraries.designsystem.preview.PreviewsDayNight
import io.element.android.libraries.designsystem.theme.components.CircularProgressIndicator import io.element.android.libraries.designsystem.theme.components.CircularProgressIndicator
import io.element.android.libraries.designsystem.theme.components.ListItem import io.element.android.libraries.designsystem.theme.components.ListItem
import io.element.android.libraries.designsystem.theme.components.Text import io.element.android.libraries.designsystem.theme.components.Text
import io.element.android.libraries.matrix.api.core.DeviceId
import io.element.android.libraries.ui.strings.CommonStrings import io.element.android.libraries.ui.strings.CommonStrings
import io.mhssn.colorpicker.ColorPickerDialog import io.mhssn.colorpicker.ColorPickerDialog
import io.mhssn.colorpicker.ColorPickerType import io.mhssn.colorpicker.ColorPickerType
@@ -75,6 +78,7 @@ fun DeveloperSettingsView(
state = state.appDeveloperSettingsState, state = state.appDeveloperSettingsState,
onOpenShowkase = onOpenShowkase, onOpenShowkase = onOpenShowkase,
) )
SessionCategory(deviceId = state.deviceId)
NotificationCategory(onPushHistoryClick) NotificationCategory(onPushHistoryClick)
MarkAllRoomsAsReadCategory(state) MarkAllRoomsAsReadCategory(state)
@@ -168,6 +172,24 @@ fun DeveloperSettingsView(
) )
} }
@Composable
private fun SessionCategory(deviceId: DeviceId) {
PreferenceCategory(title = "Session") {
val toastMessage = stringResource(CommonStrings.common_copied_to_clipboard)
val context = LocalContext.current
ListItem(
headlineContent = { Text("DeviceId") },
supportingContent = { Text(text = deviceId.value) },
onClick = {
context.copyToClipboard(
text = deviceId.value,
toastMessage = toastMessage,
)
}
)
}
}
@Composable @Composable
private fun MarkAllRoomsAsReadCategory(state: DeveloperSettingsState) { private fun MarkAllRoomsAsReadCategory(state: DeveloperSettingsState) {
PreferenceCategory(title = "Room list") { PreferenceCategory(title = "Room list") {
@@ -25,6 +25,7 @@ import io.element.android.features.rageshake.api.preferences.RageshakePreference
import io.element.android.libraries.architecture.AsyncData import io.element.android.libraries.architecture.AsyncData
import io.element.android.libraries.architecture.Presenter import io.element.android.libraries.architecture.Presenter
import io.element.android.libraries.core.extensions.runCatchingExceptions import io.element.android.libraries.core.extensions.runCatchingExceptions
import io.element.android.libraries.core.meta.BuildMeta
import io.element.android.libraries.featureflag.api.FeatureFlagService import io.element.android.libraries.featureflag.api.FeatureFlagService
import io.element.android.libraries.featureflag.ui.model.FeatureUiModel import io.element.android.libraries.featureflag.ui.model.FeatureUiModel
import io.element.android.libraries.preferences.api.store.AppPreferencesStore import io.element.android.libraries.preferences.api.store.AppPreferencesStore
@@ -42,6 +43,7 @@ class AppDeveloperSettingsPresenter(
private val featureFlagService: FeatureFlagService, private val featureFlagService: FeatureFlagService,
private val rageshakePresenter: Presenter<RageshakePreferencesState>, private val rageshakePresenter: Presenter<RageshakePreferencesState>,
private val appPreferencesStore: AppPreferencesStore, private val appPreferencesStore: AppPreferencesStore,
private val buildMeta: BuildMeta,
) : Presenter<AppDeveloperSettingsState> { ) : Presenter<AppDeveloperSettingsState> {
@Composable @Composable
override fun present(): AppDeveloperSettingsState { override fun present(): AppDeveloperSettingsState {
@@ -110,6 +112,8 @@ class AppDeveloperSettingsPresenter(
), ),
tracingLogLevel = tracingLogLevel, tracingLogLevel = tracingLogLevel,
tracingLogPacks = tracingLogPacks, tracingLogPacks = tracingLogPacks,
gitBranch = buildMeta.gitBranchName,
gitSha = buildMeta.gitRevision,
eventSink = ::handleEvent, eventSink = ::handleEvent,
) )
} }
@@ -20,6 +20,8 @@ data class AppDeveloperSettingsState(
val customElementCallBaseUrlState: CustomElementCallBaseUrlState, val customElementCallBaseUrlState: CustomElementCallBaseUrlState,
val tracingLogLevel: AsyncData<LogLevelItem>, val tracingLogLevel: AsyncData<LogLevelItem>,
val tracingLogPacks: ImmutableList<TraceLogPack>, val tracingLogPacks: ImmutableList<TraceLogPack>,
val gitBranch: String,
val gitSha: String,
val eventSink: (AppDeveloperSettingsEvent) -> Unit val eventSink: (AppDeveloperSettingsEvent) -> Unit
) )
@@ -37,6 +37,8 @@ fun anAppDeveloperSettingsState(
customElementCallBaseUrlState = customElementCallBaseUrlState, customElementCallBaseUrlState = customElementCallBaseUrlState,
tracingLogLevel = AsyncData.Success(LogLevelItem.INFO), tracingLogLevel = AsyncData.Success(LogLevelItem.INFO),
tracingLogPacks = traceLogPacks.toImmutableList(), tracingLogPacks = traceLogPacks.toImmutableList(),
gitBranch = "feature/awesome-feature",
gitSha = "1234567890",
eventSink = eventSink, eventSink = eventSink,
) )
@@ -14,6 +14,7 @@ import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.ExperimentalComposeUiApi import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.input.KeyboardType import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.tooling.preview.PreviewParameter
@@ -22,6 +23,7 @@ import io.element.android.compound.theme.ElementTheme
import io.element.android.features.preferences.impl.R import io.element.android.features.preferences.impl.R
import io.element.android.features.preferences.impl.developer.tracing.LogLevelItem import io.element.android.features.preferences.impl.developer.tracing.LogLevelItem
import io.element.android.features.rageshake.api.preferences.RageshakePreferencesView import io.element.android.features.rageshake.api.preferences.RageshakePreferencesView
import io.element.android.libraries.androidutils.system.copyToClipboard
import io.element.android.libraries.designsystem.components.preferences.PreferenceCategory import io.element.android.libraries.designsystem.components.preferences.PreferenceCategory
import io.element.android.libraries.designsystem.components.preferences.PreferenceDropdown import io.element.android.libraries.designsystem.components.preferences.PreferenceDropdown
import io.element.android.libraries.designsystem.components.preferences.PreferenceSwitch import io.element.android.libraries.designsystem.components.preferences.PreferenceSwitch
@@ -33,6 +35,7 @@ import io.element.android.libraries.designsystem.theme.components.Text
import io.element.android.libraries.featureflag.ui.FeatureListView import io.element.android.libraries.featureflag.ui.FeatureListView
import io.element.android.libraries.featureflag.ui.model.FeatureUiModel import io.element.android.libraries.featureflag.ui.model.FeatureUiModel
import io.element.android.libraries.matrix.api.tracing.TraceLogPack import io.element.android.libraries.matrix.api.tracing.TraceLogPack
import io.element.android.libraries.ui.strings.CommonStrings
import kotlinx.collections.immutable.toImmutableList import kotlinx.collections.immutable.toImmutableList
@OptIn(ExperimentalComposeUiApi::class) @OptIn(ExperimentalComposeUiApi::class)
@@ -98,6 +101,41 @@ fun AppDeveloperSettingsView(
onClick = { error("This crash is a test.") } onClick = { error("This crash is a test.") }
) )
} }
GitCategory(
gitBranch = state.gitBranch,
gitSha = state.gitSha,
)
}
}
@Composable
private fun GitCategory(
gitBranch: String,
gitSha: String,
) {
PreferenceCategory(title = "Git") {
val toastMessage = stringResource(CommonStrings.common_copied_to_clipboard)
val context = LocalContext.current
ListItem(
headlineContent = { Text("Git branch") },
supportingContent = { Text(text = gitBranch) },
onClick = {
context.copyToClipboard(
text = gitBranch,
toastMessage = toastMessage,
)
}
)
ListItem(
headlineContent = { Text("Git SHA") },
supportingContent = { Text(text = gitSha) },
onClick = {
context.copyToClipboard(
text = gitSha,
toastMessage = toastMessage,
)
}
)
} }
} }
@@ -142,7 +142,6 @@ class PreferencesRootPresenter(
myUser = matrixUser.value, myUser = matrixUser.value,
userStatusState = userStatusState, userStatusState = userStatusState,
version = remember { versionFormatter.get() }, version = remember { versionFormatter.get() },
deviceId = matrixClient.deviceId,
isMultiAccountEnabled = isMultiAccountEnabled, isMultiAccountEnabled = isMultiAccountEnabled,
otherSessions = otherSessions, otherSessions = otherSessions,
showSecureBackup = !canVerifyUserSession, showSecureBackup = !canVerifyUserSession,
@@ -11,7 +11,6 @@ package io.element.android.features.preferences.impl.root
import io.element.android.features.logout.api.direct.DirectLogoutState import io.element.android.features.logout.api.direct.DirectLogoutState
import io.element.android.features.preferences.impl.userstatus.UserStatusState import io.element.android.features.preferences.impl.userstatus.UserStatusState
import io.element.android.libraries.designsystem.utils.snackbar.SnackbarMessage import io.element.android.libraries.designsystem.utils.snackbar.SnackbarMessage
import io.element.android.libraries.matrix.api.core.DeviceId
import io.element.android.libraries.matrix.api.user.MatrixUser import io.element.android.libraries.matrix.api.user.MatrixUser
import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.ImmutableList
@@ -19,7 +18,6 @@ data class PreferencesRootState(
val myUser: MatrixUser, val myUser: MatrixUser,
val userStatusState: UserStatusState?, val userStatusState: UserStatusState?,
val version: String, val version: String,
val deviceId: DeviceId?,
val isMultiAccountEnabled: Boolean, val isMultiAccountEnabled: Boolean,
val otherSessions: ImmutableList<MatrixUser>, val otherSessions: ImmutableList<MatrixUser>,
val showSecureBackup: Boolean, val showSecureBackup: Boolean,
@@ -15,7 +15,6 @@ import io.element.android.features.preferences.impl.userstatus.UserStatusPickerS
import io.element.android.features.preferences.impl.userstatus.UserStatusState import io.element.android.features.preferences.impl.userstatus.UserStatusState
import io.element.android.features.preferences.impl.userstatus.aUserStatusState import io.element.android.features.preferences.impl.userstatus.aUserStatusState
import io.element.android.libraries.designsystem.utils.snackbar.SnackbarMessage import io.element.android.libraries.designsystem.utils.snackbar.SnackbarMessage
import io.element.android.libraries.matrix.api.core.DeviceId
import io.element.android.libraries.matrix.api.user.MatrixUser import io.element.android.libraries.matrix.api.user.MatrixUser
import io.element.android.libraries.matrix.ui.components.aMatrixUser import io.element.android.libraries.matrix.ui.components.aMatrixUser
import io.element.android.libraries.matrix.ui.components.aMatrixUserList import io.element.android.libraries.matrix.ui.components.aMatrixUserList
@@ -29,7 +28,6 @@ open class PreferencesRootStateProvider : PreviewParameterProvider<PreferencesRo
aPreferencesRootState( aPreferencesRootState(
myUser = aMatrixUser(avatarUrl = "anAvatarUrl"), myUser = aMatrixUser(avatarUrl = "anAvatarUrl"),
version = "Version 1.1 (1)", version = "Version 1.1 (1)",
deviceId = DeviceId("ILAKNDNASDLK"),
isMultiAccountEnabled = true, isMultiAccountEnabled = true,
otherSessions = aMatrixUserList().drop(1).take(1), otherSessions = aMatrixUserList().drop(1).take(1),
showSecureBackup = true, showSecureBackup = true,
@@ -55,7 +53,6 @@ open class PreferencesRootStateProvider : PreviewParameterProvider<PreferencesRo
showSecureBackupBadge = true, showSecureBackupBadge = true,
), ),
aPreferencesRootState( aPreferencesRootState(
deviceId = DeviceId("ILAKNDNASDLK"),
showLabsItem = true, showLabsItem = true,
canReportBug = true, canReportBug = true,
nbOfBlockedUsers = 3, nbOfBlockedUsers = 3,
@@ -76,7 +73,6 @@ open class PreferencesRootStateProvider : PreviewParameterProvider<PreferencesRo
fun aPreferencesRootState( fun aPreferencesRootState(
myUser: MatrixUser = aMatrixUser(), myUser: MatrixUser = aMatrixUser(),
version: String = "Version 1.1 (1)", version: String = "Version 1.1 (1)",
deviceId: DeviceId? = null,
isMultiAccountEnabled: Boolean = false, isMultiAccountEnabled: Boolean = false,
otherSessions: List<MatrixUser> = emptyList(), otherSessions: List<MatrixUser> = emptyList(),
showSecureBackup: Boolean = false, showSecureBackup: Boolean = false,
@@ -96,7 +92,6 @@ fun aPreferencesRootState(
) = PreferencesRootState( ) = PreferencesRootState(
myUser = myUser, myUser = myUser,
version = version, version = version,
deviceId = deviceId,
isMultiAccountEnabled = isMultiAccountEnabled, isMultiAccountEnabled = isMultiAccountEnabled,
otherSessions = otherSessions.toImmutableList(), otherSessions = otherSessions.toImmutableList(),
showSecureBackup = showSecureBackup, showSecureBackup = showSecureBackup,
@@ -13,7 +13,6 @@ import androidx.compose.foundation.layout.ColumnScope
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
@@ -43,7 +42,6 @@ import io.element.android.libraries.designsystem.utils.snackbar.SnackbarHost
import io.element.android.libraries.designsystem.utils.snackbar.rememberSnackbarHostState import io.element.android.libraries.designsystem.utils.snackbar.rememberSnackbarHostState
import io.element.android.libraries.emoji.api.picker.EmojiPickerRenderer import io.element.android.libraries.emoji.api.picker.EmojiPickerRenderer
import io.element.android.libraries.emoji.api.picker.NoOpEmojiPickerRenderer import io.element.android.libraries.emoji.api.picker.NoOpEmojiPickerRenderer
import io.element.android.libraries.matrix.api.core.DeviceId
import io.element.android.libraries.matrix.api.user.MatrixUser import io.element.android.libraries.matrix.api.user.MatrixUser
import io.element.android.libraries.matrix.ui.components.MatrixUserRow import io.element.android.libraries.matrix.ui.components.MatrixUserRow
import io.element.android.libraries.ui.strings.CommonStrings import io.element.android.libraries.ui.strings.CommonStrings
@@ -129,7 +127,6 @@ fun PreferencesRootView(
// Version // Version
Footer( Footer(
version = state.version, version = state.version,
deviceId = state.deviceId,
onClick = if (!state.showDeveloperSettings) { onClick = if (!state.showDeveloperSettings) {
{ state.eventSink(PreferencesRootEvent.OnVersionInfoClick) } { state.eventSink(PreferencesRootEvent.OnVersionInfoClick) }
} else { } else {
@@ -326,25 +323,15 @@ private fun ColumnScope.GeneralSection(
@Composable @Composable
private fun ColumnScope.Footer( private fun ColumnScope.Footer(
version: String, version: String,
deviceId: DeviceId?,
onClick: (() -> Unit)?, onClick: (() -> Unit)?,
) { ) {
val text = remember(version, deviceId) {
buildString {
append(version)
if (deviceId != null) {
append("\n")
append(deviceId)
}
}
}
Text( Text(
modifier = Modifier modifier = Modifier
.align(Alignment.CenterHorizontally) .align(Alignment.CenterHorizontally)
.clickable(enabled = onClick != null, onClick = onClick ?: {}) .clickable(enabled = onClick != null, onClick = onClick ?: {})
.padding(start = 16.dp, end = 16.dp, top = 16.dp, bottom = 24.dp), .padding(start = 16.dp, end = 16.dp, top = 16.dp, bottom = 24.dp),
textAlign = TextAlign.Center, textAlign = TextAlign.Center,
text = text, text = version,
style = ElementTheme.typography.fontBodySmRegular, style = ElementTheme.typography.fontBodySmRegular,
color = ElementTheme.colors.textSecondary, color = ElementTheme.colors.textSecondary,
) )
@@ -24,16 +24,10 @@ class DefaultVersionFormatter(
private val buildMeta: BuildMeta, private val buildMeta: BuildMeta,
) : VersionFormatter { ) : VersionFormatter {
override fun get(): String { override fun get(): String {
val base = stringProvider.getString( return stringProvider.getString(
CommonStrings.settings_version_number, CommonStrings.settings_version_number,
buildMeta.versionName, buildMeta.versionName,
buildMeta.versionCode.toString() buildMeta.versionCode.toString()
) )
return if (buildMeta.gitBranchName == "main") {
base
} else {
// In case of a build not from main, we display the branch name and the revision
"$base\n${buildMeta.gitBranchName} (${buildMeta.gitRevision})"
}
} }
} }
@@ -25,7 +25,9 @@ import io.element.android.libraries.architecture.AsyncData
import io.element.android.libraries.core.data.megaBytes import io.element.android.libraries.core.data.megaBytes
import io.element.android.libraries.matrix.api.analytics.GetDatabaseSizesUseCase import io.element.android.libraries.matrix.api.analytics.GetDatabaseSizesUseCase
import io.element.android.libraries.matrix.api.analytics.SdkStoreSizes import io.element.android.libraries.matrix.api.analytics.SdkStoreSizes
import io.element.android.libraries.matrix.api.core.DeviceId
import io.element.android.libraries.matrix.api.core.SessionId import io.element.android.libraries.matrix.api.core.SessionId
import io.element.android.libraries.matrix.test.A_DEVICE_ID
import io.element.android.libraries.matrix.test.A_SESSION_ID import io.element.android.libraries.matrix.test.A_SESSION_ID
import io.element.android.tests.testutils.WarmUpRule import io.element.android.tests.testutils.WarmUpRule
import io.element.android.tests.testutils.lambda.lambdaRecorder import io.element.android.tests.testutils.lambda.lambdaRecorder
@@ -57,6 +59,7 @@ class DeveloperSettingsPresenterTest {
assertThat(state.cacheSize).isEqualTo(AsyncData.Uninitialized) assertThat(state.cacheSize).isEqualTo(AsyncData.Uninitialized)
assertThat(state.isEnterpriseBuild).isFalse() assertThat(state.isEnterpriseBuild).isFalse()
assertThat(state.showColorPicker).isFalse() assertThat(state.showColorPicker).isFalse()
assertThat(state.deviceId).isEqualTo(A_DEVICE_ID)
} }
awaitItem().also { state -> awaitItem().also { state ->
assertThat(state.cacheSize.isLoading()).isTrue() assertThat(state.cacheSize.isLoading()).isTrue()
@@ -169,6 +172,7 @@ class DeveloperSettingsPresenterTest {
private fun createDeveloperSettingsPresenter( private fun createDeveloperSettingsPresenter(
sessionId: SessionId = A_SESSION_ID, sessionId: SessionId = A_SESSION_ID,
deviceId: DeviceId = A_DEVICE_ID,
cacheSizeUseCase: FakeComputeCacheSizeUseCase = FakeComputeCacheSizeUseCase(), cacheSizeUseCase: FakeComputeCacheSizeUseCase = FakeComputeCacheSizeUseCase(),
clearCacheUseCase: FakeClearCacheUseCase = FakeClearCacheUseCase(), clearCacheUseCase: FakeClearCacheUseCase = FakeClearCacheUseCase(),
enterpriseService: EnterpriseService = FakeEnterpriseService(), enterpriseService: EnterpriseService = FakeEnterpriseService(),
@@ -179,6 +183,7 @@ class DeveloperSettingsPresenterTest {
return DeveloperSettingsPresenter( return DeveloperSettingsPresenter(
appDeveloperSettingsPresenter = { anAppDeveloperSettingsState() }, appDeveloperSettingsPresenter = { anAppDeveloperSettingsState() },
sessionId = sessionId, sessionId = sessionId,
deviceId = deviceId,
computeCacheSizeUseCase = cacheSizeUseCase, computeCacheSizeUseCase = cacheSizeUseCase,
clearCacheUseCase = clearCacheUseCase, clearCacheUseCase = clearCacheUseCase,
enterpriseService = enterpriseService, enterpriseService = enterpriseService,
@@ -16,6 +16,7 @@ import io.element.android.libraries.architecture.AsyncData
import io.element.android.libraries.featureflag.api.Feature import io.element.android.libraries.featureflag.api.Feature
import io.element.android.libraries.featureflag.test.FakeFeature import io.element.android.libraries.featureflag.test.FakeFeature
import io.element.android.libraries.featureflag.test.FakeFeatureFlagService import io.element.android.libraries.featureflag.test.FakeFeatureFlagService
import io.element.android.libraries.matrix.test.core.aBuildMeta
import io.element.android.libraries.preferences.test.InMemoryAppPreferencesStore import io.element.android.libraries.preferences.test.InMemoryAppPreferencesStore
import io.element.android.tests.testutils.WarmUpRule import io.element.android.tests.testutils.WarmUpRule
import io.element.android.tests.testutils.lambda.lambdaRecorder import io.element.android.tests.testutils.lambda.lambdaRecorder
@@ -53,6 +54,8 @@ class AppDeveloperSettingsPresenterTest {
assertThat(state.rageshakeState.isSupported).isTrue() assertThat(state.rageshakeState.isSupported).isTrue()
assertThat(state.rageshakeState.sensitivity).isEqualTo(0.3f) assertThat(state.rageshakeState.sensitivity).isEqualTo(0.3f)
assertThat(state.tracingLogLevel).isEqualTo(AsyncData.Uninitialized) assertThat(state.tracingLogLevel).isEqualTo(AsyncData.Uninitialized)
assertThat(state.gitBranch).isEqualTo("feature/awesome-feature")
assertThat(state.gitSha).isEqualTo("1234567890")
} }
awaitItem().also { state -> awaitItem().also { state ->
assertThat(state.features).isNotEmpty() assertThat(state.features).isNotEmpty()
@@ -145,6 +148,10 @@ class AppDeveloperSettingsPresenterTest {
featureFlagService = featureFlagService, featureFlagService = featureFlagService,
rageshakePresenter = { aRageshakePreferencesState() }, rageshakePresenter = { aRageshakePreferencesState() },
appPreferencesStore = preferencesStore, appPreferencesStore = preferencesStore,
buildMeta = aBuildMeta(
gitRevision = "1234567890",
gitBranchName = "feature/awesome-feature"
)
) )
} }
} }
@@ -16,7 +16,7 @@ import org.junit.Test
class VersionFormatterTest { class VersionFormatterTest {
@Test @Test
fun `version formatter should return simplified version for main branch`() = runTest { fun `version formatter should return formatted version`() = runTest {
val sut = DefaultVersionFormatter( val sut = DefaultVersionFormatter(
stringProvider = FakeStringProvider(defaultResult = VERSION), stringProvider = FakeStringProvider(defaultResult = VERSION),
buildMeta = aBuildMeta( buildMeta = aBuildMeta(
@@ -28,21 +28,7 @@ class VersionFormatterTest {
assertThat(sut.get()).isEqualTo("${VERSION}versionName, 123") assertThat(sut.get()).isEqualTo("${VERSION}versionName, 123")
} }
@Test
fun `version formatter should return simplified version for other branch`() = runTest {
val sut = DefaultVersionFormatter(
stringProvider = FakeStringProvider(defaultResult = VERSION),
buildMeta = aBuildMeta(
versionName = "versionName",
versionCode = 123,
gitBranchName = "branch",
gitRevision = "1234567890",
)
)
assertThat(sut.get()).isEqualTo("${VERSION}versionName, 123\nbranch (1234567890)")
}
companion object { companion object {
const val VERSION = "version" const val VERSION = "version: "
} }
} }
@@ -15,6 +15,7 @@ import io.element.android.libraries.di.SessionScope
import io.element.android.libraries.di.annotations.SessionCoroutineScope import io.element.android.libraries.di.annotations.SessionCoroutineScope
import io.element.android.libraries.matrix.api.HomeserverCapabilitiesProvider import io.element.android.libraries.matrix.api.HomeserverCapabilitiesProvider
import io.element.android.libraries.matrix.api.MatrixClient import io.element.android.libraries.matrix.api.MatrixClient
import io.element.android.libraries.matrix.api.core.DeviceId
import io.element.android.libraries.matrix.api.core.SessionId import io.element.android.libraries.matrix.api.core.SessionId
import io.element.android.libraries.matrix.api.encryption.EncryptionService import io.element.android.libraries.matrix.api.encryption.EncryptionService
import io.element.android.libraries.matrix.api.media.MatrixMediaLoader import io.element.android.libraries.matrix.api.media.MatrixMediaLoader
@@ -37,6 +38,11 @@ object SessionMatrixModule {
return matrixClient.sessionId return matrixClient.sessionId
} }
@Provides
fun providesDeviceId(matrixClient: MatrixClient): DeviceId {
return matrixClient.deviceId
}
@Provides @Provides
fun providesSessionVerificationService(matrixClient: MatrixClient): SessionVerificationService { fun providesSessionVerificationService(matrixClient: MatrixClient): SessionVerificationService {
return matrixClient.sessionVerificationService return matrixClient.sessionVerificationService