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 :(
+