Add source pinning (closes #2322)

This commit is contained in:
arkon 2020-04-10 18:38:24 -04:00
parent a1df78517f
commit 8fe79a1fb5
5 changed files with 46 additions and 26 deletions

View file

@ -198,6 +198,8 @@ class PreferencesHelper(val context: Context) {
fun hiddenCatalogues() = rxPrefs.getStringSet("hidden_catalogues", emptySet()) fun hiddenCatalogues() = rxPrefs.getStringSet("hidden_catalogues", emptySet())
fun pinnedCatalogues() = rxPrefs.getStringSet("pinned_catalogues", emptySet())
fun downloadNew() = rxPrefs.getBoolean(Keys.downloadNew, false) fun downloadNew() = rxPrefs.getBoolean(Keys.downloadNew, false)
fun downloadNewCategories() = rxPrefs.getStringSet(Keys.downloadNewCategories, emptySet()) fun downloadNewCategories() = rxPrefs.getStringSet(Keys.downloadNewCategories, emptySet())

View file

@ -57,24 +57,13 @@ class CatalogueController : NucleusController<CataloguePresenter>(),
private lateinit var binding: CatalogueMainControllerBinding private lateinit var binding: CatalogueMainControllerBinding
init { init {
// Enable the option menu
setHasOptionsMenu(true) setHasOptionsMenu(true)
} }
/**
* Set the title of controller.
*
* @return title.
*/
override fun getTitle(): String? { override fun getTitle(): String? {
return applicationContext?.getString(R.string.label_sources) return applicationContext?.getString(R.string.label_sources)
} }
/**
* Create the [CataloguePresenter] used in controller.
*
* @return instance of [CataloguePresenter]
*/
override fun createPresenter(): CataloguePresenter { override fun createPresenter(): CataloguePresenter {
return CataloguePresenter() return CataloguePresenter()
} }
@ -91,11 +80,6 @@ class CatalogueController : NucleusController<CataloguePresenter>(),
return binding.root return binding.root
} }
/**
* Called when the view is created
*
* @param view view of controller
*/
override fun onViewCreated(view: View) { override fun onViewCreated(view: View) {
super.onViewCreated(view) super.onViewCreated(view)
@ -133,14 +117,18 @@ class CatalogueController : NucleusController<CataloguePresenter>(),
val activity = activity ?: return val activity = activity ?: return
val item = adapter?.getItem(position) as? SourceItem ?: return val item = adapter?.getItem(position) as? SourceItem ?: return
val isPinned = item.header?.code?.equals(CataloguePresenter.PINNED_KEY) ?: false
MaterialDialog.Builder(activity) MaterialDialog.Builder(activity)
.title(item.source.name) .title(item.source.name)
.items(activity.getString(R.string.action_hide)) .items(
activity.getString(R.string.action_hide),
activity.getString(if (isPinned) R.string.action_unpin else R.string.action_pin)
)
.itemsCallback { _, _, which, _ -> .itemsCallback { _, _, which, _ ->
when (which) { when (which) {
0 -> { 0 -> hideCatalogue(item.source)
hideCatalogue(item.source) 1 -> pinCatalogue(item.source, isPinned)
}
} }
}.show() }.show()
} }
@ -152,6 +140,17 @@ class CatalogueController : NucleusController<CataloguePresenter>(),
presenter.updateSources() presenter.updateSources()
} }
private fun pinCatalogue(source: Source, isPinned: Boolean) {
val current = preferences.pinnedCatalogues().getOrDefault()
if (isPinned) {
preferences.pinnedCatalogues().set(current - source.id.toString())
} else {
preferences.pinnedCatalogues().set(current + source.id.toString())
}
presenter.updateSources()
}
/** /**
* Called when browse is clicked in [CatalogueAdapter] * Called when browse is clicked in [CatalogueAdapter]
*/ */

View file

@ -27,9 +27,6 @@ class CataloguePresenter(
private val preferences: PreferencesHelper = Injekt.get() private val preferences: PreferencesHelper = Injekt.get()
) : BasePresenter<CatalogueController>() { ) : BasePresenter<CatalogueController>() {
/**
* Enabled sources.
*/
var sources = getEnabledSources() var sources = getEnabledSources()
/** /**
@ -48,9 +45,12 @@ class CataloguePresenter(
/** /**
* Unsubscribe and create a new subscription to fetch enabled sources. * Unsubscribe and create a new subscription to fetch enabled sources.
*/ */
fun loadSources() { private fun loadSources() {
sourceSubscription?.unsubscribe() sourceSubscription?.unsubscribe()
val pinnedSources = mutableListOf<SourceItem>()
val pinnedCatalogues = preferences.pinnedCatalogues().getOrDefault()
val map = TreeMap<String, MutableList<CatalogueSource>> { d1, d2 -> val map = TreeMap<String, MutableList<CatalogueSource>> { d1, d2 ->
// Catalogues without a lang defined will be placed at the end // Catalogues without a lang defined will be placed at the end
when { when {
@ -60,9 +60,19 @@ class CataloguePresenter(
} }
} }
val byLang = sources.groupByTo(map, { it.lang }) val byLang = sources.groupByTo(map, { it.lang })
val sourceItems = byLang.flatMap { var sourceItems = byLang.flatMap {
val langItem = LangItem(it.key) val langItem = LangItem(it.key)
it.value.map { source -> SourceItem(source, langItem) } it.value.map { source ->
if (source.id.toString() in pinnedCatalogues) {
pinnedSources.add(SourceItem(source, LangItem(PINNED_KEY)))
}
SourceItem(source, langItem)
}
}
if (pinnedSources.isNotEmpty()) {
sourceItems = pinnedSources + sourceItems
} }
sourceSubscription = Observable.just(sourceItems) sourceSubscription = Observable.just(sourceItems)
@ -101,4 +111,8 @@ class CataloguePresenter(
.sortedBy { "(${it.lang}) ${it.name}" } + .sortedBy { "(${it.lang}) ${it.name}" } +
sourceManager.get(LocalSource.ID) as LocalSource sourceManager.get(LocalSource.ID) as LocalSource
} }
companion object {
const val PINNED_KEY = "pinned"
}
} }

View file

@ -7,6 +7,7 @@ import android.os.Build
import android.view.ContextThemeWrapper import android.view.ContextThemeWrapper
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.preference.PreferencesHelper import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.ui.catalogue.CataloguePresenter
import java.util.Locale import java.util.Locale
import uy.kohesive.injekt.injectLazy import uy.kohesive.injekt.injectLazy
@ -50,6 +51,7 @@ object LocaleHelper {
return when (lang) { return when (lang) {
null -> "" null -> ""
"" -> context.getString(R.string.other_source) "" -> context.getString(R.string.other_source)
CataloguePresenter.PINNED_KEY -> context.getString(R.string.pinned_sources)
"all" -> context.getString(R.string.all_lang) "all" -> context.getString(R.string.all_lang)
else -> { else -> {
val locale = getLocale(lang) val locale = getLocale(lang)

View file

@ -85,6 +85,8 @@
<string name="action_display_list">List</string> <string name="action_display_list">List</string>
<string name="action_display_download_badge">Download badges</string> <string name="action_display_download_badge">Download badges</string>
<string name="action_hide">Hide</string> <string name="action_hide">Hide</string>
<string name="action_pin">Pin</string>
<string name="action_unpin">Unpin</string>
<string name="action_cancel">Cancel</string> <string name="action_cancel">Cancel</string>
<string name="action_cancel_all">Cancel all</string> <string name="action_cancel_all">Cancel all</string>
<string name="action_sort">Sort</string> <string name="action_sort">Sort</string>
@ -388,6 +390,7 @@
<string name="http_error_hint">Check website in WebView</string> <string name="http_error_hint">Check website in WebView</string>
<string name="local_source">Local manga</string> <string name="local_source">Local manga</string>
<string name="other_source">Other</string> <string name="other_source">Other</string>
<string name="pinned_sources">Pinned</string>
<string name="invalid_combination">Default can\'t be selected with other categories</string> <string name="invalid_combination">Default can\'t be selected with other categories</string>
<string name="added_to_library">The manga has been added to your library</string> <string name="added_to_library">The manga has been added to your library</string>
<string name="action_global_search_hint">Global search…</string> <string name="action_global_search_hint">Global search…</string>