Improve API and fix theme glitch when switching between accounts.
This commit is contained in:
parent
ea2fc290b7
commit
c2c77aad2a
13 changed files with 120 additions and 61 deletions
|
|
@ -16,6 +16,9 @@ import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.CompositionLocalProvider
|
import androidx.compose.runtime.CompositionLocalProvider
|
||||||
|
import androidx.compose.runtime.collectAsState
|
||||||
|
import androidx.compose.runtime.getValue
|
||||||
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.platform.LocalUriHandler
|
import androidx.compose.ui.platform.LocalUriHandler
|
||||||
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
|
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
|
||||||
|
|
@ -26,6 +29,7 @@ import com.bumble.appyx.core.integration.NodeHost
|
||||||
import com.bumble.appyx.core.integrationpoint.NodeActivity
|
import com.bumble.appyx.core.integrationpoint.NodeActivity
|
||||||
import com.bumble.appyx.core.plugin.NodeReadyObserver
|
import com.bumble.appyx.core.plugin.NodeReadyObserver
|
||||||
import io.element.android.compound.theme.ElementTheme
|
import io.element.android.compound.theme.ElementTheme
|
||||||
|
import io.element.android.features.enterprise.api.SemanticColorsLightDark
|
||||||
import io.element.android.features.lockscreen.api.LockScreenEntryPoint
|
import io.element.android.features.lockscreen.api.LockScreenEntryPoint
|
||||||
import io.element.android.features.lockscreen.api.LockScreenLockState
|
import io.element.android.features.lockscreen.api.LockScreenLockState
|
||||||
import io.element.android.features.lockscreen.api.LockScreenService
|
import io.element.android.features.lockscreen.api.LockScreenService
|
||||||
|
|
@ -61,9 +65,13 @@ class MainActivity : NodeActivity() {
|
||||||
@Composable
|
@Composable
|
||||||
private fun MainContent(appBindings: AppBindings) {
|
private fun MainContent(appBindings: AppBindings) {
|
||||||
val migrationState = appBindings.migrationEntryPoint().present()
|
val migrationState = appBindings.migrationEntryPoint().present()
|
||||||
|
val colors by remember {
|
||||||
|
appBindings.enterpriseService().semanticColorsFlow(sessionId = null)
|
||||||
|
}.collectAsState(SemanticColorsLightDark.default)
|
||||||
ElementThemeApp(
|
ElementThemeApp(
|
||||||
appPreferencesStore = appBindings.preferencesStore(),
|
appPreferencesStore = appBindings.preferencesStore(),
|
||||||
enterpriseService = appBindings.enterpriseService(),
|
compoundLight = colors.light,
|
||||||
|
compoundDark = colors.dark,
|
||||||
buildMeta = appBindings.buildMeta()
|
buildMeta = appBindings.buildMeta()
|
||||||
) {
|
) {
|
||||||
CompositionLocalProvider(
|
CompositionLocalProvider(
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.collectAsState
|
import androidx.compose.runtime.collectAsState
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
import com.bumble.appyx.core.composable.PermanentChild
|
import com.bumble.appyx.core.composable.PermanentChild
|
||||||
|
|
@ -46,6 +47,8 @@ import io.element.android.appnav.loggedin.SendQueues
|
||||||
import io.element.android.appnav.room.RoomFlowNode
|
import io.element.android.appnav.room.RoomFlowNode
|
||||||
import io.element.android.appnav.room.RoomNavigationTarget
|
import io.element.android.appnav.room.RoomNavigationTarget
|
||||||
import io.element.android.appnav.room.joined.JoinedRoomLoadedFlowNode
|
import io.element.android.appnav.room.joined.JoinedRoomLoadedFlowNode
|
||||||
|
import io.element.android.features.enterprise.api.EnterpriseService
|
||||||
|
import io.element.android.features.enterprise.api.SemanticColorsLightDark
|
||||||
import io.element.android.features.enterprise.api.SessionEnterpriseService
|
import io.element.android.features.enterprise.api.SessionEnterpriseService
|
||||||
import io.element.android.features.ftue.api.FtueEntryPoint
|
import io.element.android.features.ftue.api.FtueEntryPoint
|
||||||
import io.element.android.features.ftue.api.state.FtueService
|
import io.element.android.features.ftue.api.state.FtueService
|
||||||
|
|
@ -66,6 +69,8 @@ import io.element.android.libraries.architecture.BackstackView
|
||||||
import io.element.android.libraries.architecture.BaseFlowNode
|
import io.element.android.libraries.architecture.BaseFlowNode
|
||||||
import io.element.android.libraries.architecture.createNode
|
import io.element.android.libraries.architecture.createNode
|
||||||
import io.element.android.libraries.architecture.waitForNavTargetAttached
|
import io.element.android.libraries.architecture.waitForNavTargetAttached
|
||||||
|
import io.element.android.libraries.core.meta.BuildMeta
|
||||||
|
import io.element.android.libraries.designsystem.theme.ElementThemeApp
|
||||||
import io.element.android.libraries.designsystem.utils.snackbar.SnackbarDispatcher
|
import io.element.android.libraries.designsystem.utils.snackbar.SnackbarDispatcher
|
||||||
import io.element.android.libraries.di.SessionScope
|
import io.element.android.libraries.di.SessionScope
|
||||||
import io.element.android.libraries.di.annotations.SessionCoroutineScope
|
import io.element.android.libraries.di.annotations.SessionCoroutineScope
|
||||||
|
|
@ -79,6 +84,7 @@ import io.element.android.libraries.matrix.api.core.toRoomIdOrAlias
|
||||||
import io.element.android.libraries.matrix.api.permalink.PermalinkData
|
import io.element.android.libraries.matrix.api.permalink.PermalinkData
|
||||||
import io.element.android.libraries.matrix.api.verification.SessionVerificationServiceListener
|
import io.element.android.libraries.matrix.api.verification.SessionVerificationServiceListener
|
||||||
import io.element.android.libraries.matrix.api.verification.VerificationRequest
|
import io.element.android.libraries.matrix.api.verification.VerificationRequest
|
||||||
|
import io.element.android.libraries.preferences.api.store.AppPreferencesStore
|
||||||
import io.element.android.libraries.push.api.notifications.conversations.NotificationConversationService
|
import io.element.android.libraries.push.api.notifications.conversations.NotificationConversationService
|
||||||
import io.element.android.libraries.ui.common.nodes.emptyNode
|
import io.element.android.libraries.ui.common.nodes.emptyNode
|
||||||
import io.element.android.services.appnavstate.api.AppNavigationStateService
|
import io.element.android.services.appnavstate.api.AppNavigationStateService
|
||||||
|
|
@ -122,6 +128,9 @@ class LoggedInFlowNode(
|
||||||
private val sessionEnterpriseService: SessionEnterpriseService,
|
private val sessionEnterpriseService: SessionEnterpriseService,
|
||||||
private val networkMonitor: NetworkMonitor,
|
private val networkMonitor: NetworkMonitor,
|
||||||
private val notificationConversationService: NotificationConversationService,
|
private val notificationConversationService: NotificationConversationService,
|
||||||
|
private val enterpriseService: EnterpriseService,
|
||||||
|
private val appPreferencesStore: AppPreferencesStore,
|
||||||
|
private val buildMeta: BuildMeta,
|
||||||
snackbarDispatcher: SnackbarDispatcher,
|
snackbarDispatcher: SnackbarDispatcher,
|
||||||
) : BaseFlowNode<LoggedInFlowNode.NavTarget>(
|
) : BaseFlowNode<LoggedInFlowNode.NavTarget>(
|
||||||
backstack = BackStack(
|
backstack = BackStack(
|
||||||
|
|
@ -538,11 +547,21 @@ class LoggedInFlowNode(
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
override fun View(modifier: Modifier) {
|
override fun View(modifier: Modifier) {
|
||||||
Box(modifier = modifier) {
|
val colors by remember {
|
||||||
val ftueState by ftueService.state.collectAsState()
|
enterpriseService.semanticColorsFlow(sessionId = matrixClient.sessionId)
|
||||||
BackstackView()
|
}.collectAsState(SemanticColorsLightDark.default)
|
||||||
if (ftueState is FtueState.Complete) {
|
ElementThemeApp(
|
||||||
PermanentChild(permanentNavModel = permanentNavModel, navTarget = NavTarget.LoggedInPermanent)
|
appPreferencesStore = appPreferencesStore,
|
||||||
|
compoundLight = colors.light,
|
||||||
|
compoundDark = colors.dark,
|
||||||
|
buildMeta = buildMeta,
|
||||||
|
) {
|
||||||
|
Box(modifier = modifier) {
|
||||||
|
val ftueState by ftueService.state.collectAsState()
|
||||||
|
BackstackView()
|
||||||
|
if (ftueState is FtueState.Complete) {
|
||||||
|
PermanentChild(permanentNavModel = permanentNavModel, navTarget = NavTarget.LoggedInPermanent)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1 +1 @@
|
||||||
Subproject commit f662f079f911b728e5769d10268e2c2775d7287a
|
Subproject commit b5ab0a6aa01aa03e89fa7593ea144a043b8f7487
|
||||||
|
|
@ -31,3 +31,10 @@ sealed interface CallType : NodeInputs, Parcelable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun CallType.getSessionId(): SessionId? {
|
||||||
|
return when (this) {
|
||||||
|
is CallType.ExternalUrl -> null
|
||||||
|
is CallType.RoomCall -> sessionId
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -23,8 +23,10 @@ import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.DisposableEffect
|
import androidx.compose.runtime.DisposableEffect
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
|
import androidx.compose.runtime.collectAsState
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.runtime.rememberUpdatedState
|
import androidx.compose.runtime.rememberUpdatedState
|
||||||
import androidx.core.app.PictureInPictureModeChangedInfo
|
import androidx.core.app.PictureInPictureModeChangedInfo
|
||||||
import androidx.core.content.IntentCompat
|
import androidx.core.content.IntentCompat
|
||||||
|
|
@ -33,6 +35,7 @@ import androidx.lifecycle.Lifecycle
|
||||||
import dev.zacsweers.metro.Inject
|
import dev.zacsweers.metro.Inject
|
||||||
import io.element.android.features.call.api.CallType
|
import io.element.android.features.call.api.CallType
|
||||||
import io.element.android.features.call.api.CallType.ExternalUrl
|
import io.element.android.features.call.api.CallType.ExternalUrl
|
||||||
|
import io.element.android.features.call.api.getSessionId
|
||||||
import io.element.android.features.call.impl.DefaultElementCallEntryPoint
|
import io.element.android.features.call.impl.DefaultElementCallEntryPoint
|
||||||
import io.element.android.features.call.impl.di.CallBindings
|
import io.element.android.features.call.impl.di.CallBindings
|
||||||
import io.element.android.features.call.impl.pip.PictureInPictureEvents
|
import io.element.android.features.call.impl.pip.PictureInPictureEvents
|
||||||
|
|
@ -42,6 +45,7 @@ import io.element.android.features.call.impl.pip.PipView
|
||||||
import io.element.android.features.call.impl.services.CallForegroundService
|
import io.element.android.features.call.impl.services.CallForegroundService
|
||||||
import io.element.android.features.call.impl.utils.CallIntentDataParser
|
import io.element.android.features.call.impl.utils.CallIntentDataParser
|
||||||
import io.element.android.features.enterprise.api.EnterpriseService
|
import io.element.android.features.enterprise.api.EnterpriseService
|
||||||
|
import io.element.android.features.enterprise.api.SemanticColorsLightDark
|
||||||
import io.element.android.libraries.androidutils.browser.ConsoleMessageLogger
|
import io.element.android.libraries.androidutils.browser.ConsoleMessageLogger
|
||||||
import io.element.android.libraries.architecture.Presenter
|
import io.element.android.libraries.architecture.Presenter
|
||||||
import io.element.android.libraries.architecture.bindings
|
import io.element.android.libraries.architecture.bindings
|
||||||
|
|
@ -105,9 +109,13 @@ class ElementCallActivity :
|
||||||
setContent {
|
setContent {
|
||||||
val pipState = pictureInPicturePresenter.present()
|
val pipState = pictureInPicturePresenter.present()
|
||||||
ListenToAndroidEvents(pipState)
|
ListenToAndroidEvents(pipState)
|
||||||
|
val colors by remember(webViewTarget.value?.getSessionId()) {
|
||||||
|
enterpriseService.semanticColorsFlow(sessionId = webViewTarget.value?.getSessionId())
|
||||||
|
}.collectAsState(SemanticColorsLightDark.default)
|
||||||
ElementThemeApp(
|
ElementThemeApp(
|
||||||
appPreferencesStore = appPreferencesStore,
|
appPreferencesStore = appPreferencesStore,
|
||||||
enterpriseService = enterpriseService,
|
compoundLight = colors.light,
|
||||||
|
compoundDark = colors.dark,
|
||||||
buildMeta = buildMeta,
|
buildMeta = buildMeta,
|
||||||
) {
|
) {
|
||||||
val state = presenter.present()
|
val state = presenter.present()
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,9 @@ import android.os.Bundle
|
||||||
import android.view.WindowManager
|
import android.view.WindowManager
|
||||||
import androidx.activity.compose.setContent
|
import androidx.activity.compose.setContent
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
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.core.content.IntentCompat
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
import dev.zacsweers.metro.Inject
|
import dev.zacsweers.metro.Inject
|
||||||
|
|
@ -21,6 +24,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.ActiveCallManager
|
||||||
import io.element.android.features.call.impl.utils.CallState
|
import io.element.android.features.call.impl.utils.CallState
|
||||||
import io.element.android.features.enterprise.api.EnterpriseService
|
import io.element.android.features.enterprise.api.EnterpriseService
|
||||||
|
import io.element.android.features.enterprise.api.SemanticColorsLightDark
|
||||||
import io.element.android.libraries.architecture.bindings
|
import io.element.android.libraries.architecture.bindings
|
||||||
import io.element.android.libraries.core.meta.BuildMeta
|
import io.element.android.libraries.core.meta.BuildMeta
|
||||||
import io.element.android.libraries.designsystem.theme.ElementThemeApp
|
import io.element.android.libraries.designsystem.theme.ElementThemeApp
|
||||||
|
|
@ -78,9 +82,13 @@ class IncomingCallActivity : AppCompatActivity() {
|
||||||
val notificationData = intent?.let { IntentCompat.getParcelableExtra(it, EXTRA_NOTIFICATION_DATA, CallNotificationData::class.java) }
|
val notificationData = intent?.let { IntentCompat.getParcelableExtra(it, EXTRA_NOTIFICATION_DATA, CallNotificationData::class.java) }
|
||||||
if (notificationData != null) {
|
if (notificationData != null) {
|
||||||
setContent {
|
setContent {
|
||||||
|
val colors by remember {
|
||||||
|
enterpriseService.semanticColorsFlow(sessionId = notificationData.sessionId)
|
||||||
|
}.collectAsState(SemanticColorsLightDark.default)
|
||||||
ElementThemeApp(
|
ElementThemeApp(
|
||||||
appPreferencesStore = appPreferencesStore,
|
appPreferencesStore = appPreferencesStore,
|
||||||
enterpriseService = enterpriseService,
|
compoundLight = colors.light,
|
||||||
|
compoundDark = colors.dark,
|
||||||
buildMeta = buildMeta,
|
buildMeta = buildMeta,
|
||||||
) {
|
) {
|
||||||
IncomingCallScreen(
|
IncomingCallScreen(
|
||||||
|
|
|
||||||
|
|
@ -7,9 +7,9 @@
|
||||||
|
|
||||||
package io.element.android.features.enterprise.api
|
package io.element.android.features.enterprise.api
|
||||||
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import androidx.compose.runtime.State
|
|
||||||
import io.element.android.compound.tokens.generated.SemanticColors
|
import io.element.android.compound.tokens.generated.SemanticColors
|
||||||
|
import io.element.android.compound.tokens.generated.compoundColorsDark
|
||||||
|
import io.element.android.compound.tokens.generated.compoundColorsLight
|
||||||
import io.element.android.libraries.matrix.api.core.SessionId
|
import io.element.android.libraries.matrix.api.core.SessionId
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
|
||||||
|
|
@ -26,16 +26,12 @@ interface EnterpriseService {
|
||||||
*/
|
*/
|
||||||
suspend fun overrideBrandColor(sessionId: SessionId?, brandColor: String?)
|
suspend fun overrideBrandColor(sessionId: SessionId?, brandColor: String?)
|
||||||
|
|
||||||
@Composable
|
fun semanticColorsFlow(sessionId: SessionId?): Flow<SemanticColorsLightDark>
|
||||||
fun semanticColorsLight(): State<SemanticColors>
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun semanticColorsDark(): State<SemanticColors>
|
|
||||||
|
|
||||||
fun firebasePushGateway(): String?
|
fun firebasePushGateway(): String?
|
||||||
fun unifiedPushDefaultPushGateway(): String?
|
fun unifiedPushDefaultPushGateway(): String?
|
||||||
|
|
||||||
val bugReportUrlFlow: Flow<BugReportUrl>
|
fun bugReportUrlFlow(sessionId: SessionId?): Flow<BugReportUrl>
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
const val ANY_ACCOUNT_PROVIDER = "*"
|
const val ANY_ACCOUNT_PROVIDER = "*"
|
||||||
|
|
@ -47,3 +43,15 @@ fun EnterpriseService.canConnectToAnyHomeserver(): Boolean {
|
||||||
it.isEmpty() || it.contains(EnterpriseService.ANY_ACCOUNT_PROVIDER)
|
it.isEmpty() || it.contains(EnterpriseService.ANY_ACCOUNT_PROVIDER)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
data class SemanticColorsLightDark(
|
||||||
|
val light: SemanticColors,
|
||||||
|
val dark: SemanticColors,
|
||||||
|
) {
|
||||||
|
companion object {
|
||||||
|
val default = SemanticColorsLightDark(
|
||||||
|
light = compoundColorsLight,
|
||||||
|
dark = compoundColorsDark,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,19 +7,14 @@
|
||||||
|
|
||||||
package io.element.android.features.enterprise.impl
|
package io.element.android.features.enterprise.impl
|
||||||
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import androidx.compose.runtime.State
|
|
||||||
import androidx.compose.runtime.derivedStateOf
|
|
||||||
import androidx.compose.runtime.remember
|
|
||||||
import dev.zacsweers.metro.AppScope
|
import dev.zacsweers.metro.AppScope
|
||||||
import dev.zacsweers.metro.ContributesBinding
|
import dev.zacsweers.metro.ContributesBinding
|
||||||
import dev.zacsweers.metro.Inject
|
import dev.zacsweers.metro.Inject
|
||||||
import io.element.android.compound.tokens.generated.SemanticColors
|
|
||||||
import io.element.android.compound.tokens.generated.compoundColorsDark
|
|
||||||
import io.element.android.compound.tokens.generated.compoundColorsLight
|
|
||||||
import io.element.android.features.enterprise.api.BugReportUrl
|
import io.element.android.features.enterprise.api.BugReportUrl
|
||||||
import io.element.android.features.enterprise.api.EnterpriseService
|
import io.element.android.features.enterprise.api.EnterpriseService
|
||||||
|
import io.element.android.features.enterprise.api.SemanticColorsLightDark
|
||||||
import io.element.android.libraries.matrix.api.core.SessionId
|
import io.element.android.libraries.matrix.api.core.SessionId
|
||||||
|
import kotlinx.coroutines.flow.Flow
|
||||||
import kotlinx.coroutines.flow.flowOf
|
import kotlinx.coroutines.flow.flowOf
|
||||||
|
|
||||||
@ContributesBinding(AppScope::class)
|
@ContributesBinding(AppScope::class)
|
||||||
|
|
@ -34,18 +29,14 @@ class DefaultEnterpriseService : EnterpriseService {
|
||||||
|
|
||||||
override suspend fun overrideBrandColor(sessionId: SessionId?, brandColor: String?) = Unit
|
override suspend fun overrideBrandColor(sessionId: SessionId?, brandColor: String?) = Unit
|
||||||
|
|
||||||
@Composable
|
override fun semanticColorsFlow(sessionId: SessionId?): Flow<SemanticColorsLightDark> {
|
||||||
override fun semanticColorsLight(): State<SemanticColors> {
|
return flowOf(SemanticColorsLightDark.default)
|
||||||
return remember { derivedStateOf { compoundColorsLight } }
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
override fun semanticColorsDark(): State<SemanticColors> {
|
|
||||||
return remember { derivedStateOf { compoundColorsDark } }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun firebasePushGateway(): String? = null
|
override fun firebasePushGateway(): String? = null
|
||||||
override fun unifiedPushDefaultPushGateway(): String? = null
|
override fun unifiedPushDefaultPushGateway(): String? = null
|
||||||
|
|
||||||
override val bugReportUrlFlow = flowOf(BugReportUrl.UseDefault)
|
override fun bugReportUrlFlow(sessionId: SessionId?): Flow<BugReportUrl> {
|
||||||
|
return flowOf(BugReportUrl.UseDefault)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,11 +7,9 @@
|
||||||
|
|
||||||
package io.element.android.features.enterprise.test
|
package io.element.android.features.enterprise.test
|
||||||
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import androidx.compose.runtime.State
|
|
||||||
import io.element.android.compound.tokens.generated.SemanticColors
|
|
||||||
import io.element.android.features.enterprise.api.BugReportUrl
|
import io.element.android.features.enterprise.api.BugReportUrl
|
||||||
import io.element.android.features.enterprise.api.EnterpriseService
|
import io.element.android.features.enterprise.api.EnterpriseService
|
||||||
|
import io.element.android.features.enterprise.api.SemanticColorsLightDark
|
||||||
import io.element.android.libraries.matrix.api.core.SessionId
|
import io.element.android.libraries.matrix.api.core.SessionId
|
||||||
import io.element.android.tests.testutils.lambda.lambdaError
|
import io.element.android.tests.testutils.lambda.lambdaError
|
||||||
import io.element.android.tests.testutils.simulateLongTask
|
import io.element.android.tests.testutils.simulateLongTask
|
||||||
|
|
@ -24,12 +22,13 @@ class FakeEnterpriseService(
|
||||||
private val isEnterpriseUserResult: (SessionId) -> Boolean = { lambdaError() },
|
private val isEnterpriseUserResult: (SessionId) -> Boolean = { lambdaError() },
|
||||||
private val defaultHomeserverListResult: () -> List<String> = { emptyList() },
|
private val defaultHomeserverListResult: () -> List<String> = { emptyList() },
|
||||||
private val isAllowedToConnectToHomeserverResult: (String) -> Boolean = { lambdaError() },
|
private val isAllowedToConnectToHomeserverResult: (String) -> Boolean = { lambdaError() },
|
||||||
private val semanticColorsLightResult: () -> State<SemanticColors> = { lambdaError() },
|
initialSemanticColors: SemanticColorsLightDark = SemanticColorsLightDark.default,
|
||||||
private val semanticColorsDarkResult: () -> State<SemanticColors> = { lambdaError() },
|
|
||||||
private val overrideBrandColorResult: (SessionId?, String?) -> Unit = { _, _ -> lambdaError() },
|
private val overrideBrandColorResult: (SessionId?, String?) -> Unit = { _, _ -> lambdaError() },
|
||||||
private val firebasePushGatewayResult: () -> String? = { lambdaError() },
|
private val firebasePushGatewayResult: () -> String? = { lambdaError() },
|
||||||
private val unifiedPushDefaultPushGatewayResult: () -> String? = { lambdaError() },
|
private val unifiedPushDefaultPushGatewayResult: () -> String? = { lambdaError() },
|
||||||
) : EnterpriseService {
|
) : EnterpriseService {
|
||||||
|
private val semanticColorsState = MutableStateFlow(initialSemanticColors)
|
||||||
|
|
||||||
override suspend fun isEnterpriseUser(sessionId: SessionId): Boolean = simulateLongTask {
|
override suspend fun isEnterpriseUser(sessionId: SessionId): Boolean = simulateLongTask {
|
||||||
isEnterpriseUserResult(sessionId)
|
isEnterpriseUserResult(sessionId)
|
||||||
}
|
}
|
||||||
|
|
@ -46,14 +45,8 @@ class FakeEnterpriseService(
|
||||||
overrideBrandColorResult(sessionId, brandColor)
|
overrideBrandColorResult(sessionId, brandColor)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
override fun semanticColorsFlow(sessionId: SessionId?): Flow<SemanticColorsLightDark> {
|
||||||
override fun semanticColorsLight(): State<SemanticColors> {
|
return semanticColorsState.asStateFlow()
|
||||||
return semanticColorsLightResult()
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
override fun semanticColorsDark(): State<SemanticColors> {
|
|
||||||
return semanticColorsDarkResult()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun firebasePushGateway(): String? {
|
override fun firebasePushGateway(): String? {
|
||||||
|
|
@ -65,5 +58,7 @@ class FakeEnterpriseService(
|
||||||
}
|
}
|
||||||
|
|
||||||
val bugReportUrlMutableFlow = MutableStateFlow<BugReportUrl>(BugReportUrl.UseDefault)
|
val bugReportUrlMutableFlow = MutableStateFlow<BugReportUrl>(BugReportUrl.UseDefault)
|
||||||
override val bugReportUrlFlow: Flow<BugReportUrl> = bugReportUrlMutableFlow.asStateFlow()
|
override fun bugReportUrlFlow(sessionId: SessionId?): Flow<BugReportUrl> {
|
||||||
|
return bugReportUrlMutableFlow.asStateFlow()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,9 +14,13 @@ import androidx.activity.OnBackPressedCallback
|
||||||
import androidx.activity.compose.setContent
|
import androidx.activity.compose.setContent
|
||||||
import androidx.activity.enableEdgeToEdge
|
import androidx.activity.enableEdgeToEdge
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
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 androidx.lifecycle.lifecycleScope
|
||||||
import dev.zacsweers.metro.Inject
|
import dev.zacsweers.metro.Inject
|
||||||
import io.element.android.features.enterprise.api.EnterpriseService
|
import io.element.android.features.enterprise.api.EnterpriseService
|
||||||
|
import io.element.android.features.enterprise.api.SemanticColorsLightDark
|
||||||
import io.element.android.features.lockscreen.api.LockScreenLockState
|
import io.element.android.features.lockscreen.api.LockScreenLockState
|
||||||
import io.element.android.features.lockscreen.api.LockScreenService
|
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.PinUnlockPresenter
|
||||||
|
|
@ -46,9 +50,13 @@ class PinUnlockActivity : AppCompatActivity() {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
bindings<PinUnlockBindings>().inject(this)
|
bindings<PinUnlockBindings>().inject(this)
|
||||||
setContent {
|
setContent {
|
||||||
|
val colors by remember {
|
||||||
|
enterpriseService.semanticColorsFlow(sessionId = null)
|
||||||
|
}.collectAsState(SemanticColorsLightDark.default)
|
||||||
ElementThemeApp(
|
ElementThemeApp(
|
||||||
appPreferencesStore = appPreferencesStore,
|
appPreferencesStore = appPreferencesStore,
|
||||||
enterpriseService = enterpriseService,
|
compoundLight = colors.light,
|
||||||
|
compoundDark = colors.dark,
|
||||||
buildMeta = buildMeta,
|
buildMeta = buildMeta,
|
||||||
) {
|
) {
|
||||||
val state = presenter.present()
|
val state = presenter.present()
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,12 @@ import dev.zacsweers.metro.Inject
|
||||||
import io.element.android.appconfig.RageshakeConfig
|
import io.element.android.appconfig.RageshakeConfig
|
||||||
import io.element.android.features.enterprise.api.BugReportUrl
|
import io.element.android.features.enterprise.api.BugReportUrl
|
||||||
import io.element.android.features.enterprise.api.EnterpriseService
|
import io.element.android.features.enterprise.api.EnterpriseService
|
||||||
|
import io.element.android.libraries.matrix.api.core.SessionId
|
||||||
|
import io.element.android.libraries.sessionstorage.api.SessionStore
|
||||||
|
import io.element.android.libraries.sessionstorage.api.sessionIdFlow
|
||||||
|
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
import kotlinx.coroutines.flow.flatMapLatest
|
||||||
import kotlinx.coroutines.flow.flowOf
|
import kotlinx.coroutines.flow.flowOf
|
||||||
import kotlinx.coroutines.flow.map
|
import kotlinx.coroutines.flow.map
|
||||||
import okhttp3.HttpUrl
|
import okhttp3.HttpUrl
|
||||||
|
|
@ -24,17 +29,21 @@ import okhttp3.HttpUrl.Companion.toHttpUrl
|
||||||
class DefaultBugReporterUrlProvider(
|
class DefaultBugReporterUrlProvider(
|
||||||
private val bugReportAppNameProvider: BugReportAppNameProvider,
|
private val bugReportAppNameProvider: BugReportAppNameProvider,
|
||||||
private val enterpriseService: EnterpriseService,
|
private val enterpriseService: EnterpriseService,
|
||||||
|
private val sessionStore: SessionStore,
|
||||||
) : BugReporterUrlProvider {
|
) : BugReporterUrlProvider {
|
||||||
|
@OptIn(ExperimentalCoroutinesApi::class)
|
||||||
override fun provide(): Flow<HttpUrl?> {
|
override fun provide(): Flow<HttpUrl?> {
|
||||||
if (bugReportAppNameProvider.provide().isEmpty()) return flowOf(null)
|
if (bugReportAppNameProvider.provide().isEmpty()) return flowOf(null)
|
||||||
return enterpriseService.bugReportUrlFlow
|
return sessionStore.sessionIdFlow().flatMapLatest { sessionId ->
|
||||||
.map { bugReportUrl ->
|
enterpriseService.bugReportUrlFlow(sessionId?.let(::SessionId))
|
||||||
when (bugReportUrl) {
|
.map { bugReportUrl ->
|
||||||
is BugReportUrl.Custom -> bugReportUrl.url
|
when (bugReportUrl) {
|
||||||
BugReportUrl.Disabled -> null
|
is BugReportUrl.Custom -> bugReportUrl.url
|
||||||
BugReportUrl.UseDefault -> RageshakeConfig.BUG_REPORT_URL.takeIf { it.isNotEmpty() }
|
BugReportUrl.Disabled -> null
|
||||||
|
BugReportUrl.UseDefault -> RageshakeConfig.BUG_REPORT_URL.takeIf { it.isNotEmpty() }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
.map { it?.toHttpUrl() }
|
||||||
.map { it?.toHttpUrl() }
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,6 @@ android {
|
||||||
implementation(libs.androidx.compose.material3.adaptive)
|
implementation(libs.androidx.compose.material3.adaptive)
|
||||||
implementation(libs.coil.compose)
|
implementation(libs.coil.compose)
|
||||||
implementation(libs.vanniktech.blurhash)
|
implementation(libs.vanniktech.blurhash)
|
||||||
implementation(projects.features.enterprise.api)
|
|
||||||
implementation(projects.libraries.androidutils)
|
implementation(projects.libraries.androidutils)
|
||||||
implementation(projects.libraries.architecture)
|
implementation(projects.libraries.architecture)
|
||||||
implementation(projects.libraries.core)
|
implementation(projects.libraries.core)
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ import io.element.android.compound.theme.ElementTheme
|
||||||
import io.element.android.compound.theme.Theme
|
import io.element.android.compound.theme.Theme
|
||||||
import io.element.android.compound.theme.isDark
|
import io.element.android.compound.theme.isDark
|
||||||
import io.element.android.compound.theme.mapToTheme
|
import io.element.android.compound.theme.mapToTheme
|
||||||
import io.element.android.features.enterprise.api.EnterpriseService
|
import io.element.android.compound.tokens.generated.SemanticColors
|
||||||
import io.element.android.libraries.core.meta.BuildMeta
|
import io.element.android.libraries.core.meta.BuildMeta
|
||||||
import io.element.android.libraries.core.meta.BuildType
|
import io.element.android.libraries.core.meta.BuildType
|
||||||
import io.element.android.libraries.preferences.api.store.AppPreferencesStore
|
import io.element.android.libraries.preferences.api.store.AppPreferencesStore
|
||||||
|
|
@ -53,7 +53,8 @@ val LocalBuildMeta = staticCompositionLocalOf {
|
||||||
@Composable
|
@Composable
|
||||||
fun ElementThemeApp(
|
fun ElementThemeApp(
|
||||||
appPreferencesStore: AppPreferencesStore,
|
appPreferencesStore: AppPreferencesStore,
|
||||||
enterpriseService: EnterpriseService,
|
compoundLight: SemanticColors,
|
||||||
|
compoundDark: SemanticColors,
|
||||||
buildMeta: BuildMeta,
|
buildMeta: BuildMeta,
|
||||||
content: @Composable () -> Unit,
|
content: @Composable () -> Unit,
|
||||||
) {
|
) {
|
||||||
|
|
@ -70,8 +71,6 @@ fun ElementThemeApp(
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
val compoundLight by enterpriseService.semanticColorsLight()
|
|
||||||
val compoundDark by enterpriseService.semanticColorsDark()
|
|
||||||
CompositionLocalProvider(
|
CompositionLocalProvider(
|
||||||
LocalBuildMeta provides buildMeta,
|
LocalBuildMeta provides buildMeta,
|
||||||
) {
|
) {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue