package com.pixelized.rplexicon import android.app.Activity import android.os.Bundle import androidx.activity.ComponentActivity import androidx.activity.compose.BackHandler import androidx.activity.compose.setContent import androidx.activity.viewModels import androidx.compose.foundation.layout.WindowInsets import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.navigationBarsPadding import androidx.compose.foundation.layout.padding import androidx.compose.foundation.shape.CutCornerShape import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Scaffold import androidx.compose.material3.Snackbar import androidx.compose.material3.SnackbarHost import androidx.compose.material3.SnackbarHostState import androidx.compose.material3.Surface import androidx.compose.material3.Text import androidx.compose.material3.TextButton import androidx.compose.material3.surfaceColorAtElevation import androidx.compose.runtime.Composable import androidx.compose.runtime.CompositionLocalProvider import androidx.compose.runtime.compositionLocalOf import androidx.compose.runtime.derivedStateOf import androidx.compose.runtime.remember import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen import androidx.core.view.WindowCompat import com.pixelized.rplexicon.ui.composable.BlurredOverlayHost import com.pixelized.rplexicon.ui.composable.error.HandleFetchError import com.pixelized.rplexicon.ui.navigation.ScreenNavHost import com.pixelized.rplexicon.ui.screens.rolls.BlurredRollOverlayHostState import com.pixelized.rplexicon.ui.screens.rolls.RollOverlay import com.pixelized.rplexicon.ui.screens.rolls.RollOverlayViewModel import com.pixelized.rplexicon.ui.screens.rolls.rememberBlurredRollOverlayHostState import com.pixelized.rplexicon.ui.theme.LexiconTheme import com.pixelized.rplexicon.utilitary.extentions.modifier.ddBorder import dagger.hilt.android.AndroidEntryPoint val NO_WINDOW_INSETS = WindowInsets(0, 0, 0, 0) val LocalActivity = compositionLocalOf { error("Activity not available") } val LocalSnack = compositionLocalOf { error("SnackbarHostState not available") } val LocalRollOverlay = compositionLocalOf { error("LocalRollOverlay not yet ready") } @AndroidEntryPoint class MainActivity : ComponentActivity() { private val themeViewModel: ThemeViewModel by viewModels() private val launcherViewModel: LauncherViewModel by viewModels() private val rollViewModel: RollOverlayViewModel by viewModels() override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // Disable system inset consuming. WindowCompat.setDecorFitsSystemWindows(window, false) // splashscreen management installSplashScreen().apply { setKeepOnScreenCondition { launcherViewModel.isLoading } } setContent { val snack = remember { SnackbarHostState() } val overlay = rememberBlurredRollOverlayHostState( viewModel = rollViewModel, ) CompositionLocalProvider( LocalActivity provides this, LocalSnack provides snack, LocalRollOverlay provides overlay, ) { LexiconTheme( isDarkTheme = themeViewModel.useDarkTheme.value ) { Scaffold( contentWindowInsets = NO_WINDOW_INSETS, content = { padding -> Surface( modifier = Modifier .fillMaxSize() .padding(paddingValues = padding), color = MaterialTheme.colorScheme.background ) { BlurredOverlayHost( rollOverlayState = overlay, overlay = { RollOverlay( viewModel = rollViewModel, ) }, content = { ScreenNavHost() }, ) } }, snackbarHost = { val isDarkTheme = themeViewModel.useDarkTheme.value val elevation = remember { derivedStateOf { if (isDarkTheme) 2.dp else 0.dp } } SnackbarHost( modifier = Modifier.navigationBarsPadding(), hostState = LocalSnack.current, ) { val actionComposable: (@Composable () -> Unit)? = it.visuals.actionLabel?.let { actionLabel -> @Composable { TextButton( onClick = { it.performAction() }, content = { Text(actionLabel) } ) } } Snackbar( modifier = Modifier .padding(horizontal = 16.dp) .ddBorder( inner = remember { RoundedCornerShape(size = 8.dp) }, outline = remember { CutCornerShape(size = 16.dp) }, ), containerColor = MaterialTheme.colorScheme.surfaceColorAtElevation( elevation = elevation.value ), action = actionComposable, content = { Text( modifier = Modifier.padding(vertical = 8.dp), color = MaterialTheme.colorScheme.onSurface, text = it.visuals.message, ) } ) } } ) BackHandler( enabled = overlay.isOverlayVisible, onBack = { overlay.hideOverlay() }, ) HandleFetchError( snack = snack, errors = launcherViewModel.error, ) } } } } }