package eu.kanade.presentation.crash import androidx.compose.foundation.background import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.WindowInsets import androidx.compose.foundation.layout.asPaddingValues import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.navigationBars import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.systemBars import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.verticalScroll import androidx.compose.material.icons.Icons import androidx.compose.material.icons.outlined.BugReport import androidx.compose.material3.Button import androidx.compose.material3.Icon import androidx.compose.material3.MaterialTheme import androidx.compose.material3.OutlinedButton import androidx.compose.material3.Scaffold import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.draw.drawBehind import androidx.compose.ui.geometry.Offset import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp import eu.kanade.presentation.util.horizontalPadding import eu.kanade.presentation.util.verticalPadding import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.util.CrashLogUtil import kotlinx.coroutines.launch @Composable fun CrashScreen( exception: Throwable?, onRestartClick: () -> Unit, ) { val scope = rememberCoroutineScope() val context = LocalContext.current Scaffold( contentWindowInsets = WindowInsets.systemBars, bottomBar = { val strokeWidth = Dp.Hairline val borderColor = MaterialTheme.colorScheme.outline Column( modifier = Modifier .background(MaterialTheme.colorScheme.surface) .drawBehind { drawLine( borderColor, Offset(0f, 0f), Offset(size.width, 0f), strokeWidth.value, ) } .padding(WindowInsets.navigationBars.asPaddingValues()) .padding(horizontal = horizontalPadding, vertical = verticalPadding), verticalArrangement = Arrangement.spacedBy(verticalPadding), ) { Button( onClick = { scope.launch { CrashLogUtil(context).dumpLogs() } }, modifier = Modifier.fillMaxWidth(), ) { Text(text = stringResource(id = R.string.pref_dump_crash_logs)) } OutlinedButton( onClick = onRestartClick, modifier = Modifier.fillMaxWidth(), ) { Text(text = stringResource(R.string.crash_screen_restart_application)) } } }, ) { paddingValues -> Column( modifier = Modifier .verticalScroll(rememberScrollState()) .padding(paddingValues) .padding(top = 56.dp) .padding(horizontal = horizontalPadding), horizontalAlignment = Alignment.CenterHorizontally, ) { Icon( imageVector = Icons.Outlined.BugReport, contentDescription = null, modifier = Modifier .size(64.dp), ) Text( text = stringResource(R.string.crash_screen_title), style = MaterialTheme.typography.titleLarge, ) Text( text = stringResource(R.string.crash_screen_description, stringResource(id = R.string.app_name)), modifier = Modifier .padding(vertical = verticalPadding), ) Box( modifier = Modifier .padding(vertical = verticalPadding) .clip(MaterialTheme.shapes.small) .fillMaxWidth() .background(MaterialTheme.colorScheme.surfaceVariant), ) { Text( text = exception.toString(), modifier = Modifier .padding(all = verticalPadding), color = MaterialTheme.colorScheme.onSurfaceVariant, ) } } } }