Compare commits

...

5 Commits

Author SHA1 Message Date
e37455e790 Update parsers and add support for Upcoming state 2023-12-28 17:48:00 +02:00
Paper Jack
36259ba901 Translated using Weblate (Italian)
Currently translated at 100.0% (546 of 546 strings)

Co-authored-by: Paper Jack <paperjack@tutanota.com>
Translate-URL: https://hosted.weblate.org/projects/kotatsu/strings/it/
Translation: Kotatsu/Strings
2023-12-28 16:50:47 +02:00
Nicolò Bertazzo
5b041b9a49 Translated using Weblate (Italian)
Currently translated at 100.0% (546 of 546 strings)

Co-authored-by: Nicolò Bertazzo <n.bertazzo@protonmail.com>
Translate-URL: https://hosted.weblate.org/projects/kotatsu/strings/it/
Translation: Kotatsu/Strings
2023-12-28 16:50:47 +02:00
1734e888d6 Move new sources tip to catalog 2023-12-26 20:24:14 +02:00
9108646cea Update parsers 2023-12-25 19:52:37 +02:00
16 changed files with 296 additions and 92 deletions

1
.gitignore vendored
View File

@@ -10,6 +10,7 @@
/.idea/compiler.xml
/.idea/workspace.xml
/.idea/navEditor.xml
/.idea/ktlint-plugin.xml
/.idea/assetWizardSettings.xml
/.idea/kotlinScripting.xml
/.idea/kotlinc.xml

View File

@@ -16,8 +16,8 @@ android {
applicationId 'org.koitharu.kotatsu'
minSdk = 21
targetSdk = 34
versionCode = 608
versionName = '6.5.2'
versionCode = 609
versionName = '6.5.3'
generatedDensities = []
testInstrumentationRunner 'org.koitharu.kotatsu.HiltTestRunner'
ksp {
@@ -82,7 +82,7 @@ afterEvaluate {
}
dependencies {
//noinspection GradleDependency
implementation('com.github.KotatsuApp:kotatsu-parsers:4a0e7221b0') {
implementation('com.github.KotatsuApp:kotatsu-parsers:a228d71d57') {
exclude group: 'org.json', module: 'json'
}

View File

@@ -12,6 +12,7 @@ import org.koitharu.kotatsu.parsers.model.MangaChapter
import org.koitharu.kotatsu.parsers.model.MangaSource
import org.koitharu.kotatsu.parsers.model.MangaState
import org.koitharu.kotatsu.parsers.util.mapToSet
import com.google.android.material.R as materialR
@JvmName("mangaIds")
fun Collection<Manga>.ids() = mapToSet { it.id }
@@ -42,15 +43,17 @@ val MangaState.titleResId: Int
MangaState.FINISHED -> R.string.state_finished
MangaState.ABANDONED -> R.string.state_abandoned
MangaState.PAUSED -> R.string.state_paused
MangaState.UPCOMING -> R.string.state_upcoming
}
@get:DrawableRes
val MangaState.iconResId: Int
get() = when (this) {
MangaState.ONGOING -> R.drawable.ic_state_ongoing
MangaState.ONGOING -> R.drawable.ic_play
MangaState.FINISHED -> R.drawable.ic_state_finished
MangaState.ABANDONED -> R.drawable.ic_state_abandoned
MangaState.PAUSED -> R.drawable.ic_action_pause
MangaState.UPCOMING -> materialR.drawable.ic_clock_black_24dp
}
fun Manga.findChapter(id: Long): MangaChapter? {

View File

@@ -12,4 +12,5 @@ val SortOrder.titleRes: Int
SortOrder.RATING -> R.string.by_rating
SortOrder.NEWEST -> R.string.newest
SortOrder.ALPHABETICAL -> R.string.by_name
SortOrder.ALPHABETICAL_DESC -> R.string.by_name_reverse
}

View File

@@ -30,6 +30,8 @@ import org.koitharu.kotatsu.bookmarks.domain.Bookmark
import org.koitharu.kotatsu.bookmarks.ui.adapter.BookmarksAdapter
import org.koitharu.kotatsu.bookmarks.ui.sheet.BookmarksSheet
import org.koitharu.kotatsu.core.model.countChaptersByBranch
import org.koitharu.kotatsu.core.model.iconResId
import org.koitharu.kotatsu.core.model.titleResId
import org.koitharu.kotatsu.core.ui.BaseFragment
import org.koitharu.kotatsu.core.ui.BaseListAdapter
import org.koitharu.kotatsu.core.ui.image.CoverSizeResolver
@@ -66,7 +68,6 @@ import org.koitharu.kotatsu.list.ui.size.StaticItemSizeResolver
import org.koitharu.kotatsu.main.ui.owners.NoModalBottomSheetOwner
import org.koitharu.kotatsu.parsers.model.Manga
import org.koitharu.kotatsu.parsers.model.MangaSource
import org.koitharu.kotatsu.parsers.model.MangaState
import org.koitharu.kotatsu.parsers.model.MangaTag
import org.koitharu.kotatsu.reader.ui.ReaderActivity
import org.koitharu.kotatsu.scrobbling.common.domain.model.ScrobblingInfo
@@ -181,28 +182,13 @@ class DetailsFragment :
ratingBar.isVisible = false
}
when (manga.state) {
MangaState.FINISHED -> infoLayout.textViewState.apply {
textAndVisible = resources.getString(R.string.state_finished)
drawableTop = ContextCompat.getDrawable(context, R.drawable.ic_state_finished)
infoLayout.textViewState.apply {
manga.state?.let { state ->
textAndVisible = resources.getString(state.titleResId)
drawableTop = ContextCompat.getDrawable(context, state.iconResId)
} ?: run {
isVisible = false
}
MangaState.ONGOING -> infoLayout.textViewState.apply {
textAndVisible = resources.getString(R.string.state_ongoing)
drawableTop = ContextCompat.getDrawable(context, R.drawable.ic_state_ongoing)
}
MangaState.ABANDONED -> infoLayout.textViewState.apply {
textAndVisible = resources.getString(R.string.state_abandoned)
drawableTop = ContextCompat.getDrawable(context, R.drawable.ic_state_abandoned)
}
MangaState.PAUSED -> infoLayout.textViewState.apply {
textAndVisible = resources.getString(R.string.state_paused)
drawableTop = ContextCompat.getDrawable(context, R.drawable.ic_action_pause)
}
null -> infoLayout.textViewState.isVisible = false
}
if (manga.source == MangaSource.LOCAL) {
infoLayout.textViewSource.isVisible = false

View File

@@ -111,7 +111,7 @@ class ExploreFragment :
}
override fun onListHeaderClick(item: ListHeader, view: View) {
startActivity(SettingsActivity.newManageSourcesIntent(view.context))
startActivity(Intent(view.context, SourcesCatalogActivity::class.java))
}
override fun onPrimaryButtonClick(tipView: TipView) {

View File

@@ -29,7 +29,6 @@ import org.koitharu.kotatsu.list.ui.model.EmptyHint
import org.koitharu.kotatsu.list.ui.model.ListHeader
import org.koitharu.kotatsu.list.ui.model.ListModel
import org.koitharu.kotatsu.list.ui.model.LoadingState
import org.koitharu.kotatsu.list.ui.model.TipModel
import org.koitharu.kotatsu.parsers.model.Manga
import org.koitharu.kotatsu.parsers.model.MangaSource
import org.koitharu.kotatsu.parsers.util.runCatchingCancellable
@@ -126,24 +125,18 @@ class ExploreViewModel @Inject constructor(
randomLoading: Boolean,
newSources: Set<MangaSource>,
): List<ListModel> {
val result = ArrayList<ListModel>(sources.size + 4)
val result = ArrayList<ListModel>(sources.size + 3)
result += ExploreButtons(randomLoading)
if (recommendation != null) {
result += ListHeader(R.string.suggestions)
result += RecommendationsItem(recommendation)
}
if (sources.isNotEmpty()) {
result += ListHeader(R.string.remote_sources, R.string.manage)
if (newSources.isNotEmpty()) {
result += TipModel(
key = TIP_NEW_SOURCES,
title = R.string.new_sources_text,
text = R.string.new_sources_text,
icon = R.drawable.ic_explore_normal,
primaryButtonText = R.string.manage,
secondaryButtonText = R.string.discard,
)
}
result += ListHeader(
textRes = R.string.remote_sources,
buttonTextRes = R.string.catalog,
badge = if (newSources.isNotEmpty()) "" else null,
)
sources.mapTo(result) { MangaSourceItem(it, isGrid) }
} else {
result += EmptyHint(

View File

@@ -14,22 +14,37 @@ import com.google.android.material.R as materialR
@CheckResult
fun View.bindBadge(badge: BadgeDrawable?, counter: Int): BadgeDrawable? {
return if (counter > 0) {
val badgeDrawable = badge ?: initBadge(this)
badgeDrawable.number = counter
badgeDrawable.isVisible = true
badgeDrawable.align(this)
badgeDrawable
} else {
badge?.isVisible = false
badge
}
return bindBadgeImpl(badge, null, counter)
}
@CheckResult
fun View.bindBadge(badge: BadgeDrawable?, text: String?): BadgeDrawable? {
return bindBadgeImpl(badge, text, 0)
}
fun View.clearBadge(badge: BadgeDrawable?) {
BadgeUtils.detachBadgeDrawable(badge, this)
}
private fun View.bindBadgeImpl(
badge: BadgeDrawable?,
text: String?,
counter: Int,
): BadgeDrawable? = if (text != null || counter > 0) {
val badgeDrawable = badge ?: initBadge(this)
if (counter > 0) {
badgeDrawable.number = counter
} else {
badgeDrawable.text = text?.takeUnless { it.isEmpty() }
}
badgeDrawable.isVisible = true
badgeDrawable.align(this)
badgeDrawable
} else {
badge?.isVisible = false
badge
}
private fun initBadge(anchor: View): BadgeDrawable {
val badge = BadgeDrawable.create(anchor.context)
val resources = anchor.resources

View File

@@ -2,6 +2,7 @@ package org.koitharu.kotatsu.list.ui.adapter
import androidx.core.view.isInvisible
import androidx.core.view.isVisible
import com.google.android.material.badge.BadgeDrawable
import com.hannesdorfmann.adapterdelegates4.dsl.adapterDelegateViewBinding
import org.koitharu.kotatsu.databinding.ItemHeaderButtonBinding
import org.koitharu.kotatsu.list.ui.model.ListHeader
@@ -12,6 +13,8 @@ fun listHeaderAD(
) = adapterDelegateViewBinding<ListHeader, ListModel, ItemHeaderButtonBinding>(
{ inflater, parent -> ItemHeaderButtonBinding.inflate(inflater, parent, false) },
) {
var badge: BadgeDrawable? = null
if (listener != null) {
binding.buttonMore.setOnClickListener {
listener.onListHeaderClick(item, it)
@@ -23,9 +26,11 @@ fun listHeaderAD(
if (item.buttonTextRes == 0) {
binding.buttonMore.isInvisible = true
binding.buttonMore.text = null
binding.buttonMore.clearBadge(badge)
} else {
binding.buttonMore.setText(item.buttonTextRes)
binding.buttonMore.isVisible = true
badge = itemView.bindBadge(badge, item.badge)
}
}
}

View File

@@ -6,38 +6,41 @@ import org.koitharu.kotatsu.core.ui.model.DateTimeAgo
@Suppress("DataClassPrivateConstructor")
data class ListHeader private constructor(
private val text: CharSequence?,
@StringRes private val textRes: Int,
private val dateTimeAgo: DateTimeAgo?,
private val textRaw: Any,
@StringRes val buttonTextRes: Int,
val payload: Any?,
val badge: String?,
) : ListModel {
constructor(
text: CharSequence,
@StringRes buttonTextRes: Int = 0,
payload: Any? = null,
) : this(text, 0, null, buttonTextRes, payload)
badge: String? = null,
) : this(textRaw = text, buttonTextRes, payload, badge)
constructor(
@StringRes textRes: Int,
@StringRes buttonTextRes: Int = 0,
payload: Any? = null,
) : this(null, textRes, null, buttonTextRes, payload)
badge: String? = null,
) : this(textRaw = textRes, buttonTextRes, payload, badge)
constructor(
dateTimeAgo: DateTimeAgo,
@StringRes buttonTextRes: Int = 0,
payload: Any? = null,
) : this(null, 0, dateTimeAgo, buttonTextRes, payload)
badge: String? = null,
) : this(textRaw = dateTimeAgo, buttonTextRes, payload, badge)
fun getText(context: Context): CharSequence? = when {
text != null -> text
textRes != 0 -> context.getString(textRes)
else -> dateTimeAgo?.format(context.resources)
fun getText(context: Context): CharSequence? = when (textRaw) {
is CharSequence -> textRaw
is Int -> if (textRaw != 0) context.getString(textRaw) else null
is DateTimeAgo -> textRaw.format(context.resources)
else -> null
}
override fun areItemsTheSame(other: ListModel): Boolean {
return other is ListHeader && text == other.text && dateTimeAgo == other.dateTimeAgo && textRes == other.textRes
return other is ListHeader && textRaw == other.textRaw
}
}

View File

@@ -125,7 +125,7 @@ class MainActivity : BaseActivity<ActivityMainBinding>(), AppBarOwner, BottomNav
viewModel.onError.observeEvent(this, SnackbarErrorObserver(viewBinding.container, null))
viewModel.isLoading.observe(this, this::onLoadingStateChanged)
viewModel.isResumeEnabled.observe(this, this::onResumeEnabledChanged)
viewModel.counters.observe(this, ::onCountersChanged)
viewModel.feedCounter.observe(this, ::onFeedCounterChanged)
viewModel.appUpdate.observe(this, MenuInvalidator(this))
viewModel.onFirstStart.observeEvent(this) {
WelcomeSheet.show(supportFragmentManager)
@@ -278,10 +278,8 @@ class MainActivity : BaseActivity<ActivityMainBinding>(), AppBarOwner, BottomNav
startActivity(IntentBuilder(this).manga(manga).build(), options)
}
private fun onCountersChanged(counters: Map<NavItem, Int>) {
counters.forEach { (navItem, counter) ->
navigationDelegate.setCounter(navItem, counter)
}
private fun onFeedCounterChanged(counter: Int) {
navigationDelegate.setCounter(NavItem.FEED, counter)
}
private fun onIncognitoModeChanged(isIncognito: Boolean) {

View File

@@ -4,15 +4,11 @@ import androidx.lifecycle.viewModelScope
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.plus
import org.koitharu.kotatsu.core.exceptions.EmptyHistoryException
import org.koitharu.kotatsu.core.github.AppUpdateRepository
import org.koitharu.kotatsu.core.prefs.AppSettings
import org.koitharu.kotatsu.core.prefs.NavItem
import org.koitharu.kotatsu.core.prefs.observeAsStateFlow
import org.koitharu.kotatsu.core.ui.BaseViewModel
import org.koitharu.kotatsu.core.util.ext.MutableEventFlow
@@ -22,7 +18,6 @@ import org.koitharu.kotatsu.history.data.HistoryRepository
import org.koitharu.kotatsu.main.domain.ReadingResumeEnabledUseCase
import org.koitharu.kotatsu.parsers.model.Manga
import org.koitharu.kotatsu.tracker.domain.TrackingRepository
import java.util.EnumMap
import javax.inject.Inject
@HiltViewModel
@@ -52,19 +47,8 @@ class MainViewModel @Inject constructor(
val appUpdate = appUpdateRepository.observeAvailableUpdate()
val counters = combine(
trackingRepository.observeUpdatedMangaCount(),
observeNewSourcesCount(),
) { tracks, newSources ->
val em = EnumMap<NavItem, Int>(NavItem::class.java)
em[NavItem.EXPLORE] = newSources
em[NavItem.FEED] = tracks
em
}.stateIn(
scope = viewModelScope + Dispatchers.Default,
started = SharingStarted.WhileSubscribed(5000),
initialValue = emptyMap<NavItem, Int>(),
)
val feedCounter = trackingRepository.observeUpdatedMangaCount()
.stateIn(viewModelScope + Dispatchers.Default, SharingStarted.Lazily, 0)
init {
launchJob {
@@ -87,8 +71,4 @@ class MainViewModel @Inject constructor(
fun setIncognitoMode(isEnabled: Boolean) {
settings.isIncognitoModeEnabled = isEnabled
}
private fun observeNewSourcesCount() = sourcesRepository.observeNewSources()
.map { if (sourcesRepository.isSetupRequired()) 0 else it.size }
.distinctUntilChanged()
}

View File

@@ -10,8 +10,10 @@ import androidx.core.view.isVisible
import androidx.core.view.updatePadding
import coil.ImageLoader
import com.google.android.material.appbar.AppBarLayout
import com.google.android.material.snackbar.Snackbar
import com.google.android.material.tabs.TabLayoutMediator
import dagger.hilt.android.AndroidEntryPoint
import org.koitharu.kotatsu.R
import org.koitharu.kotatsu.core.ui.BaseActivity
import org.koitharu.kotatsu.core.ui.list.OnListItemClickListener
import org.koitharu.kotatsu.core.ui.util.ReversibleActionObserver
@@ -21,6 +23,7 @@ import org.koitharu.kotatsu.core.util.ext.observeEvent
import org.koitharu.kotatsu.core.util.ext.toLocale
import org.koitharu.kotatsu.databinding.ActivitySourcesCatalogBinding
import org.koitharu.kotatsu.main.ui.owners.AppBarOwner
import org.koitharu.kotatsu.settings.newsources.NewSourcesDialogFragment
import javax.inject.Inject
@AndroidEntryPoint
@@ -31,6 +34,8 @@ class SourcesCatalogActivity : BaseActivity<ActivitySourcesCatalogBinding>(),
@Inject
lateinit var coil: ImageLoader
private var newSourcesSnackbar: Snackbar? = null
override val appBar: AppBarLayout
get() = viewBinding.appbar
@@ -45,6 +50,7 @@ class SourcesCatalogActivity : BaseActivity<ActivitySourcesCatalogBinding>(),
val tabMediator = TabLayoutMediator(viewBinding.tabs, viewBinding.pager, pagerAdapter)
tabMediator.attach()
viewModel.content.observe(this, pagerAdapter)
viewModel.hasNewSources.observe(this, ::onHasNewSourcesChanged)
viewModel.onActionDone.observeEvent(
this,
ReversibleActionObserver(viewBinding.pager),
@@ -80,4 +86,31 @@ class SourcesCatalogActivity : BaseActivity<ActivitySourcesCatalogBinding>(),
viewModel.performSearch(null)
return true
}
private fun onHasNewSourcesChanged(hasNewSources: Boolean) {
if (hasNewSources) {
if (newSourcesSnackbar?.isShownOrQueued == true) {
return
}
val snackbar = Snackbar.make(viewBinding.pager, R.string.new_sources_text, Snackbar.LENGTH_INDEFINITE)
snackbar.setAction(R.string.explore) {
NewSourcesDialogFragment.show(supportFragmentManager)
}
snackbar.addCallback(
object : Snackbar.Callback() {
override fun onDismissed(transientBottomBar: Snackbar?, event: Int) {
super.onDismissed(transientBottomBar, event)
if (event == DISMISS_EVENT_SWIPE) {
viewModel.skipNewSources()
}
}
},
)
snackbar.show()
newSourcesSnackbar = snackbar
} else {
newSourcesSnackbar?.dismiss()
newSourcesSnackbar = null
}
}
}

View File

@@ -41,6 +41,10 @@ class SourcesCatalogViewModel @Inject constructor(
val locales = repository.allMangaSources.mapToSet { it.locale }
val locale = MutableStateFlow(Locale.getDefault().language.takeIf { it in locales })
val hasNewSources = repository.observeNewSources()
.map { it.isNotEmpty() }
.stateIn(viewModelScope + Dispatchers.Default, SharingStarted.Lazily, false)
private val listProducers = locale.map { lc ->
createListProducers(lc)
}.stateIn(viewModelScope, SharingStarted.Eagerly, createListProducers(locale.value))
@@ -71,6 +75,12 @@ class SourcesCatalogViewModel @Inject constructor(
}
}
fun skipNewSources() {
launchJob {
repository.assimilateNewSources()
}
}
@MainThread
private fun createListProducers(lc: String?): Map<ContentType, SourcesCatalogListProducer> {
val types = EnumSet.allOf(ContentType::class.java)

View File

@@ -268,7 +268,7 @@
<string name="show_reading_indicators">Mostrare gli indicatori di progresso della lettura</string>
<string name="data_deletion">Eliminazione dei dati</string>
<string name="show_reading_indicators_summary">Mostra la percentuale di lettura nella cronologia e nei preferiti</string>
<string name="exclude_nsfw_from_history_summary">I manga contrassegnati come per adulti non verranno mai aggiunti alla cronologia e i vostri progressi non verranno salvati</string>
<string name="exclude_nsfw_from_history_summary">I manga contrassegnati come per adulti non verranno mai aggiunti alla cronologia e i progressi non saranno salvati</string>
<string name="clear_cookies_summary">Può aiutare in caso di problemi. Tutte le autorizzazioni saranno invalidate</string>
<string name="show_all">Mostra tutto</string>
<string name="logout">Esci</string>
@@ -345,12 +345,12 @@
\n Tutti i manga in esso contenuti andranno persi e questo non può essere annullato.</string>
<string name="history_shortcuts_summary">Rendere disponibili i manga recenti premendo a lungo sull\'icona dell\'applicazione</string>
<string name="reader_info_bar">Mostra la barra delle informazioni nel lettore</string>
<string name="manga_error_description_pattern">Dettagli dell\'errore:&lt;br&gt;&lt;tt&gt;%1$s&lt;/tt&gt;&lt;br&gt;1. Prova ad &lt;a href=%2$s&gt;aprire il manga in un browser web&lt;/a&gt; per assicurarsi che sia disponibile sulla sua fonte&lt;br&gt;2. Se è disponibile, inviare una segnalazione di errore agli sviluppatori.</string>
<string name="manga_error_description_pattern">Dettagli dell\'errore:&lt;br&gt;&lt;tt&gt;%1$s&lt;/tt&gt;&lt;br&gt;&lt;br&gt;1. Prova ad &lt;a href=%2$s&gt;aprire il manga in un browser web&lt;/a&gt; per assicurarsi che sia disponibile sulla sua fonte&lt;br&gt;2. Controllare di stare usando la &lt;a href=kotatsu://about&gt;versione più recente di Kotatsu&lt;/a&gt;&lt;br&gt;3. Se è disponibile, inviare una segnalazione di errore agli sviluppatori.</string>
<string name="text_unsaved_changes_prompt">Salvare o eliminare le modifiche non salvate\?</string>
<string name="discard">Abbandona</string>
<string name="language">Lingua</string>
<string name="share_logs">Condividi i registri</string>
<string name="enable_logging_summary">Registra alcune azioni a scopo di debug</string>
<string name="enable_logging_summary">Registra alcune azioni a scopo di debug. Non attivare se non si è sicuri di cosa si stia facendo</string>
<string name="enable_logging">Abilita la registrazione</string>
<string name="show_suspicious_content">Mostra il contenuto sospetto</string>
<string name="theme_name_dynamic">Dinamico</string>
@@ -366,7 +366,181 @@
<string name="theme_name_rikka">Rikka</string>
<string name="theme_name_miku">Miku</string>
<string name="allow_unstable_updates">Permetti aggiornamenti instabili</string>
<string name="allow_unstable_updates_summary">Proponi aggiornamenti alle versioni beta dell\'app</string>
<string name="allow_unstable_updates_summary">Ricevi notifiche riguardo versioni instabili</string>
<string name="download_started">Scaricamento iniziato</string>
<string name="theme_name_sakura">Sakura</string>
<string name="languages">Lingue</string>
<string name="zoom_in">Ingrandire</string>
<string name="captcha_required_summary">%s richiede il completamento di un captcha per funzionare correttamente</string>
<string name="sources_catalog">Catalogo fonti</string>
<string name="download_option_all_unread">Tutti i capitoli non letti</string>
<string name="frequency_every_day">Ogni giorno</string>
<string name="categories">Categorie</string>
<string name="progress">Progresso</string>
<string name="cancel_all">Annulla tutti</string>
<string name="sync_host_description">Puoi usare un server di sincronizzazione self-hosted oppure uno di default. Non cambiare se non si è sicuri di cosa si stia facendo.</string>
<string name="error_corrupted_file">Dati non validi in ritorno o file corrotto</string>
<string name="pick_custom_directory">Seleziona cartella personalizzata</string>
<string name="list_options">Mostra lista opzioni</string>
<string name="related_manga_summary">Mostra una lista di manga correlati. In alcuni casi potrebbe essere imprecisa o mancante</string>
<string name="remove_completed_downloads_confirm">La tua cronologia dei download sarà permanentemente cancellata</string>
<string name="reader_zoom_buttons_summary">Se mostrare o no i tasti di controllo dello zoom in basso a destra</string>
<string name="content_type_manga">Manga</string>
<string name="tracker_wifi_only_summary">Non controllare nuovi capitoli mentre è in uso una connessione a consumo</string>
<string name="error_multiple_states_not_supported">Questa fonte di manga non supporta il filtraggio per multipli stati</string>
<string name="order_added">Aggiunto</string>
<string name="source_summary_pattern">%1$s, %2$s</string>
<string name="on_device">Su dispositivo</string>
<string name="password">Password</string>
<string name="download_option_whole_manga">L\'intero manga</string>
<string name="settings_apply_restart_required">Riavviare l\'applicazione per applicare queste modifiche</string>
<string name="backup_frequency">Frequenza creazione backup</string>
<string name="data_and_privacy">Dati e privacy</string>
<string name="content_type_hentai">Hentai</string>
<string name="clear_source_cookies_summary">Pulisci cookies solo per dominio specifico. Nella maggior parte dei casi invaliderà l\'autorizzazione</string>
<string name="downloads_wifi_only_summary">Smetti di scaricare quando si passa a rete mobile</string>
<string name="suggest_new_sources">Suggerisci nuove fonti dopo aggiornamento dell\'app</string>
<string name="user_agent">Intestazione UserAgent</string>
<string name="error_filter_states_genre_not_supported">Questa fonte non supporta il filtraggio per sia genere che stato</string>
<string name="ignore_ssl_errors">Ignora errori SSL</string>
<string name="error_filter_locale_genre_not_supported">Questa fonte non supporta il filtraggio per sia genere che localizzazione</string>
<string name="periodic_backups_enable">Abilita backup periodici</string>
<string name="server_address">Indirizzo server</string>
<string name="content_type_comics">Fumetti</string>
<string name="moved_to_top">Spostato in cima</string>
<string name="find_similar">Trova simili</string>
<string name="data_not_restored_text">Assicurati di aver selezionato il file di backup corretto</string>
<string name="catalog">Catalogo</string>
<string name="view_list">Vedi lista</string>
<string name="welcome_text">Selezionare le fonti di contenuti da abilitare. Si può configurare anche successivamente nelle impostazioni</string>
<string name="unknown">Sconosciuto</string>
<string name="in_progress">In progresso</string>
<string name="download_option_manual_selection">Selezione manuale capitoli</string>
<string name="enhanced_colors_summary">Riduce il banding, ma può impattare la performance</string>
<string name="pause">Pausa</string>
<string name="remove_completed">Rimuovi completati</string>
<string name="items_limit_exceeded">Impossibile aggiungere altri oggetti</string>
<string name="frequency_every_2_days">Ogni 2 giorni</string>
<string name="suggestions_notifications_summary">A volte mostra le notifiche sui manga suggeriti</string>
<string name="invalid_value_message">Valore non valido</string>
<string name="downloads_cancelled">I download sono stati annullati</string>
<string name="reader_optimize">Riduci consumo di memoria (beta)</string>
<string name="apply">Applica</string>
<string name="restore">Ripristina</string>
<string name="data_not_restored">Dati non ripristinati</string>
<string name="manage_sources">Gestisci fonti</string>
<string name="directories">Cartelle</string>
<string name="local_manga_directories">Cartelle manga locali</string>
<string name="manage_categories">Gestisci categorie</string>
<string name="no_manga_sources_found">Nessuna fonte manga trovata in base alla tua query</string>
<string name="color_light">Chiaro</string>
<string name="web_view_unavailable">WebView non disponibile: controlla se è installato un provider di WebView</string>
<string name="genres_search_hint">Inizia a scrivere il nome del genere</string>
<string name="port">Porta</string>
<string name="type">Tipo</string>
<string name="search_hint">Inserisci titolo manga, genere o nome fonte</string>
<string name="frequency_once_per_week">Una volta a settimana</string>
<string name="description">Descrizione</string>
<string name="periodic_backups">Backup periodici</string>
<string name="reader_zoom_buttons">Mostra tasti zoom</string>
<string name="sources_reorder_tip">Tocca e tieni premuto su un elemento per riordinarlo</string>
<string name="globally">Globalmente</string>
<string name="resume">Riprendi</string>
<string name="images_proxy_title">Proxy ottimizzazione immagini</string>
<string name="username">Nome utente</string>
<string name="frequency_twice_per_month">Due volte al mese</string>
<string name="main_screen_sections">Sezioni principali schermo</string>
<string name="advanced">Avanzate</string>
<string name="downloads_settings_info">Se stai avendo problemi di blocco dal server, puoi abilitare il rallentamento dei download per ogni fonte di manga nelle impostazioni delle fonti</string>
<string name="sync_settings">Impostazioni di sincronizzazione</string>
<string name="online_variant">Variante online</string>
<string name="disable_battery_optimization_summary_downloads">Potrebbe aiutare a far iniziare il download in caso di problemi</string>
<string name="error_multiple_genres_not_supported">Questa fonte di manga non supporta il filtraggio per multipli generi</string>
<string name="download_option_all_unread_b">Tutti i capitoli non letti (%s)</string>
<string name="authorization_optional">Autorizzazione (opzionale)</string>
<string name="color_dark">Scuro</string>
<string name="this_manga">Questo manga</string>
<string name="reader_info_bar_summary">Mostra l\'orario attuale e il progresso di lettura in cima allo schermo</string>
<string name="translations">Traduzioni</string>
<string name="downloads_paused">I download sono stati messi in pausa</string>
<string name="too_many_requests_message">Troppe richieste. Riprova più tardi</string>
<string name="downloads_wifi_only">Scarica solo via Wi-Fi</string>
<string name="lock_screen_rotation">Blocca rotazione schermo</string>
<string name="cancel_all_downloads_confirm">Tutti i download attivi saranno annullati, i dati scaricati parzialmente saranno persi</string>
<string name="by_relevance">Rilevanza</string>
<string name="related_manga">Manga correlati</string>
<string name="state_abandoned">Abbandonato</string>
<string name="download_option_first_n_chapters">Primo %s</string>
<string name="keep_screen_on">Tieni schermo acceso</string>
<string name="paused">In pausa</string>
<string name="text_downloads_list_holder">Non hai alcun download</string>
<string name="skip">Salta</string>
<string name="error_search_not_supported">Questa fonte di manga non supporta la ricerca</string>
<string name="invalid_port_number">Numero di porta non valido</string>
<string name="suggestions_wifi_only_summary">Non aggiornare suggerimenti mentre è in uso una connessione a consumo</string>
<string name="webtoon_zoom_summary">Consenti gesto di zoom in modalità webtoon</string>
<string name="frequency_once_per_month">Una volta al mese</string>
<string name="network">Rete</string>
<string name="downloaded">Scaricato</string>
<string name="suggestions_enable_prompt">Vuoi ricevere suggerimenti personalizzati di manga?</string>
<string name="manual">Manuale</string>
<string name="custom_directory">Cartella personalizzata</string>
<string name="more">Di più</string>
<string name="reader_optimize_summary">Riduci la qualità delle pagine fuori schermo per usare meno memoria</string>
<string name="address">Indirizzo</string>
<string name="color_correction_apply_text">Queste impostazioni possono essere applicate globalmente o per solo questo manga. Le applicazioni globali non sovrascrivono quelle individuali.</string>
<string name="source_enabled">Fonte abilitata</string>
<string name="enhanced_colors">Modalità colori 32-bit</string>
<string name="folder_with_images_import_description">Puoi selezionare una cartella contenente archivi o immagini. Ogni archivio (o sottocartella) sarà riconosciuto come singolo capitolo.</string>
<string name="default_section">Sezione default</string>
<string name="background">Sfondo</string>
<string name="disable_nsfw_summary">Disabilita fonti per adulti e nascondi manga per adulti dalla lista se possibile</string>
<string name="speed_value">x%.1f</string>
<string name="downloads_removed">I download sono stati rimossi</string>
<string name="pages_animation_summary">Animazioni cambio pagina</string>
<string name="no_access_to_file">Non hai accesso a questo file o cartella</string>
<string name="mirror_switching">Scegli mirror automaticamente</string>
<string name="restore_summary">Ripristina backup creato in precedenza</string>
<string name="show_pages_numbers_summary">Mostra numeri di pagina nell\'angolo inferiore</string>
<string name="zoom_out">Rimpicciolire</string>
<string name="keep_screen_on_summary">Non spegnere lo schermo durante la lettura di manga</string>
<string name="download_option_next_unread_n_chapters">Prossimo %s non letto</string>
<string name="clear_network_cache">Pulisci cache di rete</string>
<string name="voice_search">Ricerca vocale</string>
<string name="enable">Abilita</string>
<string name="backup_date_">Data del backup: %s</string>
<string name="images_procy_description">Usa il servizio wsrv.nl per ridurre i consumi di rete e velocizzare il caricamento delle immagini, se possibile</string>
<string name="no_manga_sources_catalog_text">Non sono disponibili fonti in questa sezione, o potrebbero essere state aggiunte tutte.
\nRimani sintonizzato</string>
<string name="available_d">Disponibile: %1$d</string>
<string name="manga_branch_title_template">%1$s (%2$s)</string>
<string name="state">Stato</string>
<string name="manga_list">Lista manga</string>
<string name="grayscale">Bianco e nero</string>
<string name="disable_nsfw">Disabilita contenuti per adulti</string>
<string name="last_successful_backup">Ultimo backup completato: %s</string>
<string name="color_white">Bianco</string>
<string name="downloads_resumed">I download sono stati ripresi</string>
<string name="details_button_tip">Tocca e tieni premuto il tasto Leggi per vedere più opzioni</string>
<string name="state_paused">In pausa</string>
<string name="to_top">Va in cima</string>
<string name="show">Mostra</string>
<string name="sync_auth_hint">Puoi accedere ad un account esistente o crearne uno nuovo</string>
<string name="backups_output_directory">Cartella salvataggio backup</string>
<string name="invert_colors">Inverti colori</string>
<string name="mirror_switching_summary">Cambiare dominio di fonte del manga automaticamente in caso di errore se sono disponibili mirror</string>
<string name="no_thanks">No grazie</string>
<string name="suggest_new_sources_summary">Chiedi se aggiungere nuove fonti dopo aggiornamento dell\'applicazione</string>
<string name="speed">Velocità</string>
<string name="download_option_all_chapters">Tutti i capitoli con traduzioni %s</string>
<string name="content_type_other">Altro</string>
<string name="suggestion_manga">Consigliato: %s</string>
<string name="color_black">Nero</string>
<string name="this_month">Questo mese</string>
<string name="sync_auth">Accedi per sincronizzare l\'account</string>
<string name="proxy">Proxy</string>
<string name="restore_backup_description">Importa un backup di dati utente creato precedentemente</string>
<string name="got_it">Ho capito</string>
<string name="comics_archive_import_description">Puoi selezionare uno o più file .cbz o .zip, ogni file sarà riconosciuto come un manga a parte.</string>
<string name="show_on_shelf">Mostra sullo Scaffale</string>
</resources>

View File

@@ -548,4 +548,6 @@
<string name="sync_auth">Login to sync account</string>
<string name="restore">Restore</string>
<string name="backup_date_">Backup date: %s</string>
<string name="state_upcoming">Upcoming</string>
<string name="by_name_reverse">Name reversed</string>
</resources>