diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 6062f661b..a830b2841 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -152,6 +152,7 @@ jmdns = { module = "org.jmdns:jmdns", version.ref = "jmdns" } zxing-core = { module = "com.google.zxing:core", version.ref = "zxingCore" } acra-mail = { module = "ch.acra:acra-mail", version.ref = "acra" } acra-dialog = { module = "ch.acra:acra-dialog", version.ref = "acra" } +acra-notification = { module = "ch.acra:acra-notification", version.ref = "acra" } adapterdelegates4 = { module = "com.hannesdorfmann:adapterdelegates4", version.ref = "adapterdelegates4" } bcprov-jdk15to18 = { module = "org.bouncycastle:bcprov-jdk15to18", version.ref = "bouncycastle" } bcpkix-jdk15to18 = { module = "org.bouncycastle:bcpkix-jdk15to18", version.ref = "bouncycastle" } diff --git a/next/build.gradle.kts b/next/build.gradle.kts index 1be24544c..b43288b9c 100644 --- a/next/build.gradle.kts +++ b/next/build.gradle.kts @@ -22,6 +22,9 @@ android { } buildTypes { + all { + buildConfigField("String", "ACRA_REPORT_EMAIL", "\"t+fdroidnext@grobox.de\"") + } release { isMinifyEnabled = false proguardFiles( @@ -83,6 +86,9 @@ dependencies { implementation(libs.logback.android) implementation(libs.microutils.kotlin.logging) + implementation(libs.acra.mail) + implementation(libs.acra.dialog) + implementation(libs.hilt.android) implementation(libs.androidx.hilt.navigation.compose) ksp(libs.hilt.android.compiler) diff --git a/next/src/main/AndroidManifest.xml b/next/src/main/AndroidManifest.xml index 13803d9ab..16fa2c41b 100644 --- a/next/src/main/AndroidManifest.xml +++ b/next/src/main/AndroidManifest.xml @@ -67,6 +67,12 @@ + + helper.sendCrash(comment, userEmail) + finishAfterTransition() + }, + modifier = Modifier.safeContentPadding() + ) + } + } + } +} + +@Composable +private fun CrashContent( + onCancel: () -> Unit, + onSend: (String, String) -> Unit, + modifier: Modifier = Modifier +) { + val scrollState = rememberScrollState() + Column( + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.SpaceBetween, + modifier = modifier + .fillMaxSize() + .padding(horizontal = 16.dp) + .verticalScroll(scrollState) + ) { + Image( + painter = painterResource(id = R.drawable.ic_crash), + colorFilter = ColorFilter.tint(MaterialTheme.colorScheme.primary), + contentDescription = null, // decorative element + modifier = Modifier + .fillMaxWidth(0.5f) + .aspectRatio(1f) + .padding(vertical = 16.dp) + ) + val textFieldState = rememberTextFieldState() + Column(verticalArrangement = spacedBy(16.dp)) { + Text( + text = stringResource(R.string.crash_dialog_title), + style = MaterialTheme.typography.titleLarge, + modifier = Modifier.align(Alignment.CenterHorizontally) + ) + Text( + text = stringResource(R.string.crash_report_text), + style = MaterialTheme.typography.bodyLarge, + modifier = Modifier + ) + TextField( + state = textFieldState, + placeholder = { Text(stringResource(R.string.crash_report_comment_hint)) }, + modifier = Modifier.fillMaxWidth() + ) + } + Row( + horizontalArrangement = Arrangement.SpaceEvenly, + modifier = Modifier + .fillMaxWidth() + .padding(vertical = 16.dp) + ) { + OutlinedButton(onClick = onCancel) { + Text(stringResource(R.string.cancel)) + } + Button(onClick = { + onSend(textFieldState.text.toString(), "") + }) { + Text(stringResource(R.string.crash_report_button_send)) + } + } + } +} + +@Preview +@Composable +private fun Preview() { + FDroidContent { + CrashContent({}, { _, _ -> }) + } +} diff --git a/next/src/main/res/drawable/ic_crash.xml b/next/src/main/res/drawable/ic_crash.xml new file mode 100644 index 000000000..6cd8e1bf1 --- /dev/null +++ b/next/src/main/res/drawable/ic_crash.xml @@ -0,0 +1,12 @@ + + + + diff --git a/next/src/main/res/values/strings-next.xml b/next/src/main/res/values/strings-next.xml index f56fa4c17..132d27037 100644 --- a/next/src/main/res/values/strings-next.xml +++ b/next/src/main/res/values/strings-next.xml @@ -88,4 +88,12 @@ Here you can apply filters to the list of apps, e.g. showing only apps within a certain category or repository. Changing the sort order is also possible. Got it + An unexpected error occurred. + This is not your fault. + Would you like to e-mail the details to help us fix the issue? + + Tell us what happened right before the crash + Send report + Could not send report. No email program found :( +