Browse Source

[Architecture] : create appnav module so we can use only api feature modules

misc/jme/add-logging-to-state-machine
ganfra 2 years ago
parent
commit
a13cba9571
  1. 1
      app/build.gradle.kts
  2. 21
      app/src/main/kotlin/io/element/android/x/MainNode.kt
  3. 3
      app/src/main/kotlin/io/element/android/x/di/AppBindings.kt
  4. 2
      app/src/main/kotlin/io/element/android/x/di/MainDaggerComponentsOwner.kt
  5. 63
      app/src/main/kotlin/io/element/android/x/root/MatrixClientsHolder.kt
  6. 62
      appnav/build.gradle.kts
  7. 2
      appnav/src/main/kotlin/io/element/android/appnav/BackstackExt.kt
  8. 4
      appnav/src/main/kotlin/io/element/android/appnav/LoggedInFlowNode.kt
  9. 3
      appnav/src/main/kotlin/io/element/android/appnav/MatrixClientsHolder.kt
  10. 2
      appnav/src/main/kotlin/io/element/android/appnav/NodeLifecycleCallback.kt
  11. 2
      appnav/src/main/kotlin/io/element/android/appnav/NotLoggedInFlowNode.kt
  12. 2
      appnav/src/main/kotlin/io/element/android/appnav/RoomFlowNode.kt
  13. 20
      appnav/src/main/kotlin/io/element/android/appnav/RootFlowNode.kt
  14. 2
      appnav/src/main/kotlin/io/element/android/appnav/root/RootEvents.kt
  15. 2
      appnav/src/main/kotlin/io/element/android/appnav/root/RootPresenter.kt
  16. 3
      appnav/src/main/kotlin/io/element/android/appnav/root/RootState.kt
  17. 2
      appnav/src/main/kotlin/io/element/android/appnav/root/RootStateProvider.kt
  18. 10
      appnav/src/main/kotlin/io/element/android/appnav/root/RootView.kt
  19. 2
      appnav/src/main/kotlin/io/element/android/appnav/root/ShowkaseButton.kt
  20. 2
      appnav/src/test/kotlin/io/element/android/appnav/FakeBugReporter.kt
  21. 2
      appnav/src/test/kotlin/io/element/android/appnav/FakeCrashDataStore.kt
  22. 2
      appnav/src/test/kotlin/io/element/android/appnav/FakeRageShake.kt
  23. 2
      appnav/src/test/kotlin/io/element/android/appnav/FakeRageshakeDataStore.kt
  24. 2
      appnav/src/test/kotlin/io/element/android/appnav/FakeScreenshotHolder.kt
  25. 4
      appnav/src/test/kotlin/io/element/android/appnav/RootPresenterTest.kt
  26. 2
      settings.gradle.kts

1
app/build.gradle.kts

@ -200,6 +200,7 @@ dependencies {
allFeatures() allFeatures()
implementation(projects.tests.uitests) implementation(projects.tests.uitests)
implementation(projects.anvilannotations) implementation(projects.anvilannotations)
implementation(projects.appnav)
anvil(projects.anvilcodegen) anvil(projects.anvilcodegen)
// https://developer.android.com/studio/write/java8-support#library-desugaring-versions // https://developer.android.com/studio/write/java8-support#library-desugaring-versions

21
app/src/main/kotlin/io/element/android/x/MainNode.kt

@ -16,6 +16,7 @@
package io.element.android.x package io.element.android.x
import android.os.Parcelable
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import com.bumble.appyx.core.composable.Children import com.bumble.appyx.core.composable.Children
@ -23,25 +24,26 @@ import com.bumble.appyx.core.modality.BuildContext
import com.bumble.appyx.core.navigation.model.permanent.PermanentNavModel import com.bumble.appyx.core.navigation.model.permanent.PermanentNavModel
import com.bumble.appyx.core.node.Node import com.bumble.appyx.core.node.Node
import com.bumble.appyx.core.node.ParentNode import com.bumble.appyx.core.node.ParentNode
import io.element.android.appnav.LoggedInFlowNode
import io.element.android.appnav.RoomFlowNode
import io.element.android.appnav.RootFlowNode
import io.element.android.libraries.architecture.bindings import io.element.android.libraries.architecture.bindings
import io.element.android.libraries.architecture.createNode import io.element.android.libraries.architecture.createNode
import io.element.android.libraries.di.DaggerComponentOwner import io.element.android.libraries.di.DaggerComponentOwner
import io.element.android.libraries.matrix.MatrixClient import io.element.android.libraries.matrix.MatrixClient
import io.element.android.libraries.matrix.room.MatrixRoom import io.element.android.libraries.matrix.room.MatrixRoom
import io.element.android.x.di.MainDaggerComponentOwner import io.element.android.x.di.MainDaggerComponentsOwner
import io.element.android.x.di.RoomComponent import io.element.android.x.di.RoomComponent
import io.element.android.x.di.SessionComponent import io.element.android.x.di.SessionComponent
import io.element.android.x.node.LoggedInFlowNode import kotlinx.parcelize.Parcelize
import io.element.android.x.node.RoomFlowNode
import io.element.android.x.node.RootFlowNode
class MainNode( class MainNode(
buildContext: BuildContext, buildContext: BuildContext,
private val mainDaggerComponentOwner: MainDaggerComponentOwner, private val mainDaggerComponentOwner: MainDaggerComponentsOwner,
) : ) :
ParentNode<MainNode.NavTarget>( ParentNode<MainNode.RootNavTarget>(
navModel = PermanentNavModel( navModel = PermanentNavModel(
navTargets = setOf(NavTarget), navTargets = setOf(RootNavTarget),
savedStateMap = buildContext.savedStateMap, savedStateMap = buildContext.savedStateMap,
), ),
buildContext = buildContext, buildContext = buildContext,
@ -70,7 +72,7 @@ class MainNode(
} }
} }
override fun resolve(navTarget: NavTarget, buildContext: BuildContext): Node { override fun resolve(navTarget: RootNavTarget, buildContext: BuildContext): Node {
return createNode<RootFlowNode>(buildContext, plugins = listOf(loggedInFlowNodeCallback, roomFlowNodeCallback)) return createNode<RootFlowNode>(buildContext, plugins = listOf(loggedInFlowNodeCallback, roomFlowNodeCallback))
} }
@ -79,5 +81,6 @@ class MainNode(
Children(navModel = navModel) Children(navModel = navModel)
} }
object NavTarget @Parcelize
object RootNavTarget : Parcelable
} }

3
app/src/main/kotlin/io/element/android/x/di/AppBindings.kt

@ -17,10 +17,11 @@
package io.element.android.x.di package io.element.android.x.di
import com.squareup.anvil.annotations.ContributesTo import com.squareup.anvil.annotations.ContributesTo
import io.element.android.appnav.MatrixClientsHolder
import io.element.android.libraries.di.AppScope import io.element.android.libraries.di.AppScope
@ContributesTo(AppScope::class) @ContributesTo(AppScope::class)
interface AppBindings { interface AppBindings {
fun matrixClientsHolder(): MatrixClientsHolder fun matrixClientsHolder(): MatrixClientsHolder
fun mainDaggerComponentOwner(): MainDaggerComponentOwner fun mainDaggerComponentOwner(): MainDaggerComponentsOwner
} }

2
app/src/main/kotlin/io/element/android/x/di/MainDaggerComponentOwner.kt → app/src/main/kotlin/io/element/android/x/di/MainDaggerComponentsOwner.kt

@ -24,7 +24,7 @@ import io.element.android.libraries.di.SingleIn
import javax.inject.Inject import javax.inject.Inject
@SingleIn(AppScope::class) @SingleIn(AppScope::class)
class MainDaggerComponentOwner @Inject constructor(@ApplicationContext context: Context) : DaggerComponentOwner { class MainDaggerComponentsOwner @Inject constructor(@ApplicationContext context: Context) : DaggerComponentOwner {
private val daggerComponents = LinkedHashMap<String, Any>().apply { private val daggerComponents = LinkedHashMap<String, Any>().apply {
put("app", (context as DaggerComponentOwner).daggerComponent) put("app", (context as DaggerComponentOwner).daggerComponent)

63
app/src/main/kotlin/io/element/android/x/root/MatrixClientsHolder.kt

@ -1,63 +0,0 @@
package io.element.android.x.root
import android.os.Bundle
import io.element.android.libraries.di.AppScope
import io.element.android.libraries.di.SingleIn
import io.element.android.libraries.matrix.MatrixClient
import io.element.android.libraries.matrix.auth.MatrixAuthenticationService
import io.element.android.libraries.matrix.core.SessionId
import kotlinx.coroutines.runBlocking
import timber.log.Timber
import java.util.concurrent.ConcurrentHashMap
import javax.inject.Inject
private const val SAVE_INSTANCE_KEY = "io.element.android.x.di.MatrixClientsHolder.SaveInstanceKey"
@SingleIn(AppScope::class)
class MatrixClientsHolder @Inject constructor(private val authenticationService: MatrixAuthenticationService) {
private val sessionIdsToMatrixClient = ConcurrentHashMap<SessionId, MatrixClient>()
fun add(matrixClient: MatrixClient) {
sessionIdsToMatrixClient[matrixClient.sessionId] = matrixClient
}
fun removeAll() {
sessionIdsToMatrixClient.clear()
}
fun remove(sessionId: SessionId) {
sessionIdsToMatrixClient.remove(sessionId)
}
fun isEmpty(): Boolean = sessionIdsToMatrixClient.isEmpty()
fun knowSession(sessionId: SessionId): Boolean = sessionIdsToMatrixClient.containsKey(sessionId)
fun getOrNull(sessionId: SessionId): MatrixClient? {
return sessionIdsToMatrixClient[sessionId]
}
@Suppress("DEPRECATION")
fun restore(savedInstanceState: Bundle?) {
if (savedInstanceState == null || sessionIdsToMatrixClient.isNotEmpty()) return
val sessionIds = savedInstanceState.getSerializable(SAVE_INSTANCE_KEY) as? Array<SessionId>
if (sessionIds.isNullOrEmpty()) return
// Not ideal but should only happens in case of process recreation. This ensure we restore all the active sessions before restoring the node graphs.
runBlocking {
sessionIds.forEach { sessionId ->
Timber.v("Restore matrix session: $sessionId")
val matrixClient = authenticationService.restoreSession(sessionId)
if (matrixClient != null) {
add(matrixClient)
}
}
}
}
fun onSaveInstanceState(outState: Bundle) {
val sessionKeys = sessionIdsToMatrixClient.keys.toTypedArray()
Timber.v("Save matrix session keys = $sessionKeys")
outState.putSerializable(SAVE_INSTANCE_KEY, sessionKeys)
}
}

62
appnav/build.gradle.kts

@ -0,0 +1,62 @@
/*
* Copyright (c) 2022 New Vector Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
@file:Suppress("UnstableApiUsage")
// TODO: Remove once https://youtrack.jetbrains.com/issue/KTIJ-19369 is fixed
@Suppress("DSL_SCOPE_VIOLATION")
plugins {
id("io.element.android-compose-library")
alias(libs.plugins.anvil)
alias(libs.plugins.ksp)
alias(libs.plugins.kapt)
id("kotlin-parcelize")
}
android {
namespace = "io.element.android.appnav"
}
dependencies {
implementation(projects.anvilannotations)
anvil(projects.anvilcodegen)
implementation(libs.dagger)
kapt(libs.dagger.compiler)
implementation(projects.features.messages.api)
implementation(projects.features.roomlist)
implementation(projects.features.rageshake)
implementation(projects.features.login)
implementation(projects.features.preferences)
implementation(projects.features.logout)
implementation(projects.features.onboarding)
implementation(projects.libraries.core)
implementation(projects.libraries.architecture)
implementation(projects.libraries.matrix)
implementation(projects.libraries.designsystem)
implementation(projects.libraries.matrixui)
implementation(projects.tests.uitests)
implementation(libs.coil)
testImplementation(libs.test.junit)
testImplementation(libs.coroutines.test)
testImplementation(libs.molecule.runtime)
testImplementation(libs.test.truth)
testImplementation(libs.test.turbine)
testImplementation(projects.libraries.matrixtest)
}

2
app/src/main/kotlin/io/element/android/x/node/BackstackExt.kt → appnav/src/main/kotlin/io/element/android/appnav/BackstackExt.kt

@ -14,7 +14,7 @@
* limitations under the License. * limitations under the License.
*/ */
package io.element.android.x.node package io.element.android.appnav
import com.bumble.appyx.navmodel.backstack.BackStack import com.bumble.appyx.navmodel.backstack.BackStack
import com.bumble.appyx.navmodel.backstack.operation.NewRoot import com.bumble.appyx.navmodel.backstack.operation.NewRoot

4
app/src/main/kotlin/io/element/android/x/node/LoggedInFlowNode.kt → appnav/src/main/kotlin/io/element/android/appnav/LoggedInFlowNode.kt

@ -14,7 +14,7 @@
* limitations under the License. * limitations under the License.
*/ */
package io.element.android.x.node package io.element.android.appnav
import android.os.Parcelable import android.os.Parcelable
import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Box
@ -92,9 +92,9 @@ class LoggedInFlowNode @AssistedInject constructor(
inputs.matrixClient.startSync() inputs.matrixClient.startSync()
}, },
onDestroy = { onDestroy = {
plugins<LifecycleCallback>().forEach { it.onFlowReleased(inputs.matrixClient) }
val imageLoaderFactory = bindings<MatrixUIBindings>().notLoggedInImageLoaderFactory() val imageLoaderFactory = bindings<MatrixUIBindings>().notLoggedInImageLoaderFactory()
Coil.setImageLoader(imageLoaderFactory) Coil.setImageLoader(imageLoaderFactory)
plugins<LifecycleCallback>().forEach { it.onFlowReleased(inputs.matrixClient) }
} }
) )
} }

3
app/src/main/kotlin/io/element/android/x/di/MatrixClientsHolder.kt → appnav/src/main/kotlin/io/element/android/appnav/MatrixClientsHolder.kt

@ -14,7 +14,7 @@
* limitations under the License. * limitations under the License.
*/ */
package io.element.android.x.di package io.element.android.appnav
import android.os.Bundle import android.os.Bundle
import io.element.android.libraries.di.AppScope import io.element.android.libraries.di.AppScope
@ -28,6 +28,7 @@ import java.util.concurrent.ConcurrentHashMap
import javax.inject.Inject import javax.inject.Inject
private const val SAVE_INSTANCE_KEY = "io.element.android.x.di.MatrixClientsHolder.SaveInstanceKey" private const val SAVE_INSTANCE_KEY = "io.element.android.x.di.MatrixClientsHolder.SaveInstanceKey"
@SingleIn(AppScope::class) @SingleIn(AppScope::class)
class MatrixClientsHolder @Inject constructor(private val authenticationService: MatrixAuthenticationService) { class MatrixClientsHolder @Inject constructor(private val authenticationService: MatrixAuthenticationService) {

2
app/src/main/kotlin/io/element/android/x/node/NodeLifecycleCallback.kt → appnav/src/main/kotlin/io/element/android/appnav/NodeLifecycleCallback.kt

@ -14,7 +14,7 @@
* limitations under the License. * limitations under the License.
*/ */
package io.element.android.x.node package io.element.android.appnav
import com.bumble.appyx.core.plugin.Plugin import com.bumble.appyx.core.plugin.Plugin

2
app/src/main/kotlin/io/element/android/x/node/NotLoggedInFlowNode.kt → appnav/src/main/kotlin/io/element/android/appnav/NotLoggedInFlowNode.kt

@ -14,7 +14,7 @@
* limitations under the License. * limitations under the License.
*/ */
package io.element.android.x.node package io.element.android.appnav
import android.os.Parcelable import android.os.Parcelable
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable

2
app/src/main/kotlin/io/element/android/x/node/RoomFlowNode.kt → appnav/src/main/kotlin/io/element/android/appnav/RoomFlowNode.kt

@ -14,7 +14,7 @@
* limitations under the License. * limitations under the License.
*/ */
package io.element.android.x.node package io.element.android.appnav
import android.os.Parcelable import android.os.Parcelable
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable

20
app/src/main/kotlin/io/element/android/x/node/RootFlowNode.kt → appnav/src/main/kotlin/io/element/android/appnav/RootFlowNode.kt

@ -14,14 +14,17 @@
* limitations under the License. * limitations under the License.
*/ */
package io.element.android.x.node package io.element.android.appnav
import android.app.Activity
import android.content.Context
import android.os.Parcelable import android.os.Parcelable
import androidx.compose.foundation.layout.Box 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.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import com.bumble.appyx.core.composable.Children import com.bumble.appyx.core.composable.Children
import com.bumble.appyx.core.modality.BuildContext import com.bumble.appyx.core.modality.BuildContext
@ -36,6 +39,8 @@ import com.bumble.appyx.navmodel.backstack.operation.push
import dagger.assisted.Assisted import dagger.assisted.Assisted
import dagger.assisted.AssistedInject import dagger.assisted.AssistedInject
import io.element.android.anvilannotations.ContributesNode import io.element.android.anvilannotations.ContributesNode
import io.element.android.appnav.root.RootPresenter
import io.element.android.appnav.root.RootView
import io.element.android.features.rageshake.bugreport.BugReportEntryPoint import io.element.android.features.rageshake.bugreport.BugReportEntryPoint
import io.element.android.libraries.architecture.BackstackNode import io.element.android.libraries.architecture.BackstackNode
import io.element.android.libraries.architecture.animation.rememberDefaultTransitionHandler import io.element.android.libraries.architecture.animation.rememberDefaultTransitionHandler
@ -43,11 +48,10 @@ import io.element.android.libraries.architecture.createNode
import io.element.android.libraries.architecture.nodeInputsProvider import io.element.android.libraries.architecture.nodeInputsProvider
import io.element.android.libraries.designsystem.theme.components.CircularProgressIndicator import io.element.android.libraries.designsystem.theme.components.CircularProgressIndicator
import io.element.android.libraries.di.AppScope import io.element.android.libraries.di.AppScope
import io.element.android.libraries.di.ApplicationContext
import io.element.android.libraries.matrix.auth.MatrixAuthenticationService import io.element.android.libraries.matrix.auth.MatrixAuthenticationService
import io.element.android.libraries.matrix.core.SessionId import io.element.android.libraries.matrix.core.SessionId
import io.element.android.x.root.MatrixClientsHolder import io.element.android.tests.uitests.openShowkase
import io.element.android.x.root.RootPresenter
import io.element.android.x.root.RootView
import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.onEach
@ -56,8 +60,9 @@ import timber.log.Timber
@ContributesNode(AppScope::class) @ContributesNode(AppScope::class)
class RootFlowNode @AssistedInject constructor( class RootFlowNode @AssistedInject constructor(
@Assisted buildContext: BuildContext, @Assisted val buildContext: BuildContext,
@Assisted plugins: List<Plugin>, @Assisted plugins: List<Plugin>,
@ApplicationContext private val appContext: Context,
private val authenticationService: MatrixAuthenticationService, private val authenticationService: MatrixAuthenticationService,
private val matrixClientsHolder: MatrixClientsHolder, private val matrixClientsHolder: MatrixClientsHolder,
private val presenter: RootPresenter, private val presenter: RootPresenter,
@ -132,11 +137,16 @@ class RootFlowNode @AssistedInject constructor(
@Composable @Composable
override fun View(modifier: Modifier) { override fun View(modifier: Modifier) {
val activity = LocalContext.current as Activity
fun openShowkase() {
openShowkase(activity)
}
val state = presenter.present() val state = presenter.present()
RootView( RootView(
state = state, state = state,
modifier = modifier, modifier = modifier,
onOpenBugReport = this::onOpenBugReport, onOpenBugReport = this::onOpenBugReport,
onOpenShowkase = ::openShowkase
) { ) {
Children( Children(
navModel = backstack, navModel = backstack,

2
app/src/main/kotlin/io/element/android/x/root/RootEvents.kt → appnav/src/main/kotlin/io/element/android/appnav/root/RootEvents.kt

@ -14,7 +14,7 @@
* limitations under the License. * limitations under the License.
*/ */
package io.element.android.x.root package io.element.android.appnav.root
sealed interface RootEvents { sealed interface RootEvents {
object HideShowkaseButton : RootEvents object HideShowkaseButton : RootEvents

2
app/src/main/kotlin/io/element/android/x/root/RootPresenter.kt → appnav/src/main/kotlin/io/element/android/appnav/root/RootPresenter.kt

@ -14,7 +14,7 @@
* limitations under the License. * limitations under the License.
*/ */
package io.element.android.x.root package io.element.android.appnav.root
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf

3
app/src/main/kotlin/io/element/android/x/root/RootState.kt → appnav/src/main/kotlin/io/element/android/appnav/root/RootState.kt

@ -14,9 +14,10 @@
* limitations under the License. * limitations under the License.
*/ */
package io.element.android.x.root package io.element.android.appnav.root
import androidx.compose.runtime.Stable import androidx.compose.runtime.Stable
import io.element.android.appnav.root.RootEvents
import io.element.android.features.rageshake.crash.ui.CrashDetectionState import io.element.android.features.rageshake.crash.ui.CrashDetectionState
import io.element.android.features.rageshake.detection.RageshakeDetectionState import io.element.android.features.rageshake.detection.RageshakeDetectionState

2
app/src/main/kotlin/io/element/android/x/root/RootStateProvider.kt → appnav/src/main/kotlin/io/element/android/appnav/root/RootStateProvider.kt

@ -14,7 +14,7 @@
* limitations under the License. * limitations under the License.
*/ */
package io.element.android.x.root package io.element.android.appnav.root
import androidx.compose.ui.tooling.preview.PreviewParameterProvider import androidx.compose.ui.tooling.preview.PreviewParameterProvider
import io.element.android.features.rageshake.crash.ui.aCrashDetectionState import io.element.android.features.rageshake.crash.ui.aCrashDetectionState

10
app/src/main/kotlin/io/element/android/x/root/RootView.kt → appnav/src/main/kotlin/io/element/android/appnav/root/RootView.kt

@ -14,16 +14,14 @@
* limitations under the License. * limitations under the License.
*/ */
package io.element.android.x.root package io.element.android.appnav.root
import android.app.Activity
import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.BoxScope import androidx.compose.foundation.layout.BoxScope
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.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.tooling.preview.PreviewParameter
import io.element.android.features.rageshake.crash.ui.CrashDetectionEvents import io.element.android.features.rageshake.crash.ui.CrashDetectionEvents
@ -33,14 +31,13 @@ import io.element.android.features.rageshake.detection.RageshakeDetectionView
import io.element.android.libraries.designsystem.preview.ElementPreviewDark import io.element.android.libraries.designsystem.preview.ElementPreviewDark
import io.element.android.libraries.designsystem.preview.ElementPreviewLight import io.element.android.libraries.designsystem.preview.ElementPreviewLight
import io.element.android.libraries.designsystem.theme.components.Text import io.element.android.libraries.designsystem.theme.components.Text
import io.element.android.tests.uitests.openShowkase
import io.element.android.x.component.ShowkaseButton
@Composable @Composable
fun RootView( fun RootView(
state: RootState, state: RootState,
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
onOpenBugReport: () -> Unit = {}, onOpenBugReport: () -> Unit = {},
onOpenShowkase: () -> Unit = {},
children: @Composable BoxScope.() -> Unit, children: @Composable BoxScope.() -> Unit,
) { ) {
Box( Box(
@ -50,7 +47,6 @@ fun RootView(
) { ) {
children() children()
val eventSink = state.eventSink val eventSink = state.eventSink
val context = LocalContext.current
fun onOpenBugReport() { fun onOpenBugReport() {
state.crashDetectionState.eventSink(CrashDetectionEvents.ResetAppHasCrashed) state.crashDetectionState.eventSink(CrashDetectionEvents.ResetAppHasCrashed)
@ -61,7 +57,7 @@ fun RootView(
ShowkaseButton( ShowkaseButton(
isVisible = state.isShowkaseButtonVisible, isVisible = state.isShowkaseButtonVisible,
onCloseClicked = { eventSink(RootEvents.HideShowkaseButton) }, onCloseClicked = { eventSink(RootEvents.HideShowkaseButton) },
onClick = { openShowkase(context as Activity) } onClick = onOpenShowkase
) )
RageshakeDetectionView( RageshakeDetectionView(
state = state.rageshakeDetectionState, state = state.rageshakeDetectionState,

2
app/src/main/kotlin/io/element/android/x/component/ShowkaseButton.kt → appnav/src/main/kotlin/io/element/android/appnav/root/ShowkaseButton.kt

@ -14,7 +14,7 @@
* limitations under the License. * limitations under the License.
*/ */
package io.element.android.x.component package io.element.android.appnav.root
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.size

2
app/src/test/kotlin/io/element/android/x/root/FakeBugReporter.kt → appnav/src/test/kotlin/io/element/android/appnav/FakeBugReporter.kt

@ -14,7 +14,7 @@
* limitations under the License. * limitations under the License.
*/ */
package io.element.android.x.root package io.element.android.appnav
import io.element.android.features.rageshake.reporter.BugReporter import io.element.android.features.rageshake.reporter.BugReporter
import io.element.android.features.rageshake.reporter.BugReporterListener import io.element.android.features.rageshake.reporter.BugReporterListener

2
app/src/test/kotlin/io/element/android/x/root/FakeCrashDataStore.kt → appnav/src/test/kotlin/io/element/android/appnav/FakeCrashDataStore.kt

@ -14,7 +14,7 @@
* limitations under the License. * limitations under the License.
*/ */
package io.element.android.x.root package io.element.android.appnav
import io.element.android.features.rageshake.crash.CrashDataStore import io.element.android.features.rageshake.crash.CrashDataStore
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow

2
app/src/test/kotlin/io/element/android/x/root/FakeRageShake.kt → appnav/src/test/kotlin/io/element/android/appnav/FakeRageShake.kt

@ -14,7 +14,7 @@
* limitations under the License. * limitations under the License.
*/ */
package io.element.android.x.root package io.element.android.appnav
import io.element.android.features.rageshake.rageshake.RageShake import io.element.android.features.rageshake.rageshake.RageShake

2
app/src/test/kotlin/io/element/android/x/root/FakeRageshakeDataStore.kt → appnav/src/test/kotlin/io/element/android/appnav/FakeRageshakeDataStore.kt

@ -14,7 +14,7 @@
* limitations under the License. * limitations under the License.
*/ */
package io.element.android.x.root package io.element.android.appnav
import io.element.android.features.rageshake.rageshake.RageshakeDataStore import io.element.android.features.rageshake.rageshake.RageshakeDataStore
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow

2
app/src/test/kotlin/io/element/android/x/root/FakeScreenshotHolder.kt → appnav/src/test/kotlin/io/element/android/appnav/FakeScreenshotHolder.kt

@ -14,7 +14,7 @@
* limitations under the License. * limitations under the License.
*/ */
package io.element.android.x.root package io.element.android.appnav
import android.graphics.Bitmap import android.graphics.Bitmap
import io.element.android.features.rageshake.screenshot.ScreenshotHolder import io.element.android.features.rageshake.screenshot.ScreenshotHolder

4
app/src/test/kotlin/io/element/android/x/root/RootPresenterTest.kt → appnav/src/test/kotlin/io/element/android/appnav/RootPresenterTest.kt

@ -16,12 +16,14 @@
@file:OptIn(ExperimentalCoroutinesApi::class) @file:OptIn(ExperimentalCoroutinesApi::class)
package io.element.android.x.root package io.element.android.appnav
import app.cash.molecule.RecompositionClock import app.cash.molecule.RecompositionClock
import app.cash.molecule.moleculeFlow import app.cash.molecule.moleculeFlow
import app.cash.turbine.test import app.cash.turbine.test
import com.google.common.truth.Truth.assertThat import com.google.common.truth.Truth.assertThat
import io.element.android.appnav.root.RootEvents
import io.element.android.appnav.root.RootPresenter
import io.element.android.features.rageshake.crash.ui.CrashDetectionPresenter import io.element.android.features.rageshake.crash.ui.CrashDetectionPresenter
import io.element.android.features.rageshake.detection.RageshakeDetectionPresenter import io.element.android.features.rageshake.detection.RageshakeDetectionPresenter
import io.element.android.features.rageshake.preferences.RageshakePreferencesPresenter import io.element.android.features.rageshake.preferences.RageshakePreferencesPresenter

2
settings.gradle.kts

@ -37,6 +37,7 @@ enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS")
rootProject.name = "ElementX" rootProject.name = "ElementX"
include(":app") include(":app")
include(":appnav")
include(":libraries:core") include(":libraries:core")
include(":libraries:rustsdk") include(":libraries:rustsdk")
include(":libraries:matrix") include(":libraries:matrix")
@ -65,4 +66,3 @@ include(":libraries:androidutils")
include(":samples:minimal") include(":samples:minimal")
include(":features:messages:api") include(":features:messages:api")
include(":features:messages:impl") include(":features:messages:impl")
include(":appnav")

Loading…
Cancel
Save