More work on single list + fully restored pager

Pager is now back to default preference
Addedname for the setting in lbrary
Single list:
*Popup to when moving manga from one category to another (to switch to D&D or use current category sorting)
*Made current spinner option reselectable
*In filter bottom sheet, sort options are gone in single list, now always using D&D mode for sorting single list since categories have sort options
* When hiding filters, list reverts back to library sorting and header modifies library sorting
Pager:
* Header item no longer shows
* Restored tabs
This commit is contained in:
Jay 2020-02-18 21:27:24 -08:00
parent 21d7f342e6
commit da2f3d4524
14 changed files with 329 additions and 267 deletions

View File

@ -31,18 +31,31 @@ interface Category : Serializable {
UPDATED_ASC, UPDATED_DSC -> LibrarySort.LAST_UPDATED UPDATED_ASC, UPDATED_DSC -> LibrarySort.LAST_UPDATED
UNREAD_ASC, UNREAD_DSC -> LibrarySort.UNREAD UNREAD_ASC, UNREAD_DSC -> LibrarySort.UNREAD
LAST_READ_ASC, LAST_READ_DSC -> LibrarySort.LAST_READ LAST_READ_ASC, LAST_READ_DSC -> LibrarySort.LAST_READ
TOTAL_ASC, TOTAL_DSC -> LibrarySort.TOTAL
DRAG_AND_DROP -> LibrarySort.DRAG_AND_DROP
else -> null else -> null
} }
fun sortRes(): Int = when (mangaSort) {
ALPHA_ASC, ALPHA_DSC -> R.string.title
UPDATED_ASC, UPDATED_DSC -> R.string.action_sort_last_updated
UNREAD_ASC, UNREAD_DSC -> R.string.action_filter_unread
LAST_READ_ASC, LAST_READ_DSC -> R.string.action_sort_last_read
TOTAL_ASC, TOTAL_DSC -> R.string.action_sort_total
else -> R.string.action_sort_drag_and_drop
}
fun catSortingMode(): Int? = when (mangaSort) { fun catSortingMode(): Int? = when (mangaSort) {
ALPHA_ASC, ALPHA_DSC -> 0 ALPHA_ASC, ALPHA_DSC -> 0
UPDATED_ASC, UPDATED_DSC -> 1 UPDATED_ASC, UPDATED_DSC -> 1
UNREAD_ASC, UNREAD_DSC -> 2 UNREAD_ASC, UNREAD_DSC -> 2
LAST_READ_ASC, LAST_READ_DSC -> 3 LAST_READ_ASC, LAST_READ_DSC -> 3
TOTAL_ASC, TOTAL_DSC -> 4
else -> null else -> null
} }
companion object { companion object {
private const val DRAG_AND_DROP = 'D'
private const val ALPHA_ASC = 'a' private const val ALPHA_ASC = 'a'
private const val ALPHA_DSC = 'b' private const val ALPHA_DSC = 'b'
private const val UPDATED_ASC = 'c' private const val UPDATED_ASC = 'c'
@ -51,15 +64,34 @@ interface Category : Serializable {
private const val UNREAD_DSC = 'f' private const val UNREAD_DSC = 'f'
private const val LAST_READ_ASC = 'g' private const val LAST_READ_ASC = 'g'
private const val LAST_READ_DSC = 'h' private const val LAST_READ_DSC = 'h'
private const val TOTAL_ASC = 'i'
private const val TOTAL_DSC = 'j'
fun create(name: String): Category = CategoryImpl().apply { fun create(name: String): Category = CategoryImpl().apply {
this.name = name this.name = name
} }
fun createDefault(context: Context): Category = create(context.getString(R.string.default_columns)) fun createDefault(context: Context): Category =
.apply { create(context.getString(R.string.default_columns)).apply {
id = id = 0
0 } }
fun createAll(context: Context, libSort: Int, ascending: Boolean): Category =
create(context.getString(R.string.all)).apply {
id = -1
mangaSort = when (libSort) {
LibrarySort.ALPHA -> ALPHA_ASC
LibrarySort.LAST_UPDATED -> UPDATED_ASC
LibrarySort.UNREAD -> UNREAD_ASC
LibrarySort.LAST_READ -> LAST_READ_ASC
LibrarySort.TOTAL -> TOTAL_ASC
else -> 'D'
}
if (mangaSort != 'D' && !ascending) {
mangaSort?.plus(1)
}
order = -1
}
} }
} }

View File

@ -113,7 +113,7 @@ object PreferenceKeys {
const val libraryLayout = "pref_display_library_layout" const val libraryLayout = "pref_display_library_layout"
const val libraryUsingPager = "library_using_pager" const val libraryAsSingleList = "library_as_single_list"
const val lang = "app_language" const val lang = "app_language"

View File

@ -173,7 +173,7 @@ class PreferencesHelper(val context: Context) {
fun libraryLayout() = rxPrefs.getInteger(Keys.libraryLayout, 1) fun libraryLayout() = rxPrefs.getInteger(Keys.libraryLayout, 1)
fun libraryUsingPager() = rxPrefs.getBoolean(Keys.libraryUsingPager, false) fun libraryAsSingleList() = rxPrefs.getBoolean(Keys.libraryAsSingleList, false)
fun downloadBadge() = rxPrefs.getBoolean(Keys.downloadBadge, false) fun downloadBadge() = rxPrefs.getBoolean(Keys.downloadBadge, false)

View File

@ -25,7 +25,7 @@ class LibraryCategoryAdapter(val libraryListener: LibraryListener) :
FlexibleAdapter<IFlexible<*>>(null, libraryListener, true) { FlexibleAdapter<IFlexible<*>>(null, libraryListener, true) {
init { init {
setDisplayHeadersAtStartUp(!Injekt.get<PreferencesHelper>().libraryUsingPager() setDisplayHeadersAtStartUp(Injekt.get<PreferencesHelper>().libraryAsSingleList()
.getOrDefault()) .getOrDefault())
} }
/** /**

View File

@ -184,6 +184,7 @@ class LibraryCategoryView @JvmOverloads constructor(context: Context, attrs: Att
val filterOff = preferences.filterCompleted().getOrDefault() + val filterOff = preferences.filterCompleted().getOrDefault() +
preferences.filterTracked().getOrDefault() + preferences.filterTracked().getOrDefault() +
preferences.filterUnread().getOrDefault() + preferences.filterUnread().getOrDefault() +
preferences.filterMangaType().getOrDefault() +
preferences.filterCompleted().getOrDefault() == 0 && preferences.filterCompleted().getOrDefault() == 0 &&
!preferences.hideCategories().getOrDefault() !preferences.hideCategories().getOrDefault()
return sortingMode == LibrarySort.DRAG_AND_DROP && filterOff && return sortingMode == LibrarySort.DRAG_AND_DROP && filterOff &&
@ -212,7 +213,6 @@ class LibraryCategoryView @JvmOverloads constructor(context: Context, attrs: Att
val mangaForCategory = event.getMangaForCategory(category).orEmpty() val mangaForCategory = event.getMangaForCategory(category).orEmpty()
adapter.setItems(mangaForCategory) adapter.setItems(mangaForCategory)
adapter.hideAllHeaders()
swipe_refresh.isEnabled = !preferences.hideCategories().getOrDefault() swipe_refresh.isEnabled = !preferences.hideCategories().getOrDefault()

View File

@ -5,6 +5,7 @@ import android.content.Context
import android.content.res.Configuration import android.content.res.Configuration
import android.graphics.Color import android.graphics.Color
import android.os.Bundle import android.os.Bundle
import android.util.AttributeSet
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.Menu import android.view.Menu
import android.view.MenuInflater import android.view.MenuInflater
@ -15,10 +16,8 @@ import android.view.WindowInsets
import android.view.inputmethod.InputMethodManager import android.view.inputmethod.InputMethodManager
import android.widget.ArrayAdapter import android.widget.ArrayAdapter
import android.widget.Spinner import android.widget.Spinner
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.view.ActionMode import androidx.appcompat.view.ActionMode
import androidx.appcompat.widget.AppCompatSpinner
import androidx.appcompat.widget.SearchView import androidx.appcompat.widget.SearchView
import androidx.core.graphics.drawable.DrawableCompat import androidx.core.graphics.drawable.DrawableCompat
import androidx.core.math.MathUtils.clamp import androidx.core.math.MathUtils.clamp
@ -33,6 +32,7 @@ import com.f2prateek.rx.preferences.Preference
import com.google.android.material.bottomsheet.BottomSheetBehavior import com.google.android.material.bottomsheet.BottomSheetBehavior
import com.google.android.material.snackbar.BaseTransientBottomBar import com.google.android.material.snackbar.BaseTransientBottomBar
import com.google.android.material.snackbar.Snackbar import com.google.android.material.snackbar.Snackbar
import com.google.android.material.tabs.TabLayout
import com.jakewharton.rxrelay.BehaviorRelay import com.jakewharton.rxrelay.BehaviorRelay
import com.jakewharton.rxrelay.PublishRelay import com.jakewharton.rxrelay.PublishRelay
import eu.davidea.flexibleadapter.FlexibleAdapter import eu.davidea.flexibleadapter.FlexibleAdapter
@ -48,6 +48,7 @@ import eu.kanade.tachiyomi.data.library.LibraryUpdateService
import eu.kanade.tachiyomi.data.preference.PreferencesHelper import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.data.preference.getOrDefault import eu.kanade.tachiyomi.data.preference.getOrDefault
import eu.kanade.tachiyomi.ui.base.controller.BaseController import eu.kanade.tachiyomi.ui.base.controller.BaseController
import eu.kanade.tachiyomi.ui.base.controller.TabbedController
import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction
import eu.kanade.tachiyomi.ui.category.CategoryController import eu.kanade.tachiyomi.ui.category.CategoryController
import eu.kanade.tachiyomi.ui.download.DownloadController import eu.kanade.tachiyomi.ui.download.DownloadController
@ -73,16 +74,18 @@ import eu.kanade.tachiyomi.widget.AutofitRecyclerView
import eu.kanade.tachiyomi.widget.IgnoreFirstSpinnerListener import eu.kanade.tachiyomi.widget.IgnoreFirstSpinnerListener
import kotlinx.android.synthetic.main.filter_bottom_sheet.* import kotlinx.android.synthetic.main.filter_bottom_sheet.*
import kotlinx.android.synthetic.main.library_controller.* import kotlinx.android.synthetic.main.library_controller.*
import kotlinx.android.synthetic.main.main_activity.*
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
import timber.log.Timber import rx.Subscription
import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get import uy.kohesive.injekt.api.get
import java.util.Locale
import kotlin.math.min
class LibraryController( class LibraryController(
bundle: Bundle? = null, bundle: Bundle? = null,
private val preferences: PreferencesHelper = Injekt.get() private val preferences: PreferencesHelper = Injekt.get()
) : BaseController(bundle), ) : BaseController(bundle), TabbedController,
//TabbedController,
ActionMode.Callback, ActionMode.Callback,
ChangeMangaCategoriesDialog.Listener, ChangeMangaCategoriesDialog.Listener,
MigrationInterface, MigrationInterface,
@ -163,9 +166,9 @@ class LibraryController(
/** /**
* Drawer listener to allow swipe only for closing the drawer. * Drawer listener to allow swipe only for closing the drawer.
*/ */
// private var tabsVisibilityRelay: BehaviorRelay<Boolean> = BehaviorRelay.create(false) private var tabsVisibilityRelay: BehaviorRelay<Boolean> = BehaviorRelay.create(false)
// private var tabsVisibilitySubscription: Subscription? = null private var tabsVisibilitySubscription: Subscription? = null
private var observeLater:Boolean = false private var observeLater:Boolean = false
@ -196,12 +199,11 @@ class LibraryController(
val category = presenter.categories.find { it.order == order } val category = presenter.categories.find { it.order == order }
bottom_sheet.lastCategory = category bottom_sheet.lastCategory = category
if (preferences.librarySortingMode().getOrDefault() == LibrarySort.DRAG_AND_DROP)
bottom_sheet.updateTitle() bottom_sheet.updateTitle()
if (spinner.selectedItemPosition != order + 1) {
updateScroll = true updateScroll = true
spinner.setSelection(order + 1) spinner.setSelection(order + 1, true)
spinnerAdapter?.setCustomText(category?.name) }
} }
} }
} }
@ -211,7 +213,7 @@ class LibraryController(
*/ */
private lateinit var recycler: RecyclerView private lateinit var recycler: RecyclerView
var usePager = preferences.libraryUsingPager().getOrDefault() private var usePager: Boolean = !preferences.libraryAsSingleList().getOrDefault()
init { init {
setHasOptionsMenu(true) setHasOptionsMenu(true)
@ -219,13 +221,7 @@ class LibraryController(
} }
override fun getTitle(): String? { override fun getTitle(): String? {
return null//if (title != null) null else resources?.getString(R.string.label_library) return if (usePager) resources?.getString(R.string.label_library) else null
}
private var title: String? = null
set(value) {
field = value
setTitle()
} }
override fun inflateView(inflater: LayoutInflater, container: ViewGroup): View { override fun inflateView(inflater: LayoutInflater, container: ViewGroup): View {
@ -283,14 +279,15 @@ class LibraryController(
adapter.fastScroller = fast_scroller adapter.fastScroller = fast_scroller
recycler.addOnScrollListener(scrollListener) recycler.addOnScrollListener(scrollListener)
spinner = recycler_layout.inflate(R.layout.library_spinner) as AppCompatSpinner spinner = ReSpinner(view.context)
(activity as MainActivity).supportActionBar?.setDisplayShowCustomEnabled(true) (activity as MainActivity).supportActionBar?.setDisplayShowCustomEnabled(true)
(activity as MainActivity).supportActionBar?.customView = spinner (activity as MainActivity).supportActionBar?.customView = spinner
spinnerAdapter = SpinnerAdapter(view.context, R.layout.library_spinner_textview, spinnerAdapter = SpinnerAdapter(view.context, R.layout.library_spinner_textview,
arrayOf(resources!!.getString(R.string.label_library))) arrayOf(resources!!.getString(R.string.label_library)))
spinnerAdapter?.setDropDownViewResource(R.layout.library_spinner_entry_text)
spinner.adapter = spinnerAdapter spinner.adapter = spinnerAdapter
spinnerAdapter?.setCustomText(resources?.getString(R.string.label_library)) //spinnerAdapter?.setCustomText(resources?.getString(R.string.label_library))
} }
@ -318,22 +315,14 @@ class LibraryController(
router.pushController(DownloadController().withFadeTransaction()) router.pushController(DownloadController().withFadeTransaction())
} }
// spinner.onItemSelectedListener = listener
/*spinner.onItemSelectedListener = IgnoreFirstSpinnerListener { position ->
if (!updateScroll) return@IgnoreFirstSpinnerListener
val headerPosition = adapter.indexOf(position) + 1
if (headerPosition > -1) (recycler.layoutManager as LinearLayoutManager)
.scrollToPositionWithOffset(position, 0)
}*/
val config = resources?.configuration val config = resources?.configuration
val phoneLandscape = (config?.orientation == Configuration.ORIENTATION_LANDSCAPE && val phoneLandscape = (config?.orientation == Configuration.ORIENTATION_LANDSCAPE &&
(config.screenLayout.and(Configuration.SCREENLAYOUT_SIZE_MASK)) < (config.screenLayout.and(Configuration.SCREENLAYOUT_SIZE_MASK)) <
Configuration.SCREENLAYOUT_SIZE_LARGE) Configuration.SCREENLAYOUT_SIZE_LARGE)
// pad the recycler if the filter bottom sheet is visible // pad the recycler if the filter bottom sheet is visible
if (!usePager && !phoneLandscape) { if (!usePager && !phoneLandscape) {
val height = view.context.resources.getDimensionPixelSize(R.dimen.rounder_radius) + 5.dpToPx val height = view.context.resources.getDimensionPixelSize(R.dimen.rounder_radius) + 4.dpToPx
recycler.updatePaddingRelative(bottom = height) recycler.updatePaddingRelative(bottom = height)
} }
@ -358,7 +347,8 @@ class LibraryController(
if (type.isEnter) { if (type.isEnter) {
if (!usePager) if (!usePager)
(activity as MainActivity).supportActionBar?.setDisplayShowCustomEnabled(true) (activity as MainActivity).supportActionBar?.setDisplayShowCustomEnabled(true)
//activity?.tabs?.setupWithViewPager(library_pager) else
activity?.tabs?.setupWithViewPager(library_pager)
presenter.getLibrary() presenter.getLibrary()
DownloadService.addListener(this) DownloadService.addListener(this)
DownloadService.callListeners() DownloadService.callListeners()
@ -389,13 +379,13 @@ class LibraryController(
} }
override fun onDestroyView(view: View) { override fun onDestroyView(view: View) {
//adapter.onDestroy() pagerAdapter?.onDestroy()
DownloadService.removeListener(this) DownloadService.removeListener(this)
LibraryUpdateService.removeListener() LibraryUpdateService.removeListener()
//adapter = null pagerAdapter = null
actionMode = null actionMode = null
//tabsVisibilitySubscription?.unsubscribe() tabsVisibilitySubscription?.unsubscribe()
//tabsVisibilitySubscription = null tabsVisibilitySubscription = null
super.onDestroyView(view) super.onDestroyView(view)
} }
@ -421,7 +411,7 @@ class LibraryController(
super.onDetach(view) super.onDetach(view)
} }
/*override fun configureTabs(tabs: TabLayout) { override fun configureTabs(tabs: TabLayout) {
with(tabs) { with(tabs) {
tabGravity = TabLayout.GRAVITY_CENTER tabGravity = TabLayout.GRAVITY_CENTER
tabMode = TabLayout.MODE_SCROLLABLE tabMode = TabLayout.MODE_SCROLLABLE
@ -440,7 +430,7 @@ class LibraryController(
override fun cleanupTabs(tabs: TabLayout) { override fun cleanupTabs(tabs: TabLayout) {
tabsVisibilitySubscription?.unsubscribe() tabsVisibilitySubscription?.unsubscribe()
tabsVisibilitySubscription = null tabsVisibilitySubscription = null
}*/ }
fun onNextLibraryUpdate(mangaMap: List<LibraryItem>, freshStart: Boolean = false) { fun onNextLibraryUpdate(mangaMap: List<LibraryItem>, freshStart: Boolean = false) {
if (mangaMap.isNotEmpty()) { if (mangaMap.isNotEmpty()) {
@ -455,14 +445,14 @@ class LibraryController(
spinner.onItemSelectedListener = null spinner.onItemSelectedListener = null
spinnerAdapter = SpinnerAdapter(view!!.context, R.layout.library_spinner_textview, spinnerAdapter = SpinnerAdapter(view!!.context, R.layout.library_spinner_textview,
presenter.categories.map { it.name }.toTypedArray()) presenter.categories.map { it.name }.toTypedArray())
spinnerAdapter?.setDropDownViewResource(R.layout.library_spinner_entry_text)
spinner.adapter = spinnerAdapter spinner.adapter = spinnerAdapter
spinnerAdapter?.setCustomText(presenter.categories.find { it.order == activeCategory spinner.setSelection(min(presenter.categories.size - 1, activeCategory + 1))
}?.name ?: resources?.getString(R.string.label_library)) /* spinnerAdapter?.setCustomText(presenter.categories.find { it.order == activeCategory
}?.name ?: resources?.getString(R.string.label_library))*/
if (!freshStart) { if (!freshStart) {
spinnerAdapter?.setCustomText(presenter.categories.find { it.order == activeCategory
}?.name ?: resources?.getString(R.string.label_library))
justStarted = false justStarted = false
if (recycler_layout.alpha == 0f) if (recycler_layout.alpha == 0f)
recycler_layout.animate().alpha(1f).setDuration(500).start() recycler_layout.animate().alpha(1f).setDuration(500).start()
@ -474,6 +464,7 @@ class LibraryController(
.scrollToPositionWithOffset(position, 0) .scrollToPositionWithOffset(position, 0)
} }
adapter.isLongPressDragEnabled = canDrag() adapter.isLongPressDragEnabled = canDrag()
tabsVisibilityRelay.call(false)
bottom_sheet.lastCategory = presenter.categories[clamp(activeCategory, bottom_sheet.lastCategory = presenter.categories[clamp(activeCategory,
0, 0,
@ -527,13 +518,13 @@ class LibraryController(
bottom_sheet.lastCategory = adapter.categories.getOrNull(activeCat) bottom_sheet.lastCategory = adapter.categories.getOrNull(activeCat)
bottom_sheet.updateTitle() bottom_sheet.updateTitle()
//tabsVisibilityRelay.call(categories.size > 1) tabsVisibilityRelay.call(categories.size > 1)
if (freshStart || !justStarted) { if (freshStart || !justStarted) {
// Delay the scroll position to allow the view to be properly measured. // Delay the scroll position to allow the view to be properly measured.
view.post { view.post {
if (isAttached) { if (isAttached) {
//activity?.tabs?.setScrollPosition(library_pager.currentItem, 0f, true) activity?.tabs?.setScrollPosition(library_pager.currentItem, 0f, true)
} }
} }
@ -583,19 +574,33 @@ class LibraryController(
} }
fun onCatSortChanged(id: Int? = null) { fun onCatSortChanged(id: Int? = null) {
val catId = id ?: presenter.categories.find { it.order == activeCategory }?.id ?: return val catId =
(if (usePager)(id ?: pagerAdapter?.categories?.getOrNull(library_pager.currentItem)?.id)
else (id ?: presenter.categories.find { it.order == activeCategory }?.id))
?: return
presenter.requestCatSortUpdate(catId) presenter.requestCatSortUpdate(catId)
//val catId = id ?: adapter?.categories?.getOrNull(library_pager.currentItem)?.id ?: return
// presenter.requestCatSortUpdate(catId)
} }
/** /**
* Reattaches the adapter to the view pager to recreate fragments * Reattaches the adapter to the view pager to recreate fragments
*/ */
private fun reattachAdapter() { private fun reattachAdapter() {
val position = (recycler.layoutManager as LinearLayoutManager).findFirstVisibleItemPosition() if (usePager) {
if (recycler is AutofitRecyclerView && preferences.libraryLayout().getOrDefault() == 0 || val adapter = pagerAdapter ?: return
recycler !is AutofitRecyclerView && preferences.libraryLayout().getOrDefault() > 0) {
val position = library_pager.currentItem
adapter.recycle = false
library_pager.adapter = adapter
library_pager.currentItem = position
adapter.recycle = true
}
else {
val position =
(recycler.layoutManager as LinearLayoutManager).findFirstVisibleItemPosition()
// if switching from list to grid
if (recycler is AutofitRecyclerView && preferences.libraryLayout().getOrDefault() == 0
|| recycler !is AutofitRecyclerView && preferences.libraryLayout().getOrDefault() > 0) {
destroyActionModeIfNeeded() destroyActionModeIfNeeded()
recycler_layout.removeView(recycler) recycler_layout.removeView(recycler)
recycler = if (preferences.libraryLayout().getOrDefault() == 0) { recycler = if (preferences.libraryLayout().getOrDefault() == 0) {
@ -608,8 +613,7 @@ class LibraryController(
manager.spanSizeLookup = (object : GridLayoutManager.SpanSizeLookup() { manager.spanSizeLookup = (object : GridLayoutManager.SpanSizeLookup() {
override fun getSpanSize(position: Int): Int { override fun getSpanSize(position: Int): Int {
val item = this@LibraryController.adapter.getItem(position) val item = this@LibraryController.adapter.getItem(position)
return if (item is LibraryHeaderItem) return if (item is LibraryHeaderItem) manager.spanCount else 1
manager.spanCount else 1
} }
}) })
} }
@ -621,19 +625,21 @@ class LibraryController(
adapter.isLongPressDragEnabled = canDrag() adapter.isLongPressDragEnabled = canDrag()
recycler_layout.addView(recycler) recycler_layout.addView(recycler)
adapter.setItems(presenter.getList()) adapter.setItems(presenter.getList())
val config = resources?.configuration
val phoneLandscape = (config?.orientation == Configuration.ORIENTATION_LANDSCAPE &&
(config.screenLayout.and(Configuration.SCREENLAYOUT_SIZE_MASK)) <
Configuration.SCREENLAYOUT_SIZE_LARGE)
if (!usePager && !phoneLandscape) {
val height = recycler.resources.getDimensionPixelSize(R.dimen
.rounder_radius) + 4.dpToPx
recycler.updatePaddingRelative(bottom = height)
}
} else { } else {
recycler.adapter = adapter recycler.adapter = adapter
} }
(recycler.layoutManager as LinearLayoutManager).scrollToPositionWithOffset(position, 0) (recycler.layoutManager as LinearLayoutManager).scrollToPositionWithOffset(position, 0)
//val adapter = adapter ?: return }
/*val position = library_pager.currentItem
adapter.recycle = false
library_pager.adapter = adapter
library_pager.currentItem = position
adapter.recycle = true*/
} }
/** /**
@ -921,7 +927,10 @@ class LibraryController(
override fun startReading(position: Int) { override fun startReading(position: Int) {
val activity = activity ?: return val activity = activity ?: return
val manga = (adapter.getItem(position) as? LibraryItem)?.manga ?: return val manga = (adapter.getItem(position) as? LibraryItem)?.manga ?: return
if (adapter.mode == SelectableAdapter.Mode.MULTI) toggleSelection(position) if (adapter.mode == SelectableAdapter.Mode.MULTI) {
toggleSelection(position)
return
}
val chapter = presenter.getFirstUnread(manga) ?: return val chapter = presenter.getFirstUnread(manga) ?: return
val intent = ReaderActivity.newIntent(activity, manga, chapter) val intent = ReaderActivity.newIntent(activity, manga, chapter)
destroyActionModeIfNeeded() destroyActionModeIfNeeded()
@ -937,14 +946,13 @@ class LibraryController(
} }
override fun canDrag(): Boolean { override fun canDrag(): Boolean {
val sortingMode = preferences.librarySortingMode().getOrDefault()
val filterOff = preferences.filterCompleted().getOrDefault() + val filterOff = preferences.filterCompleted().getOrDefault() +
preferences.filterTracked().getOrDefault() + preferences.filterTracked().getOrDefault() +
preferences.filterUnread().getOrDefault() + preferences.filterUnread().getOrDefault() +
preferences.filterMangaType().getOrDefault() +
preferences.filterCompleted().getOrDefault() == 0 && preferences.filterCompleted().getOrDefault() == 0 &&
!preferences.hideCategories().getOrDefault() !preferences.hideCategories().getOrDefault()
return sortingMode == LibrarySort.DRAG_AND_DROP && filterOff && return filterOff && adapter.mode != SelectableAdapter.Mode.MULTI
adapter.mode != SelectableAdapter.Mode.MULTI
} }
/** /**
@ -1020,13 +1028,32 @@ class LibraryController(
if (adapter.selectedItemCount > 0) return if (adapter.selectedItemCount > 0) return
val item = adapter.getItem(position) as? LibraryItem ?: return val item = adapter.getItem(position) as? LibraryItem ?: return
val newHeader = adapter.getSectionHeader(position) as? LibraryHeaderItem val newHeader = adapter.getSectionHeader(position) as? LibraryHeaderItem
val libraryItems = adapter.getSectionItems(adapter.getSectionHeader(position)).filterIsInstance<LibraryItem>() val libraryItems = adapter.getSectionItems(adapter.getSectionHeader(position))
.filterIsInstance<LibraryItem>()
val mangaIds = libraryItems.mapNotNull { (it as? LibraryItem)?.manga?.id } val mangaIds = libraryItems.mapNotNull { (it as? LibraryItem)?.manga?.id }
if (newHeader?.category?.id == item.manga.category) { if (newHeader?.category?.id == item.manga.category) {
presenter.rearrangeCategory(item.manga.category, mangaIds) presenter.rearrangeCategory(item.manga.category, mangaIds)
} else { } else {
presenter.moveMangaToCategory(item, newHeader?.category?.id, mangaIds) if (newHeader?.category?.mangaSort == null) {
Timber.d("Manga has Moved") presenter.moveMangaToCategory(item, newHeader?.category?.id, mangaIds, true)
} else {
MaterialDialog(activity!!).message(R.string.switch_to_dnd)
.positiveButton(R.string.action_switch) {
presenter.moveMangaToCategory(item, newHeader.category.id, mangaIds, true)
}.negativeButton(
text = resources?.getString(
R.string.keep_current_sort,
resources!!.getString(newHeader.category.sortRes()).toLowerCase
(Locale.getDefault())
)
) {
presenter.moveMangaToCategory(
item, newHeader.category.id, mangaIds, false
)
}
.cancelOnTouchOutside(false)
.show()
}
} }
} }
@ -1077,26 +1104,32 @@ object HeightTopWindowInsetsListener : View.OnApplyWindowInsetsListener {
class SpinnerAdapter(context: Context, layoutId: Int, val array: Array<String>) : class SpinnerAdapter(context: Context, layoutId: Int, val array: Array<String>) :
ArrayAdapter<String> ArrayAdapter<String>
(context, layoutId, array) { (context, layoutId, array)
private var mCustomText = ""
override fun getView(position: Int, convertView: View?, parent: ViewGroup): View { class ReSpinner : Spinner {
val view = super.getView(position, convertView, parent) constructor(context: Context?) : super(context) {}
val tv: TextView = view as TextView constructor(context: Context?, attrs: AttributeSet?) : super(context, attrs) {}
tv.text = mCustomText constructor(context: Context?, attrs: AttributeSet?, defStyle: Int) : super(
return view context, attrs, defStyle
)
override fun setSelection(position: Int, animate: Boolean) {
val sameSelected = position == selectedItemPosition
super.setSelection(position, animate)
if (sameSelected) { // Spinner does not call the OnItemSelectedListener if the same item is selected, so do it manually now
onItemSelectedListener?.onItemSelected(
this, selectedView, position, selectedItemId
)
}
} }
fun setCustomText(customText: String?) { override fun setSelection(position: Int) {
// Call to set the text that must be shown in the spinner for the custom option. val sameSelected = position == selectedItemPosition
val text = customText ?: return super.setSelection(position)
mCustomText = text if (sameSelected) { // Spinner does not call the OnItemSelectedListener if the same item is selected, so do it manually now
notifyDataSetChanged() onItemSelectedListener?.onItemSelected(
} this, selectedView, position, selectedItemId
)
override fun getDropDownView(position: Int, convertView: View?, parent: ViewGroup): View { }
val view = parent.inflate(R.layout.library_spinner_entry_text) as TextView
view.text = array[position]
return view
} }
} }

View File

@ -90,14 +90,22 @@ class LibraryHeaderItem(val category: Category) : AbstractHeaderItem<LibraryHead
} }
) )
if (LibraryUpdateService.categoryInQueue(item.category.id)) {
when {
item.category.id == -1 -> {
updateButton.invisible()
catProgress.gone()
}
LibraryUpdateService.categoryInQueue(item.category.id) -> {
catProgress.visible() catProgress.visible()
updateButton.invisible() updateButton.invisible()
} else { }
else -> {
catProgress.gone() catProgress.gone()
updateButton.visible() updateButton.visible()
} }
} }
}
private fun addCategoryToUpdate() { private fun addCategoryToUpdate() {
if (adapter.libraryListener.updateCategory(adapterPosition)) { if (adapter.libraryListener.updateCategory(adapterPosition)) {
@ -113,7 +121,9 @@ class LibraryHeaderItem(val category: Category) : AbstractHeaderItem<LibraryHead
val popup = PopupMenu(itemView.context, sortText) val popup = PopupMenu(itemView.context, sortText)
// Inflate our menu resource into the PopupMenu's Menu // Inflate our menu resource into the PopupMenu's Menu
popup.menuInflater.inflate(R.menu.cat_sort, popup.menu) popup.menuInflater.inflate(
if (category.id == -1) R.menu.main_sort
else R.menu.cat_sort, popup.menu)
// Set a listener so we are notified if a menu item is clicked // Set a listener so we are notified if a menu item is clicked
popup.setOnMenuItemClickListener { menuItem -> popup.setOnMenuItemClickListener { menuItem ->
@ -140,8 +150,11 @@ class LibraryHeaderItem(val category: Category) : AbstractHeaderItem<LibraryHead
} }
currentItem?.icon = tintVector( currentItem?.icon = tintVector(
if (category.isAscending()) R.drawable.ic_arrow_up_white_24dp when {
else R.drawable.ic_arrow_down_white_24dp sortingMode == LibrarySort.DRAG_AND_DROP -> R.drawable.ic_check_white_24dp
category.isAscending() -> R.drawable.ic_arrow_up_white_24dp
else -> R.drawable.ic_arrow_down_white_24dp
}
) )
// Finally show the PopupMenu // Finally show the PopupMenu
@ -162,6 +175,7 @@ class LibraryHeaderItem(val category: Category) : AbstractHeaderItem<LibraryHead
} }
else { else {
val order = when (menuId) { val order = when (menuId) {
R.id.action_total_chaps -> 4
R.id.action_last_read -> 3 R.id.action_last_read -> 3
R.id.action_unread -> 2 R.id.action_unread -> 2
R.id.action_update -> 1 R.id.action_update -> 1

View File

@ -23,8 +23,8 @@ import uy.kohesive.injekt.injectLazy
class LibraryItem(val manga: LibraryManga, class LibraryItem(val manga: LibraryManga,
private val libraryLayout: Preference<Int>, private val libraryLayout: Preference<Int>,
header: LibraryHeaderItem) : header: LibraryHeaderItem?) :
AbstractSectionableItem<LibraryHolder, LibraryHeaderItem>(header), IFilterable<String> { AbstractSectionableItem<LibraryHolder, LibraryHeaderItem?>(header), IFilterable<String> {
var downloadCount = -1 var downloadCount = -1
var unreadType = 1 var unreadType = 1

View File

@ -94,6 +94,8 @@ class LibraryPresenter(
fun getLibrary() { fun getLibrary() {
launchUI { launchUI {
val freshStart = !preferences.libraryAsSingleList().getOrDefault()
&& (currentMangaMap?.values?.firstOrNull()?.firstOrNull()?.header != null)
val mangaMap = withContext(Dispatchers.IO) { val mangaMap = withContext(Dispatchers.IO) {
val library = getLibraryFromDB() val library = getLibraryFromDB()
library.apply { setDownloadCount(library.mangaMap) } library.apply { setDownloadCount(library.mangaMap) }
@ -104,7 +106,7 @@ class LibraryPresenter(
mangaMap mangaMap
} }
currentMangaMap = mangaMap currentMangaMap = mangaMap
updateView(categories, mangaMap) updateView(categories, mangaMap, freshStart)
} }
} }
@ -252,41 +254,7 @@ class LibraryPresenter(
} }
val sortFn: (LibraryItem, LibraryItem) -> Int = { i1, i2 -> val sortFn: (LibraryItem, LibraryItem) -> Int = { i1, i2 ->
val compare = when { sortCategory(i1, i2, lastReadManga, category)
category.mangaSort != null -> {
var sort = when (category.sortingMode()) {
LibrarySort.ALPHA -> sortAlphabetical(i1, i2)
LibrarySort.LAST_UPDATED -> i2.manga.last_update.compareTo(i1.manga.last_update)
LibrarySort.UNREAD -> when {
i1.manga.unread == i2.manga.unread -> 0
i1.manga.unread == 0 -> if (category.isAscending()) 1 else -1
i2.manga.unread == 0 -> if (category.isAscending()) -1 else 1
else -> i1.manga.unread.compareTo(i2.manga.unread)
}
LibrarySort.LAST_READ -> {
val manga1LastRead = lastReadManga[i1.manga.id!!] ?: lastReadManga.size
val manga2LastRead = lastReadManga[i2.manga.id!!] ?: lastReadManga.size
manga1LastRead.compareTo(manga2LastRead)
}
else -> sortAlphabetical(i1, i2)
}
if (!category.isAscending()) sort *= -1
sort
}
category.mangaOrder.isNotEmpty() -> {
val order = category.mangaOrder
val index1 = order.indexOf(i1.manga.id!!)
val index2 = order.indexOf(i2.manga.id!!)
when {
index1 == index2 -> 0
index1 == -1 -> -1
index2 == -1 -> 1
else -> index1.compareTo(index2)
}
}
else -> 0
}
compare
} }
val comparator = Comparator(sortFn) val comparator = Comparator(sortFn)
@ -309,38 +277,57 @@ class LibraryPresenter(
var counter = 0 var counter = 0
db.getTotalChapterManga().executeAsBlocking().associate { it.id!! to counter++ } db.getTotalChapterManga().executeAsBlocking().associate { it.id!! to counter++ }
} }
val catListing by lazy {
val default = createDefaultCategory()
listOf(default) + db.getCategories().executeAsBlocking()
}
val ascending = preferences.librarySortingAscending().getOrDefault() val ascending = preferences.librarySortingAscending().getOrDefault()
val useDnD = preferences.libraryAsSingleList().getOrDefault() && !preferences
.hideCategories().getOrDefault()
val sortFn: (LibraryItem, LibraryItem) -> Int = { i1, i2 -> val sortFn: (LibraryItem, LibraryItem) -> Int = { i1, i2 ->
val compare = when (sortingMode) { val compare = when {
LibrarySort.ALPHA -> sortAlphabetical(i1, i2) sortingMode == LibrarySort.DRAG_AND_DROP || useDnD ->
LibrarySort.LAST_READ -> { sortCategory(i1, i2, lastReadManga)
sortingMode == LibrarySort.ALPHA -> sortAlphabetical(i1, i2)
sortingMode == LibrarySort.LAST_READ -> {
// Get index of manga, set equal to list if size unknown. // Get index of manga, set equal to list if size unknown.
val manga1LastRead = lastReadManga[i1.manga.id!!] ?: lastReadManga.size val manga1LastRead = lastReadManga[i1.manga.id!!] ?: lastReadManga.size
val manga2LastRead = lastReadManga[i2.manga.id!!] ?: lastReadManga.size val manga2LastRead = lastReadManga[i2.manga.id!!] ?: lastReadManga.size
manga1LastRead.compareTo(manga2LastRead) manga1LastRead.compareTo(manga2LastRead)
} }
LibrarySort.LAST_UPDATED -> i2.manga.last_update.compareTo(i1.manga.last_update) sortingMode == LibrarySort.LAST_UPDATED -> i2.manga.last_update.compareTo(i1
LibrarySort.UNREAD -> .manga.last_update)
sortingMode == LibrarySort.UNREAD ->
when { when {
i1.manga.unread == i2.manga.unread -> 0 i1.manga.unread == i2.manga.unread -> 0
i1.manga.unread == 0 -> if (ascending) 1 else -1 i1.manga.unread == 0 -> if (ascending) 1 else -1
i2.manga.unread == 0 -> if (ascending) -1 else 1 i2.manga.unread == 0 -> if (ascending) -1 else 1
else -> i1.manga.unread.compareTo(i2.manga.unread) else -> i1.manga.unread.compareTo(i2.manga.unread)
} }
LibrarySort.TOTAL -> { sortingMode == LibrarySort.TOTAL -> {
val manga1TotalChapter = totalChapterManga[i1.manga.id!!] ?: 0 val manga1TotalChapter = totalChapterManga[i1.manga.id!!] ?: 0
val mange2TotalChapter = totalChapterManga[i2.manga.id!!] ?: 0 val mange2TotalChapter = totalChapterManga[i2.manga.id!!] ?: 0
manga1TotalChapter.compareTo(mange2TotalChapter) manga1TotalChapter.compareTo(mange2TotalChapter)
} }
LibrarySort.DRAG_AND_DROP -> { else -> 0
if (i1.manga.category == i2.manga.category) { }
val category = catListing.find { it.id == i1.manga.category } if (compare == 0) {
if (ascending) sortAlphabetical(i1, i2)
else sortAlphabetical(i2, i1)
}
else compare
}
val comparator = if (ascending)
Comparator(sortFn)
else
Collections.reverseOrder(sortFn)
return map.mapValues { entry -> entry.value.sortedWith(comparator) }
}
private fun sortCategory(i1: LibraryItem, i2: LibraryItem,
lastReadManga: Map<Long, Int>, initCat: Category? = null): Int {
return if (initCat != null || i1.manga.category == i2.manga.category) {
val category = initCat ?: allCategories.find { it.id == i1.manga.category }
when { when {
category?.mangaSort != null -> { category?.mangaSort != null -> {
var sort = when (category.sortingMode()) { var sort = when (category.sortingMode()) {
@ -378,27 +365,12 @@ class LibraryPresenter(
} }
} }
else { else {
val category = catListing.find { it.id == i1.manga.category }?.order ?: -1 val category = allCategories.find { it.id == i1.manga.category }?.order ?: -1
val category2 = catListing.find { it.id == i2.manga.category }?.order ?: -1 val category2 = allCategories.find { it.id == i2.manga.category }?.order ?: -1
category.compareTo(category2) category.compareTo(category2)
} }
} }
else -> 0
}
if (compare == 0) {
if (ascending) sortAlphabetical(i1, i2)
else sortAlphabetical(i2, i1)
}
else compare
}
val comparator = if (ascending)
Comparator(sortFn)
else
Collections.reverseOrder(sortFn)
return map.mapValues { entry -> entry.value.sortedWith(comparator) }
}
private fun sortAlphabetical(i1: LibraryItem, i2: LibraryItem): Int { private fun sortAlphabetical(i1: LibraryItem, i2: LibraryItem): Int {
return if (preferences.removeArticles().getOrDefault()) return if (preferences.removeArticles().getOrDefault())
@ -424,11 +396,13 @@ class LibraryPresenter(
}.groupBy { }.groupBy {
if (showCategories) it.manga.category else 0 if (showCategories) it.manga.category else 0
}*/ }*/
val catItemMain = LibraryHeaderItem(categories.firstOrNull() ?: createDefaultCategory()) val catItemAll = LibraryHeaderItem(Category.createAll(context,
preferences.librarySortingMode().getOrDefault(),
preferences.librarySortingAscending().getOrDefault()))
val libraryMap = val libraryMap =
if (preferences.libraryUsingPager().getOrDefault()) { if (!preferences.libraryAsSingleList().getOrDefault()) {
libraryManga.map { manga -> libraryManga.map { manga ->
LibraryItem(manga, libraryLayout, catItemMain).apply { unreadType = unreadBadgeType } LibraryItem(manga, libraryLayout, null).apply { unreadType = unreadBadgeType }
}.groupBy { }.groupBy {
if (showCategories) it.manga.category else 0 if (showCategories) it.manga.category else 0
} }
@ -438,8 +412,10 @@ class LibraryPresenter(
if (showCategories) manga.category else 0 if (showCategories) manga.category else 0
//LibraryItem(manga, libraryLayout).apply { unreadType = unreadBadgeType } //LibraryItem(manga, libraryLayout).apply { unreadType = unreadBadgeType }
}.map { entry -> }.map { entry ->
val categoryItem = LibraryHeaderItem(categories.find { entry.key == it.id } val categoryItem =
?: createDefaultCategory()) if (!showCategories) catItemAll else
(LibraryHeaderItem(categories.find { entry.key == it.id }
?: createDefaultCategory()))
entry.value.map { entry.value.map {
LibraryItem( LibraryItem(
it, libraryLayout, categoryItem it, libraryLayout, categoryItem
@ -455,8 +431,7 @@ class LibraryPresenter(
categories.add(0, createDefaultCategory()) categories.add(0, createDefaultCategory())
this.allCategories = categories this.allCategories = categories
this.categories = if (preferences.hideCategories().getOrDefault()) this.categories = if (!showCategories) arrayListOf(catItemAll.category)
arrayListOf(createDefaultCategory())
else categories else categories
return Library(this.categories, libraryMap) return Library(this.categories, libraryMap)
@ -486,8 +461,8 @@ class LibraryPresenter(
suspend fun updateView(categories: List<Category>, mangaMap: LibraryMap, freshStart:Boolean suspend fun updateView(categories: List<Category>, mangaMap: LibraryMap, freshStart:Boolean
= false) { = false) {
if (preferences.libraryUsingPager().getOrDefault()) { if (!preferences.libraryAsSingleList().getOrDefault()) {
view.onNextLibraryUpdate(categories, mangaMap, true) view.onNextLibraryUpdate(categories, mangaMap, freshStart)
} }
else { else {
val mangaList = withContext(Dispatchers.IO) { val mangaList = withContext(Dispatchers.IO) {
@ -514,20 +489,15 @@ class LibraryPresenter(
} }
fun updateViewBlocking() { fun updateViewBlocking() {
/* val list = withContext(Dispatchers.IO) {
val showCategories = !preferences.hideCategories().getOrDefault()
val current = mangaMap.values.first()
current.groupBy {
if (showCategories) it.manga.category else 0
}.flatMap { it.value }
}*/
val mangaMap = currentMangaMap ?: return val mangaMap = currentMangaMap ?: return
if (preferences.libraryUsingPager().getOrDefault()) { if (!preferences.libraryAsSingleList().getOrDefault()) {
if (mangaMap.values.firstOrNull()?.firstOrNull()?.header != null)
return
view.onNextLibraryUpdate(categories, mangaMap, true) view.onNextLibraryUpdate(categories, mangaMap, true)
} }
else { else {
val list = mutableListOf<LibraryItem>() val list = mutableListOf<LibraryItem>()
for (element in mangaMap?.toSortedMap(compareBy { entry -> for (element in mangaMap.toSortedMap(compareBy { entry ->
categories.find { it.id == entry }?.order ?: -1 categories.find { it.id == entry }?.order ?: -1
})) { })) {
list.addAll(element.value) list.addAll(element.value)
@ -776,12 +746,18 @@ class LibraryPresenter(
fun sortCategory(catId: Int, order: Int) { fun sortCategory(catId: Int, order: Int) {
val category = categories.find { catId == it.id } ?: return val category = categories.find { catId == it.id } ?: return
category.mangaSort = ('a' + (order - 1)) category.mangaSort = ('a' + (order - 1))
if (category.id == 0) if (catId == -1) {
preferences.defaultMangaOrder().set(category.mangaSort.toString()) val sort = category.sortingMode() ?: LibrarySort.ALPHA
else preferences.librarySortingMode().set(sort)
Injekt.get<DatabaseHelper>().insertCategory(category).asRxObservable().subscribe() preferences.librarySortingAscending().set(category.isAscending())
requestSortUpdate()
}
else {
if (category.id == 0) preferences.defaultMangaOrder().set(category.mangaSort.toString())
else Injekt.get<DatabaseHelper>().insertCategory(category).asRxObservable().subscribe()
requestCatSortUpdate(category.id!!) requestCatSortUpdate(category.id!!)
} }
}
fun rearrangeCategory(catId: Int?, mangaIds: List<Long>) { fun rearrangeCategory(catId: Int?, mangaIds: List<Long>) {
GlobalScope.launch(Dispatchers.IO) { GlobalScope.launch(Dispatchers.IO) {
@ -794,7 +770,7 @@ class LibraryPresenter(
} }
} }
fun moveMangaToCategory(item: LibraryItem, catId: Int?, mangaIds: List<Long>) { fun moveMangaToCategory(item: LibraryItem, catId: Int?, mangaIds: List<Long>, useDND: Boolean) {
GlobalScope.launch(Dispatchers.IO) { GlobalScope.launch(Dispatchers.IO) {
val categoryId = catId ?: return@launch val categoryId = catId ?: return@launch
val category = categories.find { catId == it.id } ?: return@launch val category = categories.find { catId == it.id } ?: return@launch
@ -812,6 +788,7 @@ class LibraryPresenter(
item.manga.category = categoryId item.manga.category = categoryId
val mc = ArrayList<MangaCategory>() val mc = ArrayList<MangaCategory>()
val categories = val categories =
db.getCategoriesForManga(manga).executeAsBlocking().filter { it.id != oldCatId } + listOf(category) db.getCategoriesForManga(manga).executeAsBlocking().filter { it.id != oldCatId } + listOf(category)
@ -822,13 +799,14 @@ class LibraryPresenter(
db.setMangaCategories(mc, listOf(manga)) db.setMangaCategories(mc, listOf(manga))
if (useDND) {
category.mangaSort = null category.mangaSort = null
val ids = mangaIds.toMutableList() val ids = mangaIds.toMutableList()
if (!ids.contains(manga.id!!)) if (!ids.contains(manga.id!!)) ids.add(manga.id!!)
ids.add(manga.id!!)
category.mangaOrder = ids category.mangaOrder = ids
if (category.id == 0) preferences.defaultMangaOrder().set(mangaIds.joinToString("/")) if (category.id == 0) preferences.defaultMangaOrder().set(mangaIds.joinToString("/"))
else db.insertCategory(category).executeAsBlocking() else db.insertCategory(category).executeAsBlocking()
}
getLibrary() getLibrary()
} }
} }

View File

@ -179,6 +179,9 @@ class SortFilterBottomSheet @JvmOverloads constructor(context: Context, attrs: A
} }
} }
createTags() createTags()
sorting_layout.visibility =
if (preferences.libraryAsSingleList().getOrDefault()) View.GONE
else View.VISIBLE
library_sort_text.setOnClickListener { showMainSortOptions() } library_sort_text.setOnClickListener { showMainSortOptions() }
category_sort_text.setOnClickListener { showCatSortOptions() } category_sort_text.setOnClickListener { showCatSortOptions() }
@ -290,16 +293,12 @@ class SortFilterBottomSheet @JvmOverloads constructor(context: Context, attrs: A
fun sorting(trueSort:Boolean = false): Int { fun sorting(trueSort:Boolean = false): Int {
val sortingMode = preferences.librarySortingMode().getOrDefault() val sortingMode = preferences.librarySortingMode().getOrDefault()
return if (!trueSort && sortingMode == LibrarySort.DRAG_AND_DROP && val singleList = preferences.libraryAsSingleList().getOrDefault()
return if (!trueSort &&
(sortingMode == LibrarySort.DRAG_AND_DROP || singleList) &&
lastCategory != null && lastCategory != null &&
!preferences.hideCategories().getOrDefault()) { !preferences.hideCategories().getOrDefault()) {
when (lastCategory?.mangaSort) { lastCategory?.sortingMode() ?: LibrarySort.DRAG_AND_DROP
'a', 'b' -> LibrarySort.ALPHA
'c', 'd' -> LibrarySort.LAST_UPDATED
'e', 'f' -> LibrarySort.UNREAD
'g', 'h' -> LibrarySort.LAST_READ
else -> LibrarySort.DRAG_AND_DROP
}
} }
else { else {
sortingMode sortingMode

View File

@ -40,8 +40,8 @@ class SettingsLibraryController : SettingsController() {
} }
Observable.combineLatest(preferences.portraitColumns().asObservable(), Observable.combineLatest(preferences.portraitColumns().asObservable(),
preferences.landscapeColumns().asObservable(), preferences.landscapeColumns().asObservable()
{ portraitCols, landscapeCols -> Pair(portraitCols, landscapeCols) }) ) { portraitCols, landscapeCols -> Pair(portraitCols, landscapeCols) }
.subscribeUntilDestroy { (portraitCols, landscapeCols) -> .subscribeUntilDestroy { (portraitCols, landscapeCols) ->
val portrait = getColumnValue(portraitCols) val portrait = getColumnValue(portraitCols)
val landscape = getColumnValue(landscapeCols) val landscape = getColumnValue(landscapeCols)
@ -53,9 +53,9 @@ class SettingsLibraryController : SettingsController() {
} }
switchPreference { switchPreference {
key = Keys.libraryUsingPager key = Keys.libraryAsSingleList
titleRes = R.string.pref_remove_articles titleRes = R.string.pref_library_single_list
summaryRes = R.string.pref_remove_articles_summary summaryRes = R.string.pref_library_single_list_summary
defaultValue = false defaultValue = false
} }

View File

@ -19,6 +19,7 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_gravity="end" android:layout_gravity="end"
app:fastScrollerIgnoreTouchesOutsideHandle="true"
app:fastScrollerBubbleEnabled="true" app:fastScrollerBubbleEnabled="true"
tools:visibility="visible" /> tools:visibility="visible" />
</eu.kanade.tachiyomi.ui.library.LibraryCategoryView> </eu.kanade.tachiyomi.ui.library.LibraryCategoryView>

View File

@ -30,6 +30,7 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_gravity="end" android:layout_gravity="end"
app:fastScrollerIgnoreTouchesOutsideHandle="true"
app:fastScrollerBubbleEnabled="false" app:fastScrollerBubbleEnabled="false"
tools:visibility="visible" /> tools:visibility="visible" />

View File

@ -129,6 +129,7 @@
<string name="action_move_to_bottom">Move to bottom</string> <string name="action_move_to_bottom">Move to bottom</string>
<string name="action_track">Track</string> <string name="action_track">Track</string>
<string name="action_sort_by">Sort category by…</string> <string name="action_sort_by">Sort category by…</string>
<string name="action_switch">Switch</string>
<!-- Operations --> <!-- Operations -->
<string name="loading">Loading…</string> <string name="loading">Loading…</string>
@ -198,8 +199,9 @@
<string name="pref_update_only_non_completed">Only update ongoing manga</string> <string name="pref_update_only_non_completed">Only update ongoing manga</string>
<string name="pref_auto_update_manga_sync">Sync chapters after reading</string> <string name="pref_auto_update_manga_sync">Sync chapters after reading</string>
<string name="pref_remove_articles">Sort by ignoring articles</string> <string name="pref_remove_articles">Sort by ignoring articles</string>
<string name="pref_fixed_grid">Fixed grid size in library</string> <string name="pref_library_single_list">Show library as a single list</string>
<string name="pref_fixed_grid_summary">Show all covers as the same height by cropping</string> <string name="pref_library_single_list_summary">Show all categories under a single
sectioned list</string>
<string name="pref_remove_articles_summary">When sorting alphabetically, sort ignoring <string name="pref_remove_articles_summary">When sorting alphabetically, sort ignoring
articles (a, an, the) at the start of manga titles</string> articles (a, an, the) at the start of manga titles</string>
<string name="pref_skip_pre_migration">Skip pre-migration</string> <string name="pref_skip_pre_migration">Skip pre-migration</string>
@ -413,6 +415,8 @@
<string name="category_already_in_queue">%1$s is already in queue</string> <string name="category_already_in_queue">%1$s is already in queue</string>
<string name="local_source_badge">Local</string> <string name="local_source_badge">Local</string>
<string name="confirm_manga_deletion">Remove from library?</string> <string name="confirm_manga_deletion">Remove from library?</string>
<string name="switch_to_dnd">Switch to Drag &amp; Drop mode?</string>
<string name="keep_current_sort">Keep sorting by %1$s</string>
<string name="confirm_category_deletion">Delete category?</string> <string name="confirm_category_deletion">Delete category?</string>
<string name="confirm_category_deletion_message">Manga in this category will moved into the <string name="confirm_category_deletion_message">Manga in this category will moved into the
default category.</string> default category.</string>