package com.peachpasswords import android.content.res.Configuration import android.graphics.Color as AndroidColor import android.graphics.drawable.ColorDrawable import android.os.Bundle import android.view.WindowManager import androidx.activity.compose.setContent import androidx.activity.enableEdgeToEdge import androidx.compose.foundation.isSystemInDarkTheme import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen import androidx.fragment.app.FragmentActivity import dagger.hilt.android.AndroidEntryPoint import javax.inject.Inject import com.peachpasswords.ui.PeachAppNavHost import com.peachpasswords.ui.onboarding.ONBOARD_KEY import com.peachpasswords.ui.onboarding.ONBOARD_PREFS import com.peachpasswords.ui.onboarding.onboardingStartDestination import com.peachpasswords.ui.theme.ACCENT_COLORS import com.peachpasswords.ui.theme.DEFAULT_ACCENT import com.peachpasswords.ui.theme.PeachTheme import com.peachpasswords.vault.VaultLockTimer import com.peachpasswords.vault.VaultRepository // FragmentActivity (not ComponentActivity) so androidx BiometricPrompt can attach. @AndroidEntryPoint class MainActivity : FragmentActivity() { @Inject lateinit var vault: VaultRepository @Inject lateinit var lockTimer: VaultLockTimer // Every touch/key event resets the idle auto-lock countdown (CF-1). override fun onUserInteraction() { super.onUserInteraction() lockTimer.poke() } override fun onCreate(savedInstanceState: Bundle?) { installSplashScreen() super.onCreate(savedInstanceState) // Match the splash/window fill to the resolved theme's --bg so launch // never flashes the wrong colour before Compose draws. Resolved from the // persisted setting synchronously (system mode reads the device night mode). val initialTheme = vault.settings.value.theme val initialDark = when (initialTheme) { "light" -> false "system" -> (resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK) == Configuration.UI_MODE_NIGHT_YES else -> true } window.setBackgroundDrawable( ColorDrawable(AndroidColor.parseColor(if (initialDark) "#0C0A06" else "#EFEEE9")), ) enableEdgeToEdge() // Block screenshots / recents thumbnails of the vault in release builds. if (!BuildConfig.DEBUG) { window.setFlags( WindowManager.LayoutParams.FLAG_SECURE, WindowManager.LayoutParams.FLAG_SECURE, ) } // Onboarding runs once, only on a fresh install with no vault yet. val onboarded = getSharedPreferences(ONBOARD_PREFS, MODE_PRIVATE) .getBoolean(ONBOARD_KEY, false) val start = onboardingStartDestination(hasVault = vault.hasVault(), onboarded = onboarded) setContent { val settings by vault.settings.collectAsState() val darkTheme = when (settings.theme) { "light" -> false "system" -> isSystemInDarkTheme() else -> true } val accent = ACCENT_COLORS[settings.accentColor] ?: DEFAULT_ACCENT PeachTheme( darkTheme = darkTheme, accent = accent, reduceMotion = settings.reduceMotion, ) { PeachAppNavHost(startDestination = start, isUnlocked = vault.isUnlocked) } } } }