Initial integration.
This commit is contained in:
parent
f09f731d30
commit
7db91b0f11
@ -1,6 +1,7 @@
|
|||||||
import java.io.ByteArrayOutputStream
|
import java.io.ByteArrayOutputStream
|
||||||
|
|
||||||
val ignoreGitVersion: String by project
|
val ignoreGitVersion: String by project
|
||||||
|
val acraVersion = "5.9.7"
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
id("com.android.application")
|
id("com.android.application")
|
||||||
@ -187,6 +188,9 @@ dependencies {
|
|||||||
testImplementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.0")
|
testImplementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.0")
|
||||||
implementation("org.jetbrains.kotlinx:kotlinx-datetime:0.4.0")
|
implementation("org.jetbrains.kotlinx:kotlinx-datetime:0.4.0")
|
||||||
|
|
||||||
|
implementation("ch.acra:acra-http:$acraVersion")
|
||||||
|
implementation("ch.acra:acra-toast:$acraVersion")
|
||||||
|
|
||||||
// Matomo
|
// Matomo
|
||||||
implementation("com.github.matomo-org:matomo-sdk-android:4.1.4")
|
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.CoroutineScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.launch
|
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.DIAware
|
||||||
import org.kodein.di.android.closestDI
|
import org.kodein.di.android.closestDI
|
||||||
import org.kodein.di.instance
|
import org.kodein.di.instance
|
||||||
import org.matomo.sdk.Tracker
|
import org.matomo.sdk.Tracker
|
||||||
import org.matomo.sdk.extra.TrackHelper
|
import org.matomo.sdk.extra.TrackHelper
|
||||||
|
import java.security.MessageDigest
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
|
|
||||||
|
|
||||||
@ -306,6 +310,8 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener, DIAwar
|
|||||||
|
|
||||||
handleBottomBarActions()
|
handleBottomBarActions()
|
||||||
|
|
||||||
|
handleGDPRDialog(appSettingsService.settings.getBoolean("GDPR_shown", false))
|
||||||
|
|
||||||
handleRecurringTask()
|
handleRecurringTask()
|
||||||
|
|
||||||
CoroutineScope(Dispatchers.Main).launch {
|
CoroutineScope(Dispatchers.Main).launch {
|
||||||
@ -315,6 +321,26 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener, DIAwar
|
|||||||
getElementsAccordingToTab()
|
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() {
|
private fun initDrawer() {
|
||||||
DrawerImageLoader.init(object : AbstractDrawerImageLoader() {
|
DrawerImageLoader.init(object : AbstractDrawerImageLoader() {
|
||||||
override fun set(imageView: ImageView, uri: Uri, placeholder: Drawable, tag: String?) {
|
override fun set(imageView: ImageView, uri: Uri, placeholder: Drawable, tag: String?) {
|
||||||
@ -487,6 +513,7 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener, DIAwar
|
|||||||
val gdColor = try {
|
val gdColor = try {
|
||||||
Color.parseColor(it.color)
|
Color.parseColor(it.color)
|
||||||
} catch (e: IllegalArgumentException) {
|
} catch (e: IllegalArgumentException) {
|
||||||
|
e.sendSilentlyWithAcra()
|
||||||
resources.getColor(R.color.colorPrimary)
|
resources.getColor(R.color.colorPrimary)
|
||||||
}
|
}
|
||||||
gd.setColor(gdColor)
|
gd.setColor(gdColor)
|
||||||
|
@ -29,6 +29,12 @@ import kotlinx.coroutines.CoroutineScope
|
|||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
import kotlinx.coroutines.launch
|
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.kodein.di.*
|
||||||
import org.matomo.sdk.Matomo
|
import org.matomo.sdk.Matomo
|
||||||
import org.matomo.sdk.Tracker
|
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() {
|
private fun handleNotificationChannels() {
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||||
val notificationManager = getSystemService(NOTIFICATION_SERVICE) as NotificationManager
|
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.CoroutineScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
import org.acra.ktx.sendSilentlyWithAcra
|
||||||
|
import org.acra.ktx.sendWithAcra
|
||||||
import org.kodein.di.DI
|
import org.kodein.di.DI
|
||||||
import org.kodein.di.DIAware
|
import org.kodein.di.DIAware
|
||||||
import org.kodein.di.android.x.closestDI
|
import org.kodein.di.android.x.closestDI
|
||||||
@ -112,6 +114,7 @@ class ArticleFragment : Fragment(), DIAware {
|
|||||||
typeface = try {
|
typeface = try {
|
||||||
ResourcesCompat.getFont(requireContext(), resId)!!
|
ResourcesCompat.getFont(requireContext(), resId)!!
|
||||||
} catch (e: java.lang.Exception) {
|
} catch (e: java.lang.Exception) {
|
||||||
|
e.sendSilentlyWithAcra()
|
||||||
// Just to be sure
|
// Just to be sure
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
@ -217,6 +220,7 @@ class ArticleFragment : Fragment(), DIAware {
|
|||||||
)
|
)
|
||||||
|
|
||||||
} catch (e: InflateException) {
|
} catch (e: InflateException) {
|
||||||
|
e.sendSilentlyWithAcra()
|
||||||
AlertDialog.Builder(requireContext())
|
AlertDialog.Builder(requireContext())
|
||||||
.setMessage(requireContext().getString(R.string.webview_dialog_issue_message))
|
.setMessage(requireContext().getString(R.string.webview_dialog_issue_message))
|
||||||
.setTitle(requireContext().getString(R.string.webview_dialog_issue_title))
|
.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)
|
||||||
url = response.data!!.url
|
url = response.data!!.url
|
||||||
} catch (e: MalformedURLException) {
|
} catch (e: MalformedURLException) {
|
||||||
// Mercury returned a relative url. We do nothing.
|
// Mercury returned a relative url
|
||||||
|
e.sendSilentlyWithAcra()
|
||||||
}
|
}
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
|
e.sendSilentlyWithAcra()
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
contentText = response.data!!.content.orEmpty()
|
contentText = response.data!!.content.orEmpty()
|
||||||
htmlToWebview()
|
htmlToWebview()
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
|
e.sendSilentlyWithAcra()
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -288,13 +295,13 @@ class ArticleFragment : Fragment(), DIAware {
|
|||||||
.apply(RequestOptions.fitCenterTransform())
|
.apply(RequestOptions.fitCenterTransform())
|
||||||
.into(binding.imageView)
|
.into(binding.imageView)
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
|
e.sendSilentlyWithAcra()
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
binding.imageView.visibility = View.GONE
|
binding.imageView.visibility = View.GONE
|
||||||
}
|
}
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
if (context != null) {
|
e.sendSilentlyWithAcra()
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -302,20 +309,17 @@ class ArticleFragment : Fragment(), DIAware {
|
|||||||
|
|
||||||
binding.progressBar.visibility = View.GONE
|
binding.progressBar.visibility = View.GONE
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
if (context != null) {
|
e.sendSilentlyWithAcra()
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
try {
|
try {
|
||||||
openInBrowserAfterFailing()
|
openInBrowserAfterFailing()
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
if (context != null) {
|
e.sendSilentlyWithAcra()
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
if (context != null) {
|
e.sendSilentlyWithAcra()
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
openInBrowserAfterFailing()
|
openInBrowserAfterFailing()
|
||||||
@ -359,19 +363,25 @@ class ArticleFragment : Fragment(), DIAware {
|
|||||||
try {
|
try {
|
||||||
val image = Glide.with(view).asBitmap().apply(glideOptions).load(url).submit().get()
|
val image = Glide.with(view).asBitmap().apply(glideOptions).load(url).submit().get()
|
||||||
return WebResourceResponse("image/jpg", "UTF-8", getBitmapInputStream(image, Bitmap.CompressFormat.JPEG))
|
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")) {
|
else if (url.lowercase(Locale.US).contains(".png")) {
|
||||||
try {
|
try {
|
||||||
val image = Glide.with(view).asBitmap().apply(glideOptions).load(url).submit().get()
|
val image = Glide.with(view).asBitmap().apply(glideOptions).load(url).submit().get()
|
||||||
return WebResourceResponse("image/jpg", "UTF-8", getBitmapInputStream(image, Bitmap.CompressFormat.PNG))
|
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")) {
|
else if (url.lowercase(Locale.US).contains(".webp")) {
|
||||||
try {
|
try {
|
||||||
val image = Glide.with(view).asBitmap().apply(glideOptions).load(url).submit().get()
|
val image = Glide.with(view).asBitmap().apply(glideOptions).load(url).submit().get()
|
||||||
return WebResourceResponse("image/jpg", "UTF-8", getBitmapInputStream(image, Bitmap.CompressFormat.WEBP))
|
return WebResourceResponse("image/jpg", "UTF-8", getBitmapInputStream(image, Bitmap.CompressFormat.WEBP))
|
||||||
}catch ( e : ExecutionException) {}
|
} catch ( e : ExecutionException) {
|
||||||
|
e.sendSilentlyWithAcra()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return super.shouldInterceptRequest(view, url)
|
return super.shouldInterceptRequest(view, url)
|
||||||
@ -395,6 +405,7 @@ class ArticleFragment : Fragment(), DIAware {
|
|||||||
val itemUrl = URL(url)
|
val itemUrl = URL(url)
|
||||||
baseUrl = itemUrl.protocol + "://" + itemUrl.host
|
baseUrl = itemUrl.protocol + "://" + itemUrl.host
|
||||||
} catch (e: MalformedURLException) {
|
} catch (e: MalformedURLException) {
|
||||||
|
e.sendSilentlyWithAcra()
|
||||||
}
|
}
|
||||||
|
|
||||||
val fontName = when (font) {
|
val fontName = when (font) {
|
||||||
|
@ -7,6 +7,7 @@ import bou.amine.apps.readerforselfossv2.utils.getImages
|
|||||||
import com.bumptech.glide.Glide
|
import com.bumptech.glide.Glide
|
||||||
import com.bumptech.glide.load.engine.DiskCacheStrategy
|
import com.bumptech.glide.load.engine.DiskCacheStrategy
|
||||||
import com.bumptech.glide.request.RequestOptions
|
import com.bumptech.glide.request.RequestOptions
|
||||||
|
import org.acra.ktx.sendSilentlyWithAcra
|
||||||
|
|
||||||
fun SelfossModel.Item.preloadImages(context: Context) : Boolean {
|
fun SelfossModel.Item.preloadImages(context: Context) : Boolean {
|
||||||
val imageUrls = this.getImages()
|
val imageUrls = this.getImages()
|
||||||
@ -23,6 +24,7 @@ fun SelfossModel.Item.preloadImages(context: Context) : Boolean {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (e : Error) {
|
} catch (e : Error) {
|
||||||
|
e.sendSilentlyWithAcra()
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -35,7 +37,7 @@ fun String.toTextDrawableString(): String {
|
|||||||
try {
|
try {
|
||||||
textDrawable.append(s[0])
|
textDrawable.append(s[0])
|
||||||
} catch (e: StringIndexOutOfBoundsException) {
|
} catch (e: StringIndexOutOfBoundsException) {
|
||||||
// We do nothing
|
e.sendSilentlyWithAcra()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return textDrawable.toString()
|
return textDrawable.toString()
|
||||||
|
@ -17,6 +17,8 @@ import androidx.preference.PreferenceFragmentCompat
|
|||||||
import bou.amine.apps.readerforselfossv2.android.R
|
import bou.amine.apps.readerforselfossv2.android.R
|
||||||
import bou.amine.apps.readerforselfossv2.android.databinding.ActivitySettingsBinding
|
import bou.amine.apps.readerforselfossv2.android.databinding.ActivitySettingsBinding
|
||||||
import bou.amine.apps.readerforselfossv2.service.AppSettingsService
|
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.DIAware
|
||||||
import org.kodein.di.android.closestDI
|
import org.kodein.di.android.closestDI
|
||||||
import org.kodein.di.instance
|
import org.kodein.di.instance
|
||||||
@ -117,6 +119,7 @@ class SettingsActivity : AppCompatActivity(),
|
|||||||
val input: Int = (dest.toString() + source.toString()).toInt()
|
val input: Int = (dest.toString() + source.toString()).toInt()
|
||||||
if (input in 1..200) return@InputFilter null
|
if (input in 1..200) return@InputFilter null
|
||||||
} catch (nfe: NumberFormatException) {
|
} catch (nfe: NumberFormatException) {
|
||||||
|
nfe.sendSilentlyWithAcra()
|
||||||
Toast.makeText(activity, R.string.items_number_should_be_number, Toast.LENGTH_LONG).show()
|
Toast.makeText(activity, R.string.items_number_should_be_number, Toast.LENGTH_LONG).show()
|
||||||
}
|
}
|
||||||
""
|
""
|
||||||
@ -140,6 +143,7 @@ class SettingsActivity : AppCompatActivity(),
|
|||||||
try {
|
try {
|
||||||
editText.textSize = editable.toString().toInt().toFloat()
|
editText.textSize = editable.toString().toInt().toFloat()
|
||||||
} catch (e: NumberFormatException) {
|
} catch (e: NumberFormatException) {
|
||||||
|
e.sendSilentlyWithAcra()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} }
|
} }
|
||||||
@ -149,6 +153,7 @@ class SettingsActivity : AppCompatActivity(),
|
|||||||
val input = (dest.toString() + source.toString()).toInt()
|
val input = (dest.toString() + source.toString()).toInt()
|
||||||
if (input > 0) return@InputFilter null
|
if (input > 0) return@InputFilter null
|
||||||
} catch (nfe: NumberFormatException) {
|
} catch (nfe: NumberFormatException) {
|
||||||
|
nfe.sendSilentlyWithAcra()
|
||||||
}
|
}
|
||||||
""
|
""
|
||||||
}
|
}
|
||||||
|
@ -134,4 +134,7 @@
|
|||||||
<string name="mode_light">Light mode</string>
|
<string name="mode_light">Light mode</string>
|
||||||
<string name="drawer_error_loading_sources">Error loading sources…</string>
|
<string name="drawer_error_loading_sources">Error loading sources…</string>
|
||||||
<string name="pref_switch_enable_analytics">Enable analytics</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>
|
</resources>
|
||||||
|
@ -134,4 +134,7 @@
|
|||||||
<string name="mode_light">Light mode</string>
|
<string name="mode_light">Light mode</string>
|
||||||
<string name="drawer_error_loading_sources">Error loading sources…</string>
|
<string name="drawer_error_loading_sources">Error loading sources…</string>
|
||||||
<string name="pref_switch_enable_analytics">Enable analytics</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>
|
</resources>
|
||||||
|
@ -134,4 +134,7 @@
|
|||||||
<string name="mode_light">Light mode</string>
|
<string name="mode_light">Light mode</string>
|
||||||
<string name="drawer_error_loading_sources">Error loading sources…</string>
|
<string name="drawer_error_loading_sources">Error loading sources…</string>
|
||||||
<string name="pref_switch_enable_analytics">Enable analytics</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>
|
</resources>
|
||||||
|
@ -134,4 +134,7 @@
|
|||||||
<string name="mode_light">Light mode</string>
|
<string name="mode_light">Light mode</string>
|
||||||
<string name="drawer_error_loading_sources">Error loading sources…</string>
|
<string name="drawer_error_loading_sources">Error loading sources…</string>
|
||||||
<string name="pref_switch_enable_analytics">Enable analytics</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>
|
</resources>
|
||||||
|
@ -134,4 +134,7 @@
|
|||||||
<string name="mode_light">Thème clair</string>
|
<string name="mode_light">Thème clair</string>
|
||||||
<string name="drawer_error_loading_sources">Error loading sources…</string>
|
<string name="drawer_error_loading_sources">Error loading sources…</string>
|
||||||
<string name="pref_switch_enable_analytics">Enable analytics</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>
|
</resources>
|
||||||
|
@ -134,4 +134,7 @@
|
|||||||
<string name="mode_light">Light mode</string>
|
<string name="mode_light">Light mode</string>
|
||||||
<string name="drawer_error_loading_sources">Error loading sources…</string>
|
<string name="drawer_error_loading_sources">Error loading sources…</string>
|
||||||
<string name="pref_switch_enable_analytics">Enable analytics</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>
|
</resources>
|
||||||
|
@ -134,4 +134,7 @@
|
|||||||
<string name="mode_light">Light mode</string>
|
<string name="mode_light">Light mode</string>
|
||||||
<string name="drawer_error_loading_sources">Error loading sources…</string>
|
<string name="drawer_error_loading_sources">Error loading sources…</string>
|
||||||
<string name="pref_switch_enable_analytics">Enable analytics</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>
|
</resources>
|
||||||
|
@ -134,4 +134,7 @@
|
|||||||
<string name="mode_light">Light mode</string>
|
<string name="mode_light">Light mode</string>
|
||||||
<string name="drawer_error_loading_sources">Error loading sources…</string>
|
<string name="drawer_error_loading_sources">Error loading sources…</string>
|
||||||
<string name="pref_switch_enable_analytics">Enable analytics</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>
|
</resources>
|
||||||
|
@ -134,4 +134,7 @@
|
|||||||
<string name="mode_light">Light mode</string>
|
<string name="mode_light">Light mode</string>
|
||||||
<string name="drawer_error_loading_sources">Error loading sources…</string>
|
<string name="drawer_error_loading_sources">Error loading sources…</string>
|
||||||
<string name="pref_switch_enable_analytics">Enable analytics</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>
|
</resources>
|
||||||
|
@ -1,4 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources>
|
<resources>
|
||||||
<string name="pref_switch_enable_analytics">Enable analytics</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>
|
</resources>
|
@ -134,4 +134,7 @@
|
|||||||
<string name="mode_light">Light mode</string>
|
<string name="mode_light">Light mode</string>
|
||||||
<string name="drawer_error_loading_sources">Error loading sources…</string>
|
<string name="drawer_error_loading_sources">Error loading sources…</string>
|
||||||
<string name="pref_switch_enable_analytics">Enable analytics</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>
|
</resources>
|
||||||
|
@ -134,4 +134,7 @@
|
|||||||
<string name="mode_light">Light mode</string>
|
<string name="mode_light">Light mode</string>
|
||||||
<string name="drawer_error_loading_sources">Error loading sources…</string>
|
<string name="drawer_error_loading_sources">Error loading sources…</string>
|
||||||
<string name="pref_switch_enable_analytics">Enable analytics</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>
|
</resources>
|
||||||
|
@ -134,4 +134,7 @@
|
|||||||
<string name="mode_light">Light mode</string>
|
<string name="mode_light">Light mode</string>
|
||||||
<string name="drawer_error_loading_sources">Error loading sources…</string>
|
<string name="drawer_error_loading_sources">Error loading sources…</string>
|
||||||
<string name="pref_switch_enable_analytics">Enable analytics</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>
|
</resources>
|
||||||
|
@ -134,4 +134,7 @@
|
|||||||
<string name="mode_light">Light mode</string>
|
<string name="mode_light">Light mode</string>
|
||||||
<string name="drawer_error_loading_sources">Error loading sources…</string>
|
<string name="drawer_error_loading_sources">Error loading sources…</string>
|
||||||
<string name="pref_switch_enable_analytics">Enable analytics</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>
|
</resources>
|
||||||
|
@ -134,4 +134,7 @@
|
|||||||
<string name="mode_light">Light mode</string>
|
<string name="mode_light">Light mode</string>
|
||||||
<string name="drawer_error_loading_sources">Error loading sources…</string>
|
<string name="drawer_error_loading_sources">Error loading sources…</string>
|
||||||
<string name="pref_switch_enable_analytics">Enable analytics</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>
|
</resources>
|
||||||
|
@ -134,4 +134,7 @@
|
|||||||
<string name="mode_light">浅色模式</string>
|
<string name="mode_light">浅色模式</string>
|
||||||
<string name="drawer_error_loading_sources">Error loading sources…</string>
|
<string name="drawer_error_loading_sources">Error loading sources…</string>
|
||||||
<string name="pref_switch_enable_analytics">Enable analytics</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>
|
</resources>
|
||||||
|
@ -134,4 +134,7 @@
|
|||||||
<string name="mode_light">Light mode</string>
|
<string name="mode_light">Light mode</string>
|
||||||
<string name="drawer_error_loading_sources">Error loading sources…</string>
|
<string name="drawer_error_loading_sources">Error loading sources…</string>
|
||||||
<string name="pref_switch_enable_analytics">Enable analytics</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>
|
</resources>
|
||||||
|
@ -137,4 +137,7 @@
|
|||||||
<string name="mode_system">Follow the system setting</string>
|
<string name="mode_system">Follow the system setting</string>
|
||||||
<string name="mode_light">Light mode</string>
|
<string name="mode_light">Light mode</string>
|
||||||
<string name="pref_switch_enable_analytics">Enable analytics</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>
|
</resources>
|
||||||
|
Loading…
Reference in New Issue
Block a user