From 7c37cdee5fd0ea10aeda8d96ec0dcea23f59ce02 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Mon, 8 Jul 2024 18:17:44 +0200 Subject: [PATCH] Ensure `PinUnlockActivity` and `IncomingCallActivity` use the internal theme set by the user. --- .../call/impl/ui/IncomingCallActivity.kt | 29 +++- .../call/impl/ui/IncomingCallScreen.kt | 149 +++++++++--------- features/lockscreen/impl/build.gradle.kts | 1 + .../impl/unlock/activity/PinUnlockActivity.kt | 16 +- 4 files changed, 113 insertions(+), 82 deletions(-) diff --git a/features/call/impl/src/main/kotlin/io/element/android/features/call/impl/ui/IncomingCallActivity.kt b/features/call/impl/src/main/kotlin/io/element/android/features/call/impl/ui/IncomingCallActivity.kt index 02cd612bcf..cbbeaef47c 100644 --- a/features/call/impl/src/main/kotlin/io/element/android/features/call/impl/ui/IncomingCallActivity.kt +++ b/features/call/impl/src/main/kotlin/io/element/android/features/call/impl/ui/IncomingCallActivity.kt @@ -20,8 +20,15 @@ import android.os.Bundle import android.view.WindowManager import androidx.activity.compose.setContent import androidx.appcompat.app.AppCompatActivity +import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.getValue +import androidx.compose.runtime.remember import androidx.core.content.IntentCompat import androidx.lifecycle.lifecycleScope +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.call.api.CallType import io.element.android.features.call.api.ElementCallEntryPoint import io.element.android.features.call.impl.di.CallBindings @@ -29,6 +36,7 @@ import io.element.android.features.call.impl.notifications.CallNotificationData import io.element.android.features.call.impl.utils.ActiveCallManager import io.element.android.features.call.impl.utils.CallState import io.element.android.libraries.architecture.bindings +import io.element.android.libraries.preferences.api.store.AppPreferencesStore import kotlinx.coroutines.flow.filter import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach @@ -51,6 +59,9 @@ class IncomingCallActivity : AppCompatActivity() { @Inject lateinit var activeCallManager: ActiveCallManager + @Inject + lateinit var appPreferencesStore: AppPreferencesStore + override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -68,11 +79,19 @@ class IncomingCallActivity : AppCompatActivity() { val notificationData = intent?.let { IntentCompat.getParcelableExtra(it, EXTRA_NOTIFICATION_DATA, CallNotificationData::class.java) } if (notificationData != null) { setContent { - IncomingCallScreen( - notificationData = notificationData, - onAnswer = ::onAnswer, - onCancel = ::onCancel, - ) + val theme by remember { + appPreferencesStore.getThemeFlow().mapToTheme() + } + .collectAsState(initial = Theme.System) + ElementTheme( + darkTheme = theme.isDark() + ) { + IncomingCallScreen( + notificationData = notificationData, + onAnswer = ::onAnswer, + onCancel = ::onCancel, + ) + } } } else { // No data, finish the activity diff --git a/features/call/impl/src/main/kotlin/io/element/android/features/call/impl/ui/IncomingCallScreen.kt b/features/call/impl/src/main/kotlin/io/element/android/features/call/impl/ui/IncomingCallScreen.kt index 80dc2353ca..d663f15807 100644 --- a/features/call/impl/src/main/kotlin/io/element/android/features/call/impl/ui/IncomingCallScreen.kt +++ b/features/call/impl/src/main/kotlin/io/element/android/features/call/impl/ui/IncomingCallScreen.kt @@ -64,67 +64,65 @@ internal fun IncomingCallScreen( onAnswer: (CallNotificationData) -> Unit, onCancel: () -> Unit, ) { - ElementTheme { - OnboardingBackground() + OnboardingBackground() + Column( + modifier = Modifier.fillMaxSize(), + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.Bottom + ) { Column( - modifier = Modifier.fillMaxSize(), - horizontalAlignment = Alignment.CenterHorizontally, - verticalArrangement = Arrangement.Bottom + modifier = Modifier + .fillMaxWidth() + .padding(start = 20.dp, end = 20.dp, top = 124.dp) + .weight(1f), + horizontalAlignment = Alignment.CenterHorizontally ) { - Column( - modifier = Modifier - .fillMaxWidth() - .padding(start = 20.dp, end = 20.dp, top = 124.dp) - .weight(1f), - horizontalAlignment = Alignment.CenterHorizontally - ) { - Avatar( - avatarData = AvatarData( - id = notificationData.senderId.value, - name = notificationData.senderName, - url = notificationData.avatarUrl, - size = AvatarSize.IncomingCall, - ) - ) - Spacer(modifier = Modifier.height(24.dp)) - Text( - text = notificationData.senderName ?: notificationData.senderId.value, - style = ElementTheme.typography.fontHeadingMdBold, - textAlign = TextAlign.Center, - ) - Spacer(modifier = Modifier.height(8.dp)) - Text( - text = stringResource(R.string.screen_incoming_call_subtitle_android), - style = ElementTheme.typography.fontBodyLgRegular, - color = ElementTheme.colors.textSecondary, - textAlign = TextAlign.Center, - ) - } - Row( - modifier = Modifier - .fillMaxWidth() - .padding(start = 24.dp, end = 24.dp, bottom = 64.dp), - horizontalArrangement = Arrangement.SpaceBetween, - verticalAlignment = Alignment.CenterVertically - ) { - ActionButton( - size = 64.dp, - onClick = { onAnswer(notificationData) }, - icon = CompoundIcons.VoiceCall(), - title = stringResource(CommonStrings.action_accept), - backgroundColor = ElementTheme.colors.iconSuccessPrimary, - borderColor = ElementTheme.colors.borderSuccessSubtle + Avatar( + avatarData = AvatarData( + id = notificationData.senderId.value, + name = notificationData.senderName, + url = notificationData.avatarUrl, + size = AvatarSize.IncomingCall, ) + ) + Spacer(modifier = Modifier.height(24.dp)) + Text( + text = notificationData.senderName ?: notificationData.senderId.value, + style = ElementTheme.typography.fontHeadingMdBold, + textAlign = TextAlign.Center, + ) + Spacer(modifier = Modifier.height(8.dp)) + Text( + text = stringResource(R.string.screen_incoming_call_subtitle_android), + style = ElementTheme.typography.fontBodyLgRegular, + color = ElementTheme.colors.textSecondary, + textAlign = TextAlign.Center, + ) + } + Row( + modifier = Modifier + .fillMaxWidth() + .padding(start = 24.dp, end = 24.dp, bottom = 64.dp), + horizontalArrangement = Arrangement.SpaceBetween, + verticalAlignment = Alignment.CenterVertically + ) { + ActionButton( + size = 64.dp, + onClick = { onAnswer(notificationData) }, + icon = CompoundIcons.VoiceCall(), + title = stringResource(CommonStrings.action_accept), + backgroundColor = ElementTheme.colors.iconSuccessPrimary, + borderColor = ElementTheme.colors.borderSuccessSubtle + ) - ActionButton( - size = 64.dp, - onClick = onCancel, - icon = CompoundIcons.EndCall(), - title = stringResource(CommonStrings.action_reject), - backgroundColor = ElementTheme.colors.iconCriticalPrimary, - borderColor = ElementTheme.colors.borderCriticalSubtle - ) - } + ActionButton( + size = 64.dp, + onClick = onCancel, + icon = CompoundIcons.EndCall(), + title = stringResource(CommonStrings.action_reject), + backgroundColor = ElementTheme.colors.iconCriticalPrimary, + borderColor = ElementTheme.colors.borderCriticalSubtle + ) } } } @@ -145,7 +143,8 @@ private fun ActionButton( horizontalAlignment = Alignment.CenterHorizontally ) { FilledIconButton( - modifier = Modifier.size(size + borderSize) + modifier = Modifier + .size(size + borderSize) .border(borderSize, borderColor, CircleShape), onClick = onClick, colors = IconButtonDefaults.filledIconButtonColors( @@ -171,22 +170,20 @@ private fun ActionButton( @PreviewsDayNight @Composable -internal fun IncomingCallScreenPreview() { - ElementPreview { - IncomingCallScreen( - notificationData = CallNotificationData( - sessionId = SessionId("@alice:matrix.org"), - roomId = RoomId("!1234:matrix.org"), - eventId = EventId("\$asdadadsad:matrix.org"), - senderId = UserId("@bob:matrix.org"), - roomName = "A room", - senderName = "Bob", - avatarUrl = null, - notificationChannelId = "incoming_call", - timestamp = 0L, - ), - onAnswer = {}, - onCancel = {}, - ) - } +internal fun IncomingCallScreenPreview() = ElementPreview { + IncomingCallScreen( + notificationData = CallNotificationData( + sessionId = SessionId("@alice:matrix.org"), + roomId = RoomId("!1234:matrix.org"), + eventId = EventId("\$asdadadsad:matrix.org"), + senderId = UserId("@bob:matrix.org"), + roomName = "A room", + senderName = "Bob", + avatarUrl = null, + notificationChannelId = "incoming_call", + timestamp = 0L, + ), + onAnswer = {}, + onCancel = {}, + ) } diff --git a/features/lockscreen/impl/build.gradle.kts b/features/lockscreen/impl/build.gradle.kts index 1cbe9692cf..21f3e05421 100644 --- a/features/lockscreen/impl/build.gradle.kts +++ b/features/lockscreen/impl/build.gradle.kts @@ -40,6 +40,7 @@ dependencies { implementation(projects.libraries.designsystem) implementation(projects.libraries.featureflag.api) implementation(projects.libraries.cryptography.api) + implementation(projects.libraries.preferences.api) implementation(projects.libraries.uiStrings) implementation(projects.libraries.sessionStorage.api) implementation(projects.services.appnavstate.api) diff --git a/features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/unlock/activity/PinUnlockActivity.kt b/features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/unlock/activity/PinUnlockActivity.kt index 9c228b0736..ce87613c24 100644 --- a/features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/unlock/activity/PinUnlockActivity.kt +++ b/features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/unlock/activity/PinUnlockActivity.kt @@ -23,14 +23,21 @@ import androidx.activity.OnBackPressedCallback import androidx.activity.compose.setContent import androidx.activity.enableEdgeToEdge import androidx.appcompat.app.AppCompatActivity +import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.getValue +import androidx.compose.runtime.remember import androidx.lifecycle.lifecycleScope 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.lockscreen.api.LockScreenLockState import io.element.android.features.lockscreen.api.LockScreenService 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.preferences.api.store.AppPreferencesStore import kotlinx.coroutines.launch import javax.inject.Inject @@ -43,13 +50,20 @@ class PinUnlockActivity : AppCompatActivity() { @Inject lateinit var presenter: PinUnlockPresenter @Inject lateinit var lockScreenService: LockScreenService + @Inject lateinit var appPreferencesStore: AppPreferencesStore override fun onCreate(savedInstanceState: Bundle?) { enableEdgeToEdge() super.onCreate(savedInstanceState) bindings().inject(this) setContent { - ElementTheme { + val theme by remember { + appPreferencesStore.getThemeFlow().mapToTheme() + } + .collectAsState(initial = Theme.System) + ElementTheme( + darkTheme = theme.isDark() + ) { val state = presenter.present() PinUnlockView(state = state, isInAppUnlock = false) }