Crash screen tweak

master
Zakhar Timoshenko 2 years ago
parent 746934d421
commit 44b6f1b52f
Signed by: Xtimms
SSH Key Fingerprint: SHA256:wH6spYepK/A5erBh7ZyAnr1ru9H4eaMVBEuiw6DSpxI

@ -4,8 +4,10 @@ import android.app.Application
import android.content.Context
import android.content.pm.PackageInfo
import android.content.pm.PackageManager
import android.net.ConnectivityManager
import android.os.Build
import android.os.StrictMode
import androidx.core.content.getSystemService
import androidx.hilt.work.HiltWorkerFactory
import androidx.work.Configuration
import androidx.work.WorkManager
@ -21,9 +23,10 @@ import org.acra.ktx.initAcra
import org.acra.sender.HttpSender
import org.koitharu.kotatsu.parsers.MangaLoaderContext
import org.xtimms.shirizu.core.database.ShirizuDatabase
import org.xtimms.shirizu.core.prefs.AppSettings
import org.xtimms.shirizu.core.prefs.KotatsuAppSettings
import org.xtimms.shirizu.core.updates.Updater
import org.xtimms.shirizu.crash.CrashActivity
import org.xtimms.shirizu.crash.GlobalExceptionHandler
import org.xtimms.shirizu.utils.lang.processLifecycleScope
import org.xtimms.shirizu.work.WorkScheduleManager
import javax.inject.Inject
@ -61,6 +64,7 @@ class App : Application(), Configuration.Provider {
) else getPackageInfo(packageName, 0)
}
DynamicColors.applyToActivitiesIfAvailable(this)
connectivityManager = getSystemService()!!
processLifecycleScope.launch(Dispatchers.IO) {
try {
@ -70,8 +74,6 @@ class App : Application(), Configuration.Provider {
}
}
// GlobalExceptionHandler.initialize(applicationContext, CrashActivity::class.java)
if (AppSettings.isACRAEnabled()) {
initAcra {
buildConfigClass = BuildConfig::class.java
reportFormat = StringFormat.JSON
@ -93,7 +95,8 @@ class App : Application(), Configuration.Provider {
ReportField.CUSTOM_DATA,
)
}
}
GlobalExceptionHandler.initialize(applicationContext, CrashActivity::class.java)
workScheduleManager.init()
}
@ -123,8 +126,8 @@ class App : Application(), Configuration.Provider {
companion object {
lateinit var packageInfo: PackageInfo
lateinit var connectivityManager: ConnectivityManager
@Suppress("DEPRECATION")
fun getVersionReport(): String {
val versionName = packageInfo.versionName
val versionCode = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {

@ -1,12 +1,21 @@
package org.xtimms.shirizu.core.screens
import androidx.compose.animation.AnimatedContent
import androidx.compose.animation.core.RepeatMode
import androidx.compose.animation.core.VectorConverter
import androidx.compose.animation.core.animateFloat
import androidx.compose.animation.core.animateValue
import androidx.compose.animation.core.infiniteRepeatable
import androidx.compose.animation.core.rememberInfiniteTransition
import androidx.compose.animation.core.tween
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.ColumnScope
import androidx.compose.foundation.layout.absoluteOffset
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.requiredSize
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.windowInsetsPadding
import androidx.compose.foundation.rememberScrollState
@ -21,20 +30,34 @@ import androidx.compose.material3.OutlinedButton
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.drawBehind
import androidx.compose.ui.draw.rotate
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.layout.onGloballyPositioned
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.tooling.preview.PreviewLightDark
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import androidx.compose.ui.zIndex
import org.xtimms.shirizu.R
import org.xtimms.shirizu.sections.stats.Size
import org.xtimms.shirizu.ui.theme.ShirizuTheme
import org.xtimms.shirizu.utils.composable.secondaryItemAlpha
import org.xtimms.shirizu.utils.material.combineColors
@Composable
fun InfoScreen(
icon: ImageVector,
headingText: String,
headingText1: String,
headingText2: String,
subtitleText: String,
acceptText: String,
onAcceptClick: () -> Unit,
@ -43,6 +66,9 @@ fun InfoScreen(
onRejectClick: (() -> Unit)? = null,
content: @Composable ColumnScope.() -> Unit,
) {
val localDensity = LocalDensity.current
Scaffold(
bottomBar = {
val strokeWidth = Dp.Hairline
@ -82,16 +108,51 @@ fun InfoScreen(
}
},
) { paddingValues ->
// Status bar scrim
var headerSize by remember { mutableStateOf(Size(0.dp, 0.dp)) }
Box(
modifier = Modifier
.zIndex(2f)
.secondaryItemAlpha()
.background(MaterialTheme.colorScheme.background)
.fillMaxWidth()
.height(paddingValues.calculateTopPadding()),
.onGloballyPositioned {
headerSize = Size(
width = with(localDensity) { it.size.width.toDp() },
height = with(localDensity) { it.size.height.toDp() }
)
},
contentAlignment = Alignment.Center,
) {
val halfWidth = headerSize.width / 2
val halfHeight = headerSize.height / 2
val starColor1 = combineColors(
MaterialTheme.colorScheme.primaryContainer,
MaterialTheme.colorScheme.surface,
0.5f,
)
val angleStar1 by rememberInfiniteTransition("angleStar1").animateFloat(
label = "angleStar1",
initialValue = -20f,
targetValue = 20f,
animationSpec = infiniteRepeatable(tween(5000), RepeatMode.Reverse)
)
Icon(
modifier = Modifier
.requiredSize(256.dp)
.absoluteOffset(
x = halfWidth * 0.7f,
y = -halfHeight * 0.6f
)
.rotate(angleStar1)
.zIndex(-1f),
painter = painterResource(R.drawable.shape_soft_star_1),
tint = starColor1,
contentDescription = null,
)
}
Column(
modifier = Modifier
.verticalScroll(rememberScrollState())
@ -108,10 +169,24 @@ fun InfoScreen(
.size(48.dp),
tint = MaterialTheme.colorScheme.primary,
)
val infiniteTransition by rememberInfiniteTransition("infiniteTransition").animateValue(
label = "infiniteTransition",
initialValue = 0,
targetValue = 2,
typeConverter = Int.VectorConverter,
animationSpec = infiniteRepeatable(tween(15000), RepeatMode.Restart)
)
val heading = when (infiniteTransition) {
0 -> headingText1
1 -> headingText2
else -> headingText2
}
AnimatedContent(targetState = heading, label = "heading animation") {
Text(
text = headingText,
text = it,
style = MaterialTheme.typography.headlineLarge,
)
}
Text(
text = subtitleText,
modifier = Modifier
@ -128,9 +203,11 @@ fun InfoScreen(
@PreviewLightDark
@Composable
private fun InfoScaffoldPreview() {
ShirizuTheme {
InfoScreen(
icon = Icons.Outlined.Newspaper,
headingText = "Heading",
headingText1 = "Heading 1",
headingText2 = "Heading 2",
subtitleText = "Subtitle",
acceptText = "Accept",
onAcceptClick = {},
@ -139,4 +216,5 @@ private fun InfoScaffoldPreview() {
) {
Text("Hello world")
}
}
}

@ -8,6 +8,7 @@ import androidx.activity.enableEdgeToEdge
import dagger.hilt.android.AndroidEntryPoint
import org.xtimms.shirizu.LocalDarkTheme
import org.xtimms.shirizu.LocalDynamicColorSwitch
import org.xtimms.shirizu.LocalWindowWidthState
import org.xtimms.shirizu.MainActivity
import org.xtimms.shirizu.SettingsProvider
import org.xtimms.shirizu.ui.theme.ShirizuTheme
@ -21,7 +22,7 @@ class CrashActivity : ComponentActivity() {
val exception = GlobalExceptionHandler.getThrowableFromIntent(intent)
setContent {
SettingsProvider {
SettingsProvider(LocalWindowWidthState.current) {
ShirizuTheme(
darkTheme = LocalDarkTheme.current.isDarkTheme(),
isDynamicColorEnabled = LocalDynamicColorSwitch.current,

@ -1,5 +1,6 @@
package org.xtimms.shirizu.crash
import android.app.Activity
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
@ -9,7 +10,6 @@ import androidx.compose.material.icons.outlined.BugReport
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.platform.LocalContext
@ -17,29 +17,30 @@ import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.tooling.preview.PreviewLightDark
import androidx.compose.ui.unit.dp
import kotlinx.coroutines.launch
import org.acra.ktx.sendWithAcra
import org.xtimms.shirizu.R
import org.xtimms.shirizu.core.screens.InfoScreen
import org.xtimms.shirizu.ui.theme.ShirizuTheme
import org.xtimms.shirizu.utils.CrashLogUtil
import org.xtimms.shirizu.utils.system.toast
@Composable
fun CrashScreen(
exception: Throwable?,
onRestartClick: () -> Unit,
) {
val scope = rememberCoroutineScope()
val context = LocalContext.current
val activity = (context as? Activity)
InfoScreen(
icon = Icons.Outlined.BugReport,
headingText = stringResource(R.string.crash_screen_title),
headingText1 = stringResource(R.string.crash_screen_title),
headingText2 = stringResource(id = R.string.crash_screen_something_went_wrong),
subtitleText = stringResource(R.string.crash_screen_description, stringResource(R.string.app_name)),
acceptText = stringResource(R.string.pref_dump_crash_logs),
acceptText = stringResource(R.string.pref_send_crash_logs),
onAcceptClick = {
scope.launch {
CrashLogUtil(context).dumpLogs()
}
exception?.sendWithAcra()
context.toast(context.resources.getString(R.string.crash_screen_toast))
activity?.finishAndRemoveTask()
},
rejectText = stringResource(R.string.crash_screen_restart_application),
onRejectClick = onRestartClick,

Loading…
Cancel
Save