diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/core/db/dao/ChaptersDao.kt b/app/src/main/kotlin/org/koitharu/kotatsu/core/db/dao/ChaptersDao.kt index 174e26c29..3a716b24d 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/core/db/dao/ChaptersDao.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/core/db/dao/ChaptersDao.kt @@ -2,6 +2,7 @@ package org.koitharu.kotatsu.core.db.dao import androidx.room.Dao import androidx.room.Insert +import androidx.room.OnConflictStrategy import androidx.room.Query import androidx.room.Transaction import org.koitharu.kotatsu.core.db.entity.ChapterEntity @@ -24,6 +25,6 @@ abstract class ChaptersDao { insert(entities) } - @Insert + @Insert(onConflict = OnConflictStrategy.REPLACE) protected abstract suspend fun insert(entities: Collection) } diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/core/db/dao/MangaSourcesDao.kt b/app/src/main/kotlin/org/koitharu/kotatsu/core/db/dao/MangaSourcesDao.kt index ab1b77150..3e11fda1c 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/core/db/dao/MangaSourcesDao.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/core/db/dao/MangaSourcesDao.kt @@ -10,7 +10,6 @@ import androidx.room.Upsert import androidx.sqlite.db.SimpleSQLiteQuery import androidx.sqlite.db.SupportSQLiteQuery import kotlinx.coroutines.flow.Flow -import org.intellij.lang.annotations.Language import org.koitharu.kotatsu.BuildConfig import org.koitharu.kotatsu.core.db.entity.MangaSourceEntity import org.koitharu.kotatsu.explore.data.SourcesSortOrder @@ -61,21 +60,11 @@ abstract class MangaSourcesDao { @Query("SELECT * FROM sources WHERE pinned = 1") abstract suspend fun findAllPinned(): List - fun observeEnabled(order: SourcesSortOrder): Flow> { - val orderBy = getOrderBy(order) + fun observeAll(enabledOnly: Boolean, order: SourcesSortOrder): Flow> = + observeImpl(getQuery(enabledOnly, order)) - @Language("RoomSql") - val query = SimpleSQLiteQuery("SELECT * FROM sources WHERE enabled = 1 ORDER BY pinned DESC, $orderBy") - return observeImpl(query) - } - - suspend fun findAllEnabled(order: SourcesSortOrder): List { - val orderBy = getOrderBy(order) - - @Language("RoomSql") - val query = SimpleSQLiteQuery("SELECT * FROM sources WHERE enabled = 1 ORDER BY pinned DESC, $orderBy") - return findAllImpl(query) - } + suspend fun findAll(enabledOnly: Boolean, order: SourcesSortOrder): List = + findAllImpl(getQuery(enabledOnly, order)) @Transaction open suspend fun setEnabled(source: String, isEnabled: Boolean) { @@ -101,6 +90,17 @@ abstract class MangaSourcesDao { @RawQuery protected abstract suspend fun findAllImpl(query: SupportSQLiteQuery): List + private fun getQuery(enabledOnly: Boolean, order: SourcesSortOrder) = SimpleSQLiteQuery( + buildString { + append("SELECT * FROM sources ") + if (enabledOnly) { + append("WHERE enabled = 1 ") + } + append("ORDER BY pinned DESC, ") + append(getOrderBy(order)) + }, + ) + private fun getOrderBy(order: SourcesSortOrder) = when (order) { SourcesSortOrder.ALPHABETIC -> "source ASC" SourcesSortOrder.POPULARITY -> "(SELECT COUNT(*) FROM manga WHERE source = sources.source) DESC" diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/core/prefs/AppSettings.kt b/app/src/main/kotlin/org/koitharu/kotatsu/core/prefs/AppSettings.kt index dc738ecc8..aea0309be 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/core/prefs/AppSettings.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/core/prefs/AppSettings.kt @@ -299,6 +299,10 @@ class AppSettings @Inject constructor(@ApplicationContext context: Context) { get() = prefs.getInt(KEY_SOURCES_VERSION, 0) set(value) = prefs.edit { putInt(KEY_SOURCES_VERSION, value) } + var isAllSourcesEnabled: Boolean + get() = prefs.getBoolean(KEY_SOURCES_ENABLED_ALL, false) + set(value) = prefs.edit { putBoolean(KEY_SOURCES_ENABLED_ALL, value) } + val isPagesNumbersEnabled: Boolean get() = prefs.getBoolean(KEY_PAGES_NUMBERS, false) @@ -717,6 +721,7 @@ class AppSettings @Inject constructor(@ApplicationContext context: Context) { const val KEY_FEED_HEADER = "feed_header" const val KEY_SEARCH_SUGGESTION_TYPES = "search_suggest_types" const val KEY_SOURCES_VERSION = "sources_version" + const val KEY_SOURCES_ENABLED_ALL = "sources_enabled_all" const val KEY_QUICK_FILTER = "quick_filter" const val KEY_BACKUP_TG_ENABLED = "backup_periodic_tg_enabled" const val KEY_BACKUP_TG_CHAT = "backup_periodic_tg_chat_id" diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/explore/data/MangaSourcesRepository.kt b/app/src/main/kotlin/org/koitharu/kotatsu/explore/data/MangaSourcesRepository.kt index 04249df34..818e76400 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/explore/data/MangaSourcesRepository.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/explore/data/MangaSourcesRepository.kt @@ -14,6 +14,7 @@ import kotlinx.coroutines.flow.callbackFlow import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.conflate import kotlinx.coroutines.flow.distinctUntilChanged +import kotlinx.coroutines.flow.flatMapLatest import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.onStart import org.koitharu.kotatsu.BuildConfig @@ -61,13 +62,14 @@ class MangaSourcesRepository @Inject constructor( suspend fun getEnabledSources(): List { assimilateNewSources() val order = settings.sourcesSortOrder - return dao.findAllEnabled(order).toSources(settings.isNsfwContentDisabled, order).let { enabled -> - val external = getExternalSources() - val list = ArrayList(enabled.size + external.size) - external.mapTo(list) { MangaSourceInfo(it, isEnabled = true, isPinned = true) } - list.addAll(enabled) - list - } + return dao.findAll(!settings.isAllSourcesEnabled, order).toSources(settings.isNsfwContentDisabled, order) + .let { enabled -> + val external = getExternalSources() + val list = ArrayList(enabled.size + external.size) + external.mapTo(list) { MangaSourceInfo(it, isEnabled = true, isPinned = true) } + list.addAll(enabled) + list + } } suspend fun getPinnedSources(): Set { @@ -85,6 +87,9 @@ class MangaSourcesRepository @Inject constructor( suspend fun getDisabledSources(): Set { assimilateNewSources() + if (settings.isAllSourcesEnabled) { + return emptySet() + } val result = EnumSet.copyOf(allMangaSources) val enabled = dao.findAllEnabledNames() for (name in enabled) { @@ -105,7 +110,7 @@ class MangaSourcesRepository @Inject constructor( ): List { assimilateNewSources() val entities = dao.findAll().toMutableList() - if (isDisabledOnly) { + if (isDisabledOnly && !settings.isAllSourcesEnabled) { entities.removeAll { it.isEnabled } } if (isNewOnly) { @@ -141,7 +146,9 @@ class MangaSourcesRepository @Inject constructor( fun observeEnabledSourcesCount(): Flow { return combine( observeIsNsfwDisabled(), - dao.observeEnabled(SourcesSortOrder.MANUAL), + observeAllEnabled().flatMapLatest { isAllSourcesEnabled -> + dao.observeAll(!isAllSourcesEnabled, SourcesSortOrder.MANUAL) + }, ) { skipNsfw, sources -> sources.count { it.source.toMangaSourceOrNull()?.let { s -> !skipNsfw || !s.isNsfw() } == true @@ -152,7 +159,9 @@ class MangaSourcesRepository @Inject constructor( fun observeAvailableSourcesCount(): Flow { return combine( observeIsNsfwDisabled(), - dao.observeEnabled(SourcesSortOrder.MANUAL), + observeAllEnabled().flatMapLatest { isAllSourcesEnabled -> + dao.observeAll(!isAllSourcesEnabled, SourcesSortOrder.MANUAL) + }, ) { skipNsfw, enabledSources -> val enabled = enabledSources.mapToSet { it.source } allMangaSources.count { x -> @@ -163,9 +172,10 @@ class MangaSourcesRepository @Inject constructor( fun observeEnabledSources(): Flow> = combine( observeIsNsfwDisabled(), + observeAllEnabled(), observeSortOrder(), - ) { skipNsfw, order -> - dao.observeEnabled(order).map { + ) { skipNsfw, allEnabled, order -> + dao.observeAll(!allEnabled, order).map { it.toSources(skipNsfw, order) } }.flattenLatest() @@ -249,10 +259,11 @@ class MangaSourcesRepository @Inject constructor( return false } var maxSortKey = dao.getMaxSortKey() + val isAllEnabled = settings.isAllSourcesEnabled val entities = new.map { x -> MangaSourceEntity( source = x.name, - isEnabled = false, + isEnabled = isAllEnabled, sortKey = ++maxSortKey, addedIn = BuildConfig.VERSION_CODE, lastUsedAt = 0, @@ -355,6 +366,7 @@ class MangaSourcesRepository @Inject constructor( skipNsfwSources: Boolean, sortOrder: SourcesSortOrder?, ): MutableList { + val isAllEnabled = settings.isAllSourcesEnabled val result = ArrayList(size) for (entity in this) { val source = entity.source.toMangaSourceOrNull() ?: continue @@ -365,7 +377,7 @@ class MangaSourcesRepository @Inject constructor( result.add( MangaSourceInfo( mangaSource = source, - isEnabled = entity.isEnabled, + isEnabled = entity.isEnabled || isAllEnabled, isPinned = entity.isPinned, ), ) @@ -385,5 +397,9 @@ class MangaSourcesRepository @Inject constructor( sourcesSortOrder } + private fun observeAllEnabled() = settings.observeAsFlow(AppSettings.KEY_SOURCES_ENABLED_ALL) { + isAllSourcesEnabled + } + private fun String.toMangaSourceOrNull(): MangaParserSource? = MangaParserSource.entries.find { it.name == this } } diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/explore/ui/ExploreFragment.kt b/app/src/main/kotlin/org/koitharu/kotatsu/explore/ui/ExploreFragment.kt index 52f9c5f77..34de65789 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/explore/ui/ExploreFragment.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/explore/ui/ExploreFragment.kt @@ -112,6 +112,8 @@ class ExploreFragment : override fun onListHeaderClick(item: ListHeader, view: View) { if (item.payload == R.id.nav_suggestions) { router.openSuggestions() + } else if (viewModel.isAllSourcesEnabled.value) { + router.openManageSources() } else { router.openSourcesCatalog() } @@ -166,7 +168,8 @@ class ExploreFragment : menu.findItem(R.id.action_shortcut).isVisible = isSingleSelection menu.findItem(R.id.action_pin).isVisible = selectedSources.all { !it.isPinned } menu.findItem(R.id.action_unpin).isVisible = selectedSources.all { it.isPinned } - menu.findItem(R.id.action_disable)?.isVisible = selectedSources.all { it.mangaSource is MangaParserSource } + menu.findItem(R.id.action_disable)?.isVisible = !viewModel.isAllSourcesEnabled.value && + selectedSources.all { it.mangaSource is MangaParserSource } menu.findItem(R.id.action_delete)?.isVisible = selectedSources.all { it.mangaSource is ExternalMangaSource } return super.onPrepareActionMode(controller, mode, menu) } diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/explore/ui/ExploreViewModel.kt b/app/src/main/kotlin/org/koitharu/kotatsu/explore/ui/ExploreViewModel.kt index 717d6c321..161a75a1d 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/explore/ui/ExploreViewModel.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/explore/ui/ExploreViewModel.kt @@ -7,7 +7,6 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow -import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.flatMapLatest import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.flow.mapLatest @@ -23,6 +22,7 @@ import org.koitharu.kotatsu.core.ui.BaseViewModel import org.koitharu.kotatsu.core.ui.util.ReversibleAction import org.koitharu.kotatsu.core.util.ext.MutableEventFlow import org.koitharu.kotatsu.core.util.ext.call +import org.koitharu.kotatsu.core.util.ext.combine import org.koitharu.kotatsu.explore.data.MangaSourcesRepository import org.koitharu.kotatsu.explore.domain.ExploreRepository import org.koitharu.kotatsu.explore.ui.model.ExploreButtons @@ -54,6 +54,12 @@ class ExploreViewModel @Inject constructor( valueProducer = { isSourcesGridMode }, ) + val isAllSourcesEnabled = settings.observeAsStateFlow( + scope = viewModelScope + Dispatchers.IO, + key = AppSettings.KEY_SOURCES_ENABLED_ALL, + valueProducer = { isAllSourcesEnabled }, + ) + private val isSuggestionsEnabled = settings.observeAsFlow( key = AppSettings.KEY_SUGGESTIONS, valueProducer = { isSuggestionsEnabled }, @@ -137,9 +143,10 @@ class ExploreViewModel @Inject constructor( getSuggestionFlow(), isGrid, isRandomLoading, + isAllSourcesEnabled, sourcesRepository.observeHasNewSourcesForBadge(), - ) { content, suggestions, grid, randomLoading, newSources -> - buildList(content, suggestions, grid, randomLoading, newSources) + ) { content, suggestions, grid, randomLoading, allSourcesEnabled, newSources -> + buildList(content, suggestions, grid, randomLoading, allSourcesEnabled, newSources) }.withErrorHandling() private fun buildList( @@ -147,6 +154,7 @@ class ExploreViewModel @Inject constructor( recommendation: List, isGrid: Boolean, randomLoading: Boolean, + allSourcesEnabled: Boolean, hasNewSources: Boolean, ): List { val result = ArrayList(sources.size + 3) @@ -158,8 +166,8 @@ class ExploreViewModel @Inject constructor( if (sources.isNotEmpty()) { result += ListHeader( textRes = R.string.remote_sources, - buttonTextRes = R.string.catalog, - badge = if (hasNewSources) "" else null, + buttonTextRes = if (allSourcesEnabled) R.string.manage else R.string.catalog, + badge = if (!allSourcesEnabled && hasNewSources) "" else null, ) sources.mapTo(result) { MangaSourceItem(it, isGrid) } } else { diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/settings/sources/SourceSettingsFragment.kt b/app/src/main/kotlin/org/koitharu/kotatsu/settings/sources/SourceSettingsFragment.kt index 5bd148025..f183b971e 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/settings/sources/SourceSettingsFragment.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/settings/sources/SourceSettingsFragment.kt @@ -42,7 +42,7 @@ class SourceSettingsFragment : BasePreferenceFragment(0), Preference.OnPreferenc val isValidSource = viewModel.repository !is EmptyMangaRepository findPreference(KEY_ENABLE)?.run { - isVisible = isValidSource + isVisible = isValidSource && !settings.isAllSourcesEnabled onPreferenceChangeListener = this@SourceSettingsFragment } findPreference(KEY_AUTH)?.run { diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/settings/sources/SourcesSettingsFragment.kt b/app/src/main/kotlin/org/koitharu/kotatsu/settings/sources/SourcesSettingsFragment.kt index 1e493ce81..66d91e725 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/settings/sources/SourcesSettingsFragment.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/settings/sources/SourcesSettingsFragment.kt @@ -1,5 +1,6 @@ package org.koitharu.kotatsu.settings.sources +import android.content.SharedPreferences import android.os.Bundle import android.view.View import androidx.fragment.app.viewModels @@ -17,7 +18,8 @@ import org.koitharu.kotatsu.explore.data.SourcesSortOrder import org.koitharu.kotatsu.parsers.util.names @AndroidEntryPoint -class SourcesSettingsFragment : BasePreferenceFragment(R.string.remote_sources) { +class SourcesSettingsFragment : BasePreferenceFragment(R.string.remote_sources), + SharedPreferences.OnSharedPreferenceChangeListener { private val viewModel by viewModels() @@ -43,10 +45,10 @@ class SourcesSettingsFragment : BasePreferenceFragment(R.string.remote_sources) } findPreference(AppSettings.KEY_SOURCES_CATALOG)?.let { pref -> viewModel.availableSourcesCount.observe(viewLifecycleOwner) { - pref.summary = if (it >= 0) { - getString(R.string.available_d, it) - } else { - null + pref.summary = when { + it == 0 -> getString(R.string.all_sources_enabled) + it > 0 -> getString(R.string.available_d, it) + else -> null } } } @@ -55,6 +57,13 @@ class SourcesSettingsFragment : BasePreferenceFragment(R.string.remote_sources) pref.isChecked = it } } + updateEnableAllDependencies() + settings.subscribe(this) + } + + override fun onDestroyView() { + settings.unsubscribe(this) + super.onDestroyView() } override fun onPreferenceTreeClick(preference: Preference): Boolean = when (preference.key) { @@ -70,4 +79,14 @@ class SourcesSettingsFragment : BasePreferenceFragment(R.string.remote_sources) else -> super.onPreferenceTreeClick(preference) } + + override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences?, key: String?) { + when (key) { + AppSettings.KEY_SOURCES_ENABLED_ALL -> updateEnableAllDependencies() + } + } + + private fun updateEnableAllDependencies() { + findPreference(AppSettings.KEY_SOURCES_CATALOG)?.isEnabled = !settings.isAllSourcesEnabled + } } diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/settings/sources/adapter/SourceConfigAdapterDelegates.kt b/app/src/main/kotlin/org/koitharu/kotatsu/settings/sources/adapter/SourceConfigAdapterDelegates.kt index 9d705714d..d114b3036 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/settings/sources/adapter/SourceConfigAdapterDelegates.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/settings/sources/adapter/SourceConfigAdapterDelegates.kt @@ -58,7 +58,7 @@ fun sourceConfigItemDelegate2( bind { binding.textViewTitle.text = item.source.getTitle(context) binding.imageViewAdd.isGone = item.isEnabled || !item.isAvailable - binding.imageViewRemove.isVisible = item.isEnabled + binding.imageViewRemove.isVisible = item.isEnabled && item.isDisableAvailable binding.imageViewMenu.isVisible = item.isEnabled binding.textViewTitle.drawableStart = if (item.isPinned) iconPinned else null binding.textViewDescription.text = item.source.getSummary(context) diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/settings/sources/manage/SourcesListProducer.kt b/app/src/main/kotlin/org/koitharu/kotatsu/settings/sources/manage/SourcesListProducer.kt index 7df5129f6..c10147f1f 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/settings/sources/manage/SourcesListProducer.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/settings/sources/manage/SourcesListProducer.kt @@ -70,6 +70,7 @@ class SourcesListProducer @Inject constructor( val pinned = repository.getPinnedSources().mapToSet { it.name } val isNsfwDisabled = settings.isNsfwContentDisabled val isReorderAvailable = settings.sourcesSortOrder == SourcesSortOrder.MANUAL + val isDisableAvailable = !settings.isAllSourcesEnabled val withTip = isReorderAvailable && settings.isTipEnabled(TIP_REORDER) val enabledSet = enabledSources.toSet() if (query.isNotEmpty()) { @@ -83,6 +84,7 @@ class SourcesListProducer @Inject constructor( isDraggable = false, isAvailable = !isNsfwDisabled || !it.isNsfw(), isPinned = it.name in pinned, + isDisableAvailable = isDisableAvailable, ) }.ifEmpty { listOf(SourceConfigItem.EmptySearchResult) @@ -104,6 +106,7 @@ class SourcesListProducer @Inject constructor( isDraggable = isReorderAvailable, isAvailable = false, isPinned = it.name in pinned, + isDisableAvailable = isDisableAvailable, ) } } diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/settings/sources/manage/SourcesManageFragment.kt b/app/src/main/kotlin/org/koitharu/kotatsu/settings/sources/manage/SourcesManageFragment.kt index 3bc0d3cf5..daf6c98af 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/settings/sources/manage/SourcesManageFragment.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/settings/sources/manage/SourcesManageFragment.kt @@ -171,6 +171,8 @@ class SourcesManageFragment : override fun onPrepareMenu(menu: Menu) { super.onPrepareMenu(menu) menu.findItem(R.id.action_no_nsfw).isChecked = settings.isNsfwContentDisabled + menu.findItem(R.id.action_disable_all).isVisible = !settings.isAllSourcesEnabled + menu.findItem(R.id.action_catalog).isVisible = !settings.isAllSourcesEnabled } override fun onMenuItemActionExpand(item: MenuItem): Boolean { diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/settings/sources/model/SourceConfigItem.kt b/app/src/main/kotlin/org/koitharu/kotatsu/settings/sources/model/SourceConfigItem.kt index 321a54334..2c014f07e 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/settings/sources/model/SourceConfigItem.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/settings/sources/model/SourceConfigItem.kt @@ -14,6 +14,7 @@ sealed interface SourceConfigItem : ListModel { val isDraggable: Boolean, val isAvailable: Boolean, val isPinned: Boolean, + val isDisableAvailable: Boolean, ) : SourceConfigItem { val isNsfw: Boolean diff --git a/app/src/main/res/drawable/ic_disable.xml b/app/src/main/res/drawable/ic_disable.xml new file mode 100644 index 000000000..ed59a0e86 --- /dev/null +++ b/app/src/main/res/drawable/ic_disable.xml @@ -0,0 +1,12 @@ + + + + diff --git a/app/src/main/res/layout/item_source_config.xml b/app/src/main/res/layout/item_source_config.xml index 4d958f260..8799600fd 100644 --- a/app/src/main/res/layout/item_source_config.xml +++ b/app/src/main/res/layout/item_source_config.xml @@ -82,10 +82,10 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="?selectableItemBackgroundBorderless" - android:contentDescription="@string/remove" + android:contentDescription="@string/disable" android:padding="@dimen/margin_small" android:scaleType="center" - android:src="@drawable/ic_delete" - android:tooltipText="@string/remove" /> + android:src="@drawable/ic_disable" + android:tooltipText="@string/disable" /> diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index cf6167042..e75126800 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -789,4 +789,7 @@ Press to open chat with Kotatsu Backup Bot Clear database Delete information about manga that is not used + Enable all manga sources + All available manga sources will be enabled permanently + All sources are enabled diff --git a/app/src/main/res/xml/pref_sources.xml b/app/src/main/res/xml/pref_sources.xml index 687502d82..4179eed05 100644 --- a/app/src/main/res/xml/pref_sources.xml +++ b/app/src/main/res/xml/pref_sources.xml @@ -20,11 +20,17 @@ android:persistent="false" android:title="@string/manage_sources" /> + + + android:title="@string/sources_catalog" />