Safe way to getQuantityString

This commit is contained in:
Koitharu
2025-02-25 08:53:45 +02:00
parent e98f5b9d54
commit 8d44ad8866
17 changed files with 66 additions and 33 deletions

View File

@@ -27,6 +27,7 @@ import org.koitharu.kotatsu.core.ui.list.AdapterDelegateClickListenerAdapter
import org.koitharu.kotatsu.core.ui.list.OnListItemClickListener import org.koitharu.kotatsu.core.ui.list.OnListItemClickListener
import org.koitharu.kotatsu.core.util.ext.defaultPlaceholders import org.koitharu.kotatsu.core.util.ext.defaultPlaceholders
import org.koitharu.kotatsu.core.util.ext.enqueueWith import org.koitharu.kotatsu.core.util.ext.enqueueWith
import org.koitharu.kotatsu.core.util.ext.getQuantityStringSafe
import org.koitharu.kotatsu.core.util.ext.mangaExtra import org.koitharu.kotatsu.core.util.ext.mangaExtra
import org.koitharu.kotatsu.core.util.ext.mangaSourceExtra import org.koitharu.kotatsu.core.util.ext.mangaSourceExtra
import org.koitharu.kotatsu.core.util.ext.newImageRequest import org.koitharu.kotatsu.core.util.ext.newImageRequest
@@ -61,7 +62,13 @@ fun alternativeAD(
} }
binding.textViewSubtitle.text = buildSpannedString { binding.textViewSubtitle.text = buildSpannedString {
if (item.chaptersCount > 0) { if (item.chaptersCount > 0) {
append(context.resources.getQuantityString(R.plurals.chapters, item.chaptersCount, item.chaptersCount)) append(
context.resources.getQuantityStringSafe(
R.plurals.chapters,
item.chaptersCount,
item.chaptersCount,
),
)
} else { } else {
append(context.getString(R.string.no_chapters)) append(context.getString(R.string.no_chapters))
} }
@@ -77,7 +84,10 @@ fun alternativeAD(
} }
} }
} }
binding.progressView.setProgress(item.mangaModel.progress, ListModelDiffCallback.PAYLOAD_PROGRESS_CHANGED in payloads) binding.progressView.setProgress(
item.mangaModel.progress,
ListModelDiffCallback.PAYLOAD_PROGRESS_CHANGED in payloads,
)
binding.chipSource.also { chip -> binding.chipSource.also { chip ->
chip.text = item.manga.source.getTitle(chip.context) chip.text = item.manga.source.getTitle(chip.context)
ImageRequest.Builder(context) ImageRequest.Builder(context)

View File

@@ -3,6 +3,7 @@ package org.koitharu.kotatsu.core.ui.model
import android.content.Context import android.content.Context
import android.text.format.DateUtils import android.text.format.DateUtils
import org.koitharu.kotatsu.R import org.koitharu.kotatsu.R
import org.koitharu.kotatsu.core.util.ext.getQuantityStringSafe
import org.koitharu.kotatsu.core.util.ext.toMillis import org.koitharu.kotatsu.core.util.ext.toMillis
import java.time.LocalDate import java.time.LocalDate
@@ -22,7 +23,7 @@ sealed class DateTimeAgo {
data class MinutesAgo(val minutes: Int) : DateTimeAgo() { data class MinutesAgo(val minutes: Int) : DateTimeAgo() {
override fun format(context: Context): String { override fun format(context: Context): String {
return context.resources.getQuantityString( return context.resources.getQuantityStringSafe(
R.plurals.minutes_ago, R.plurals.minutes_ago,
minutes, minutes,
minutes, minutes,
@@ -34,7 +35,7 @@ sealed class DateTimeAgo {
data class HoursAgo(val hours: Int) : DateTimeAgo() { data class HoursAgo(val hours: Int) : DateTimeAgo() {
override fun format(context: Context): String { override fun format(context: Context): String {
return context.resources.getQuantityString( return context.resources.getQuantityStringSafe(
R.plurals.hours_ago, R.plurals.hours_ago,
hours, hours,
hours, hours,
@@ -66,7 +67,7 @@ sealed class DateTimeAgo {
data class DaysAgo(val days: Int) : DateTimeAgo() { data class DaysAgo(val days: Int) : DateTimeAgo() {
override fun format(context: Context): String { override fun format(context: Context): String {
return context.resources.getQuantityString(R.plurals.days_ago, days, days) return context.resources.getQuantityStringSafe(R.plurals.days_ago, days, days)
} }
override fun toString() = "days_ago_$days" override fun toString() = "days_ago_$days"
@@ -77,7 +78,7 @@ sealed class DateTimeAgo {
return if (months == 0) { return if (months == 0) {
context.getString(R.string.this_month) context.getString(R.string.this_month)
} else { } else {
context.resources.getQuantityString( context.resources.getQuantityStringSafe(
R.plurals.months_ago, R.plurals.months_ago,
months, months,
months, months,

View File

@@ -3,6 +3,7 @@ package org.koitharu.kotatsu.core.util.ext
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.content.Context import android.content.Context
import android.content.res.Resources import android.content.res.Resources
import androidx.annotation.PluralsRes
import androidx.annotation.Px import androidx.annotation.Px
import androidx.core.util.TypedValueCompat import androidx.core.util.TypedValueCompat
import kotlin.math.roundToInt import kotlin.math.roundToInt
@@ -25,3 +26,11 @@ fun Context.getSystemBoolean(resName: String, fallback: Boolean): Boolean {
fallback fallback
} }
} }
fun Resources.getQuantityStringSafe(@PluralsRes resId: Int, quantity: Int, vararg formatArgs: Any): String = try {
getQuantityString(resId, quantity, *formatArgs)
} catch (e: Resources.NotFoundException) {
e.report(silent = true)
e.printStackTraceDebug()
formatArgs.firstOrNull()?.toString() ?: quantity.toString()
}

View File

@@ -12,6 +12,7 @@ import okio.ProtocolException
import org.acra.ktx.sendSilentlyWithAcra import org.acra.ktx.sendSilentlyWithAcra
import org.acra.ktx.sendWithAcra import org.acra.ktx.sendWithAcra
import org.jsoup.HttpStatusException import org.jsoup.HttpStatusException
import org.koitharu.kotatsu.BuildConfig
import org.koitharu.kotatsu.R import org.koitharu.kotatsu.R
import org.koitharu.kotatsu.core.exceptions.BadBackupFormatException import org.koitharu.kotatsu.core.exceptions.BadBackupFormatException
import org.koitharu.kotatsu.core.exceptions.CaughtException import org.koitharu.kotatsu.core.exceptions.CaughtException
@@ -207,10 +208,10 @@ fun Throwable.isNetworkError(): Boolean {
fun Throwable.report(silent: Boolean = false) { fun Throwable.report(silent: Boolean = false) {
val exception = CaughtException(this) val exception = CaughtException(this)
if (silent) { if (!silent) {
exception.sendSilentlyWithAcra()
} else {
exception.sendWithAcra() exception.sendWithAcra()
} else if (!BuildConfig.DEBUG) {
exception.sendSilentlyWithAcra()
} }
} }

View File

@@ -2,6 +2,7 @@ package org.koitharu.kotatsu.details.data
import android.content.res.Resources import android.content.res.Resources
import org.koitharu.kotatsu.R import org.koitharu.kotatsu.R
import org.koitharu.kotatsu.core.util.ext.getQuantityStringSafe
data class ReadingTime( data class ReadingTime(
val minutes: Int, val minutes: Int,
@@ -11,12 +12,12 @@ data class ReadingTime(
fun format(resources: Resources): String = when { fun format(resources: Resources): String = when {
hours == 0 && minutes == 0 -> resources.getString(R.string.less_than_minute) hours == 0 && minutes == 0 -> resources.getString(R.string.less_than_minute)
hours == 0 -> resources.getQuantityString(R.plurals.minutes, minutes, minutes) hours == 0 -> resources.getQuantityStringSafe(R.plurals.minutes, minutes, minutes)
minutes == 0 -> resources.getQuantityString(R.plurals.hours, hours, hours) minutes == 0 -> resources.getQuantityStringSafe(R.plurals.hours, hours, hours)
else -> resources.getString( else -> resources.getString(
R.string.remaining_time_pattern, R.string.remaining_time_pattern,
resources.getQuantityString(R.plurals.hours, hours, hours), resources.getQuantityStringSafe(R.plurals.hours, hours, hours),
resources.getQuantityString(R.plurals.minutes, minutes, minutes), resources.getQuantityStringSafe(R.plurals.minutes, minutes, minutes),
) )
} }

View File

@@ -73,6 +73,7 @@ import org.koitharu.kotatsu.core.util.ext.defaultPlaceholders
import org.koitharu.kotatsu.core.util.ext.drawable import org.koitharu.kotatsu.core.util.ext.drawable
import org.koitharu.kotatsu.core.util.ext.drawableStart import org.koitharu.kotatsu.core.util.ext.drawableStart
import org.koitharu.kotatsu.core.util.ext.enqueueWith import org.koitharu.kotatsu.core.util.ext.enqueueWith
import org.koitharu.kotatsu.core.util.ext.getQuantityStringSafe
import org.koitharu.kotatsu.core.util.ext.isTextTruncated import org.koitharu.kotatsu.core.util.ext.isTextTruncated
import org.koitharu.kotatsu.core.util.ext.joinToStringWithLimit import org.koitharu.kotatsu.core.util.ext.joinToStringWithLimit
import org.koitharu.kotatsu.core.util.ext.mangaSourceExtra import org.koitharu.kotatsu.core.util.ext.mangaSourceExtra
@@ -477,7 +478,7 @@ class DetailsActivity :
info.totalChapters == 0 -> getString(R.string.no_chapters) info.totalChapters == 0 -> getString(R.string.no_chapters)
info.totalChapters == -1 -> getString(R.string.error_occurred) info.totalChapters == -1 -> getString(R.string.error_occurred)
else -> resources.getQuantityString(R.plurals.chapters, info.totalChapters, info.totalChapters) else -> resources.getQuantityStringSafe(R.plurals.chapters, info.totalChapters, info.totalChapters)
.withEstimatedTime(info.estimatedTime) .withEstimatedTime(info.estimatedTime)
} }
textViewProgress.textAndVisible = if (info.percent <= 0f) { textViewProgress.textAndVisible = if (info.percent <= 0f) {

View File

@@ -24,6 +24,7 @@ import org.koitharu.kotatsu.core.ui.AlertDialogFragment
import org.koitharu.kotatsu.core.ui.widgets.TwoLinesItemView import org.koitharu.kotatsu.core.ui.widgets.TwoLinesItemView
import org.koitharu.kotatsu.core.util.ext.findActivity import org.koitharu.kotatsu.core.util.ext.findActivity
import org.koitharu.kotatsu.core.util.ext.getDisplayMessage import org.koitharu.kotatsu.core.util.ext.getDisplayMessage
import org.koitharu.kotatsu.core.util.ext.getQuantityStringSafe
import org.koitharu.kotatsu.core.util.ext.joinToStringWithLimit import org.koitharu.kotatsu.core.util.ext.joinToStringWithLimit
import org.koitharu.kotatsu.core.util.ext.observe import org.koitharu.kotatsu.core.util.ext.observe
import org.koitharu.kotatsu.core.util.ext.observeEvent import org.koitharu.kotatsu.core.util.ext.observeEvent
@@ -169,7 +170,7 @@ class DownloadDialogFragment : AlertDialogFragment<DialogDownloadBinding>(), Vie
with(viewBinding ?: return) { with(viewBinding ?: return) {
// Whole manga // Whole manga
optionWholeManga.subtitle = if (options.wholeManga.chaptersCount > 0) { optionWholeManga.subtitle = if (options.wholeManga.chaptersCount > 0) {
resources.getQuantityString( resources.getQuantityStringSafe(
R.plurals.chapters, R.plurals.chapters,
options.wholeManga.chaptersCount, options.wholeManga.chaptersCount,
options.wholeManga.chaptersCount, options.wholeManga.chaptersCount,
@@ -185,7 +186,7 @@ class DownloadDialogFragment : AlertDialogFragment<DialogDownloadBinding>(), Vie
it.selectedBranch, it.selectedBranch,
) )
optionWholeBranch.subtitle = if (it.chaptersCount > 0) { optionWholeBranch.subtitle = if (it.chaptersCount > 0) {
resources.getQuantityString( resources.getQuantityStringSafe(
R.plurals.chapters, R.plurals.chapters,
it.chaptersCount, it.chaptersCount,
it.chaptersCount, it.chaptersCount,
@@ -199,7 +200,7 @@ class DownloadDialogFragment : AlertDialogFragment<DialogDownloadBinding>(), Vie
options.firstChapters?.let { options.firstChapters?.let {
optionFirstChapters.title = resources.getString( optionFirstChapters.title = resources.getString(
R.string.download_option_first_n_chapters, R.string.download_option_first_n_chapters,
resources.getQuantityString( resources.getQuantityStringSafe(
R.plurals.chapters, R.plurals.chapters,
it.chaptersCount, it.chaptersCount,
it.chaptersCount, it.chaptersCount,
@@ -215,7 +216,7 @@ class DownloadDialogFragment : AlertDialogFragment<DialogDownloadBinding>(), Vie
} else { } else {
resources.getString( resources.getString(
R.string.download_option_next_unread_n_chapters, R.string.download_option_next_unread_n_chapters,
resources.getQuantityString( resources.getQuantityStringSafe(
R.plurals.chapters, R.plurals.chapters,
it.chaptersCount, it.chaptersCount,
it.chaptersCount, it.chaptersCount,

View File

@@ -21,6 +21,7 @@ import org.koitharu.kotatsu.core.ui.BaseListAdapter
import org.koitharu.kotatsu.core.ui.image.TrimTransformation import org.koitharu.kotatsu.core.ui.image.TrimTransformation
import org.koitharu.kotatsu.core.util.ext.defaultPlaceholders import org.koitharu.kotatsu.core.util.ext.defaultPlaceholders
import org.koitharu.kotatsu.core.util.ext.enqueueWith import org.koitharu.kotatsu.core.util.ext.enqueueWith
import org.koitharu.kotatsu.core.util.ext.getQuantityStringSafe
import org.koitharu.kotatsu.core.util.ext.mangaSourceExtra import org.koitharu.kotatsu.core.util.ext.mangaSourceExtra
import org.koitharu.kotatsu.core.util.ext.newImageRequest import org.koitharu.kotatsu.core.util.ext.newImageRequest
import org.koitharu.kotatsu.core.util.ext.textAndVisible import org.koitharu.kotatsu.core.util.ext.textAndVisible
@@ -161,7 +162,7 @@ fun downloadItemAD(
binding.progressBar.isEnabled = true binding.progressBar.isEnabled = true
binding.textViewPercent.isVisible = false binding.textViewPercent.isVisible = false
if (item.chaptersDownloaded > 0) { if (item.chaptersDownloaded > 0) {
binding.textViewDetails.text = context.resources.getQuantityString( binding.textViewDetails.text = context.resources.getQuantityStringSafe(
R.plurals.chapters, R.plurals.chapters,
item.chaptersDownloaded, item.chaptersDownloaded,
item.chaptersDownloaded, item.chaptersDownloaded,

View File

@@ -24,6 +24,7 @@ import com.hannesdorfmann.adapterdelegates4.dsl.adapterDelegateViewBinding
import org.koitharu.kotatsu.R import org.koitharu.kotatsu.R
import org.koitharu.kotatsu.core.util.ext.enqueueWith import org.koitharu.kotatsu.core.util.ext.enqueueWith
import org.koitharu.kotatsu.core.util.ext.getAnimationDuration import org.koitharu.kotatsu.core.util.ext.getAnimationDuration
import org.koitharu.kotatsu.core.util.ext.getQuantityStringSafe
import org.koitharu.kotatsu.core.util.ext.getThemeColor import org.koitharu.kotatsu.core.util.ext.getThemeColor
import org.koitharu.kotatsu.core.util.ext.mangaSourceExtra import org.koitharu.kotatsu.core.util.ext.mangaSourceExtra
import org.koitharu.kotatsu.core.util.ext.newImageRequest import org.koitharu.kotatsu.core.util.ext.newImageRequest
@@ -79,7 +80,7 @@ fun categoryAD(
binding.textViewSubtitle.text = if (item.mangaCount == 0) { binding.textViewSubtitle.text = if (item.mangaCount == 0) {
getString(R.string.empty) getString(R.string.empty)
} else { } else {
context.resources.getQuantityString( context.resources.getQuantityStringSafe(
R.plurals.items, R.plurals.items,
item.mangaCount, item.mangaCount,
item.mangaCount, item.mangaCount,
@@ -139,7 +140,7 @@ fun allCategoriesAD(
binding.textViewSubtitle.text = if (item.mangaCount == 0) { binding.textViewSubtitle.text = if (item.mangaCount == 0) {
getString(R.string.empty) getString(R.string.empty)
} else { } else {
context.resources.getQuantityString( context.resources.getQuantityStringSafe(
R.plurals.items, R.plurals.items,
item.mangaCount, item.mangaCount,
item.mangaCount, item.mangaCount,

View File

@@ -16,6 +16,7 @@ import org.koitharu.kotatsu.core.ui.AlertDialogFragment
import org.koitharu.kotatsu.core.ui.widgets.SegmentedBarView import org.koitharu.kotatsu.core.ui.widgets.SegmentedBarView
import org.koitharu.kotatsu.core.util.FileSize import org.koitharu.kotatsu.core.util.FileSize
import org.koitharu.kotatsu.core.util.KotatsuColors import org.koitharu.kotatsu.core.util.KotatsuColors
import org.koitharu.kotatsu.core.util.ext.getQuantityStringSafe
import org.koitharu.kotatsu.core.util.ext.observe import org.koitharu.kotatsu.core.util.ext.observe
import org.koitharu.kotatsu.core.util.ext.observeEvent import org.koitharu.kotatsu.core.util.ext.observeEvent
import org.koitharu.kotatsu.core.util.ext.setProgressIcon import org.koitharu.kotatsu.core.util.ext.setProgressIcon
@@ -73,7 +74,7 @@ class LocalInfoDialog : AlertDialogFragment<DialogLocalInfoBinding>(), View.OnCl
} else { } else {
c.getString( c.getString(
R.string.chapters_deleted_pattern, R.string.chapters_deleted_pattern,
c.resources.getQuantityString(R.plurals.chapters, result.first, result.first), c.resources.getQuantityStringSafe(R.plurals.chapters, result.first, result.first),
FileSize.BYTES.format(c, result.second), FileSize.BYTES.format(c, result.second),
) )
} }

View File

@@ -20,6 +20,7 @@ import org.koitharu.kotatsu.core.prefs.AppSettings
import org.koitharu.kotatsu.core.prefs.DownloadFormat import org.koitharu.kotatsu.core.prefs.DownloadFormat
import org.koitharu.kotatsu.core.prefs.TriStateOption import org.koitharu.kotatsu.core.prefs.TriStateOption
import org.koitharu.kotatsu.core.ui.BasePreferenceFragment import org.koitharu.kotatsu.core.ui.BasePreferenceFragment
import org.koitharu.kotatsu.core.util.ext.getQuantityStringSafe
import org.koitharu.kotatsu.core.util.ext.printStackTraceDebug import org.koitharu.kotatsu.core.util.ext.printStackTraceDebug
import org.koitharu.kotatsu.core.util.ext.resolveFile import org.koitharu.kotatsu.core.util.ext.resolveFile
import org.koitharu.kotatsu.core.util.ext.setDefaultValueCompat import org.koitharu.kotatsu.core.util.ext.setDefaultValueCompat
@@ -145,7 +146,7 @@ class DownloadsSettingsFragment :
private fun Preference.bindDirectoriesCount() { private fun Preference.bindDirectoriesCount() {
viewLifecycleScope.launch { viewLifecycleScope.launch {
val dirs = storageManager.getReadableDirs().size val dirs = storageManager.getReadableDirs().size
summary = resources.getQuantityString(R.plurals.items, dirs, dirs) summary = resources.getQuantityStringSafe(R.plurals.items, dirs, dirs)
} }
} }

View File

@@ -12,6 +12,7 @@ import org.koitharu.kotatsu.R
import org.koitharu.kotatsu.core.prefs.AppSettings import org.koitharu.kotatsu.core.prefs.AppSettings
import org.koitharu.kotatsu.core.ui.BasePreferenceFragment import org.koitharu.kotatsu.core.ui.BasePreferenceFragment
import org.koitharu.kotatsu.core.util.ext.addMenuProvider import org.koitharu.kotatsu.core.util.ext.addMenuProvider
import org.koitharu.kotatsu.core.util.ext.getQuantityStringSafe
import org.koitharu.kotatsu.core.util.ext.observe import org.koitharu.kotatsu.core.util.ext.observe
import org.koitharu.kotatsu.settings.search.SettingsSearchMenuProvider import org.koitharu.kotatsu.settings.search.SettingsSearchMenuProvider
import org.koitharu.kotatsu.settings.search.SettingsSearchViewModel import org.koitharu.kotatsu.settings.search.SettingsSearchViewModel
@@ -42,7 +43,7 @@ class RootSettingsFragment : BasePreferenceFragment(0) {
pref.summary = if (it >= 0) { pref.summary = if (it >= 0) {
getString(R.string.enabled_d_of_d, it, total) getString(R.string.enabled_d_of_d, it, total)
} else { } else {
resources.getQuantityString(R.plurals.items, total, total) resources.getQuantityStringSafe(R.plurals.items, total, total)
} }
} }
} }

View File

@@ -12,6 +12,7 @@ import org.koitharu.kotatsu.R
import org.koitharu.kotatsu.core.nav.router import org.koitharu.kotatsu.core.nav.router
import org.koitharu.kotatsu.core.prefs.AppSettings import org.koitharu.kotatsu.core.prefs.AppSettings
import org.koitharu.kotatsu.core.ui.BasePreferenceFragment import org.koitharu.kotatsu.core.ui.BasePreferenceFragment
import org.koitharu.kotatsu.core.util.ext.getQuantityStringSafe
import org.koitharu.kotatsu.core.util.ext.observe import org.koitharu.kotatsu.core.util.ext.observe
import org.koitharu.kotatsu.core.util.ext.setDefaultValueCompat import org.koitharu.kotatsu.core.util.ext.setDefaultValueCompat
import org.koitharu.kotatsu.explore.data.SourcesSortOrder import org.koitharu.kotatsu.explore.data.SourcesSortOrder
@@ -37,7 +38,7 @@ class SourcesSettingsFragment : BasePreferenceFragment(R.string.remote_sources),
findPreference<Preference>(AppSettings.KEY_REMOTE_SOURCES)?.let { pref -> findPreference<Preference>(AppSettings.KEY_REMOTE_SOURCES)?.let { pref ->
viewModel.enabledSourcesCount.observe(viewLifecycleOwner) { viewModel.enabledSourcesCount.observe(viewLifecycleOwner) {
pref.summary = if (it >= 0) { pref.summary = if (it >= 0) {
resources.getQuantityString(R.plurals.items, it, it) resources.getQuantityStringSafe(R.plurals.items, it, it)
} else { } else {
null null
} }

View File

@@ -14,6 +14,7 @@ import org.koitharu.kotatsu.core.prefs.AppSettings
import org.koitharu.kotatsu.core.ui.BasePreferenceFragment import org.koitharu.kotatsu.core.ui.BasePreferenceFragment
import org.koitharu.kotatsu.core.ui.util.ReversibleActionObserver import org.koitharu.kotatsu.core.ui.util.ReversibleActionObserver
import org.koitharu.kotatsu.core.util.FileSize import org.koitharu.kotatsu.core.util.FileSize
import org.koitharu.kotatsu.core.util.ext.getQuantityStringSafe
import org.koitharu.kotatsu.core.util.ext.observe import org.koitharu.kotatsu.core.util.ext.observe
import org.koitharu.kotatsu.core.util.ext.observeEvent import org.koitharu.kotatsu.core.util.ext.observeEvent
import org.koitharu.kotatsu.local.data.CacheDir import org.koitharu.kotatsu.local.data.CacheDir
@@ -38,7 +39,7 @@ class StorageManageSettingsFragment : BasePreferenceFragment(R.string.storage_us
pref.summary = if (it < 0) { pref.summary = if (it < 0) {
view.context.getString(R.string.loading_) view.context.getString(R.string.loading_)
} else { } else {
pref.context.resources.getQuantityString(R.plurals.items, it, it) pref.context.resources.getQuantityStringSafe(R.plurals.items, it, it)
} }
} }
} }
@@ -47,7 +48,7 @@ class StorageManageSettingsFragment : BasePreferenceFragment(R.string.storage_us
pref.summary = if (it < 0) { pref.summary = if (it < 0) {
view.context.getString(R.string.loading_) view.context.getString(R.string.loading_)
} else { } else {
pref.context.resources.getQuantityString(R.plurals.items, it, it) pref.context.resources.getQuantityStringSafe(R.plurals.items, it, it)
} }
} }
} }
@@ -118,7 +119,7 @@ class StorageManageSettingsFragment : BasePreferenceFragment(R.string.storage_us
} else { } else {
c.getString( c.getString(
R.string.chapters_deleted_pattern, R.string.chapters_deleted_pattern,
c.resources.getQuantityString(R.plurals.chapters, result.first, result.first), c.resources.getQuantityStringSafe(R.plurals.chapters, result.first, result.first),
FileSize.BYTES.format(c, result.second), FileSize.BYTES.format(c, result.second),
) )
} }

View File

@@ -58,6 +58,7 @@ import org.koitharu.kotatsu.core.util.ext.awaitUniqueWorkInfoByName
import org.koitharu.kotatsu.core.util.ext.awaitWorkInfosByTag import org.koitharu.kotatsu.core.util.ext.awaitWorkInfosByTag
import org.koitharu.kotatsu.core.util.ext.checkNotificationPermission import org.koitharu.kotatsu.core.util.ext.checkNotificationPermission
import org.koitharu.kotatsu.core.util.ext.flatten import org.koitharu.kotatsu.core.util.ext.flatten
import org.koitharu.kotatsu.core.util.ext.getQuantityStringSafe
import org.koitharu.kotatsu.core.util.ext.mangaSourceExtra import org.koitharu.kotatsu.core.util.ext.mangaSourceExtra
import org.koitharu.kotatsu.core.util.ext.printStackTraceDebug import org.koitharu.kotatsu.core.util.ext.printStackTraceDebug
import org.koitharu.kotatsu.core.util.ext.sanitize import org.koitharu.kotatsu.core.util.ext.sanitize
@@ -311,7 +312,7 @@ class SuggestionsWorker @AssistedInject constructor(
appendLine() appendLine()
bold { bold {
append( append(
applicationContext.resources.getQuantityString( applicationContext.resources.getQuantityStringSafe(
R.plurals.chapters, R.plurals.chapters,
chaptersCount, chaptersCount,
chaptersCount, chaptersCount,

View File

@@ -10,6 +10,7 @@ import org.koitharu.kotatsu.core.ui.list.OnListItemClickListener
import org.koitharu.kotatsu.core.util.ext.defaultPlaceholders import org.koitharu.kotatsu.core.util.ext.defaultPlaceholders
import org.koitharu.kotatsu.core.util.ext.drawableStart import org.koitharu.kotatsu.core.util.ext.drawableStart
import org.koitharu.kotatsu.core.util.ext.enqueueWith import org.koitharu.kotatsu.core.util.ext.enqueueWith
import org.koitharu.kotatsu.core.util.ext.getQuantityStringSafe
import org.koitharu.kotatsu.core.util.ext.mangaSourceExtra import org.koitharu.kotatsu.core.util.ext.mangaSourceExtra
import org.koitharu.kotatsu.core.util.ext.newImageRequest import org.koitharu.kotatsu.core.util.ext.newImageRequest
import org.koitharu.kotatsu.databinding.ItemFeedBinding import org.koitharu.kotatsu.databinding.ItemFeedBinding
@@ -37,7 +38,7 @@ fun feedItemAD(
enqueueWith(coil) enqueueWith(coil)
} }
binding.textViewTitle.text = item.title binding.textViewTitle.text = item.title
binding.textViewSummary.text = context.resources.getQuantityString( binding.textViewSummary.text = context.resources.getQuantityStringSafe(
R.plurals.new_chapters, R.plurals.new_chapters,
item.count, item.count,
item.count, item.count,

View File

@@ -14,12 +14,12 @@ import androidx.core.app.PendingIntentCompat
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import coil3.ImageLoader import coil3.ImageLoader
import coil3.request.ImageRequest import coil3.request.ImageRequest
import dagger.hilt.android.qualifiers.ApplicationContext
import org.koitharu.kotatsu.R import org.koitharu.kotatsu.R
import org.koitharu.kotatsu.core.LocalizedAppContext import org.koitharu.kotatsu.core.LocalizedAppContext
import org.koitharu.kotatsu.core.nav.AppRouter import org.koitharu.kotatsu.core.nav.AppRouter
import org.koitharu.kotatsu.core.prefs.AppSettings import org.koitharu.kotatsu.core.prefs.AppSettings
import org.koitharu.kotatsu.core.util.ext.checkNotificationPermission import org.koitharu.kotatsu.core.util.ext.checkNotificationPermission
import org.koitharu.kotatsu.core.util.ext.getQuantityStringSafe
import org.koitharu.kotatsu.core.util.ext.mangaSourceExtra import org.koitharu.kotatsu.core.util.ext.mangaSourceExtra
import org.koitharu.kotatsu.core.util.ext.toBitmapOrNull import org.koitharu.kotatsu.core.util.ext.toBitmapOrNull
import org.koitharu.kotatsu.parsers.model.Manga import org.koitharu.kotatsu.parsers.model.Manga
@@ -55,7 +55,7 @@ class TrackerNotificationHelper @Inject constructor(
} }
val id = manga.url.hashCode() val id = manga.url.hashCode()
val builder = NotificationCompat.Builder(applicationContext, CHANNEL_ID) val builder = NotificationCompat.Builder(applicationContext, CHANNEL_ID)
val summary = applicationContext.resources.getQuantityString( val summary = applicationContext.resources.getQuantityStringSafe(
R.plurals.new_chapters, R.plurals.new_chapters,
newChapters.size, newChapters.size,
newChapters.size, newChapters.size,
@@ -107,7 +107,7 @@ class TrackerNotificationHelper @Inject constructor(
val newChaptersCount = notifications.sumOf { it.newChapters } val newChaptersCount = notifications.sumOf { it.newChapters }
val builder = NotificationCompat.Builder(applicationContext, CHANNEL_ID) val builder = NotificationCompat.Builder(applicationContext, CHANNEL_ID)
with(builder) { with(builder) {
val title = applicationContext.resources.getQuantityString( val title = applicationContext.resources.getQuantityStringSafe(
R.plurals.new_chapters, R.plurals.new_chapters,
newChaptersCount, newChaptersCount,
newChaptersCount, newChaptersCount,