feat: Allow the user to send an error report without a crash (#406)
Getting error reports with logs of strange behaviour is useful even if the app doesn't crash. Move crash reporting in to `core.activity`, and provide a menu option (in orange builds) to trigger a non-fatal crash report that is handled the same way (i.e., sent by e-mail) as a regular crash report. `BaseActivity` has to be able to create and handle menus, so adjust subclasses to call the superclass when necessary. Update `tools/mvstring` to be able to move strings between different flavour directories, not just `main`.
This commit is contained in:
parent
86d800b1c8
commit
1488c13c42
|
@ -177,8 +177,6 @@ dependencies {
|
||||||
|
|
||||||
debugImplementation(libs.leakcanary)
|
debugImplementation(libs.leakcanary)
|
||||||
|
|
||||||
orangeImplementation(libs.bundles.acra)
|
|
||||||
|
|
||||||
testImplementation(projects.core.testing)
|
testImplementation(projects.core.testing)
|
||||||
testImplementation(libs.androidx.test.junit)
|
testImplementation(libs.androidx.test.junit)
|
||||||
testImplementation(libs.robolectric)
|
testImplementation(libs.robolectric)
|
||||||
|
|
|
@ -382,6 +382,7 @@ class MainActivity : BottomSheetActivity(), ActionButtonActivity, MenuProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCreateMenu(menu: Menu, menuInflater: MenuInflater) {
|
override fun onCreateMenu(menu: Menu, menuInflater: MenuInflater) {
|
||||||
|
super.onCreateMenu(menu, menuInflater)
|
||||||
menuInflater.inflate(R.menu.activity_main, menu)
|
menuInflater.inflate(R.menu.activity_main, menu)
|
||||||
menu.findItem(R.id.action_search)?.apply {
|
menu.findItem(R.id.action_search)?.apply {
|
||||||
icon = IconicsDrawable(this@MainActivity, GoogleMaterial.Icon.gmd_search).apply {
|
icon = IconicsDrawable(this@MainActivity, GoogleMaterial.Icon.gmd_search).apply {
|
||||||
|
@ -392,20 +393,21 @@ class MainActivity : BottomSheetActivity(), ActionButtonActivity, MenuProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onPrepareMenu(menu: Menu) {
|
override fun onPrepareMenu(menu: Menu) {
|
||||||
super.onPrepareMenu(menu)
|
super<BottomSheetActivity>.onPrepareMenu(menu)
|
||||||
|
|
||||||
// If the main toolbar is hidden then there's no space in the top/bottomNav to show
|
// If the main toolbar is hidden then there's no space in the top/bottomNav to show
|
||||||
// the menu items as icons, so forceably disable them
|
// the menu items as icons, so forceably disable them
|
||||||
if (!binding.mainToolbar.isVisible) menu.forEach { it.setShowAsAction(SHOW_AS_ACTION_NEVER) }
|
if (!binding.mainToolbar.isVisible) menu.forEach { it.setShowAsAction(SHOW_AS_ACTION_NEVER) }
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onMenuItemSelected(item: MenuItem): Boolean {
|
override fun onMenuItemSelected(menuItem: MenuItem): Boolean {
|
||||||
return when (item.itemId) {
|
super.onMenuItemSelected(menuItem)
|
||||||
|
return when (menuItem.itemId) {
|
||||||
R.id.action_search -> {
|
R.id.action_search -> {
|
||||||
startActivity(SearchActivityIntent(this@MainActivity))
|
startActivity(SearchActivityIntent(this@MainActivity))
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
else -> super.onOptionsItemSelected(item)
|
else -> super.onOptionsItemSelected(menuItem)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,7 @@ import androidx.work.ExistingPeriodicWorkPolicy
|
||||||
import androidx.work.PeriodicWorkRequestBuilder
|
import androidx.work.PeriodicWorkRequestBuilder
|
||||||
import androidx.work.WorkManager
|
import androidx.work.WorkManager
|
||||||
import app.pachli.components.notifications.createWorkerNotificationChannel
|
import app.pachli.components.notifications.createWorkerNotificationChannel
|
||||||
|
import app.pachli.core.activity.initCrashReporter
|
||||||
import app.pachli.core.preferences.AppTheme
|
import app.pachli.core.preferences.AppTheme
|
||||||
import app.pachli.core.preferences.NEW_INSTALL_SCHEMA_VERSION
|
import app.pachli.core.preferences.NEW_INSTALL_SCHEMA_VERSION
|
||||||
import app.pachli.core.preferences.PrefKeys
|
import app.pachli.core.preferences.PrefKeys
|
||||||
|
|
|
@ -805,6 +805,7 @@ class AccountActivity :
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCreateMenu(menu: Menu, menuInflater: MenuInflater) {
|
override fun onCreateMenu(menu: Menu, menuInflater: MenuInflater) {
|
||||||
|
super.onCreateMenu(menu, menuInflater)
|
||||||
menuInflater.inflate(R.menu.account_toolbar, menu)
|
menuInflater.inflate(R.menu.account_toolbar, menu)
|
||||||
|
|
||||||
val openAsItem = menu.findItem(R.id.action_open_as)
|
val openAsItem = menu.findItem(R.id.action_open_as)
|
||||||
|
@ -964,6 +965,7 @@ class AccountActivity :
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onMenuItemSelected(item: MenuItem): Boolean {
|
override fun onMenuItemSelected(item: MenuItem): Boolean {
|
||||||
|
super.onMenuItemSelected(item)
|
||||||
when (item.itemId) {
|
when (item.itemId) {
|
||||||
R.id.action_open_in_web -> {
|
R.id.action_open_in_web -> {
|
||||||
// If the account isn't loaded yet, eat the input.
|
// If the account isn't loaded yet, eat the input.
|
||||||
|
|
|
@ -139,6 +139,7 @@ class AnnouncementsActivity :
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCreateMenu(menu: Menu, menuInflater: MenuInflater) {
|
override fun onCreateMenu(menu: Menu, menuInflater: MenuInflater) {
|
||||||
|
super.onCreateMenu(menu, menuInflater)
|
||||||
menuInflater.inflate(R.menu.activity_announcements, menu)
|
menuInflater.inflate(R.menu.activity_announcements, menu)
|
||||||
menu.findItem(R.id.action_search)?.apply {
|
menu.findItem(R.id.action_search)?.apply {
|
||||||
icon = IconicsDrawable(this@AnnouncementsActivity, GoogleMaterial.Icon.gmd_search).apply {
|
icon = IconicsDrawable(this@AnnouncementsActivity, GoogleMaterial.Icon.gmd_search).apply {
|
||||||
|
@ -149,6 +150,7 @@ class AnnouncementsActivity :
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onMenuItemSelected(menuItem: MenuItem): Boolean {
|
override fun onMenuItemSelected(menuItem: MenuItem): Boolean {
|
||||||
|
super.onMenuItemSelected(menuItem)
|
||||||
return when (menuItem.itemId) {
|
return when (menuItem.itemId) {
|
||||||
R.id.action_refresh -> {
|
R.id.action_refresh -> {
|
||||||
binding.swipeRefreshLayout.isRefreshing = true
|
binding.swipeRefreshLayout.isRefreshing = true
|
||||||
|
|
|
@ -125,6 +125,7 @@ class ScheduledStatusActivity :
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCreateMenu(menu: Menu, menuInflater: MenuInflater) {
|
override fun onCreateMenu(menu: Menu, menuInflater: MenuInflater) {
|
||||||
|
super.onCreateMenu(menu, menuInflater)
|
||||||
menuInflater.inflate(R.menu.activity_announcements, menu)
|
menuInflater.inflate(R.menu.activity_announcements, menu)
|
||||||
menu.findItem(R.id.action_search)?.apply {
|
menu.findItem(R.id.action_search)?.apply {
|
||||||
icon = IconicsDrawable(this@ScheduledStatusActivity, GoogleMaterial.Icon.gmd_search).apply {
|
icon = IconicsDrawable(this@ScheduledStatusActivity, GoogleMaterial.Icon.gmd_search).apply {
|
||||||
|
@ -135,6 +136,7 @@ class ScheduledStatusActivity :
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onMenuItemSelected(menuItem: MenuItem): Boolean {
|
override fun onMenuItemSelected(menuItem: MenuItem): Boolean {
|
||||||
|
super.onMenuItemSelected(menuItem)
|
||||||
return when (menuItem.itemId) {
|
return when (menuItem.itemId) {
|
||||||
R.id.action_refresh -> {
|
R.id.action_refresh -> {
|
||||||
binding.swipeRefreshLayout.isRefreshing = true
|
binding.swipeRefreshLayout.isRefreshing = true
|
||||||
|
|
|
@ -75,6 +75,7 @@ class SearchActivity : BottomSheetActivity(), MenuProvider, SearchView.OnQueryTe
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCreateMenu(menu: Menu, menuInflater: MenuInflater) {
|
override fun onCreateMenu(menu: Menu, menuInflater: MenuInflater) {
|
||||||
|
super.onCreateMenu(menu, menuInflater)
|
||||||
menuInflater.inflate(R.menu.search_toolbar, menu)
|
menuInflater.inflate(R.menu.search_toolbar, menu)
|
||||||
val searchViewMenuItem = menu.findItem(R.id.action_search)
|
val searchViewMenuItem = menu.findItem(R.id.action_search)
|
||||||
searchViewMenuItem.expandActionView()
|
searchViewMenuItem.expandActionView()
|
||||||
|
@ -83,6 +84,7 @@ class SearchActivity : BottomSheetActivity(), MenuProvider, SearchView.OnQueryTe
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onMenuItemSelected(menuItem: MenuItem): Boolean {
|
override fun onMenuItemSelected(menuItem: MenuItem): Boolean {
|
||||||
|
super.onMenuItemSelected(menuItem)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -78,10 +78,12 @@ class TrendingActivity : BottomSheetActivity(), AppBarLayoutHost, MenuProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCreateMenu(menu: Menu, menuInflater: MenuInflater) {
|
override fun onCreateMenu(menu: Menu, menuInflater: MenuInflater) {
|
||||||
|
super.onCreateMenu(menu, menuInflater)
|
||||||
menuInflater.inflate(R.menu.activity_trending, menu)
|
menuInflater.inflate(R.menu.activity_trending, menu)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onMenuItemSelected(menuItem: MenuItem): Boolean {
|
override fun onMenuItemSelected(menuItem: MenuItem): Boolean {
|
||||||
|
super.onMenuItemSelected(menuItem)
|
||||||
return super.onOptionsItemSelected(menuItem)
|
return super.onOptionsItemSelected(menuItem)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -677,7 +677,6 @@
|
||||||
<string name="action_translate_undo">إلغاء الترجمة</string>
|
<string name="action_translate_undo">إلغاء الترجمة</string>
|
||||||
<string name="notification_prune_cache">صيانة ذاكرة التخزين المؤقتة…</string>
|
<string name="notification_prune_cache">صيانة ذاكرة التخزين المؤقتة…</string>
|
||||||
<string name="pref_ui_text_size">حجم نص واجهة المستخدم</string>
|
<string name="pref_ui_text_size">حجم نص واجهة المستخدم</string>
|
||||||
<string name="acra_dialog_title">لقد تحطّم %1$s</string>
|
|
||||||
<string name="load_newest_notifications">تحميل أحدث الإشعارات</string>
|
<string name="load_newest_notifications">تحميل أحدث الإشعارات</string>
|
||||||
<string name="label_filter_context">السياقات التي تم تصفيتها</string>
|
<string name="label_filter_context">السياقات التي تم تصفيتها</string>
|
||||||
<string name="dialog_follow_hashtag_hint">#وسم</string>
|
<string name="dialog_follow_hashtag_hint">#وسم</string>
|
||||||
|
|
|
@ -512,7 +512,6 @@
|
||||||
<string name="report_category_violation">Sääntörikkomus</string>
|
<string name="report_category_violation">Sääntörikkomus</string>
|
||||||
<string name="label_filter_keywords">Avainsanat tai jonot jotka suodatetaan</string>
|
<string name="label_filter_keywords">Avainsanat tai jonot jotka suodatetaan</string>
|
||||||
<string name="drafts_post_reply_removed">Julkaisu, johon olit kirjoittanut vastausluonnoksen, on poistettu</string>
|
<string name="drafts_post_reply_removed">Julkaisu, johon olit kirjoittanut vastausluonnoksen, on poistettu</string>
|
||||||
<string name="acra_dialog_text">Pyydämme anteeksi. Paina OK jos haluat lähettää kehittäjille yksityiskohtaiset tiedot</string>
|
|
||||||
<string name="limit_notifications">Rajoita aikajanan ilmoituksia</string>
|
<string name="limit_notifications">Rajoita aikajanan ilmoituksia</string>
|
||||||
<string name="account_date_joined">Liittyi %1$s</string>
|
<string name="account_date_joined">Liittyi %1$s</string>
|
||||||
<string name="ui_error_unknown">tuntematon syy</string>
|
<string name="ui_error_unknown">tuntematon syy</string>
|
||||||
|
@ -558,7 +557,6 @@
|
||||||
<string name="action_add">Lisää</string>
|
<string name="action_add">Lisää</string>
|
||||||
<string name="load_newest_notifications">Lataa uusimmat ilmoitukset</string>
|
<string name="load_newest_notifications">Lataa uusimmat ilmoitukset</string>
|
||||||
<string name="pref_title_show_cards_in_timelines">Näytä linkkien esikatselut aikajanoissa</string>
|
<string name="pref_title_show_cards_in_timelines">Näytä linkkien esikatselut aikajanoissa</string>
|
||||||
<string name="acra_dialog_title">%1$s kaatui</string>
|
|
||||||
<string name="pref_title_enable_swipe_for_tabs">Vaihda välilehteä pyyhkäisemällä</string>
|
<string name="pref_title_enable_swipe_for_tabs">Vaihda välilehteä pyyhkäisemällä</string>
|
||||||
<string name="report_remote_instance">Lähetä edelleen %s</string>
|
<string name="report_remote_instance">Lähetä edelleen %s</string>
|
||||||
<string name="poll_info_time_absolute">päättyy %s</string>
|
<string name="poll_info_time_absolute">päättyy %s</string>
|
||||||
|
@ -635,15 +633,6 @@
|
||||||
\nJos haluat tutkia muita tilejä, voit löytää niitä toisesta aikajanasta, esimerkiksi oman instanssisi paikallisesta aikajanasta [iconics gmd_group]. Voit myös etsiä niitä nimeltä [iconics gmd_search]; etsi esimerkiksi sanalla ”Pachli” löytääksesi Mastodon-tilimme.</string>
|
\nJos haluat tutkia muita tilejä, voit löytää niitä toisesta aikajanasta, esimerkiksi oman instanssisi paikallisesta aikajanasta [iconics gmd_group]. Voit myös etsiä niitä nimeltä [iconics gmd_search]; etsi esimerkiksi sanalla ”Pachli” löytääksesi Mastodon-tilimme.</string>
|
||||||
<string name="notifications_clear">Poista ilmoitukset</string>
|
<string name="notifications_clear">Poista ilmoitukset</string>
|
||||||
<string name="hint_list_name">Listan nimi</string>
|
<string name="hint_list_name">Listan nimi</string>
|
||||||
<string name="acra_email_body">Nämä tiedot lähetetään kehittäjille.
|
|
||||||
\n
|
|
||||||
\nTarkista, että tiedot eivät sisällä mitään, mitä et halua jakaa, ja kerro, mitä teit, kun ohjelma kaatui.
|
|
||||||
\n
|
|
||||||
\n------
|
|
||||||
\nKirjoita kuvaus tähän:
|
|
||||||
\n
|
|
||||||
\n------
|
|
||||||
\n</string>
|
|
||||||
<string name="expand_collapse_all_posts">Avaa/Sulje kaikki julkasut</string>
|
<string name="expand_collapse_all_posts">Avaa/Sulje kaikki julkasut</string>
|
||||||
<string name="select_list_title">Valitse lista</string>
|
<string name="select_list_title">Valitse lista</string>
|
||||||
<string name="duration_indefinite">Loputon</string>
|
<string name="duration_indefinite">Loputon</string>
|
||||||
|
|
|
@ -645,7 +645,6 @@
|
||||||
<string name="filter_keyword_addition_title">Voeg sleutelwoord toe</string>
|
<string name="filter_keyword_addition_title">Voeg sleutelwoord toe</string>
|
||||||
<string name="label_filter_keywords">Sleutelwoorden of zinnen om te filteren</string>
|
<string name="label_filter_keywords">Sleutelwoorden of zinnen om te filteren</string>
|
||||||
<string name="pref_title_show_self_boosts_description">Iemand die hun eigen post boost</string>
|
<string name="pref_title_show_self_boosts_description">Iemand die hun eigen post boost</string>
|
||||||
<string name="acra_dialog_text">Sorry daarvoor. Klik op OK om een e-mail op te stellen naar de ontwikkelaars met alle details</string>
|
|
||||||
<string name="ui_error_filter_v1_load">Laden van filters faalde: %s</string>
|
<string name="ui_error_filter_v1_load">Laden van filters faalde: %s</string>
|
||||||
<string name="confirmation_hashtag_muted">#%s verborgen</string>
|
<string name="confirmation_hashtag_muted">#%s verborgen</string>
|
||||||
<string name="janky_animation_title">Mogelijk is het noodzakelijk om je apparaat opnieuw op te starten</string>
|
<string name="janky_animation_title">Mogelijk is het noodzakelijk om je apparaat opnieuw op te starten</string>
|
||||||
|
@ -656,15 +655,6 @@
|
||||||
<string name="help_empty_home">Dit is je <b>Thuis tijdlijn</b>. Het toont de meest recente posts van accounts die je volgt.
|
<string name="help_empty_home">Dit is je <b>Thuis tijdlijn</b>. Het toont de meest recente posts van accounts die je volgt.
|
||||||
\n
|
\n
|
||||||
\nOm meer accounts te vinden, kun je ze ontdekken in een van de andere tijdlijnen. Bijvoorbeeld de lokale tijdlijn van jouw instance [iconics gmd_group]. Of je kunt zoeken op naam [iconics gmd_search]; bijvoorbeeld als je zoekt op Pachli dan vind je ons Mastodon account.</string>
|
\nOm meer accounts te vinden, kun je ze ontdekken in een van de andere tijdlijnen. Bijvoorbeeld de lokale tijdlijn van jouw instance [iconics gmd_group]. Of je kunt zoeken op naam [iconics gmd_search]; bijvoorbeeld als je zoekt op Pachli dan vind je ons Mastodon account.</string>
|
||||||
<string name="acra_email_body">Deze data wordt verzonden naar de ontwikkelaars.
|
|
||||||
\n
|
|
||||||
\nControleer alsjeblieft of er niks tussen zit dat je niet met ons wilt delen, omschrijf wat je deed wanneer de crash gebeurde.
|
|
||||||
\n
|
|
||||||
\n ----
|
|
||||||
\nJe omschrijving hier:
|
|
||||||
\n
|
|
||||||
\n ----
|
|
||||||
\n</string>
|
|
||||||
<string name="pref_update_notification_frequency_once_per_version">Eenmaal per versie</string>
|
<string name="pref_update_notification_frequency_once_per_version">Eenmaal per versie</string>
|
||||||
<string name="error_404_not_found">Je server beschikt niet over ondersteuning voor deze feature</string>
|
<string name="error_404_not_found">Je server beschikt niet over ondersteuning voor deze feature</string>
|
||||||
<string name="pref_title_font_family">Lettertype-familie</string>
|
<string name="pref_title_font_family">Lettertype-familie</string>
|
||||||
|
@ -683,5 +673,4 @@
|
||||||
<string name="action_translate_undo">Vertaling ongedaan maken</string>
|
<string name="action_translate_undo">Vertaling ongedaan maken</string>
|
||||||
<string name="notification_prune_cache">Cache onderhoud…</string>
|
<string name="notification_prune_cache">Cache onderhoud…</string>
|
||||||
<string name="pref_ui_text_size">UI tekst grootte</string>
|
<string name="pref_ui_text_size">UI tekst grootte</string>
|
||||||
<string name="acra_dialog_title">%1$s crashed</string>
|
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
@ -684,15 +684,4 @@
|
||||||
<string name="load_newest_notifications">Carregar notificações mais recentes</string>
|
<string name="load_newest_notifications">Carregar notificações mais recentes</string>
|
||||||
<string name="action_discard">Descartar mudanças</string>
|
<string name="action_discard">Descartar mudanças</string>
|
||||||
<string name="pref_ui_text_size">Tamanho do texto da UI</string>
|
<string name="pref_ui_text_size">Tamanho do texto da UI</string>
|
||||||
<string name="acra_dialog_text">Desculpas por isso. Clique em OK para preparar uma mensagem aos desenvolvedores com detalhes</string>
|
|
||||||
<string name="acra_email_body">Esses dados serão enviados aos desenvolvedores.
|
|
||||||
\n
|
|
||||||
\nPor favor, verifique se ele não inclui algo que não queriras compartilhar e, por favor, descreva o que estavas fazendo quando a falha aconteceu.
|
|
||||||
\n
|
|
||||||
\n----
|
|
||||||
\nA tua descrição aqui:
|
|
||||||
\n
|
|
||||||
\n----
|
|
||||||
\n</string>
|
|
||||||
<string name="acra_dialog_title">%1$s travou</string>
|
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
@ -671,17 +671,6 @@
|
||||||
<string name="title_tab_public_trending_hashtags">Hashtaggar</string>
|
<string name="title_tab_public_trending_hashtags">Hashtaggar</string>
|
||||||
<string name="label_image">Bild</string>
|
<string name="label_image">Bild</string>
|
||||||
<string name="action_translate_undo">Ångra översättning</string>
|
<string name="action_translate_undo">Ångra översättning</string>
|
||||||
<string name="acra_dialog_text">Förlåt för det. Klicka på OK för att förbereda ett e-postmeddelande till utvecklarna med detaljer</string>
|
|
||||||
<string name="acra_email_body">Denna data kommer att skickas till utvecklarna.
|
|
||||||
\n
|
|
||||||
\nKontrollera att den inte innehåller något du inte vill dela, och beskriv vad du gjorde när kraschen inträffade.
|
|
||||||
\n
|
|
||||||
\n ----
|
|
||||||
\nDin beskrivning här:
|
|
||||||
\n
|
|
||||||
\n----
|
|
||||||
\n</string>
|
|
||||||
<string name="acra_dialog_title">%1$s kraschade</string>
|
|
||||||
<string name="server_repository_error">Kunde inte hämta serverinformation för %1$s: %2$s</string>
|
<string name="server_repository_error">Kunde inte hämta serverinformation för %1$s: %2$s</string>
|
||||||
<string name="server_repository_error_get_well_known_node_info">misslyckades med att hämta /.well-known/nodeinfo: %1$s</string>
|
<string name="server_repository_error_get_well_known_node_info">misslyckades med att hämta /.well-known/nodeinfo: %1$s</string>
|
||||||
<string name="server_repository_error_unsupported_schema">/.well-known/nodeinfo innehöll inte begripliga scheman</string>
|
<string name="server_repository_error_unsupported_schema">/.well-known/nodeinfo innehöll inte begripliga scheman</string>
|
||||||
|
|
|
@ -708,17 +708,6 @@
|
||||||
<string name="janky_animation_title">You may need to restart your device</string>
|
<string name="janky_animation_title">You may need to restart your device</string>
|
||||||
<string name="janky_animation_msg">This version of Pachli may trigger an Android bug on some devices, and show broken animations.\n\nFor example, when tapping a post to view a thread.\n\nIf you see this you will need to restart your device.\n\nYou only need to do this once.\n\nThis is Android bug, there is nothing Pachli can do.</string>
|
<string name="janky_animation_msg">This version of Pachli may trigger an Android bug on some devices, and show broken animations.\n\nFor example, when tapping a post to view a thread.\n\nIf you see this you will need to restart your device.\n\nYou only need to do this once.\n\nThis is Android bug, there is nothing Pachli can do.</string>
|
||||||
|
|
||||||
<string name="acra_dialog_title">%1$s crashed</string>
|
|
||||||
<string name="acra_dialog_text">Sorry about that. Click OK to prepare an e-mail to the developers with details</string>
|
|
||||||
<string name="acra_email_body">This data will be sent to the developers.\n\n
|
|
||||||
|
|
||||||
Please check to make sure it does not include anything you don\'t want to share, and please describe what you were doing when the crash happened.\n\n
|
|
||||||
|
|
||||||
----\n
|
|
||||||
Your description here:\n\n
|
|
||||||
|
|
||||||
----\n
|
|
||||||
</string>
|
|
||||||
|
|
||||||
<string name="server_repository_error">Could not fetch server info for %1$s: %2$s</string>
|
<string name="server_repository_error">Could not fetch server info for %1$s: %2$s</string>
|
||||||
<string name="server_repository_error_get_well_known_node_info">fetching /.well-known/nodeinfo failed: %1$s</string>
|
<string name="server_repository_error_get_well_known_node_info">fetching /.well-known/nodeinfo failed: %1$s</string>
|
||||||
|
|
|
@ -47,6 +47,9 @@ dependencies {
|
||||||
// Loading avatars
|
// Loading avatars
|
||||||
implementation(libs.bundles.glide)
|
implementation(libs.bundles.glide)
|
||||||
|
|
||||||
|
// Crash reporting in orange (Pachli Current) builds only
|
||||||
|
orangeImplementation(libs.bundles.acra)
|
||||||
|
|
||||||
// BottomSheetActivityTest uses mockito
|
// BottomSheetActivityTest uses mockito
|
||||||
testImplementation(libs.bundles.mockito)
|
testImplementation(libs.bundles.mockito)
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
errorLine2=" ~~~~~~~~~">
|
errorLine2=" ~~~~~~~~~">
|
||||||
<location
|
<location
|
||||||
file="src/main/kotlin/app/pachli/core/activity/BaseActivity.kt"
|
file="src/main/kotlin/app/pachli/core/activity/BaseActivity.kt"
|
||||||
line="101"
|
line="104"
|
||||||
column="13"/>
|
column="13"/>
|
||||||
</issue>
|
</issue>
|
||||||
|
|
||||||
|
|
|
@ -15,9 +15,10 @@
|
||||||
* see <http://www.gnu.org/licenses>.
|
* see <http://www.gnu.org/licenses>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package app.pachli
|
package app.pachli.core.activity
|
||||||
|
|
||||||
import android.app.Application
|
import android.app.Application
|
||||||
|
|
||||||
/** Do nothing in blue builds */
|
/** Do nothing in blue builds */
|
||||||
fun initCrashReporter(app: Application) {}
|
fun initCrashReporter(app: Application) {}
|
||||||
|
fun triggerCrashReport() {}
|
|
@ -24,16 +24,19 @@ import android.content.pm.PackageManager
|
||||||
import android.graphics.BitmapFactory
|
import android.graphics.BitmapFactory
|
||||||
import android.graphics.Color
|
import android.graphics.Color
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
|
import android.view.Menu
|
||||||
|
import android.view.MenuInflater
|
||||||
import android.view.MenuItem
|
import android.view.MenuItem
|
||||||
import android.view.View
|
import android.view.View
|
||||||
|
import androidx.annotation.CallSuper
|
||||||
import androidx.annotation.StringRes
|
import androidx.annotation.StringRes
|
||||||
import androidx.annotation.StyleRes
|
import androidx.annotation.StyleRes
|
||||||
import androidx.appcompat.app.AlertDialog
|
import androidx.appcompat.app.AlertDialog
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.core.app.ActivityCompat
|
import androidx.core.app.ActivityCompat
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
|
import androidx.core.view.MenuProvider
|
||||||
import app.pachli.core.accounts.AccountManager
|
import app.pachli.core.accounts.AccountManager
|
||||||
import app.pachli.core.accounts.BuildConfig
|
|
||||||
import app.pachli.core.database.model.AccountEntity
|
import app.pachli.core.database.model.AccountEntity
|
||||||
import app.pachli.core.designsystem.EmbeddedFontFamily
|
import app.pachli.core.designsystem.EmbeddedFontFamily
|
||||||
import app.pachli.core.designsystem.R as DR
|
import app.pachli.core.designsystem.R as DR
|
||||||
|
@ -53,7 +56,7 @@ import javax.inject.Inject
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
|
|
||||||
@AndroidEntryPoint
|
@AndroidEntryPoint
|
||||||
abstract class BaseActivity : AppCompatActivity() {
|
abstract class BaseActivity : AppCompatActivity(), MenuProvider {
|
||||||
@Inject
|
@Inject
|
||||||
lateinit var accountManager: AccountManager
|
lateinit var accountManager: AccountManager
|
||||||
|
|
||||||
|
@ -294,6 +297,24 @@ abstract class BaseActivity : AppCompatActivity() {
|
||||||
ActivityCompat.requestPermissions(this, permissionsCopy, newKey)
|
ActivityCompat.requestPermissions(this, permissionsCopy, newKey)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@CallSuper
|
||||||
|
override fun onCreateMenu(menu: Menu, menuInflater: MenuInflater) {
|
||||||
|
if (BuildConfig.FLAVOR_color != "orange") return
|
||||||
|
menuInflater.inflate(R.menu.activity_base, menu)
|
||||||
|
}
|
||||||
|
|
||||||
|
@CallSuper
|
||||||
|
override fun onMenuItemSelected(menuItem: MenuItem): Boolean {
|
||||||
|
if (BuildConfig.FLAVOR_color != "orange") return false
|
||||||
|
return when (menuItem.itemId) {
|
||||||
|
R.id.action_crash_report -> {
|
||||||
|
triggerCrashReport()
|
||||||
|
true
|
||||||
|
}
|
||||||
|
else -> false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private const val REQUESTER_NONE = Int.MAX_VALUE
|
private const val REQUESTER_NONE = Int.MAX_VALUE
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!--
|
||||||
|
~ Copyright 2024 Pachli Association
|
||||||
|
~
|
||||||
|
~ This file is a part of Pachli.
|
||||||
|
~
|
||||||
|
~ This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||||
|
~ GNU General Public License as published by the Free Software Foundation; either version 3 of the
|
||||||
|
~ License, or (at your option) any later version.
|
||||||
|
~
|
||||||
|
~ Pachli is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
|
||||||
|
~ the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||||
|
~ Public License for more details.
|
||||||
|
~
|
||||||
|
~ You should have received a copy of the GNU General Public License along with Pachli; if not,
|
||||||
|
~ see <http://www.gnu.org/licenses>.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||||
|
<item
|
||||||
|
android:id="@+id/action_crash_report"
|
||||||
|
android:title="@string/send_error_report"
|
||||||
|
app:showAsAction="never" />
|
||||||
|
</menu>
|
|
@ -3,4 +3,5 @@
|
||||||
<string name="post_lookup_error_format">Error looking up post %s</string>
|
<string name="post_lookup_error_format">Error looking up post %s</string>
|
||||||
<string name="action_open_as">Open as %s</string>
|
<string name="action_open_as">Open as %s</string>
|
||||||
<string name="performing_lookup_title">Performing lookup…</string>
|
<string name="performing_lookup_title">Performing lookup…</string>
|
||||||
|
<string name="send_error_report">Send error report</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
@ -15,10 +15,11 @@
|
||||||
* see <http://www.gnu.org/licenses>.
|
* see <http://www.gnu.org/licenses>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package app.pachli
|
package app.pachli.core.activity
|
||||||
|
|
||||||
import android.app.Application
|
import android.app.Application
|
||||||
import app.pachli.core.designsystem.R as DR
|
import app.pachli.core.designsystem.R as DR
|
||||||
|
import org.acra.ACRA
|
||||||
import org.acra.config.dialog
|
import org.acra.config.dialog
|
||||||
import org.acra.config.mailSender
|
import org.acra.config.mailSender
|
||||||
import org.acra.data.StringFormat
|
import org.acra.data.StringFormat
|
||||||
|
@ -46,3 +47,10 @@ fun initCrashReporter(app: Application) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Trigger a report without a crash.
|
||||||
|
*/
|
||||||
|
fun triggerCrashReport() {
|
||||||
|
ACRA.errorReporter.handleException(null, false)
|
||||||
|
}
|
|
@ -0,0 +1,4 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<resources>
|
||||||
|
<string name="acra_dialog_title">لقد تحطّم %1$s</string>
|
||||||
|
</resources>
|
|
@ -0,0 +1,14 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<resources>
|
||||||
|
<string name="acra_dialog_title">%1$s kaatui</string>
|
||||||
|
<string name="acra_dialog_text">Pyydämme anteeksi. Paina OK jos haluat lähettää kehittäjille yksityiskohtaiset tiedot</string>
|
||||||
|
<string name="acra_email_body">Nämä tiedot lähetetään kehittäjille.
|
||||||
|
\n
|
||||||
|
\nTarkista, että tiedot eivät sisällä mitään, mitä et halua jakaa, ja kerro, mitä teit, kun ohjelma kaatui.
|
||||||
|
\n
|
||||||
|
\n------
|
||||||
|
\nKirjoita kuvaus tähän:
|
||||||
|
\n
|
||||||
|
\n------
|
||||||
|
\n</string>
|
||||||
|
</resources>
|
|
@ -0,0 +1,14 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<resources>
|
||||||
|
<string name="acra_dialog_title">%1$s crashed</string>
|
||||||
|
<string name="acra_dialog_text">Sorry daarvoor. Klik op OK om een e-mail op te stellen naar de ontwikkelaars met alle details</string>
|
||||||
|
<string name="acra_email_body">Deze data wordt verzonden naar de ontwikkelaars.
|
||||||
|
\n
|
||||||
|
\nControleer alsjeblieft of er niks tussen zit dat je niet met ons wilt delen, omschrijf wat je deed wanneer de crash gebeurde.
|
||||||
|
\n
|
||||||
|
\n ----
|
||||||
|
\nJe omschrijving hier:
|
||||||
|
\n
|
||||||
|
\n ----
|
||||||
|
\n</string>
|
||||||
|
</resources>
|
|
@ -0,0 +1,14 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<resources>
|
||||||
|
<string name="acra_dialog_title">%1$s travou</string>
|
||||||
|
<string name="acra_dialog_text">Desculpas por isso. Clique em OK para preparar uma mensagem aos desenvolvedores com detalhes</string>
|
||||||
|
<string name="acra_email_body">Esses dados serão enviados aos desenvolvedores.
|
||||||
|
\n
|
||||||
|
\nPor favor, verifique se ele não inclui algo que não queriras compartilhar e, por favor, descreva o que estavas fazendo quando a falha aconteceu.
|
||||||
|
\n
|
||||||
|
\n----
|
||||||
|
\nA tua descrição aqui:
|
||||||
|
\n
|
||||||
|
\n----
|
||||||
|
\n</string>
|
||||||
|
</resources>
|
|
@ -0,0 +1,14 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<resources>
|
||||||
|
<string name="acra_dialog_title">%1$s kraschade</string>
|
||||||
|
<string name="acra_dialog_text">Förlåt för det. Klicka på OK för att förbereda ett e-postmeddelande till utvecklarna med detaljer</string>
|
||||||
|
<string name="acra_email_body">Denna data kommer att skickas till utvecklarna.
|
||||||
|
\n
|
||||||
|
\nKontrollera att den inte innehåller något du inte vill dela, och beskriv vad du gjorde när kraschen inträffade.
|
||||||
|
\n
|
||||||
|
\n ----
|
||||||
|
\nDin beskrivning här:
|
||||||
|
\n
|
||||||
|
\n----
|
||||||
|
\n</string>
|
||||||
|
</resources>
|
|
@ -0,0 +1,14 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<resources>
|
||||||
|
<string name="acra_dialog_title">%1$s error report</string>
|
||||||
|
<string name="acra_dialog_text">Click OK to prepare an e-mail to the developers with details</string>
|
||||||
|
<string name="acra_email_body">This data will be sent to the developers.\n\n
|
||||||
|
|
||||||
|
Please check to make sure it does not include anything you don\'t want to share, and please describe what you were doing when the crash happened.\n\n
|
||||||
|
|
||||||
|
----\n
|
||||||
|
Your description here:\n\n
|
||||||
|
|
||||||
|
----\n
|
||||||
|
</string>
|
||||||
|
</resources>
|
|
@ -23,6 +23,7 @@ import com.github.ajalt.clikt.core.CliktCommand
|
||||||
import com.github.ajalt.clikt.core.UsageError
|
import com.github.ajalt.clikt.core.UsageError
|
||||||
import com.github.ajalt.clikt.parameters.arguments.argument
|
import com.github.ajalt.clikt.parameters.arguments.argument
|
||||||
import com.github.ajalt.clikt.parameters.arguments.multiple
|
import com.github.ajalt.clikt.parameters.arguments.multiple
|
||||||
|
import com.github.ajalt.clikt.parameters.options.default
|
||||||
import com.github.ajalt.clikt.parameters.options.flag
|
import com.github.ajalt.clikt.parameters.options.flag
|
||||||
import com.github.ajalt.clikt.parameters.options.option
|
import com.github.ajalt.clikt.parameters.options.option
|
||||||
import io.github.oshai.kotlinlogging.DelegatingKLogger
|
import io.github.oshai.kotlinlogging.DelegatingKLogger
|
||||||
|
@ -52,7 +53,9 @@ private val log = KotlinLogging.logger {}
|
||||||
class App : CliktCommand(help = """Move string resources between modules""") {
|
class App : CliktCommand(help = """Move string resources between modules""") {
|
||||||
private val args by argument().multiple()
|
private val args by argument().multiple()
|
||||||
|
|
||||||
private val verbose by option("-n", "--verbose", help = "show additional information").flag()
|
private val verbose by option("-v", "--verbose", help = "show additional information").flag()
|
||||||
|
private val srcVariant by option("--srcVariant").default("main")
|
||||||
|
private val dstVariant by option("--dstVariant").default("main")
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the full path to a module's `.../src/main/res` directory, starting from the
|
* Returns the full path to a module's `.../src/main/res` directory, starting from the
|
||||||
|
@ -60,7 +63,7 @@ class App : CliktCommand(help = """Move string resources between modules""") {
|
||||||
*
|
*
|
||||||
* @return the path, or null if it's not a subtree of [start] or any of its parents.
|
* @return the path, or null if it's not a subtree of [start] or any of its parents.
|
||||||
*/
|
*/
|
||||||
private fun findResourcePath(start: Path, variant: String = "main"): Path? {
|
private fun findResourcePath(start: Path, variant: String): Path? {
|
||||||
val suffix = Path("src/$variant/res")
|
val suffix = Path("src/$variant/res")
|
||||||
|
|
||||||
var prefix = start
|
var prefix = start
|
||||||
|
@ -89,8 +92,8 @@ class App : CliktCommand(help = """Move string resources between modules""") {
|
||||||
val cwd = Paths.get("").toAbsolutePath()
|
val cwd = Paths.get("").toAbsolutePath()
|
||||||
log.info { "working directory: $cwd" }
|
log.info { "working directory: $cwd" }
|
||||||
|
|
||||||
val srcRes = findResourcePath(Path(src)) ?: throw UsageError("no resources in $src")
|
val srcRes = findResourcePath(Path(src), srcVariant) ?: throw UsageError("no resources in $src")
|
||||||
val dstRes = findResourcePath(Path(dst)) ?: throw UsageError("no resources in $dst")
|
val dstRes = findResourcePath(Path(dst), dstVariant) ?: throw UsageError("no resources in $dst")
|
||||||
|
|
||||||
// Enumerate all the values-* directories that contain a strings.xml file
|
// Enumerate all the values-* directories that contain a strings.xml file
|
||||||
val resourceDirs =
|
val resourceDirs =
|
||||||
|
|
Loading…
Reference in New Issue