Initial integration.
This commit is contained in:
		@@ -1,6 +1,7 @@
 | 
			
		||||
import java.io.ByteArrayOutputStream
 | 
			
		||||
 | 
			
		||||
val ignoreGitVersion: String by project
 | 
			
		||||
val acraVersion = "5.9.7"
 | 
			
		||||
 | 
			
		||||
plugins {
 | 
			
		||||
    id("com.android.application")
 | 
			
		||||
@@ -187,6 +188,9 @@ dependencies {
 | 
			
		||||
    testImplementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.0")
 | 
			
		||||
    implementation("org.jetbrains.kotlinx:kotlinx-datetime:0.4.0")
 | 
			
		||||
 | 
			
		||||
    implementation("ch.acra:acra-http:$acraVersion")
 | 
			
		||||
    implementation("ch.acra:acra-toast:$acraVersion")
 | 
			
		||||
 | 
			
		||||
    // Matomo
 | 
			
		||||
    implementation("com.github.matomo-org:matomo-sdk-android:4.1.4")
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -59,11 +59,15 @@ import com.mikepenz.materialdrawer.util.updateBadge
 | 
			
		||||
import kotlinx.coroutines.CoroutineScope
 | 
			
		||||
import kotlinx.coroutines.Dispatchers
 | 
			
		||||
import kotlinx.coroutines.launch
 | 
			
		||||
import org.acra.ACRA
 | 
			
		||||
import org.acra.ktx.sendSilentlyWithAcra
 | 
			
		||||
import org.acra.ktx.sendWithAcra
 | 
			
		||||
import org.kodein.di.DIAware
 | 
			
		||||
import org.kodein.di.android.closestDI
 | 
			
		||||
import org.kodein.di.instance
 | 
			
		||||
import org.matomo.sdk.Tracker
 | 
			
		||||
import org.matomo.sdk.extra.TrackHelper
 | 
			
		||||
import java.security.MessageDigest
 | 
			
		||||
import java.util.concurrent.TimeUnit
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -306,6 +310,8 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener, DIAwar
 | 
			
		||||
 | 
			
		||||
        handleBottomBarActions()
 | 
			
		||||
 | 
			
		||||
        handleGDPRDialog(appSettingsService.settings.getBoolean("GDPR_shown", false))
 | 
			
		||||
 | 
			
		||||
        handleRecurringTask()
 | 
			
		||||
 | 
			
		||||
        CoroutineScope(Dispatchers.Main).launch {
 | 
			
		||||
@@ -315,6 +321,26 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener, DIAwar
 | 
			
		||||
        getElementsAccordingToTab()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    private fun handleGDPRDialog(GDPRShown: Boolean) {
 | 
			
		||||
        val messageDigest: MessageDigest = MessageDigest.getInstance("SHA-256")
 | 
			
		||||
        messageDigest.update(appSettingsService.getBaseUrl().toByteArray())
 | 
			
		||||
        ACRA.errorReporter.putCustomData("unique_id", String(messageDigest.digest()))
 | 
			
		||||
        if (!GDPRShown) {
 | 
			
		||||
            val alertDialog = AlertDialog.Builder(this).create()
 | 
			
		||||
            alertDialog.setTitle(getString(R.string.gdpr_dialog_title))
 | 
			
		||||
            alertDialog.setMessage(getString(R.string.gdpr_dialog_message))
 | 
			
		||||
            alertDialog.setButton(
 | 
			
		||||
                AlertDialog.BUTTON_NEUTRAL,
 | 
			
		||||
                "OK"
 | 
			
		||||
            ) { dialog, _ ->
 | 
			
		||||
                appSettingsService.settings.putBoolean("GDPR_shown", true)
 | 
			
		||||
                dialog.dismiss()
 | 
			
		||||
            }
 | 
			
		||||
            alertDialog.show()
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private fun initDrawer() {
 | 
			
		||||
        DrawerImageLoader.init(object : AbstractDrawerImageLoader() {
 | 
			
		||||
            override fun set(imageView: ImageView, uri: Uri, placeholder: Drawable, tag: String?) {
 | 
			
		||||
@@ -487,6 +513,7 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener, DIAwar
 | 
			
		||||
        val gdColor = try {
 | 
			
		||||
            Color.parseColor(it.color)
 | 
			
		||||
        } catch (e: IllegalArgumentException) {
 | 
			
		||||
            e.sendSilentlyWithAcra()
 | 
			
		||||
            resources.getColor(R.color.colorPrimary)
 | 
			
		||||
        }
 | 
			
		||||
        gd.setColor(gdColor)
 | 
			
		||||
 
 | 
			
		||||
@@ -29,6 +29,12 @@ import kotlinx.coroutines.CoroutineScope
 | 
			
		||||
import kotlinx.coroutines.Dispatchers
 | 
			
		||||
import kotlinx.coroutines.flow.MutableStateFlow
 | 
			
		||||
import kotlinx.coroutines.launch
 | 
			
		||||
import org.acra.ReportField
 | 
			
		||||
import org.acra.config.httpSender
 | 
			
		||||
import org.acra.config.toast
 | 
			
		||||
import org.acra.data.StringFormat
 | 
			
		||||
import org.acra.ktx.initAcra
 | 
			
		||||
import org.acra.sender.HttpSender
 | 
			
		||||
import org.kodein.di.*
 | 
			
		||||
import org.matomo.sdk.Matomo
 | 
			
		||||
import org.matomo.sdk.Tracker
 | 
			
		||||
@@ -85,6 +91,35 @@ class MyApp : MultiDexApplication(), DIAware {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    override fun attachBaseContext(base: Context?) {
 | 
			
		||||
        super.attachBaseContext(base)
 | 
			
		||||
 | 
			
		||||
        initAcra {
 | 
			
		||||
            //core configuration:
 | 
			
		||||
            buildConfigClass = BuildConfig::class.java
 | 
			
		||||
            reportFormat = StringFormat.JSON
 | 
			
		||||
 | 
			
		||||
            reportContent = listOf(
 | 
			
		||||
                ReportField.REPORT_ID, ReportField.INSTALLATION_ID,
 | 
			
		||||
                ReportField.APP_VERSION_CODE, ReportField.APP_VERSION_NAME,
 | 
			
		||||
                ReportField.BUILD, ReportField.ANDROID_VERSION, ReportField.BRAND, ReportField.PHONE_MODEL,
 | 
			
		||||
                ReportField.AVAILABLE_MEM_SIZE, ReportField.TOTAL_MEM_SIZE,
 | 
			
		||||
                ReportField.STACK_TRACE, ReportField.APPLICATION_LOG, ReportField.LOGCAT,
 | 
			
		||||
                ReportField.INITIAL_CONFIGURATION, ReportField.CRASH_CONFIGURATION, ReportField.IS_SILENT,
 | 
			
		||||
                ReportField.USER_APP_START_DATE, ReportField.USER_COMMENT, ReportField.USER_CRASH_DATE, ReportField.USER_EMAIL, ReportField.CUSTOM_DATA)
 | 
			
		||||
            toast {
 | 
			
		||||
                //required
 | 
			
		||||
                text = getString(R.string.crash_toast_text)
 | 
			
		||||
                length = Toast.LENGTH_LONG
 | 
			
		||||
            }
 | 
			
		||||
            httpSender {
 | 
			
		||||
                uri = "https://your.server.com/report"
 | 
			
		||||
                httpMethod = HttpSender.Method.POST
 | 
			
		||||
                compress = false
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private fun handleNotificationChannels() {
 | 
			
		||||
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
 | 
			
		||||
            val notificationManager = getSystemService(NOTIFICATION_SERVICE) as NotificationManager
 | 
			
		||||
 
 | 
			
		||||
@@ -44,6 +44,8 @@ import com.google.android.material.floatingactionbutton.FloatingActionButton
 | 
			
		||||
import kotlinx.coroutines.CoroutineScope
 | 
			
		||||
import kotlinx.coroutines.Dispatchers
 | 
			
		||||
import kotlinx.coroutines.launch
 | 
			
		||||
import org.acra.ktx.sendSilentlyWithAcra
 | 
			
		||||
import org.acra.ktx.sendWithAcra
 | 
			
		||||
import org.kodein.di.DI
 | 
			
		||||
import org.kodein.di.DIAware
 | 
			
		||||
import org.kodein.di.android.x.closestDI
 | 
			
		||||
@@ -112,6 +114,7 @@ class ArticleFragment : Fragment(), DIAware {
 | 
			
		||||
                typeface = try {
 | 
			
		||||
                    ResourcesCompat.getFont(requireContext(), resId)!!
 | 
			
		||||
                } catch (e: java.lang.Exception) {
 | 
			
		||||
                    e.sendSilentlyWithAcra()
 | 
			
		||||
                    // Just to be sure
 | 
			
		||||
                    null
 | 
			
		||||
                }
 | 
			
		||||
@@ -217,6 +220,7 @@ class ArticleFragment : Fragment(), DIAware {
 | 
			
		||||
            )
 | 
			
		||||
 | 
			
		||||
        } catch (e: InflateException) {
 | 
			
		||||
            e.sendSilentlyWithAcra()
 | 
			
		||||
            AlertDialog.Builder(requireContext())
 | 
			
		||||
                .setMessage(requireContext().getString(R.string.webview_dialog_issue_message))
 | 
			
		||||
                .setTitle(requireContext().getString(R.string.webview_dialog_issue_title))
 | 
			
		||||
@@ -264,15 +268,18 @@ class ArticleFragment : Fragment(), DIAware {
 | 
			
		||||
                                    URL(response.data!!.url)
 | 
			
		||||
                                    url = response.data!!.url
 | 
			
		||||
                                } catch (e: MalformedURLException) {
 | 
			
		||||
                                    // Mercury returned a relative url. We do nothing.
 | 
			
		||||
                                    // Mercury returned a relative url
 | 
			
		||||
                                    e.sendSilentlyWithAcra()
 | 
			
		||||
                                }
 | 
			
		||||
                            } catch (e: Exception) {
 | 
			
		||||
                                e.sendSilentlyWithAcra()
 | 
			
		||||
                            }
 | 
			
		||||
 | 
			
		||||
                            try {
 | 
			
		||||
                                contentText = response.data!!.content.orEmpty()
 | 
			
		||||
                                htmlToWebview()
 | 
			
		||||
                            } catch (e: Exception) {
 | 
			
		||||
                                e.sendSilentlyWithAcra()
 | 
			
		||||
                            }
 | 
			
		||||
 | 
			
		||||
                            try {
 | 
			
		||||
@@ -288,13 +295,13 @@ class ArticleFragment : Fragment(), DIAware {
 | 
			
		||||
                                            .apply(RequestOptions.fitCenterTransform())
 | 
			
		||||
                                            .into(binding.imageView)
 | 
			
		||||
                                    } catch (e: Exception) {
 | 
			
		||||
                                        e.sendSilentlyWithAcra()
 | 
			
		||||
                                    }
 | 
			
		||||
                                } else {
 | 
			
		||||
                                    binding.imageView.visibility = View.GONE
 | 
			
		||||
                                }
 | 
			
		||||
                            } catch (e: Exception) {
 | 
			
		||||
                                if (context != null) {
 | 
			
		||||
                                }
 | 
			
		||||
                                e.sendSilentlyWithAcra()
 | 
			
		||||
                            }
 | 
			
		||||
 | 
			
		||||
                            try {
 | 
			
		||||
@@ -302,20 +309,17 @@ class ArticleFragment : Fragment(), DIAware {
 | 
			
		||||
 | 
			
		||||
                                binding.progressBar.visibility = View.GONE
 | 
			
		||||
                            } catch (e: Exception) {
 | 
			
		||||
                                if (context != null) {
 | 
			
		||||
                                }
 | 
			
		||||
                                e.sendSilentlyWithAcra()
 | 
			
		||||
                            }
 | 
			
		||||
                        } else {
 | 
			
		||||
                            try {
 | 
			
		||||
                                openInBrowserAfterFailing()
 | 
			
		||||
                            } catch (e: Exception) {
 | 
			
		||||
                                if (context != null) {
 | 
			
		||||
                                }
 | 
			
		||||
                                e.sendSilentlyWithAcra()
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                    } catch (e: Exception) {
 | 
			
		||||
                        if (context != null) {
 | 
			
		||||
                        }
 | 
			
		||||
                        e.sendSilentlyWithAcra()
 | 
			
		||||
                    }
 | 
			
		||||
                } else {
 | 
			
		||||
                    openInBrowserAfterFailing()
 | 
			
		||||
@@ -359,19 +363,25 @@ class ArticleFragment : Fragment(), DIAware {
 | 
			
		||||
                    try {
 | 
			
		||||
                        val image = Glide.with(view).asBitmap().apply(glideOptions).load(url).submit().get()
 | 
			
		||||
                        return WebResourceResponse("image/jpg", "UTF-8", getBitmapInputStream(image, Bitmap.CompressFormat.JPEG))
 | 
			
		||||
                    }catch ( e : ExecutionException) {}
 | 
			
		||||
                    } catch ( e : ExecutionException) {
 | 
			
		||||
                        e.sendSilentlyWithAcra()
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                else if (url.lowercase(Locale.US).contains(".png")) {
 | 
			
		||||
                    try {
 | 
			
		||||
                        val image = Glide.with(view).asBitmap().apply(glideOptions).load(url).submit().get()
 | 
			
		||||
                        return WebResourceResponse("image/jpg", "UTF-8", getBitmapInputStream(image, Bitmap.CompressFormat.PNG))
 | 
			
		||||
                    }catch ( e : ExecutionException) {}
 | 
			
		||||
                    } catch ( e : ExecutionException) {
 | 
			
		||||
                        e.sendSilentlyWithAcra()
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                else if (url.lowercase(Locale.US).contains(".webp")) {
 | 
			
		||||
                    try {
 | 
			
		||||
                        val image = Glide.with(view).asBitmap().apply(glideOptions).load(url).submit().get()
 | 
			
		||||
                        return WebResourceResponse("image/jpg", "UTF-8", getBitmapInputStream(image, Bitmap.CompressFormat.WEBP))
 | 
			
		||||
                    }catch ( e : ExecutionException) {}
 | 
			
		||||
                    } catch ( e : ExecutionException) {
 | 
			
		||||
                        e.sendSilentlyWithAcra()
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                return super.shouldInterceptRequest(view, url)
 | 
			
		||||
@@ -395,6 +405,7 @@ class ArticleFragment : Fragment(), DIAware {
 | 
			
		||||
            val itemUrl = URL(url)
 | 
			
		||||
            baseUrl = itemUrl.protocol + "://" + itemUrl.host
 | 
			
		||||
        } catch (e: MalformedURLException) {
 | 
			
		||||
            e.sendSilentlyWithAcra()
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        val fontName =  when (font) {
 | 
			
		||||
 
 | 
			
		||||
@@ -7,6 +7,7 @@ import bou.amine.apps.readerforselfossv2.utils.getImages
 | 
			
		||||
import com.bumptech.glide.Glide
 | 
			
		||||
import com.bumptech.glide.load.engine.DiskCacheStrategy
 | 
			
		||||
import com.bumptech.glide.request.RequestOptions
 | 
			
		||||
import org.acra.ktx.sendSilentlyWithAcra
 | 
			
		||||
 | 
			
		||||
fun SelfossModel.Item.preloadImages(context: Context) : Boolean {
 | 
			
		||||
    val imageUrls = this.getImages()
 | 
			
		||||
@@ -23,6 +24,7 @@ fun SelfossModel.Item.preloadImages(context: Context) : Boolean {
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    } catch (e : Error) {
 | 
			
		||||
        e.sendSilentlyWithAcra()
 | 
			
		||||
        return false
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -35,7 +37,7 @@ fun String.toTextDrawableString(): String {
 | 
			
		||||
        try {
 | 
			
		||||
            textDrawable.append(s[0])
 | 
			
		||||
        } catch (e: StringIndexOutOfBoundsException) {
 | 
			
		||||
            // We do nothing
 | 
			
		||||
            e.sendSilentlyWithAcra()
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    return textDrawable.toString()
 | 
			
		||||
 
 | 
			
		||||
@@ -17,6 +17,8 @@ import androidx.preference.PreferenceFragmentCompat
 | 
			
		||||
import bou.amine.apps.readerforselfossv2.android.R
 | 
			
		||||
import bou.amine.apps.readerforselfossv2.android.databinding.ActivitySettingsBinding
 | 
			
		||||
import bou.amine.apps.readerforselfossv2.service.AppSettingsService
 | 
			
		||||
import org.acra.ktx.sendSilentlyWithAcra
 | 
			
		||||
import org.acra.ktx.sendWithAcra
 | 
			
		||||
import org.kodein.di.DIAware
 | 
			
		||||
import org.kodein.di.android.closestDI
 | 
			
		||||
import org.kodein.di.instance
 | 
			
		||||
@@ -117,6 +119,7 @@ class SettingsActivity : AppCompatActivity(),
 | 
			
		||||
                                val input: Int = (dest.toString() + source.toString()).toInt()
 | 
			
		||||
                                if (input in 1..200) return@InputFilter null
 | 
			
		||||
                            } catch (nfe: NumberFormatException) {
 | 
			
		||||
                                nfe.sendSilentlyWithAcra()
 | 
			
		||||
                                Toast.makeText(activity, R.string.items_number_should_be_number, Toast.LENGTH_LONG).show()
 | 
			
		||||
                            }
 | 
			
		||||
                            ""
 | 
			
		||||
@@ -140,6 +143,7 @@ class SettingsActivity : AppCompatActivity(),
 | 
			
		||||
                        try {
 | 
			
		||||
                            editText.textSize = editable.toString().toInt().toFloat()
 | 
			
		||||
                        } catch (e: NumberFormatException) {
 | 
			
		||||
                            e.sendSilentlyWithAcra()
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                } }
 | 
			
		||||
@@ -149,6 +153,7 @@ class SettingsActivity : AppCompatActivity(),
 | 
			
		||||
                                val input = (dest.toString() + source.toString()).toInt()
 | 
			
		||||
                                if (input > 0) return@InputFilter null
 | 
			
		||||
                            } catch (nfe: NumberFormatException) {
 | 
			
		||||
                                nfe.sendSilentlyWithAcra()
 | 
			
		||||
                            }
 | 
			
		||||
                            ""
 | 
			
		||||
                        }
 | 
			
		||||
 
 | 
			
		||||
@@ -134,4 +134,7 @@
 | 
			
		||||
    <string name="mode_light">Light mode</string>
 | 
			
		||||
    <string name="drawer_error_loading_sources">Error loading sources…</string>
 | 
			
		||||
    <string name="pref_switch_enable_analytics">Enable analytics</string>
 | 
			
		||||
    <string name="gdpr_dialog_title">The app does not share any personal data about you.</string>
 | 
			
		||||
    <string name="gdpr_dialog_message"><![CDATA[Crash reports sending is now enabled. It can be disabled from the settings page (Settings > Debug). Keep in mind that crash reports are essential for the app development.]]></string>
 | 
			
		||||
    <string name="crash_toast_text">A crash occured. Sending the details to the developper.</string>
 | 
			
		||||
</resources>
 | 
			
		||||
 
 | 
			
		||||
@@ -134,4 +134,7 @@
 | 
			
		||||
    <string name="mode_light">Light mode</string>
 | 
			
		||||
    <string name="drawer_error_loading_sources">Error loading sources…</string>
 | 
			
		||||
    <string name="pref_switch_enable_analytics">Enable analytics</string>
 | 
			
		||||
    <string name="gdpr_dialog_title">The app does not share any personal data about you.</string>
 | 
			
		||||
    <string name="gdpr_dialog_message"><![CDATA[Crash reports sending is now enabled. It can be disabled from the settings page (Settings > Debug). Keep in mind that crash reports are essential for the app development.]]></string>
 | 
			
		||||
    <string name="crash_toast_text">A crash occured. Sending the details to the developper.</string>
 | 
			
		||||
</resources>
 | 
			
		||||
 
 | 
			
		||||
@@ -134,4 +134,7 @@
 | 
			
		||||
    <string name="mode_light">Light mode</string>
 | 
			
		||||
    <string name="drawer_error_loading_sources">Error loading sources…</string>
 | 
			
		||||
    <string name="pref_switch_enable_analytics">Enable analytics</string>
 | 
			
		||||
    <string name="gdpr_dialog_title">The app does not share any personal data about you.</string>
 | 
			
		||||
    <string name="gdpr_dialog_message"><![CDATA[Crash reports sending is now enabled. It can be disabled from the settings page (Settings > Debug). Keep in mind that crash reports are essential for the app development.]]></string>
 | 
			
		||||
    <string name="crash_toast_text">A crash occured. Sending the details to the developper.</string>
 | 
			
		||||
</resources>
 | 
			
		||||
 
 | 
			
		||||
@@ -134,4 +134,7 @@
 | 
			
		||||
    <string name="mode_light">Light mode</string>
 | 
			
		||||
    <string name="drawer_error_loading_sources">Error loading sources…</string>
 | 
			
		||||
    <string name="pref_switch_enable_analytics">Enable analytics</string>
 | 
			
		||||
    <string name="gdpr_dialog_title">The app does not share any personal data about you.</string>
 | 
			
		||||
    <string name="gdpr_dialog_message"><![CDATA[Crash reports sending is now enabled. It can be disabled from the settings page (Settings > Debug). Keep in mind that crash reports are essential for the app development.]]></string>
 | 
			
		||||
    <string name="crash_toast_text">A crash occured. Sending the details to the developper.</string>
 | 
			
		||||
</resources>
 | 
			
		||||
 
 | 
			
		||||
@@ -134,4 +134,7 @@
 | 
			
		||||
    <string name="mode_light">Thème clair</string>
 | 
			
		||||
    <string name="drawer_error_loading_sources">Error loading sources…</string>
 | 
			
		||||
    <string name="pref_switch_enable_analytics">Enable analytics</string>
 | 
			
		||||
    <string name="gdpr_dialog_title">The app does not share any personal data about you.</string>
 | 
			
		||||
    <string name="gdpr_dialog_message"><![CDATA[Crash reports sending is now enabled. It can be disabled from the settings page (Settings > Debug). Keep in mind that crash reports are essential for the app development.]]></string>
 | 
			
		||||
    <string name="crash_toast_text">A crash occured. Sending the details to the developper.</string>
 | 
			
		||||
</resources>
 | 
			
		||||
 
 | 
			
		||||
@@ -134,4 +134,7 @@
 | 
			
		||||
    <string name="mode_light">Light mode</string>
 | 
			
		||||
    <string name="drawer_error_loading_sources">Error loading sources…</string>
 | 
			
		||||
    <string name="pref_switch_enable_analytics">Enable analytics</string>
 | 
			
		||||
    <string name="gdpr_dialog_title">The app does not share any personal data about you.</string>
 | 
			
		||||
    <string name="gdpr_dialog_message"><![CDATA[Crash reports sending is now enabled. It can be disabled from the settings page (Settings > Debug). Keep in mind that crash reports are essential for the app development.]]></string>
 | 
			
		||||
    <string name="crash_toast_text">A crash occured. Sending the details to the developper.</string>
 | 
			
		||||
</resources>
 | 
			
		||||
 
 | 
			
		||||
@@ -134,4 +134,7 @@
 | 
			
		||||
    <string name="mode_light">Light mode</string>
 | 
			
		||||
    <string name="drawer_error_loading_sources">Error loading sources…</string>
 | 
			
		||||
    <string name="pref_switch_enable_analytics">Enable analytics</string>
 | 
			
		||||
    <string name="gdpr_dialog_title">The app does not share any personal data about you.</string>
 | 
			
		||||
    <string name="gdpr_dialog_message"><![CDATA[Crash reports sending is now enabled. It can be disabled from the settings page (Settings > Debug). Keep in mind that crash reports are essential for the app development.]]></string>
 | 
			
		||||
    <string name="crash_toast_text">A crash occured. Sending the details to the developper.</string>
 | 
			
		||||
</resources>
 | 
			
		||||
 
 | 
			
		||||
@@ -134,4 +134,7 @@
 | 
			
		||||
    <string name="mode_light">Light mode</string>
 | 
			
		||||
    <string name="drawer_error_loading_sources">Error loading sources…</string>
 | 
			
		||||
    <string name="pref_switch_enable_analytics">Enable analytics</string>
 | 
			
		||||
    <string name="gdpr_dialog_title">The app does not share any personal data about you.</string>
 | 
			
		||||
    <string name="gdpr_dialog_message"><![CDATA[Crash reports sending is now enabled. It can be disabled from the settings page (Settings > Debug). Keep in mind that crash reports are essential for the app development.]]></string>
 | 
			
		||||
    <string name="crash_toast_text">A crash occured. Sending the details to the developper.</string>
 | 
			
		||||
</resources>
 | 
			
		||||
 
 | 
			
		||||
@@ -134,4 +134,7 @@
 | 
			
		||||
    <string name="mode_light">Light mode</string>
 | 
			
		||||
    <string name="drawer_error_loading_sources">Error loading sources…</string>
 | 
			
		||||
    <string name="pref_switch_enable_analytics">Enable analytics</string>
 | 
			
		||||
    <string name="gdpr_dialog_title">The app does not share any personal data about you.</string>
 | 
			
		||||
    <string name="gdpr_dialog_message"><![CDATA[Crash reports sending is now enabled. It can be disabled from the settings page (Settings > Debug). Keep in mind that crash reports are essential for the app development.]]></string>
 | 
			
		||||
    <string name="crash_toast_text">A crash occured. Sending the details to the developper.</string>
 | 
			
		||||
</resources>
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,7 @@
 | 
			
		||||
<?xml version="1.0" encoding="utf-8"?>
 | 
			
		||||
<resources>
 | 
			
		||||
    <string name="pref_switch_enable_analytics">Enable analytics</string>
 | 
			
		||||
    <string name="gdpr_dialog_title">The app does not share any personal data about you.</string>
 | 
			
		||||
    <string name="gdpr_dialog_message"><![CDATA[Crash reports sending is now enabled. It can be disabled from the settings page (Settings > Debug). Keep in mind that crash reports are essential for the app development.]]></string>
 | 
			
		||||
    <string name="crash_toast_text">A crash occured. Sending the details to the developper.</string>
 | 
			
		||||
</resources>
 | 
			
		||||
@@ -134,4 +134,7 @@
 | 
			
		||||
    <string name="mode_light">Light mode</string>
 | 
			
		||||
    <string name="drawer_error_loading_sources">Error loading sources…</string>
 | 
			
		||||
    <string name="pref_switch_enable_analytics">Enable analytics</string>
 | 
			
		||||
    <string name="gdpr_dialog_title">The app does not share any personal data about you.</string>
 | 
			
		||||
    <string name="gdpr_dialog_message"><![CDATA[Crash reports sending is now enabled. It can be disabled from the settings page (Settings > Debug). Keep in mind that crash reports are essential for the app development.]]></string>
 | 
			
		||||
    <string name="crash_toast_text">A crash occured. Sending the details to the developper.</string>
 | 
			
		||||
</resources>
 | 
			
		||||
 
 | 
			
		||||
@@ -134,4 +134,7 @@
 | 
			
		||||
    <string name="mode_light">Light mode</string>
 | 
			
		||||
    <string name="drawer_error_loading_sources">Error loading sources…</string>
 | 
			
		||||
    <string name="pref_switch_enable_analytics">Enable analytics</string>
 | 
			
		||||
    <string name="gdpr_dialog_title">The app does not share any personal data about you.</string>
 | 
			
		||||
    <string name="gdpr_dialog_message"><![CDATA[Crash reports sending is now enabled. It can be disabled from the settings page (Settings > Debug). Keep in mind that crash reports are essential for the app development.]]></string>
 | 
			
		||||
    <string name="crash_toast_text">A crash occured. Sending the details to the developper.</string>
 | 
			
		||||
</resources>
 | 
			
		||||
 
 | 
			
		||||
@@ -134,4 +134,7 @@
 | 
			
		||||
    <string name="mode_light">Light mode</string>
 | 
			
		||||
    <string name="drawer_error_loading_sources">Error loading sources…</string>
 | 
			
		||||
    <string name="pref_switch_enable_analytics">Enable analytics</string>
 | 
			
		||||
    <string name="gdpr_dialog_title">The app does not share any personal data about you.</string>
 | 
			
		||||
    <string name="gdpr_dialog_message"><![CDATA[Crash reports sending is now enabled. It can be disabled from the settings page (Settings > Debug). Keep in mind that crash reports are essential for the app development.]]></string>
 | 
			
		||||
    <string name="crash_toast_text">A crash occured. Sending the details to the developper.</string>
 | 
			
		||||
</resources>
 | 
			
		||||
 
 | 
			
		||||
@@ -134,4 +134,7 @@
 | 
			
		||||
    <string name="mode_light">Light mode</string>
 | 
			
		||||
    <string name="drawer_error_loading_sources">Error loading sources…</string>
 | 
			
		||||
    <string name="pref_switch_enable_analytics">Enable analytics</string>
 | 
			
		||||
    <string name="gdpr_dialog_title">The app does not share any personal data about you.</string>
 | 
			
		||||
    <string name="gdpr_dialog_message"><![CDATA[Crash reports sending is now enabled. It can be disabled from the settings page (Settings > Debug). Keep in mind that crash reports are essential for the app development.]]></string>
 | 
			
		||||
    <string name="crash_toast_text">A crash occured. Sending the details to the developper.</string>
 | 
			
		||||
</resources>
 | 
			
		||||
 
 | 
			
		||||
@@ -134,4 +134,7 @@
 | 
			
		||||
    <string name="mode_light">Light mode</string>
 | 
			
		||||
    <string name="drawer_error_loading_sources">Error loading sources…</string>
 | 
			
		||||
    <string name="pref_switch_enable_analytics">Enable analytics</string>
 | 
			
		||||
    <string name="gdpr_dialog_title">The app does not share any personal data about you.</string>
 | 
			
		||||
    <string name="gdpr_dialog_message"><![CDATA[Crash reports sending is now enabled. It can be disabled from the settings page (Settings > Debug). Keep in mind that crash reports are essential for the app development.]]></string>
 | 
			
		||||
    <string name="crash_toast_text">A crash occured. Sending the details to the developper.</string>
 | 
			
		||||
</resources>
 | 
			
		||||
 
 | 
			
		||||
@@ -134,4 +134,7 @@
 | 
			
		||||
    <string name="mode_light">浅色模式</string>
 | 
			
		||||
    <string name="drawer_error_loading_sources">Error loading sources…</string>
 | 
			
		||||
    <string name="pref_switch_enable_analytics">Enable analytics</string>
 | 
			
		||||
    <string name="gdpr_dialog_title">The app does not share any personal data about you.</string>
 | 
			
		||||
    <string name="gdpr_dialog_message"><![CDATA[Crash reports sending is now enabled. It can be disabled from the settings page (Settings > Debug). Keep in mind that crash reports are essential for the app development.]]></string>
 | 
			
		||||
    <string name="crash_toast_text">A crash occured. Sending the details to the developper.</string>
 | 
			
		||||
</resources>
 | 
			
		||||
 
 | 
			
		||||
@@ -134,4 +134,7 @@
 | 
			
		||||
    <string name="mode_light">Light mode</string>
 | 
			
		||||
    <string name="drawer_error_loading_sources">Error loading sources…</string>
 | 
			
		||||
    <string name="pref_switch_enable_analytics">Enable analytics</string>
 | 
			
		||||
    <string name="gdpr_dialog_title">The app does not share any personal data about you.</string>
 | 
			
		||||
    <string name="gdpr_dialog_message"><![CDATA[Crash reports sending is now enabled. It can be disabled from the settings page (Settings > Debug). Keep in mind that crash reports are essential for the app development.]]></string>
 | 
			
		||||
    <string name="crash_toast_text">A crash occured. Sending the details to the developper.</string>
 | 
			
		||||
</resources>
 | 
			
		||||
 
 | 
			
		||||
@@ -137,4 +137,7 @@
 | 
			
		||||
    <string name="mode_system">Follow the system setting</string>
 | 
			
		||||
    <string name="mode_light">Light mode</string>
 | 
			
		||||
    <string name="pref_switch_enable_analytics">Enable analytics</string>
 | 
			
		||||
    <string name="gdpr_dialog_title">The app does not share any personal data about you.</string>
 | 
			
		||||
    <string name="gdpr_dialog_message"><![CDATA[Crash reports sending is now enabled. It can be disabled from the settings page (Settings > Debug). Keep in mind that crash reports are essential for the app development.]]></string>
 | 
			
		||||
    <string name="crash_toast_text">A crash occured. Sending the details to the developper.</string>
 | 
			
		||||
</resources>
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user