Browse Source

Add source pinning (closes #2322)

arkon 5 years ago
parent
commit
8fe79a1fb5

+ 2 - 0
app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.kt

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

+ 19 - 20
app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/CatalogueController.kt

@@ -57,24 +57,13 @@ class CatalogueController : NucleusController<CataloguePresenter>(),
     private lateinit var binding: CatalogueMainControllerBinding
 
     init {
-        // Enable the option menu
         setHasOptionsMenu(true)
     }
 
-    /**
-     * Set the title of controller.
-     *
-     * @return title.
-     */
     override fun getTitle(): String? {
         return applicationContext?.getString(R.string.label_sources)
     }
 
-    /**
-     * Create the [CataloguePresenter] used in controller.
-     *
-     * @return instance of [CataloguePresenter]
-     */
     override fun createPresenter(): CataloguePresenter {
         return CataloguePresenter()
     }
@@ -91,11 +80,6 @@ class CatalogueController : NucleusController<CataloguePresenter>(),
         return binding.root
     }
 
-    /**
-     * Called when the view is created
-     *
-     * @param view view of controller
-     */
     override fun onViewCreated(view: View) {
         super.onViewCreated(view)
 
@@ -133,14 +117,18 @@ class CatalogueController : NucleusController<CataloguePresenter>(),
         val activity = activity ?: return
         val item = adapter?.getItem(position) as? SourceItem ?: return
 
+        val isPinned = item.header?.code?.equals(CataloguePresenter.PINNED_KEY) ?: false
+
         MaterialDialog.Builder(activity)
                 .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, _ ->
                     when (which) {
-                        0 -> {
-                            hideCatalogue(item.source)
-                        }
+                        0 -> hideCatalogue(item.source)
+                        1 -> pinCatalogue(item.source, isPinned)
                     }
                 }.show()
     }
@@ -152,6 +140,17 @@ class CatalogueController : NucleusController<CataloguePresenter>(),
         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]
      */

+ 20 - 6
app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/CataloguePresenter.kt

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

+ 2 - 0
app/src/main/java/eu/kanade/tachiyomi/util/system/LocaleHelper.kt

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

+ 3 - 0
app/src/main/res/values/strings.xml

@@ -85,6 +85,8 @@
     <string name="action_display_list">List</string>
     <string name="action_display_download_badge">Download badges</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_all">Cancel all</string>
     <string name="action_sort">Sort</string>
@@ -388,6 +390,7 @@
     <string name="http_error_hint">Check website in WebView</string>
     <string name="local_source">Local manga</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="added_to_library">The manga has been added to your library</string>
     <string name="action_global_search_hint">Global search…</string>