MainActivity: extract code from onCreate

This commit is contained in:
Pierre-Yves Nicolas
2025-11-26 21:03:35 +01:00
parent 4b103c6aea
commit 156924a8ee

View File

@@ -17,6 +17,7 @@ package org.fairscan.app
import android.Manifest import android.Manifest
import android.content.ActivityNotFoundException import android.content.ActivityNotFoundException
import android.content.ClipData import android.content.ClipData
import android.content.Context
import android.content.Intent import android.content.Intent
import android.content.pm.PackageManager import android.content.pm.PackageManager
import android.content.pm.PackageManager.PERMISSION_GRANTED import android.content.pm.PackageManager.PERMISSION_GRANTED
@@ -33,6 +34,7 @@ import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge import androidx.activity.enableEdgeToEdge
import androidx.activity.result.contract.ActivityResultContracts import androidx.activity.result.contract.ActivityResultContracts
import androidx.activity.viewModels import androidx.activity.viewModels
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.ui.platform.LocalClipboard import androidx.compose.ui.platform.LocalClipboard
@@ -86,68 +88,17 @@ class MainActivity : ComponentActivity() {
} }
enableEdgeToEdge() enableEdgeToEdge()
setContent { setContent {
LaunchedEffect(Unit) {
cameraViewModel.events.collect { event ->
when (event) {
is CameraEvent.ImageCaptured -> viewModel.handleImageCaptured(event.jpegBytes)
}
}
}
val context = LocalContext.current val context = LocalContext.current
val currentScreen by viewModel.currentScreen.collectAsStateWithLifecycle() val currentScreen by viewModel.currentScreen.collectAsStateWithLifecycle()
val liveAnalysisState by cameraViewModel.liveAnalysisState.collectAsStateWithLifecycle() val liveAnalysisState by cameraViewModel.liveAnalysisState.collectAsStateWithLifecycle()
val document by viewModel.documentUiModel.collectAsStateWithLifecycle() val document by viewModel.documentUiModel.collectAsStateWithLifecycle()
val cameraPermission = rememberCameraPermissionState() val cameraPermission = rememberCameraPermissionState()
val storagePermissionLauncher = rememberLauncherForActivityResult( CollectCameraEvents(cameraViewModel, viewModel)
ActivityResultContracts.RequestPermission() CollectExportEvents(context, exportViewModel, homeViewModel)
) { isGranted -> CollectAboutEvents(context, aboutViewModel)
if (isGranted) {
exportViewModel.onSavePdfClicked()
} else {
val message = getString(R.string.storage_permission_denied)
Toast.makeText(context, message, Toast.LENGTH_SHORT).show()
}
}
LaunchedEffect(Unit) {
exportViewModel.events.collect { event ->
when (event) {
ExportEvent.RequestSavePdf -> {
checkPermissionThen(storagePermissionLauncher) {
exportViewModel.onRequestPdfSave(context, homeViewModel)
}
}
is ExportEvent.SaveError -> {
val text = getString(R.string.error_save)
Toast.makeText(context, text, Toast.LENGTH_SHORT).show()
}
}
}
}
val clipboard = LocalClipboard.current
val msgCopiedLogs = stringResource(R.string.copied_logs)
LaunchedEffect(aboutViewModel.events) {
aboutViewModel.events.collect { event ->
when (event) {
is AboutEvent.CopyLogs -> {
clipboard.setClipEntry(
ClipData.newPlainText("FairScan logs", event.logs).toClipEntry()
)
Toast.makeText(context, msgCopiedLogs, Toast.LENGTH_SHORT).show()
}
}
}
}
FairScanTheme { FairScanTheme {
val navigation = Navigation( val navigation = navigation(viewModel)
toHomeScreen = { viewModel.navigateTo(Screen.Main.Home) },
toCameraScreen = { viewModel.navigateTo(Screen.Main.Camera) },
toDocumentScreen = { viewModel.navigateTo(Screen.Main.Document()) },
toExportScreen = { viewModel.navigateTo(Screen.Main.Export) },
toAboutScreen = { viewModel.navigateTo(Screen.Overlay.About) },
toLibrariesScreen = { viewModel.navigateTo(Screen.Overlay.Libraries) },
back = { viewModel.navigateBack() }
)
when (val screen = currentScreen) { when (val screen = currentScreen) {
is Screen.Main.Home -> { is Screen.Main.Home -> {
val recentDocs by homeViewModel.recentDocuments.collectAsStateWithLifecycle() val recentDocs by homeViewModel.recentDocuments.collectAsStateWithLifecycle()
@@ -212,6 +163,75 @@ class MainActivity : ComponentActivity() {
} }
} }
@Composable
private fun CollectAboutEvents(
context: Context,
aboutViewModel: AboutViewModel,
) {
val clipboard = LocalClipboard.current
val msgCopiedLogs = stringResource(R.string.copied_logs)
LaunchedEffect(Unit) {
aboutViewModel.events.collect { event ->
when (event) {
is AboutEvent.CopyLogs -> {
clipboard.setClipEntry(
ClipData.newPlainText("FairScan logs", event.logs).toClipEntry()
)
Toast.makeText(context, msgCopiedLogs, Toast.LENGTH_SHORT).show()
}
}
}
}
}
@Composable
private fun CollectExportEvents(
context: Context,
exportViewModel: ExportViewModel,
homeViewModel: HomeViewModel,
) {
val storagePermissionLauncher = rememberLauncherForActivityResult(
ActivityResultContracts.RequestPermission()
) { isGranted ->
if (isGranted) {
exportViewModel.onSavePdfClicked()
} else {
val message = getString(R.string.storage_permission_denied)
Toast.makeText(context, message, Toast.LENGTH_SHORT).show()
}
}
LaunchedEffect(Unit) {
exportViewModel.events.collect { event ->
when (event) {
ExportEvent.RequestSavePdf -> {
checkPermissionThen(storagePermissionLauncher) {
exportViewModel.onRequestPdfSave(context, homeViewModel)
}
}
is ExportEvent.SaveError -> {
val text = getString(R.string.error_save)
Toast.makeText(context, text, Toast.LENGTH_SHORT).show()
}
}
}
}
}
@Composable
private fun CollectCameraEvents(
cameraViewModel: CameraViewModel,
viewModel: MainViewModel,
) {
LaunchedEffect(Unit) {
cameraViewModel.events.collect { event ->
when (event) {
is CameraEvent.ImageCaptured -> viewModel.handleImageCaptured(event.jpegBytes)
}
}
}
}
private fun sharePdf(generatedPdf: GeneratedPdf?, viewModel: ExportViewModel) { private fun sharePdf(generatedPdf: GeneratedPdf?, viewModel: ExportViewModel) {
if (generatedPdf == null) if (generatedPdf == null)
return return
@@ -275,3 +295,13 @@ class MainActivity : ComponentActivity() {
} }
} }
} }
private fun navigation(viewModel: MainViewModel): Navigation = Navigation(
toHomeScreen = { viewModel.navigateTo(Screen.Main.Home) },
toCameraScreen = { viewModel.navigateTo(Screen.Main.Camera) },
toDocumentScreen = { viewModel.navigateTo(Screen.Main.Document()) },
toExportScreen = { viewModel.navigateTo(Screen.Main.Export) },
toAboutScreen = { viewModel.navigateTo(Screen.Overlay.About) },
toLibrariesScreen = { viewModel.navigateTo(Screen.Overlay.Libraries) },
back = { viewModel.navigateBack() }
)