mirror of
https://github.com/tachiyomiorg/tachiyomi.git
synced 2024-11-13 07:35:06 +01:00
More updates to long list library
Added update button + sort option to each category header Reset glide cache/memory back to default
This commit is contained in:
parent
73ecfa389b
commit
3df6f10316
@ -1,7 +1,6 @@
|
|||||||
package eu.kanade.tachiyomi.data.glide
|
package eu.kanade.tachiyomi.data.glide
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.graphics.drawable.Drawable
|
|
||||||
import com.bumptech.glide.Glide
|
import com.bumptech.glide.Glide
|
||||||
import com.bumptech.glide.GlideBuilder
|
import com.bumptech.glide.GlideBuilder
|
||||||
import com.bumptech.glide.Registry
|
import com.bumptech.glide.Registry
|
||||||
@ -9,9 +8,7 @@ import com.bumptech.glide.annotation.GlideModule
|
|||||||
import com.bumptech.glide.integration.okhttp3.OkHttpUrlLoader
|
import com.bumptech.glide.integration.okhttp3.OkHttpUrlLoader
|
||||||
import com.bumptech.glide.load.DecodeFormat
|
import com.bumptech.glide.load.DecodeFormat
|
||||||
import com.bumptech.glide.load.engine.cache.InternalCacheDiskCacheFactory
|
import com.bumptech.glide.load.engine.cache.InternalCacheDiskCacheFactory
|
||||||
import com.bumptech.glide.load.engine.cache.LruResourceCache
|
|
||||||
import com.bumptech.glide.load.model.GlideUrl
|
import com.bumptech.glide.load.model.GlideUrl
|
||||||
import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions
|
|
||||||
import com.bumptech.glide.module.AppGlideModule
|
import com.bumptech.glide.module.AppGlideModule
|
||||||
import com.bumptech.glide.request.RequestOptions
|
import com.bumptech.glide.request.RequestOptions
|
||||||
import eu.kanade.tachiyomi.data.database.models.Manga
|
import eu.kanade.tachiyomi.data.database.models.Manga
|
||||||
@ -27,10 +24,10 @@ import java.io.InputStream
|
|||||||
class TachiGlideModule : AppGlideModule() {
|
class TachiGlideModule : AppGlideModule() {
|
||||||
|
|
||||||
override fun applyOptions(context: Context, builder: GlideBuilder) {
|
override fun applyOptions(context: Context, builder: GlideBuilder) {
|
||||||
builder.setDiskCache(InternalCacheDiskCacheFactory(context, 100 * 1024 * 1024))
|
builder.setDiskCache(InternalCacheDiskCacheFactory(context, 50 * 1024 * 1024))
|
||||||
builder.setDefaultRequestOptions(RequestOptions().format(DecodeFormat.PREFER_RGB_565))
|
builder.setDefaultRequestOptions(RequestOptions().format(DecodeFormat.PREFER_RGB_565))
|
||||||
val memoryCacheSizeBytes = 1024 * 1024 * 100 // 100mb
|
//val memoryCacheSizeBytes = 1024 * 1024 * 100 // 100mb
|
||||||
builder.setMemoryCache(LruResourceCache(memoryCacheSizeBytes.toLong()))
|
//builder.setMemoryCache(LruResourceCache(memoryCacheSizeBytes.toLong()))
|
||||||
|
|
||||||
/* builder.setDefaultTransitionOptions(
|
/* builder.setDefaultTransitionOptions(
|
||||||
Drawable::class.java,
|
Drawable::class.java,
|
||||||
|
@ -35,17 +35,15 @@ import eu.kanade.tachiyomi.source.model.SChapter
|
|||||||
import eu.kanade.tachiyomi.source.model.SManga
|
import eu.kanade.tachiyomi.source.model.SManga
|
||||||
import eu.kanade.tachiyomi.source.online.HttpSource
|
import eu.kanade.tachiyomi.source.online.HttpSource
|
||||||
import eu.kanade.tachiyomi.ui.main.MainActivity
|
import eu.kanade.tachiyomi.ui.main.MainActivity
|
||||||
import kotlinx.coroutines.CoroutineExceptionHandler
|
|
||||||
import kotlinx.coroutines.CoroutineStart
|
|
||||||
import kotlinx.coroutines.Dispatchers
|
|
||||||
import kotlinx.coroutines.GlobalScope
|
|
||||||
import kotlinx.coroutines.Job
|
|
||||||
import kotlinx.coroutines.launch
|
|
||||||
import eu.kanade.tachiyomi.util.chapter.syncChaptersWithSource
|
import eu.kanade.tachiyomi.util.chapter.syncChaptersWithSource
|
||||||
import eu.kanade.tachiyomi.util.lang.chop
|
import eu.kanade.tachiyomi.util.lang.chop
|
||||||
import eu.kanade.tachiyomi.util.system.isServiceRunning
|
import eu.kanade.tachiyomi.util.system.isServiceRunning
|
||||||
import eu.kanade.tachiyomi.util.system.notification
|
import eu.kanade.tachiyomi.util.system.notification
|
||||||
import eu.kanade.tachiyomi.util.system.notificationManager
|
import eu.kanade.tachiyomi.util.system.notificationManager
|
||||||
|
import kotlinx.coroutines.CoroutineExceptionHandler
|
||||||
|
import kotlinx.coroutines.GlobalScope
|
||||||
|
import kotlinx.coroutines.Job
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
import rx.Observable
|
import rx.Observable
|
||||||
import rx.Subscription
|
import rx.Subscription
|
||||||
import rx.schedulers.Schedulers
|
import rx.schedulers.Schedulers
|
||||||
@ -296,12 +294,9 @@ class LibraryUpdateService(
|
|||||||
val target = intent.getSerializableExtra(KEY_TARGET) as? Target ?: return START_NOT_STICKY
|
val target = intent.getSerializableExtra(KEY_TARGET) as? Target ?: return START_NOT_STICKY
|
||||||
|
|
||||||
// Unsubscribe from any previous subscription if needed.
|
// Unsubscribe from any previous subscription if needed.
|
||||||
|
job?.cancel()
|
||||||
subscription?.unsubscribe()
|
subscription?.unsubscribe()
|
||||||
|
|
||||||
val handler = CoroutineExceptionHandler { _, exception ->
|
|
||||||
Timber.e(exception)
|
|
||||||
stopSelf(startId)
|
|
||||||
}
|
|
||||||
val selectedScheme = preferences.libraryUpdatePrioritization().getOrDefault()
|
val selectedScheme = preferences.libraryUpdatePrioritization().getOrDefault()
|
||||||
if (target == Target.CHAPTERS) {
|
if (target == Target.CHAPTERS) {
|
||||||
updateChapters(
|
updateChapters(
|
||||||
@ -331,13 +326,15 @@ class LibraryUpdateService(
|
|||||||
private fun updateChapters(mangaToAdd: List<LibraryManga>, startId: Int) {
|
private fun updateChapters(mangaToAdd: List<LibraryManga>, startId: Int) {
|
||||||
addManga(mangaToAdd)
|
addManga(mangaToAdd)
|
||||||
|
|
||||||
if (job == null) {
|
val handler = CoroutineExceptionHandler { _, exception ->
|
||||||
job = GlobalScope.launch(Dispatchers.IO, CoroutineStart.DEFAULT) {
|
Timber.e(exception)
|
||||||
updateChaptersJob()
|
stopSelf(startId)
|
||||||
mangaToUpdate.clear()
|
}
|
||||||
categoryIds.clear()
|
job = GlobalScope.launch(handler) {
|
||||||
stopSelf(startId)
|
updateChaptersJob()
|
||||||
}
|
mangaToUpdate.clear()
|
||||||
|
categoryIds.clear()
|
||||||
|
stopSelf(startId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -160,5 +160,7 @@ class LibraryCategoryAdapter(val libraryListener: LibraryListener) :
|
|||||||
fun startReading(position: Int)
|
fun startReading(position: Int)
|
||||||
fun onItemReleased(position: Int)
|
fun onItemReleased(position: Int)
|
||||||
fun canDrag(): Boolean
|
fun canDrag(): Boolean
|
||||||
|
fun updateCategory(catId: Int): Boolean
|
||||||
|
fun sortCategory(catId: Int, sortBy: Int): String
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -90,7 +90,6 @@ class LibraryCategoryView @JvmOverloads constructor(context: Context, attrs: Att
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
recycler.setHasFixedSize(true)
|
recycler.setHasFixedSize(true)
|
||||||
recycler.adapter = adapter
|
recycler.adapter = adapter
|
||||||
swipe_refresh.addView(recycler)
|
swipe_refresh.addView(recycler)
|
||||||
@ -392,4 +391,12 @@ class LibraryCategoryView @JvmOverloads constructor(context: Context, attrs: Att
|
|||||||
controller.invalidateActionMode()
|
controller.invalidateActionMode()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun updateCategory(catId: Int): Boolean {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun sortCategory(catId: Int, sortBy: Int): String {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -20,8 +20,8 @@ import androidx.appcompat.app.AppCompatActivity
|
|||||||
import androidx.appcompat.view.ActionMode
|
import androidx.appcompat.view.ActionMode
|
||||||
import androidx.appcompat.widget.AppCompatSpinner
|
import androidx.appcompat.widget.AppCompatSpinner
|
||||||
import androidx.appcompat.widget.SearchView
|
import androidx.appcompat.widget.SearchView
|
||||||
import androidx.coordinatorlayout.widget.CoordinatorLayout
|
|
||||||
import androidx.core.graphics.drawable.DrawableCompat
|
import androidx.core.graphics.drawable.DrawableCompat
|
||||||
|
import androidx.core.math.MathUtils.clamp
|
||||||
import androidx.recyclerview.widget.GridLayoutManager
|
import androidx.recyclerview.widget.GridLayoutManager
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
@ -67,13 +67,14 @@ import eu.kanade.tachiyomi.util.view.gone
|
|||||||
import eu.kanade.tachiyomi.util.view.inflate
|
import eu.kanade.tachiyomi.util.view.inflate
|
||||||
import eu.kanade.tachiyomi.util.view.setOnQueryTextChangeListener
|
import eu.kanade.tachiyomi.util.view.setOnQueryTextChangeListener
|
||||||
import eu.kanade.tachiyomi.util.view.snack
|
import eu.kanade.tachiyomi.util.view.snack
|
||||||
import eu.kanade.tachiyomi.util.view.updateLayoutParams
|
|
||||||
import eu.kanade.tachiyomi.util.view.updatePaddingRelative
|
import eu.kanade.tachiyomi.util.view.updatePaddingRelative
|
||||||
import eu.kanade.tachiyomi.util.view.visible
|
import eu.kanade.tachiyomi.util.view.visible
|
||||||
import eu.kanade.tachiyomi.widget.AutofitRecyclerView
|
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.coroutines.delay
|
||||||
|
import timber.log.Timber
|
||||||
import uy.kohesive.injekt.Injekt
|
import uy.kohesive.injekt.Injekt
|
||||||
import uy.kohesive.injekt.api.get
|
import uy.kohesive.injekt.api.get
|
||||||
|
|
||||||
@ -179,7 +180,7 @@ class LibraryController(
|
|||||||
|
|
||||||
private var spinnerAdapter: SpinnerAdapter? = null
|
private var spinnerAdapter: SpinnerAdapter? = null
|
||||||
|
|
||||||
var scrollLister = object : RecyclerView.OnScrollListener () {
|
private var scrollListener = object : RecyclerView.OnScrollListener () {
|
||||||
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
|
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
|
||||||
super.onScrolled(recyclerView, dx, dy)
|
super.onScrolled(recyclerView, dx, dy)
|
||||||
val position =
|
val position =
|
||||||
@ -197,10 +198,10 @@ class LibraryController(
|
|||||||
bottom_sheet.lastCategory = category
|
bottom_sheet.lastCategory = category
|
||||||
if (preferences.librarySortingMode().getOrDefault() == LibrarySort.DRAG_AND_DROP)
|
if (preferences.librarySortingMode().getOrDefault() == LibrarySort.DRAG_AND_DROP)
|
||||||
bottom_sheet.updateTitle()
|
bottom_sheet.updateTitle()
|
||||||
// spinner.onItemSelectedListener = null
|
updateScroll = true
|
||||||
|
spinner.setSelection(order + 1)
|
||||||
spinnerAdapter?.setCustomText(category?.name)
|
spinnerAdapter?.setCustomText(category?.name)
|
||||||
//spinner.view
|
|
||||||
//spinner.post { spinner.onItemSelectedListener = listener }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -259,11 +260,11 @@ class LibraryController(
|
|||||||
else {
|
else {
|
||||||
adapter = LibraryCategoryAdapter(this)
|
adapter = LibraryCategoryAdapter(this)
|
||||||
recycler = if (preferences.libraryLayout().getOrDefault() == 0) {
|
recycler = if (preferences.libraryLayout().getOrDefault() == 0) {
|
||||||
(swipe_refresh.inflate(R.layout.library_list_recycler) as RecyclerView).apply {
|
(recycler_layout.inflate(R.layout.library_list_recycler) as RecyclerView).apply {
|
||||||
layoutManager = LinearLayoutManager(context)
|
layoutManager = LinearLayoutManager(context)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
(swipe_refresh.inflate(R.layout.library_grid_recycler) as AutofitRecyclerView).apply {
|
(recycler_layout.inflate(R.layout.library_grid_recycler) as AutofitRecyclerView).apply {
|
||||||
spanCount = mangaPerRow
|
spanCount = mangaPerRow
|
||||||
manager.spanSizeLookup = (object : GridLayoutManager.SpanSizeLookup() {
|
manager.spanSizeLookup = (object : GridLayoutManager.SpanSizeLookup() {
|
||||||
override fun getSpanSize(position: Int): Int {
|
override fun getSpanSize(position: Int): Int {
|
||||||
@ -280,9 +281,9 @@ class LibraryController(
|
|||||||
//adapter.setStickyHeaders(true)
|
//adapter.setStickyHeaders(true)
|
||||||
recycler_layout.addView(recycler)
|
recycler_layout.addView(recycler)
|
||||||
adapter.fastScroller = fast_scroller
|
adapter.fastScroller = fast_scroller
|
||||||
recycler.addOnScrollListener(scrollLister)
|
recycler.addOnScrollListener(scrollListener)
|
||||||
|
|
||||||
spinner = swipe_refresh.inflate(R.layout.library_spinner) as AppCompatSpinner
|
spinner = recycler_layout.inflate(R.layout.library_spinner) as AppCompatSpinner
|
||||||
(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,
|
||||||
@ -299,7 +300,7 @@ class LibraryController(
|
|||||||
|
|
||||||
|
|
||||||
//bottom_sheet.onCreate(pager_layout)
|
//bottom_sheet.onCreate(pager_layout)
|
||||||
bottom_sheet.onCreate(if (usePager) pager_layout else swipe_refresh)
|
bottom_sheet.onCreate(if (usePager) pager_layout else recycler_layout)
|
||||||
|
|
||||||
bottom_sheet.onGroupClicked = {
|
bottom_sheet.onGroupClicked = {
|
||||||
when (it) {
|
when (it) {
|
||||||
@ -334,9 +335,6 @@ class LibraryController(
|
|||||||
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) + 5.dpToPx
|
||||||
recycler.updatePaddingRelative(bottom = height)
|
recycler.updatePaddingRelative(bottom = height)
|
||||||
fast_scroller.updateLayoutParams<CoordinatorLayout.LayoutParams> {
|
|
||||||
bottomMargin = height
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (presenter.isDownloading()) {
|
if (presenter.isDownloading()) {
|
||||||
@ -350,7 +348,7 @@ class LibraryController(
|
|||||||
if (library != null) presenter.updateViewBlocking() //onNextLibraryUpdate(presenter.categories, library)
|
if (library != null) presenter.updateViewBlocking() //onNextLibraryUpdate(presenter.categories, library)
|
||||||
else {
|
else {
|
||||||
library_pager.alpha = 0f
|
library_pager.alpha = 0f
|
||||||
swipe_refresh.alpha = 0f
|
recycler_layout.alpha = 0f
|
||||||
presenter.getLibraryBlocking()
|
presenter.getLibraryBlocking()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -466,8 +464,8 @@ class LibraryController(
|
|||||||
spinnerAdapter?.setCustomText(presenter.categories.find { it.order == activeCategory
|
spinnerAdapter?.setCustomText(presenter.categories.find { it.order == activeCategory
|
||||||
}?.name ?: resources?.getString(R.string.label_library))
|
}?.name ?: resources?.getString(R.string.label_library))
|
||||||
justStarted = false
|
justStarted = false
|
||||||
if (swipe_refresh.alpha == 0f)
|
if (recycler_layout.alpha == 0f)
|
||||||
swipe_refresh.animate().alpha(1f).setDuration(500).start()
|
recycler_layout.animate().alpha(1f).setDuration(500).start()
|
||||||
|
|
||||||
|
|
||||||
}else {
|
}else {
|
||||||
@ -475,7 +473,18 @@ class LibraryController(
|
|||||||
(recycler.layoutManager as LinearLayoutManager)
|
(recycler.layoutManager as LinearLayoutManager)
|
||||||
.scrollToPositionWithOffset(position, 0)
|
.scrollToPositionWithOffset(position, 0)
|
||||||
}
|
}
|
||||||
|
adapter.isLongPressDragEnabled = canDrag()
|
||||||
|
|
||||||
|
bottom_sheet.lastCategory = presenter.categories[clamp(activeCategory,
|
||||||
|
0,
|
||||||
|
presenter.categories.size - 1)]
|
||||||
|
bottom_sheet.updateTitle()
|
||||||
|
updateScroll = false
|
||||||
spinner.onItemSelectedListener = IgnoreFirstSpinnerListener { pos ->
|
spinner.onItemSelectedListener = IgnoreFirstSpinnerListener { pos ->
|
||||||
|
if (updateScroll) {
|
||||||
|
updateScroll = false
|
||||||
|
return@IgnoreFirstSpinnerListener
|
||||||
|
}
|
||||||
val headerPosition = adapter.indexOf(pos - 1) + 1
|
val headerPosition = adapter.indexOf(pos - 1) + 1
|
||||||
if (headerPosition > -1) {
|
if (headerPosition > -1) {
|
||||||
(recycler.layoutManager as LinearLayoutManager).scrollToPositionWithOffset(
|
(recycler.layoutManager as LinearLayoutManager).scrollToPositionWithOffset(
|
||||||
@ -589,11 +598,11 @@ class LibraryController(
|
|||||||
recycler !is AutofitRecyclerView && preferences.libraryLayout().getOrDefault() > 0) {
|
recycler !is AutofitRecyclerView && preferences.libraryLayout().getOrDefault() > 0) {
|
||||||
recycler_layout.removeView(recycler)
|
recycler_layout.removeView(recycler)
|
||||||
recycler = if (preferences.libraryLayout().getOrDefault() == 0) {
|
recycler = if (preferences.libraryLayout().getOrDefault() == 0) {
|
||||||
(swipe_refresh.inflate(R.layout.library_list_recycler) as RecyclerView).apply {
|
(recycler_layout.inflate(R.layout.library_list_recycler) as RecyclerView).apply {
|
||||||
layoutManager = LinearLayoutManager(context)
|
layoutManager = LinearLayoutManager(context)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
(swipe_refresh.inflate(R.layout.library_grid_recycler) as AutofitRecyclerView).apply {
|
(recycler_layout.inflate(R.layout.library_grid_recycler) as AutofitRecyclerView).apply {
|
||||||
spanCount = mangaPerRow
|
spanCount = mangaPerRow
|
||||||
manager.spanSizeLookup = (object : GridLayoutManager.SpanSizeLookup() {
|
manager.spanSizeLookup = (object : GridLayoutManager.SpanSizeLookup() {
|
||||||
override fun getSpanSize(position: Int): Int {
|
override fun getSpanSize(position: Int): Int {
|
||||||
@ -605,7 +614,7 @@ class LibraryController(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
recycler.setHasFixedSize(true)
|
recycler.setHasFixedSize(true)
|
||||||
recycler.addOnScrollListener(scrollLister)
|
recycler.addOnScrollListener(scrollListener)
|
||||||
recycler_layout.addView(recycler)
|
recycler_layout.addView(recycler)
|
||||||
}
|
}
|
||||||
recycler.adapter = adapter
|
recycler.adapter = adapter
|
||||||
@ -667,6 +676,8 @@ class LibraryController(
|
|||||||
setOnQueryTextChangeListener(searchView) {
|
setOnQueryTextChangeListener(searchView) {
|
||||||
query = it ?: ""
|
query = it ?: ""
|
||||||
searchRelay.call(query)
|
searchRelay.call(query)
|
||||||
|
adapter.setFilter(it)
|
||||||
|
adapter.performFilter()
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
searchItem.fixExpand(onExpand = { invalidateMenuOnExpand() })
|
searchItem.fixExpand(onExpand = { invalidateMenuOnExpand() })
|
||||||
@ -800,6 +811,11 @@ class LibraryController(
|
|||||||
override fun onDestroyActionMode(mode: ActionMode?) {
|
override fun onDestroyActionMode(mode: ActionMode?) {
|
||||||
// Clear all the manga selections and notify child views.
|
// Clear all the manga selections and notify child views.
|
||||||
selectedMangas.clear()
|
selectedMangas.clear()
|
||||||
|
adapter.mode = SelectableAdapter.Mode.SINGLE
|
||||||
|
adapter.clearSelection()
|
||||||
|
adapter.notifyDataSetChanged()
|
||||||
|
lastClickPosition = -1
|
||||||
|
adapter.isLongPressDragEnabled = canDrag()
|
||||||
selectionRelay.call(LibrarySelectionEvent.Cleared())
|
selectionRelay.call(LibrarySelectionEvent.Cleared())
|
||||||
actionMode = null
|
actionMode = null
|
||||||
}
|
}
|
||||||
@ -817,11 +833,33 @@ class LibraryController(
|
|||||||
fun setSelection(manga: Manga, selected: Boolean) {
|
fun setSelection(manga: Manga, selected: Boolean) {
|
||||||
if (selected) {
|
if (selected) {
|
||||||
if (selectedMangas.add(manga)) {
|
if (selectedMangas.add(manga)) {
|
||||||
selectionRelay.call(LibrarySelectionEvent.Selected(manga))
|
if (usePager) selectionRelay.call(LibrarySelectionEvent.Selected(manga))
|
||||||
|
else {
|
||||||
|
val position = adapter.indexOf(manga)
|
||||||
|
if (adapter.mode != SelectableAdapter.Mode.MULTI) {
|
||||||
|
adapter.mode = SelectableAdapter.Mode.MULTI
|
||||||
|
}
|
||||||
|
launchUI {
|
||||||
|
delay(100)
|
||||||
|
adapter.isLongPressDragEnabled = false
|
||||||
|
}
|
||||||
|
adapter.toggleSelection(position)
|
||||||
|
(recycler.findViewHolderForItemId(manga.id!!) as? LibraryHolder)?.toggleActivation()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (selectedMangas.remove(manga)) {
|
if (selectedMangas.remove(manga)) {
|
||||||
selectionRelay.call(LibrarySelectionEvent.Unselected(manga))
|
if (usePager) selectionRelay.call(LibrarySelectionEvent.Unselected(manga))
|
||||||
|
else {
|
||||||
|
val position = adapter.indexOf(manga)
|
||||||
|
lastClickPosition = -1
|
||||||
|
if (selectedMangas.isEmpty()) {
|
||||||
|
adapter.mode = SelectableAdapter.Mode.SINGLE
|
||||||
|
adapter.isLongPressDragEnabled = canDrag()
|
||||||
|
}
|
||||||
|
adapter.toggleSelection(position)
|
||||||
|
(recycler.findViewHolderForItemId(manga.id!!) as? LibraryHolder)?.toggleActivation()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -876,16 +914,13 @@ 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)
|
||||||
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()
|
||||||
startActivity(intent)
|
startActivity(intent)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onItemReleased(position: Int) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
fun startReading(manga: Manga) {
|
fun startReading(manga: Manga) {
|
||||||
val activity = activity ?: return
|
val activity = activity ?: return
|
||||||
val chapter = presenter.getFirstUnread(manga) ?: return
|
val chapter = presenter.getFirstUnread(manga) ?: return
|
||||||
@ -953,9 +988,9 @@ class LibraryController(
|
|||||||
* @param position the position to toggle.
|
* @param position the position to toggle.
|
||||||
*/
|
*/
|
||||||
private fun toggleSelection(position: Int) {
|
private fun toggleSelection(position: Int) {
|
||||||
val item = adapter.getItem(position) ?: return
|
val item = adapter.getItem(position) as? LibraryItem ?: return
|
||||||
|
|
||||||
setSelection((item as LibraryItem).manga, !adapter.isSelected(position))
|
setSelection(item.manga, !adapter.isSelected(position))
|
||||||
invalidateActionMode()
|
invalidateActionMode()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -966,14 +1001,29 @@ class LibraryController(
|
|||||||
* @param position the position to toggle.
|
* @param position the position to toggle.
|
||||||
*/
|
*/
|
||||||
private fun setSelection(position: Int) {
|
private fun setSelection(position: Int) {
|
||||||
val item = adapter.getItem(position) ?: return
|
val item = adapter.getItem(position) as? LibraryItem ?: return
|
||||||
|
|
||||||
setSelection((item as LibraryItem).manga, true)
|
setSelection(item.manga, true)
|
||||||
invalidateActionMode()
|
invalidateActionMode()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onItemMove(fromPosition: Int, toPosition: Int) { }
|
override fun onItemMove(fromPosition: Int, toPosition: Int) { }
|
||||||
|
|
||||||
|
override fun onItemReleased(position: Int) {
|
||||||
|
if (adapter.selectedItemCount > 0) return
|
||||||
|
val item = adapter.getItem(position) as? LibraryItem ?: return
|
||||||
|
val newHeader = adapter.getSectionHeader(position) as? LibraryHeaderItem
|
||||||
|
val libraryItems = adapter.getSectionItems(adapter.getSectionHeader(position)).filterIsInstance<LibraryItem>()
|
||||||
|
val mangaIds = libraryItems.mapNotNull { (it as? LibraryItem)?.manga?.id }
|
||||||
|
if (newHeader?.category?.id == item.manga.category) {
|
||||||
|
presenter.rearrangeCategory(item.manga.category, mangaIds)
|
||||||
|
} else {
|
||||||
|
presenter.moveMangaToCategory(item, newHeader?.category?.id, mangaIds)
|
||||||
|
Timber.d("Manga has Moved")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
override fun shouldMoveItem(fromPosition: Int, toPosition: Int): Boolean {
|
override fun shouldMoveItem(fromPosition: Int, toPosition: Int): Boolean {
|
||||||
if (adapter.selectedItemCount > 1)
|
if (adapter.selectedItemCount > 1)
|
||||||
return false
|
return false
|
||||||
@ -981,6 +1031,29 @@ class LibraryController(
|
|||||||
toggleSelection(fromPosition)
|
toggleSelection(fromPosition)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun updateCategory(catId: Int): Boolean {
|
||||||
|
val category = (adapter.getItem(catId) as? LibraryHeaderItem)?.category ?:
|
||||||
|
return false
|
||||||
|
val inQueue = LibraryUpdateService.categoryInQueue(category.id)
|
||||||
|
snack?.dismiss()
|
||||||
|
snack = snackbar_layout.snack(resources!!.getString(
|
||||||
|
when {
|
||||||
|
inQueue -> R.string.category_already_in_queue
|
||||||
|
LibraryUpdateService.isRunning(view!!.context) ->
|
||||||
|
R.string.adding_category_to_queue
|
||||||
|
else -> R.string.updating_category_x
|
||||||
|
}, category.name))
|
||||||
|
if (!inQueue)
|
||||||
|
LibraryUpdateService.start(view!!.context, category)
|
||||||
|
return true
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun sortCategory(catId: Int, sortBy: Int): String {
|
||||||
|
presenter.sortCategory(catId, sortBy)
|
||||||
|
return ""
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
object HeightTopWindowInsetsListener : View.OnApplyWindowInsetsListener {
|
object HeightTopWindowInsetsListener : View.OnApplyWindowInsetsListener {
|
||||||
|
@ -1,14 +1,25 @@
|
|||||||
package eu.kanade.tachiyomi.ui.library
|
package eu.kanade.tachiyomi.ui.library
|
||||||
|
|
||||||
|
import android.graphics.drawable.Drawable
|
||||||
import android.view.View
|
import android.view.View
|
||||||
|
import android.widget.ProgressBar
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
|
import androidx.appcompat.view.menu.MenuBuilder
|
||||||
|
import androidx.appcompat.widget.PopupMenu
|
||||||
|
import androidx.core.content.ContextCompat
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
import com.google.android.material.button.MaterialButton
|
||||||
import eu.davidea.flexibleadapter.FlexibleAdapter
|
import eu.davidea.flexibleadapter.FlexibleAdapter
|
||||||
import eu.davidea.flexibleadapter.items.AbstractHeaderItem
|
import eu.davidea.flexibleadapter.items.AbstractHeaderItem
|
||||||
import eu.davidea.flexibleadapter.items.IFlexible
|
import eu.davidea.flexibleadapter.items.IFlexible
|
||||||
import eu.davidea.viewholders.FlexibleViewHolder
|
import eu.davidea.viewholders.FlexibleViewHolder
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
import eu.kanade.tachiyomi.data.database.models.Category
|
import eu.kanade.tachiyomi.data.database.models.Category
|
||||||
|
import eu.kanade.tachiyomi.data.library.LibraryUpdateService
|
||||||
|
import eu.kanade.tachiyomi.util.system.getResourceColor
|
||||||
|
import eu.kanade.tachiyomi.util.view.gone
|
||||||
|
import eu.kanade.tachiyomi.util.view.invisible
|
||||||
|
import eu.kanade.tachiyomi.util.view.visible
|
||||||
|
|
||||||
class LibraryHeaderItem(val category: Category) : AbstractHeaderItem<LibraryHeaderItem.Holder>() {
|
class LibraryHeaderItem(val category: Category) : AbstractHeaderItem<LibraryHeaderItem.Holder>() {
|
||||||
|
|
||||||
@ -20,7 +31,7 @@ class LibraryHeaderItem(val category: Category) : AbstractHeaderItem<LibraryHead
|
|||||||
view: View,
|
view: View,
|
||||||
adapter: FlexibleAdapter<IFlexible<RecyclerView.ViewHolder>>
|
adapter: FlexibleAdapter<IFlexible<RecyclerView.ViewHolder>>
|
||||||
): Holder {
|
): Holder {
|
||||||
return Holder(view, adapter)
|
return Holder(view, adapter as LibraryCategoryAdapter)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun bindViewHolder(
|
override fun bindViewHolder(
|
||||||
@ -49,16 +60,120 @@ class LibraryHeaderItem(val category: Category) : AbstractHeaderItem<LibraryHead
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun hashCode(): Int {
|
override fun hashCode(): Int {
|
||||||
return category.id!!
|
return -(category.id!!)
|
||||||
}
|
}
|
||||||
|
|
||||||
class Holder(view: View, adapter: FlexibleAdapter<IFlexible<RecyclerView.ViewHolder>>) :
|
class Holder(view: View, private val adapter: LibraryCategoryAdapter) :
|
||||||
FlexibleViewHolder(view, adapter, true) {
|
FlexibleViewHolder(view, adapter, true) {
|
||||||
|
|
||||||
private val sectionText: TextView = view.findViewById(R.id.category_title)
|
private val sectionText: TextView = view.findViewById(R.id.category_title)
|
||||||
|
private val sortText: TextView = view.findViewById(R.id.category_sort)
|
||||||
|
private val updateButton: MaterialButton = view.findViewById(R.id.update_button)
|
||||||
|
private val catProgress: ProgressBar = view.findViewById(R.id.cat_progress)
|
||||||
|
|
||||||
|
init {
|
||||||
|
updateButton.setOnClickListener { addCategoryToUpdate() }
|
||||||
|
sortText.setOnClickListener { showCatSortOptions() }
|
||||||
|
}
|
||||||
|
|
||||||
fun bind(item: LibraryHeaderItem) {
|
fun bind(item: LibraryHeaderItem) {
|
||||||
sectionText.text = item.category.name
|
sectionText.text = item.category.name
|
||||||
|
sortText.text = itemView.context.getString(
|
||||||
|
when (item.category.sortingMode()) {
|
||||||
|
LibrarySort.LAST_UPDATED -> R.string.action_sort_last_updated
|
||||||
|
LibrarySort.DRAG_AND_DROP -> R.string.action_sort_drag_and_drop
|
||||||
|
LibrarySort.TOTAL -> R.string.action_sort_total
|
||||||
|
LibrarySort.UNREAD -> R.string.action_filter_unread
|
||||||
|
LibrarySort.LAST_READ -> R.string.action_sort_last_read
|
||||||
|
LibrarySort.ALPHA -> R.string.title
|
||||||
|
else -> R.string.action_sort_drag_and_drop
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
if (LibraryUpdateService.categoryInQueue(item.category.id)) {
|
||||||
|
catProgress.visible()
|
||||||
|
updateButton.invisible()
|
||||||
|
} else {
|
||||||
|
catProgress.gone()
|
||||||
|
updateButton.visible()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun addCategoryToUpdate() {
|
||||||
|
if (adapter.libraryListener.updateCategory(adapterPosition)) {
|
||||||
|
catProgress.visible()
|
||||||
|
updateButton.invisible()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun showCatSortOptions() {
|
||||||
|
val category =
|
||||||
|
(adapter.getItem(adapterPosition) as? LibraryHeaderItem)?.category ?: return
|
||||||
|
// Create a PopupMenu, giving it the clicked view for an anchor
|
||||||
|
val popup = PopupMenu(itemView.context, sortText)
|
||||||
|
|
||||||
|
// Inflate our menu resource into the PopupMenu's Menu
|
||||||
|
popup.menuInflater.inflate(R.menu.cat_sort, popup.menu)
|
||||||
|
|
||||||
|
// Set a listener so we are notified if a menu item is clicked
|
||||||
|
popup.setOnMenuItemClickListener { menuItem ->
|
||||||
|
onCatSortClicked(category, menuItem.itemId)
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
val sortingMode = category.sortingMode()
|
||||||
|
val currentItem = if (sortingMode == null) null
|
||||||
|
else popup.menu.findItem(
|
||||||
|
when (sortingMode) {
|
||||||
|
LibrarySort.DRAG_AND_DROP -> R.id.action_drag_and_drop
|
||||||
|
LibrarySort.TOTAL -> R.id.action_total_chaps
|
||||||
|
LibrarySort.LAST_READ -> R.id.action_last_read
|
||||||
|
LibrarySort.UNREAD -> R.id.action_unread
|
||||||
|
LibrarySort.LAST_UPDATED -> R.id.action_update
|
||||||
|
else -> R.id.action_alpha
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
if (sortingMode != null && popup.menu is MenuBuilder) {
|
||||||
|
val m = popup.menu as MenuBuilder
|
||||||
|
m.setOptionalIconsVisible(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
currentItem?.icon = tintVector(
|
||||||
|
if (category.isAscending()) R.drawable.ic_arrow_up_white_24dp
|
||||||
|
else R.drawable.ic_arrow_down_white_24dp
|
||||||
|
)
|
||||||
|
|
||||||
|
// Finally show the PopupMenu
|
||||||
|
popup.show()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun tintVector(resId: Int): Drawable? {
|
||||||
|
return ContextCompat.getDrawable(itemView.context, resId)?.mutate()?.apply {
|
||||||
|
setTint(itemView.context.getResourceColor(android.R.attr.colorAccent))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun onCatSortClicked(category: Category, menuId: Int?) {
|
||||||
|
val modType = if (menuId == null) {
|
||||||
|
val t = (category.mangaSort?.minus('a') ?: 0) + 1
|
||||||
|
if (t % 2 != 0) t + 1
|
||||||
|
else t - 1
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
val order = when (menuId) {
|
||||||
|
R.id.action_last_read -> 3
|
||||||
|
R.id.action_unread -> 2
|
||||||
|
R.id.action_update -> 1
|
||||||
|
else -> 0
|
||||||
|
}
|
||||||
|
if (order == category.catSortingMode()) {
|
||||||
|
onCatSortClicked(category, null)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
(2 * order + 1)
|
||||||
|
}
|
||||||
|
adapter.libraryListener.sortCategory(category.id!!, modType)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -486,20 +486,12 @@ class LibraryPresenter(
|
|||||||
|
|
||||||
suspend fun updateView(categories: List<Category>, mangaMap: LibraryMap, freshStart:Boolean
|
suspend fun updateView(categories: List<Category>, mangaMap: LibraryMap, freshStart:Boolean
|
||||||
= false) {
|
= false) {
|
||||||
/* 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 }
|
|
||||||
}*/
|
|
||||||
if (preferences.libraryUsingPager().getOrDefault()) {
|
if (preferences.libraryUsingPager().getOrDefault()) {
|
||||||
view.onNextLibraryUpdate(categories, mangaMap, true)
|
view.onNextLibraryUpdate(categories, mangaMap, true)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
val mangaList = withContext(Dispatchers.IO) {
|
val mangaList = withContext(Dispatchers.IO) {
|
||||||
val list = mutableListOf<LibraryItem>()
|
val list = mutableListOf<LibraryItem>()
|
||||||
val many = categories.size > 1
|
|
||||||
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
|
||||||
})) {
|
})) {
|
||||||
@ -771,8 +763,67 @@ class LibraryPresenter(
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun sortCategory(catId: Int, order: Int) {
|
||||||
|
val category = categories.find { catId == it.id } ?: return
|
||||||
|
category.mangaSort = ('a' + (order - 1))
|
||||||
|
if (category.id == 0)
|
||||||
|
preferences.defaultMangaOrder().set(category.mangaSort.toString())
|
||||||
|
else
|
||||||
|
Injekt.get<DatabaseHelper>().insertCategory(category).asRxObservable().subscribe()
|
||||||
|
requestCatSortUpdate(category.id!!)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun rearrangeCategory(catId: Int?, mangaIds: List<Long>) {
|
||||||
|
GlobalScope.launch(Dispatchers.IO) {
|
||||||
|
val category = categories.find { catId == it.id } ?: return@launch
|
||||||
|
category.mangaSort = null
|
||||||
|
category.mangaOrder = mangaIds
|
||||||
|
if (category.id == 0) preferences.defaultMangaOrder().set(mangaIds.joinToString("/"))
|
||||||
|
else db.insertCategory(category).executeAsBlocking()
|
||||||
|
requestCatSortUpdate(category.id!!)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun moveMangaToCategory(item: LibraryItem, catId: Int?, mangaIds: List<Long>) {
|
||||||
|
GlobalScope.launch(Dispatchers.IO) {
|
||||||
|
val categoryId = catId ?: return@launch
|
||||||
|
val category = categories.find { catId == it.id } ?: return@launch
|
||||||
|
val manga = item.manga
|
||||||
|
|
||||||
|
val mangaMap = currentMangaMap?.toMutableMap() ?: return@launch
|
||||||
|
val oldCatId = item.manga.category
|
||||||
|
val oldCatMap = mangaMap[manga.category]?.toMutableList() ?: return@launch
|
||||||
|
val newCatMap = mangaMap[catId]?.toMutableList() ?: return@launch
|
||||||
|
oldCatMap.remove(item)
|
||||||
|
newCatMap.add(item)
|
||||||
|
mangaMap[oldCatId] = oldCatMap
|
||||||
|
mangaMap[catId] = newCatMap
|
||||||
|
currentMangaMap = mangaMap
|
||||||
|
|
||||||
|
item.manga.category = categoryId
|
||||||
|
|
||||||
|
val mc = ArrayList<MangaCategory>()
|
||||||
|
val categories =
|
||||||
|
db.getCategoriesForManga(manga).executeAsBlocking().filter { it.id != oldCatId } + listOf(category)
|
||||||
|
|
||||||
|
for (cat in categories) {
|
||||||
|
mc.add(MangaCategory.create(manga, cat))
|
||||||
|
}
|
||||||
|
|
||||||
|
db.setMangaCategories(mc, listOf(manga))
|
||||||
|
|
||||||
|
category.mangaSort = null
|
||||||
|
val ids = mangaIds.toMutableList()
|
||||||
|
if (!ids.contains(manga.id!!))
|
||||||
|
ids.add(manga.id!!)
|
||||||
|
category.mangaOrder = ids
|
||||||
|
if (category.id == 0) preferences.defaultMangaOrder().set(mangaIds.joinToString("/"))
|
||||||
|
else db.insertCategory(category).executeAsBlocking()
|
||||||
|
getLibrary()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private companion object {
|
private companion object {
|
||||||
var currentLibrary:Library? = null
|
var currentLibrary:Library? = null
|
||||||
var currentList:List<LibraryItem>? = null
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,11 +10,10 @@ import android.view.View
|
|||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import android.widget.ImageView
|
import android.widget.ImageView
|
||||||
import android.widget.LinearLayout
|
import android.widget.LinearLayout
|
||||||
import android.widget.RadioButton
|
|
||||||
import android.widget.RadioGroup
|
|
||||||
import android.widget.Spinner
|
import android.widget.Spinner
|
||||||
import androidx.appcompat.view.menu.MenuBuilder
|
import androidx.appcompat.view.menu.MenuBuilder
|
||||||
import androidx.appcompat.widget.PopupMenu
|
import androidx.appcompat.widget.PopupMenu
|
||||||
|
import androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
import com.f2prateek.rx.preferences.Preference
|
import com.f2prateek.rx.preferences.Preference
|
||||||
import com.google.android.material.bottomsheet.BottomSheetBehavior
|
import com.google.android.material.bottomsheet.BottomSheetBehavior
|
||||||
@ -122,6 +121,7 @@ class SortFilterBottomSheet @JvmOverloads constructor(context: Context, attrs: A
|
|||||||
updateTitle()
|
updateTitle()
|
||||||
val shadow2:View = (pagerView.parent as ViewGroup).findViewById(R.id.shadow2)
|
val shadow2:View = (pagerView.parent as ViewGroup).findViewById(R.id.shadow2)
|
||||||
val shadow:View = (pagerView.parent as ViewGroup).findViewById(R.id.shadow)
|
val shadow:View = (pagerView.parent as ViewGroup).findViewById(R.id.shadow)
|
||||||
|
val fastScroller:View = (pagerView.parent as ViewGroup).findViewById(R.id.fast_scroller)
|
||||||
val coordLayout:View = (pagerView.parent as ViewGroup).findViewById(R.id.snackbar_layout)
|
val coordLayout:View = (pagerView.parent as ViewGroup).findViewById(R.id.snackbar_layout)
|
||||||
val phoneLandscape = (isLandscape() && !isTablet())
|
val phoneLandscape = (isLandscape() && !isTablet())
|
||||||
if (phoneLandscape)
|
if (phoneLandscape)
|
||||||
@ -167,6 +167,9 @@ class SortFilterBottomSheet @JvmOverloads constructor(context: Context, attrs: A
|
|||||||
}
|
}
|
||||||
if (sheetBehavior?.state == BottomSheetBehavior.STATE_COLLAPSED) {
|
if (sheetBehavior?.state == BottomSheetBehavior.STATE_COLLAPSED) {
|
||||||
val height = context.resources.getDimensionPixelSize(R.dimen.rounder_radius)
|
val height = context.resources.getDimensionPixelSize(R.dimen.rounder_radius)
|
||||||
|
fastScroller.updateLayoutParams<CoordinatorLayout.LayoutParams> {
|
||||||
|
bottomMargin = if (phoneLandscape) 0 else (top_bar.height - height)
|
||||||
|
}
|
||||||
pager?.setPadding(0, 0, 0, if (phoneLandscape) 0 else
|
pager?.setPadding(0, 0, 0, if (phoneLandscape) 0 else
|
||||||
(top_bar.height - height))
|
(top_bar.height - height))
|
||||||
coordLayout.setPadding(0, 0, 0, peekingHeight)
|
coordLayout.setPadding(0, 0, 0, peekingHeight)
|
||||||
|
@ -1,154 +1,161 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:id="@+id/constraint_layout"
|
android:id="@+id/manga_layout"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_gravity="bottom"
|
android:layout_gravity="bottom">
|
||||||
android:background="@drawable/library_compact_grid_selector"
|
|
||||||
android:minHeight="200dp"
|
|
||||||
android:orientation="vertical">
|
|
||||||
|
|
||||||
<com.google.android.material.card.MaterialCardView
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
android:id="@+id/card"
|
android:id="@+id/constraint_layout"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_gravity="bottom"
|
android:layout_gravity="bottom"
|
||||||
android:layout_marginStart="8dp"
|
android:background="@drawable/library_compact_grid_selector"
|
||||||
android:layout_marginTop="10dp"
|
android:minHeight="200dp"
|
||||||
android:layout_marginEnd="8dp"
|
android:orientation="vertical">
|
||||||
app:layout_constraintBottom_toTopOf="@+id/title"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
|
||||||
app:layout_constraintVertical_bias="1.0">
|
|
||||||
|
|
||||||
|
<com.google.android.material.card.MaterialCardView
|
||||||
<ImageView
|
android:id="@+id/card"
|
||||||
android:id="@+id/cover_thumbnail"
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:adjustViewBounds="true"
|
android:layout_gravity="bottom"
|
||||||
android:background="?android:attr/colorBackground"
|
android:layout_marginStart="8dp"
|
||||||
android:maxHeight="250dp"
|
android:layout_marginTop="10dp"
|
||||||
app:layout_constrainedHeight="true"
|
android:layout_marginEnd="8dp"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toTopOf="@+id/title"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
tools:background="?android:attr/colorBackground"
|
app:layout_constraintVertical_bias="1.0">
|
||||||
tools:ignore="ContentDescription"
|
|
||||||
tools:src="@mipmap/ic_launcher" />
|
|
||||||
|
|
||||||
<FrameLayout
|
|
||||||
android:id="@+id/play_layout"
|
|
||||||
android:layout_width="50dp"
|
|
||||||
android:layout_height="50dp"
|
|
||||||
android:layout_gravity="end"
|
|
||||||
android:clickable="true"
|
|
||||||
android:focusable="true"
|
|
||||||
android:visibility="gone"
|
|
||||||
tools:visibility="visible">
|
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:id="@+id/play_button"
|
android:id="@+id/cover_thumbnail"
|
||||||
android:layout_width="30dp"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="30dp"
|
android:layout_height="wrap_content"
|
||||||
android:layout_gravity="end"
|
android:adjustViewBounds="true"
|
||||||
android:layout_marginTop="6dp"
|
android:background="?android:attr/colorBackground"
|
||||||
android:layout_marginEnd="6dp"
|
android:maxHeight="250dp"
|
||||||
android:layout_marginBottom="6dp"
|
app:layout_constrainedHeight="true"
|
||||||
android:background="@drawable/round_play_background"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
android:contentDescription="@string/start_reading"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
android:padding="6dp"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
android:src="@drawable/ic_start_reading_white_24dp"
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
android:tint="@android:color/white" />
|
tools:background="?android:attr/colorBackground"
|
||||||
|
tools:ignore="ContentDescription"
|
||||||
|
tools:src="@mipmap/ic_launcher" />
|
||||||
|
|
||||||
</FrameLayout>
|
<FrameLayout
|
||||||
|
android:id="@+id/play_layout"
|
||||||
|
android:layout_width="50dp"
|
||||||
|
android:layout_height="50dp"
|
||||||
|
android:layout_gravity="end"
|
||||||
|
android:clickable="true"
|
||||||
|
android:focusable="true"
|
||||||
|
android:visibility="gone"
|
||||||
|
tools:visibility="visible">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/play_button"
|
||||||
|
android:layout_width="30dp"
|
||||||
|
android:layout_height="30dp"
|
||||||
|
android:layout_gravity="end"
|
||||||
|
android:layout_marginTop="6dp"
|
||||||
|
android:layout_marginEnd="6dp"
|
||||||
|
android:layout_marginBottom="6dp"
|
||||||
|
android:background="@drawable/round_play_background"
|
||||||
|
android:contentDescription="@string/start_reading"
|
||||||
|
android:padding="6dp"
|
||||||
|
android:src="@drawable/ic_start_reading_white_24dp"
|
||||||
|
android:tint="@android:color/white" />
|
||||||
|
|
||||||
|
</FrameLayout>
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:id="@+id/gradient"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="150dp"
|
||||||
|
android:layout_gravity="bottom"
|
||||||
|
android:background="@drawable/gradient_shape" />
|
||||||
|
|
||||||
|
<com.google.android.material.textview.MaterialTextView
|
||||||
|
android:id="@+id/compact_title"
|
||||||
|
style="@style/TextAppearance.Regular.Body1.SemiBold"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="bottom"
|
||||||
|
android:layout_marginStart="4dp"
|
||||||
|
android:layout_marginEnd="4dp"
|
||||||
|
android:layout_marginBottom="4dp"
|
||||||
|
android:ellipsize="end"
|
||||||
|
android:maxLines="2"
|
||||||
|
android:textColor="@android:color/white"
|
||||||
|
android:textSize="13sp"
|
||||||
|
tools:text="Sample name" />
|
||||||
|
|
||||||
|
<ProgressBar
|
||||||
|
android:id="@+id/progress"
|
||||||
|
style="?android:attr/progressBarStyleSmall"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:visibility="gone"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
</com.google.android.material.card.MaterialCardView>
|
||||||
|
|
||||||
<View
|
<View
|
||||||
android:id="@+id/gradient"
|
android:id="@+id/badge_guide"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="150dp"
|
android:layout_height="10dp"
|
||||||
android:layout_gravity="bottom"
|
app:layout_constraintTop_toTopOf="@+id/card" />
|
||||||
android:background="@drawable/gradient_shape" />
|
|
||||||
|
|
||||||
<com.google.android.material.textview.MaterialTextView
|
<include
|
||||||
android:id="@+id/compact_title"
|
layout="@layout/unread_download_badge"
|
||||||
style="@style/TextAppearance.Regular.Body1.SemiBold"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_gravity="bottom"
|
|
||||||
android:layout_marginStart="4dp"
|
|
||||||
android:layout_marginEnd="4dp"
|
|
||||||
android:layout_marginBottom="4dp"
|
|
||||||
android:ellipsize="end"
|
|
||||||
android:maxLines="2"
|
|
||||||
android:textColor="@android:color/white"
|
|
||||||
android:textSize="13sp"
|
|
||||||
tools:text="Sample name" />
|
|
||||||
|
|
||||||
<ProgressBar
|
|
||||||
android:id="@+id/progress"
|
|
||||||
style="?android:attr/progressBarStyleSmall"
|
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_gravity="center"
|
app:layout_constraintBottom_toBottomOf="@id/badge_guide"
|
||||||
android:visibility="gone"
|
app:layout_constraintStart_toStartOf="parent" />
|
||||||
|
|
||||||
|
<com.google.android.material.textview.MaterialTextView
|
||||||
|
android:id="@+id/title"
|
||||||
|
style="@style/TextAppearance.Regular.Body1.Light"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="8dp"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
|
android:layout_marginEnd="8dp"
|
||||||
|
android:ellipsize="end"
|
||||||
|
android:maxLines="2"
|
||||||
|
android:textColor="?android:attr/textColorPrimary"
|
||||||
|
android:textSize="12sp"
|
||||||
|
app:layout_constraintBottom_toTopOf="@+id/subtitle"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
tools:text="Sample name" />
|
||||||
|
|
||||||
|
<com.google.android.material.textview.MaterialTextView
|
||||||
|
android:id="@+id/subtitle"
|
||||||
|
style="@style/TextAppearance.Regular.Body1.Light"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="8dp"
|
||||||
|
android:layout_marginTop="-1dp"
|
||||||
|
android:layout_marginEnd="8dp"
|
||||||
|
android:layout_marginBottom="8dp"
|
||||||
|
android:ellipsize="end"
|
||||||
|
android:singleLine="true"
|
||||||
|
android:textColor="?android:attr/textColorSecondary"
|
||||||
|
android:textSize="12sp"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toTopOf="parent" />
|
tools:text="Sample artist" />
|
||||||
|
|
||||||
</com.google.android.material.card.MaterialCardView>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
</FrameLayout>
|
||||||
<View
|
|
||||||
android:id="@+id/badge_guide"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="10dp"
|
|
||||||
app:layout_constraintTop_toTopOf="@+id/card" />
|
|
||||||
|
|
||||||
<include
|
|
||||||
layout="@layout/unread_download_badge"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
app:layout_constraintBottom_toBottomOf="@id/badge_guide"
|
|
||||||
app:layout_constraintStart_toStartOf="parent" />
|
|
||||||
|
|
||||||
<com.google.android.material.textview.MaterialTextView
|
|
||||||
android:id="@+id/title"
|
|
||||||
style="@style/TextAppearance.Regular.Body1.Light"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginStart="8dp"
|
|
||||||
android:layout_marginTop="8dp"
|
|
||||||
android:layout_marginEnd="8dp"
|
|
||||||
android:ellipsize="end"
|
|
||||||
android:maxLines="2"
|
|
||||||
android:textColor="?android:attr/textColorPrimary"
|
|
||||||
android:textSize="12sp"
|
|
||||||
app:layout_constraintBottom_toTopOf="@+id/subtitle"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
tools:text="Sample name" />
|
|
||||||
|
|
||||||
<com.google.android.material.textview.MaterialTextView
|
|
||||||
android:id="@+id/subtitle"
|
|
||||||
style="@style/TextAppearance.Regular.Body1.Light"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginStart="8dp"
|
|
||||||
android:layout_marginTop="-1dp"
|
|
||||||
android:layout_marginEnd="8dp"
|
|
||||||
android:layout_marginBottom="8dp"
|
|
||||||
android:ellipsize="end"
|
|
||||||
android:singleLine="true"
|
|
||||||
android:textColor="?android:attr/textColorSecondary"
|
|
||||||
android:textSize="12sp"
|
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
tools:text="Sample artist" />
|
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -1,27 +1,74 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout
|
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:paddingTop="15dp"
|
|
||||||
android:paddingBottom="5dp"
|
|
||||||
android:gravity="center_vertical">
|
android:gravity="center_vertical">
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/category_title"
|
android:id="@+id/category_title"
|
||||||
style="@style/TextAppearance.MaterialComponents.Headline5"
|
style="@style/TextAppearance.MaterialComponents.Headline6"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
|
android:layout_marginStart="8dp"
|
||||||
|
android:layout_marginBottom="4dp"
|
||||||
android:gravity="center|start"
|
android:gravity="center|start"
|
||||||
android:inputType="none"
|
android:inputType="none"
|
||||||
android:layout_marginStart="10dp"
|
|
||||||
android:maxLines="1"
|
android:maxLines="1"
|
||||||
android:textColor="?attr/actionBarTintColor"
|
android:textColor="?attr/actionBarTintColor"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="@id/update_button"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
app:layout_constraintWidth_default="wrap"
|
||||||
tools:text="Title" />
|
tools:text="Title" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/category_sort"
|
||||||
|
android:padding="6dp"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_marginBottom="4dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
app:layout_constraintWidth_default="wrap"
|
||||||
|
android:background="@drawable/square_ripple"
|
||||||
|
android:clickable="true"
|
||||||
|
android:layout_marginEnd="10dp"
|
||||||
|
android:drawableEnd="@drawable/ic_sort_white_24dp"
|
||||||
|
android:drawablePadding="6dp"
|
||||||
|
android:focusable="true"
|
||||||
|
android:gravity="start|center"
|
||||||
|
android:textAppearance="@style/TextAppearance.MaterialComponents.Body2"
|
||||||
|
android:textColor="?android:attr/textColorPrimary"
|
||||||
|
android:textSize="12sp"
|
||||||
|
android:textStyle="normal"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintHorizontal_bias="1.0"
|
||||||
|
app:layout_constraintStart_toEndOf="@id/update_button"
|
||||||
|
tools:text="Sort by: Recent" />
|
||||||
|
|
||||||
|
<com.google.android.material.button.MaterialButton
|
||||||
|
android:id="@+id/update_button"
|
||||||
|
style="@style/Widget.MaterialComponents.Button.TextButton"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="35dp"
|
||||||
|
android:layout_marginTop="32dp"
|
||||||
|
android:layout_marginBottom="6dp"
|
||||||
|
android:clickable="true"
|
||||||
|
android:focusable="true"
|
||||||
|
android:text="@string/ext_update"
|
||||||
|
android:textColor="?android:attr/colorAccent"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintStart_toEndOf="@+id/category_title"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
app:rippleColor="@color/fullRippleColor" />
|
||||||
|
|
||||||
|
<ProgressBar
|
||||||
|
android:id="@+id/cat_progress"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
android:layout_marginStart="0dp"
|
||||||
|
app:layout_constraintBottom_toBottomOf="@+id/category_title"
|
||||||
|
app:layout_constraintStart_toEndOf="@+id/category_title"
|
||||||
|
app:layout_constraintTop_toTopOf="@+id/category_title" />
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
@ -6,16 +6,12 @@
|
|||||||
android:id="@+id/library_layout"
|
android:id="@+id/library_layout"
|
||||||
android:layout_height="match_parent">
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
<FrameLayout
|
||||||
android:id="@+id/swipe_refresh"
|
android:id="@+id/recycler_layout"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent">
|
android:layout_height="match_parent">
|
||||||
<FrameLayout
|
|
||||||
android:id="@+id/recycler_layout"
|
</FrameLayout>
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent">
|
|
||||||
</FrameLayout>
|
|
||||||
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
|
|
||||||
|
|
||||||
<androidx.coordinatorlayout.widget.CoordinatorLayout
|
<androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||||
android:id="@+id/pager_layout"
|
android:id="@+id/pager_layout"
|
||||||
|
Loading…
Reference in New Issue
Block a user