element-x-ada/app/src/main/kotlin/io/element/android/x/MainActivity.kt
ganfra 6832b1f2db
Feature/fga/biometric unlock (#1702)
* Biometric unlock : refactor a bit existing classes

* Biometric unlock : first implementation

* Biometric: add ui for biometric setup

* Biometric unlock : use localazy strings

* Biometric unlock setup : branch skip/allow events

* Biometric : fix tests

* Biometrics: add small test

* Biometric : clean up

* Update screenshots

* Biometric unlock : address some PR review

* Biometric : improve a bit edge cases

* Fix lint issues

---------

Co-authored-by: ganfra <francoisg@element.io>
Co-authored-by: ElementBot <benoitm+elementbot@element.io>
Co-authored-by: Jorge Martín <jorgem@element.io>
2023-10-31 19:22:43 +01:00

127 lines
4.6 KiB
Kotlin

/*
* 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.
*/
package io.element.android.x
import android.content.Intent
import android.os.Bundle
import androidx.activity.compose.setContent
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalUriHandler
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
import androidx.core.view.WindowCompat
import com.bumble.appyx.core.integration.NodeHost
import com.bumble.appyx.core.integrationpoint.NodeActivity
import com.bumble.appyx.core.plugin.NodeReadyObserver
import io.element.android.libraries.architecture.bindings
import io.element.android.libraries.core.log.logger.LoggerTag
import io.element.android.libraries.designsystem.utils.snackbar.LocalSnackbarDispatcher
import io.element.android.libraries.theme.ElementTheme
import io.element.android.x.di.AppBindings
import io.element.android.x.intent.SafeUriHandler
import timber.log.Timber
private val loggerTag = LoggerTag("MainActivity")
class MainActivity : NodeActivity() {
private lateinit var mainNode: MainNode
private lateinit var appBindings: AppBindings
override fun onCreate(savedInstanceState: Bundle?) {
Timber.tag(loggerTag.value).w("onCreate, with savedInstanceState: ${savedInstanceState != null}")
installSplashScreen()
super.onCreate(savedInstanceState)
appBindings = bindings()
WindowCompat.setDecorFitsSystemWindows(window, false)
setContent {
MainContent(appBindings)
}
}
@Composable
private fun MainContent(appBindings: AppBindings) {
ElementTheme {
CompositionLocalProvider(
LocalSnackbarDispatcher provides appBindings.snackbarDispatcher(),
LocalUriHandler provides SafeUriHandler(this),
) {
Box(
modifier = Modifier
.fillMaxSize()
.background(MaterialTheme.colorScheme.background),
) {
NodeHost(integrationPoint = appyxIntegrationPoint) {
MainNode(
it,
plugins = listOf(
object : NodeReadyObserver<MainNode> {
override fun init(node: MainNode) {
Timber.tag(loggerTag.value).w("onMainNodeInit")
mainNode = node
mainNode.handleIntent(intent)
}
}
),
context = applicationContext
)
}
}
}
}
}
/**
* Called when:
* - the launcher icon is clicked (if the app is already running);
* - a notification is clicked.
* - the app is going to background (<- this is strange)
*/
override fun onNewIntent(intent: Intent) {
super.onNewIntent(intent)
Timber.tag(loggerTag.value).w("onNewIntent")
// If the mainNode is not init yet, keep the intent for later.
// It can happen when the activity is killed by the system. The methods are called in this order :
// onCreate(savedInstanceState=true) -> onNewIntent -> onResume -> onMainNodeInit
if (::mainNode.isInitialized) {
mainNode.handleIntent(intent)
} else {
setIntent(intent)
}
}
override fun onPause() {
super.onPause()
Timber.tag(loggerTag.value).w("onPause")
}
override fun onResume() {
super.onResume()
Timber.tag(loggerTag.value).w("onResume")
}
override fun onDestroy() {
super.onDestroy()
Timber.tag(loggerTag.value).w("onDestroy")
}
}