Merge pull request #4378 from element-hq/feature/bma/customSuperButton

Be able to correctly render the UI with other colors.
This commit is contained in:
Benoit Marty 2025-03-11 09:26:54 +01:00 committed by GitHub
commit 44b837a6bd
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
20 changed files with 131 additions and 37 deletions

View file

@ -64,6 +64,7 @@ class MainActivity : NodeActivity() {
ElementThemeApp(
appPreferencesStore = appBindings.preferencesStore(),
enterpriseService = appBindings.enterpriseService(),
buildMeta = appBindings.buildMeta()
) {
CompositionLocalProvider(
LocalSnackbarDispatcher provides appBindings.snackbarDispatcher(),

View file

@ -13,6 +13,7 @@ import io.element.android.features.enterprise.api.EnterpriseService
import io.element.android.features.lockscreen.api.LockScreenEntryPoint
import io.element.android.features.lockscreen.api.LockScreenService
import io.element.android.features.rageshake.api.reporter.BugReporter
import io.element.android.libraries.core.meta.BuildMeta
import io.element.android.libraries.designsystem.utils.snackbar.SnackbarDispatcher
import io.element.android.libraries.di.AppScope
import io.element.android.libraries.matrix.api.tracing.TracingService
@ -38,4 +39,6 @@ interface AppBindings {
fun analyticsService(): AnalyticsService
fun enterpriseService(): EnterpriseService
fun buildMeta(): BuildMeta
}

View file

@ -48,6 +48,7 @@ import io.element.android.features.enterprise.api.EnterpriseService
import io.element.android.libraries.architecture.Presenter
import io.element.android.libraries.architecture.bindings
import io.element.android.libraries.core.log.logger.LoggerTag
import io.element.android.libraries.core.meta.BuildMeta
import io.element.android.libraries.designsystem.theme.ElementThemeApp
import io.element.android.libraries.preferences.api.store.AppPreferencesStore
import timber.log.Timber
@ -64,6 +65,7 @@ class ElementCallActivity :
@Inject lateinit var appPreferencesStore: AppPreferencesStore
@Inject lateinit var enterpriseService: EnterpriseService
@Inject lateinit var pictureInPicturePresenter: PictureInPicturePresenter
@Inject lateinit var buildMeta: BuildMeta
private lateinit var presenter: Presenter<CallScreenState>
@ -114,6 +116,7 @@ class ElementCallActivity :
ElementThemeApp(
appPreferencesStore = appPreferencesStore,
enterpriseService = enterpriseService,
buildMeta = buildMeta,
) {
val state = presenter.present()
eventSink = state.eventSink

View file

@ -21,6 +21,7 @@ import io.element.android.features.call.impl.utils.ActiveCallManager
import io.element.android.features.call.impl.utils.CallState
import io.element.android.features.enterprise.api.EnterpriseService
import io.element.android.libraries.architecture.bindings
import io.element.android.libraries.core.meta.BuildMeta
import io.element.android.libraries.designsystem.theme.ElementThemeApp
import io.element.android.libraries.preferences.api.store.AppPreferencesStore
import kotlinx.coroutines.flow.filter
@ -51,6 +52,9 @@ class IncomingCallActivity : AppCompatActivity() {
@Inject
lateinit var enterpriseService: EnterpriseService
@Inject
lateinit var buildMeta: BuildMeta
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
@ -71,6 +75,7 @@ class IncomingCallActivity : AppCompatActivity() {
ElementThemeApp(
appPreferencesStore = appPreferencesStore,
enterpriseService = enterpriseService,
buildMeta = buildMeta,
) {
IncomingCallScreen(
notificationData = notificationData,

View file

@ -22,6 +22,7 @@ import io.element.android.features.lockscreen.impl.unlock.PinUnlockPresenter
import io.element.android.features.lockscreen.impl.unlock.PinUnlockView
import io.element.android.features.lockscreen.impl.unlock.di.PinUnlockBindings
import io.element.android.libraries.architecture.bindings
import io.element.android.libraries.core.meta.BuildMeta
import io.element.android.libraries.designsystem.theme.ElementThemeApp
import io.element.android.libraries.preferences.api.store.AppPreferencesStore
import kotlinx.coroutines.launch
@ -38,6 +39,7 @@ class PinUnlockActivity : AppCompatActivity() {
@Inject lateinit var lockScreenService: LockScreenService
@Inject lateinit var appPreferencesStore: AppPreferencesStore
@Inject lateinit var enterpriseService: EnterpriseService
@Inject lateinit var buildMeta: BuildMeta
override fun onCreate(savedInstanceState: Bundle?) {
enableEdgeToEdge()
@ -47,6 +49,7 @@ class PinUnlockActivity : AppCompatActivity() {
ElementThemeApp(
appPreferencesStore = appPreferencesStore,
enterpriseService = enterpriseService,
buildMeta = buildMeta,
) {
val state = presenter.present()
PinUnlockView(

View file

@ -8,6 +8,8 @@
package io.element.android.features.messages.impl.timeline.components
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
@ -28,7 +30,10 @@ import io.element.android.features.messages.impl.timeline.model.event.TimelineIt
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemStateContent
import io.element.android.features.messages.impl.timeline.protection.TimelineProtectionEvent
import io.element.android.features.messages.impl.timeline.protection.TimelineProtectionState
import io.element.android.libraries.designsystem.preview.ElementPreview
import io.element.android.libraries.designsystem.preview.PreviewsDayNight
import io.element.android.libraries.designsystem.text.toPx
import io.element.android.libraries.designsystem.theme.LocalBuildMeta
import io.element.android.libraries.designsystem.theme.highlightedMessageBackgroundColor
import io.element.android.libraries.matrix.api.core.EventId
import io.element.android.libraries.matrix.api.core.UserId
@ -171,8 +176,13 @@ private fun Modifier.focusedEvent(
focusedEventOffset: Dp
): Modifier {
val highlightedLineColor = ElementTheme.colors.textActionAccent
val gradientFirstColor = if (LocalBuildMeta.current.isEnterpriseBuild) {
ElementTheme.colors.textActionAccent.copy(alpha = 0.125f)
} else {
ElementTheme.colors.highlightedMessageBackgroundColor
}
val gradientColors = listOf(
ElementTheme.colors.highlightedMessageBackgroundColor,
gradientFirstColor,
ElementTheme.colors.bgCanvasDefault,
)
val verticalOffset = focusedEventOffset.toPx()
@ -196,3 +206,15 @@ private fun Modifier.focusedEvent(
}
}.padding(top = 4.dp)
}
@PreviewsDayNight
@Composable
internal fun FocusedEventPreview() = ElementPreview {
Box(
modifier = Modifier
.padding(16.dp)
.fillMaxWidth()
.height(160.dp)
.focusedEvent(0.dp),
)
}

View file

@ -37,13 +37,13 @@ internal fun TimelineItemReadMarkerView(
Text(
text = stringResource(id = R.string.screen_room_timeline_read_marker_title).uppercase(),
style = ElementTheme.typography.fontBodySmMedium,
color = ElementTheme.colors.textSecondary,
color = ElementTheme.colors.textActionAccent,
)
HorizontalDivider(
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 2.dp),
color = ElementTheme.colors.borderInteractivePrimary,
color = ElementTheme.colors.textActionAccent,
)
}
}

View file

@ -27,6 +27,7 @@ import androidx.compose.ui.draw.drawBehind
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.geometry.Size
import androidx.compose.ui.geometry.center
import androidx.compose.ui.graphics.BlendMode
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.LinearGradientShader
import androidx.compose.ui.graphics.RadialGradientShader
@ -36,10 +37,12 @@ import androidx.compose.ui.graphics.Shape
import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.unit.dp
import io.element.android.compound.annotations.CoreColorToken
import io.element.android.compound.theme.ElementTheme
import io.element.android.compound.tokens.generated.CompoundIcons
import io.element.android.compound.tokens.generated.internal.LightColorTokens
import io.element.android.libraries.designsystem.preview.ElementPreview
import io.element.android.libraries.designsystem.preview.PreviewsDayNight
import io.element.android.libraries.designsystem.theme.LocalBuildMeta
import io.element.android.libraries.designsystem.theme.components.Icon
@OptIn(CoreColorToken::class)
@ -50,6 +53,16 @@ fun GradientFloatingActionButton(
shape: Shape = RoundedCornerShape(25),
content: @Composable () -> Unit,
) {
val color1 = if (LocalBuildMeta.current.isEnterpriseBuild) {
ElementTheme.colors.textActionAccent
} else {
LightColorTokens.colorGreen700
}
val color2 = if (LocalBuildMeta.current.isEnterpriseBuild) {
ElementTheme.colors.textActionAccent
} else {
LightColorTokens.colorBlue900
}
val linearShaderBrush = remember {
object : ShaderBrush() {
override fun createShader(size: Size): Shader {
@ -57,8 +70,8 @@ fun GradientFloatingActionButton(
from = Offset(size.width, size.height),
to = Offset(size.width, 0f),
colors = listOf(
LightColorTokens.colorBlue900,
LightColorTokens.colorGreen700,
color2,
color1,
),
)
}
@ -71,8 +84,8 @@ fun GradientFloatingActionButton(
center = size.center,
radius = size.width / 2,
colors = listOf(
LightColorTokens.colorGreen700,
LightColorTokens.colorBlue900,
color1,
color2,
)
)
}
@ -85,8 +98,8 @@ fun GradientFloatingActionButton(
.graphicsLayer(shape = shape, clip = false)
.clip(shape)
.drawBehind {
drawRect(brush = radialShaderBrush, alpha = 0.4f)
drawRect(brush = linearShaderBrush)
drawRect(brush = radialShaderBrush, alpha = 0.4f, blendMode = BlendMode.Overlay)
}
.clickable(
enabled = true,

View file

@ -42,6 +42,7 @@ import io.element.android.compound.tokens.generated.internal.DarkColorTokens
import io.element.android.compound.tokens.generated.internal.LightColorTokens
import io.element.android.libraries.designsystem.preview.ElementPreview
import io.element.android.libraries.designsystem.preview.PreviewsDayNight
import io.element.android.libraries.designsystem.theme.LocalBuildMeta
import io.element.android.libraries.designsystem.theme.components.ButtonSize
import io.element.android.libraries.designsystem.theme.components.HorizontalDivider
import io.element.android.libraries.designsystem.theme.components.lowHorizontalPaddingValue
@ -66,17 +67,24 @@ fun SuperButton(
}
}
val isLightTheme = ElementTheme.isLightTheme
val colors = remember(isLightTheme) {
if (isLightTheme) {
listOf(
LightColorTokens.colorBlue900,
LightColorTokens.colorGreen1100,
)
} else {
listOf(
DarkColorTokens.colorBlue900,
DarkColorTokens.colorGreen1100,
)
val colors = if (LocalBuildMeta.current.isEnterpriseBuild) {
listOf(
ElementTheme.colors.textActionAccent,
ElementTheme.colors.textActionAccent,
)
} else {
remember(isLightTheme) {
if (isLightTheme) {
listOf(
LightColorTokens.colorBlue900,
LightColorTokens.colorGreen1100,
)
} else {
listOf(
DarkColorTokens.colorBlue900,
DarkColorTokens.colorGreen1100,
)
}
}
}

View file

@ -9,17 +9,40 @@ package io.element.android.libraries.designsystem.theme
import androidx.appcompat.app.AppCompatDelegate
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.runtime.staticCompositionLocalOf
import io.element.android.compound.theme.ElementTheme
import io.element.android.compound.theme.Theme
import io.element.android.compound.theme.isDark
import io.element.android.compound.theme.mapToTheme
import io.element.android.features.enterprise.api.EnterpriseService
import io.element.android.libraries.core.meta.BuildMeta
import io.element.android.libraries.core.meta.BuildType
import io.element.android.libraries.preferences.api.store.AppPreferencesStore
val LocalBuildMeta = staticCompositionLocalOf {
BuildMeta(
isDebuggable = true,
buildType = BuildType.DEBUG,
applicationName = "MyApp",
productionApplicationName = "MyAppProd",
desktopApplicationName = "MyAppDesktop",
applicationId = "AppId",
isEnterpriseBuild = false,
lowPrivacyLoggingEnabled = false,
versionName = "aVersion",
versionCode = 123,
gitRevision = "aRevision",
gitBranchName = "aBranch",
flavorDescription = "aFlavor",
flavorShortDescription = "aFlavorShort",
)
}
/**
* Theme to use for all the regular screens of the application.
* Will manage the light / dark theme based on the user preference.
@ -31,6 +54,7 @@ import io.element.android.libraries.preferences.api.store.AppPreferencesStore
fun ElementThemeApp(
appPreferencesStore: AppPreferencesStore,
enterpriseService: EnterpriseService,
buildMeta: BuildMeta,
content: @Composable () -> Unit,
) {
val theme by remember {
@ -48,10 +72,14 @@ fun ElementThemeApp(
}
val compoundLight = remember { enterpriseService.semanticColorsLight() }
val compoundDark = remember { enterpriseService.semanticColorsDark() }
ElementTheme(
darkTheme = theme.isDark(),
content = content,
compoundLight = compoundLight,
compoundDark = compoundDark,
)
CompositionLocalProvider(
LocalBuildMeta provides buildMeta,
) {
ElementTheme(
darkTheme = theme.isDark(),
content = content,
compoundLight = compoundLight,
compoundDark = compoundDark,
)
}
}

View file

@ -66,6 +66,7 @@ class KonsistPreviewTest {
"CallScreenPipViewPreview",
"ColorAliasesPreview",
"DefaultRoomListTopBarWithIndicatorPreview",
"FocusedEventPreview",
"GradientFloatingActionButtonCircleShapePreview",
"IconsCompoundPreview",
"IconsOtherPreview",

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:2becc435316b7adb15745bd0afbc2634cbc643b3919b2e7405b8a2b9b310acd0
size 4451
oid sha256:c899d8ca8e98ae73c8acd90cef3967834901929833c4d8287356a320f2bf4c0e
size 4523

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:eb901534fbf1e05988710ea799d94daf9fa6a881edd84463ca0e065282ffbdb2
size 4439
oid sha256:f7579ab37a0ebe9671a46e591037fbd8991d3265e203d6ad0dcec6a6b7ceb588
size 4386

View file

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:a2ea87ef947697fc3ea21c8953149db1c729be5391a4fd65f63b7b04aaf0e8cf
size 10465

View file

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:8ce07ba72b4542584273ee4004365fe50da4747e4aa06c46ea0d6b192647a1ac
size 10204

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:e51f7c0e57fbdbeea27962cf3ebf58ead3a5689251eced57f2a37cb4373c9858
size 7057
oid sha256:867a27b40625fe6d0c214c3a4bea0a09baf298aebb53d3ff77e19b3dfe250414
size 10393

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:fd6fd55c333b87c619189f4b0e1b1b0616f65982b322e03e271a59eaaf1a649b
size 6967
oid sha256:df3a081fb057accffb4179c86f46cb05b033962c0339a96767b68610b9df9ecc
size 10313

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:6eb030d6d2f1c80cb7dea618c3a47db2f7db7b26ad19b3ba9313c0535ab7a761
size 6533
oid sha256:c43a92d9ca48521da56819a405585a96255b302a517832b7375870752489dacb
size 10516

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:b955337a438e1c29cd75961dadc489d14f726f7524281f4368fac1c1cfcb58d6
size 6512
oid sha256:82e2d283d97af1db75bacef222976be6e4f646d5606e9f4aa95fa15b81bb0898
size 10414

View file

@ -229,6 +229,7 @@ Compose:
- LocalRoomMemberProfilesCache
- LocalMentionSpanTheme
- LocalAnalyticsService
- LocalBuildMeta
CompositionLocalNaming:
active: true
ContentEmitterReturningValues: