New fast scroller for library

Updated Drag handle icon
Removed outline fron update button in extensions
Moved "view options" to filter sheet as "display options"
Removed freeform cover option from library 😔
Added swipe refresh to recents page
Removed a few overflows
This commit is contained in:
Jay 2020-04-04 13:47:32 -04:00
parent 836291a59a
commit d0def563c8
36 changed files with 592 additions and 275 deletions

View File

@ -177,6 +177,8 @@ class PreferencesHelper(val context: Context) {
fun gridSize() = rxPrefs.getInteger(Keys.gridSize, 1)
fun autoHideSeeker() = rxPrefs.getBoolean("auto_hide_seeker", true)
fun uniformGrid() = rxPrefs.getBoolean(Keys.uniformGrid, true)
fun libraryAsSingleList() = rxPrefs.getBoolean(Keys.libraryAsSingleList, false)

View File

@ -91,7 +91,7 @@ class CatalogueController : NucleusController<CataloguePresenter>(),
override fun getTitle(): String? {
return if (showingExtenions)
applicationContext?.getString(R.string.label_extensions)
else applicationContext?.getString(R.string.label_catalogues)
else applicationContext?.getString(R.string.pref_category_sources)
}
/**

View File

@ -60,7 +60,7 @@ class CategoryHolder(view: View, val adapter: CategoryAdapter) : BaseFlexibleVie
} else {
title.setTextColor(ContextCompat.getColor(itemView.context, R.color.textColorPrimary))
regularDrawable = ContextCompat.getDrawable(itemView.context, R.drawable
.ic_reorder_grey_24dp)
.ic_drag_handle_black_24dp)
image.visible()
edit_text.setText(title.text)
}

View File

@ -1,6 +1,7 @@
package eu.kanade.tachiyomi.ui.extension
import android.content.res.ColorStateList
import android.graphics.Color
import android.view.View
import androidx.core.content.ContextCompat
import eu.kanade.tachiyomi.R
@ -11,6 +12,7 @@ import eu.kanade.tachiyomi.ui.base.holder.BaseFlexibleViewHolder
import eu.kanade.tachiyomi.ui.base.holder.SlicedHolder
import eu.kanade.tachiyomi.util.system.LocaleHelper
import eu.kanade.tachiyomi.util.system.getResourceColor
import eu.kanade.tachiyomi.util.view.resetStrokeColor
import io.github.mthli.slice.Slice
import kotlinx.android.synthetic.main.extension_card_item.*
@ -64,8 +66,8 @@ class ExtensionHolder(view: View, override val adapter: ExtensionAdapter) :
setTextColor(ContextCompat.getColorStateList(context, R.drawable.button_text_state))
backgroundTintList = ContextCompat.getColorStateList(context, android.R.color.transparent)
resetStrokeColor()
val extension = item.extension
val installStep = item.installStep
if (installStep != null) {
setText(when (installStep) {
@ -85,6 +87,7 @@ class ExtensionHolder(view: View, override val adapter: ExtensionAdapter) :
isActivated = true
backgroundTintList = ColorStateList.valueOf(
context.getResourceColor(R.attr.colorAccent))
strokeColor = ColorStateList.valueOf(Color.TRANSPARENT)
setText(R.string.ext_update)
}
extension.isObsolete -> {

View File

@ -64,7 +64,7 @@ class DisplayBottomSheet(private val controller: LibraryController) : BottomShee
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
initGeneralPreferences()
setBottomEdge(unread_badge_group, activity)
setBottomEdge(hide_filters, activity)
close_button.setOnClickListener {
dismiss()
true
@ -86,6 +86,9 @@ class DisplayBottomSheet(private val controller: LibraryController) : BottomShee
uniform_grid.bindToPreference(preferences.uniformGrid()) {
controller.reattachAdapter()
}
autohide_seeker.bindToPreference(preferences.autoHideSeeker()) {
controller.updateAutoHideScrollbar(autohide_seeker.isChecked)
}
grid_size_toggle_group.bindToPreference(preferences.gridSize()) {
controller.reattachAdapter()
}
@ -95,28 +98,29 @@ class DisplayBottomSheet(private val controller: LibraryController) : BottomShee
unread_badge_group.bindToPreference(preferences.unreadBadgeType()) {
controller.presenter.requestUnreadBadgesUpdate()
}
hide_filters.bindToPreference(preferences.hideFiltersAtStart())
}
/**
* Binds a checkbox or switch view with a boolean preference.
*/
private fun CompoundButton.bindToPreference(pref: Preference<Boolean>, block: () -> Unit) {
private fun CompoundButton.bindToPreference(pref: Preference<Boolean>, block: (() -> Unit)? = null) {
isChecked = pref.getOrDefault()
setOnCheckedChangeListener { _, isChecked ->
pref.set(isChecked)
block()
block?.invoke()
}
}
/**
* Binds a radio group with a int preference.
*/
private fun RadioGroup.bindToPreference(pref: Preference<Int>, block: () -> Unit) {
private fun RadioGroup.bindToPreference(pref: Preference<Int>, block: (() -> Unit)? = null) {
(getChildAt(pref.getOrDefault()) as RadioButton).isChecked = true
setOnCheckedChangeListener { _, checkedId ->
val index = indexOfChild(findViewById(checkedId))
pref.set(index)
block()
block?.invoke()
}
}
}

View File

@ -2,6 +2,7 @@ package eu.kanade.tachiyomi.ui.library
import eu.davidea.flexibleadapter.FlexibleAdapter
import eu.davidea.flexibleadapter.items.IFlexible
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.database.DatabaseHelper
import eu.kanade.tachiyomi.data.database.models.Manga
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
@ -13,6 +14,7 @@ import java.text.SimpleDateFormat
import java.util.Calendar
import java.util.Date
import java.util.Locale
import kotlin.math.max
/**
* Adapter storing a list of manga in a certain category.
@ -91,65 +93,152 @@ class LibraryCategoryAdapter(val libraryListener: LibraryListener) :
isLongPressDragEnabled = libraryListener.canDrag() && s.isNullOrBlank()
}
override fun onCreateBubbleText(position: Int): String {
return if (position < scrollableHeaders.size) {
"Top"
} else if (position >= itemCount - scrollableFooters.size) {
"Bottom"
} else { // Get and show the first character
val iFlexible: IFlexible<*>? = getItem(position)
if (iFlexible is LibraryHeaderItem) {
return iFlexible.category.name
}
val preferences: PreferencesHelper by injectLazy()
when (preferences.librarySortingMode().getOrDefault()) {
LibrarySort.DRAG_AND_DROP -> {
if (!preferences.hideCategories().getOrDefault()) {
val title = (iFlexible as LibraryItem).manga.title
if (preferences.removeArticles().getOrDefault())
title.removeArticles().substring(0, 1).toUpperCase(Locale.US)
else title.substring(0, 1).toUpperCase(Locale.US)
} else {
val db: DatabaseHelper by injectLazy()
val category = db.getCategoriesForManga((iFlexible as LibraryItem).manga)
.executeAsBlocking().firstOrNull()?.name
category?.chop(10) ?: "Default"
fun getSectionText(position: Int): String? {
val preferences: PreferencesHelper by injectLazy()
val db: DatabaseHelper by injectLazy()
return when (val item: IFlexible<*>? = getItem(position)) {
is LibraryHeaderItem ->
if (preferences.hideCategories().getOrDefault()) null
else getFirstLetter(item.category.name) +
"\u200B".repeat(max(0, item.category.order))
is LibraryItem -> {
when (preferences.librarySortingMode().getOrDefault()) {
LibrarySort.DRAG_AND_DROP -> {
val category = db.getCategoriesForManga(item.manga).executeAsBlocking()
.firstOrNull()
if (category == null) null
else getFirstLetter(category.name) + "\u200B".repeat(max(0, category.order))
}
LibrarySort.LAST_READ -> {
val id = item.manga.id ?: return ""
val history = db.getHistoryByMangaId(id).executeAsBlocking()
val last = history.maxBy { it.last_read }
if (last != null && last.last_read > 100) getShorterDate(Date(last.last_read))
else "*"
}
LibrarySort.TOTAL -> {
val unread = item.chapterCount
(unread / 100).toString()
}
LibrarySort.UNREAD -> {
val unread = item.manga.unread
if (unread > 0) (unread / 100).toString()
else "R"
}
LibrarySort.LATEST_CHAPTER -> {
val lastUpdate = item.manga.last_update
if (lastUpdate > 0) getShorterDate(Date(lastUpdate))
else "*"
}
LibrarySort.DATE_ADDED -> {
val lastUpdate = item.manga.date_added
if (lastUpdate > 0) getShorterDate(Date(lastUpdate))
else "*"
}
else -> {
val title = if (preferences.removeArticles()
.getOrDefault()
) item.manga.title.removeArticles()
else item.manga.title
getFirstLetter(title)
}
}
LibrarySort.LAST_READ -> {
val db: DatabaseHelper by injectLazy()
val id = (iFlexible as LibraryItem).manga.id ?: return ""
val history = db.getHistoryByMangaId(id).executeAsBlocking()
val last = history.maxBy { it.last_read }
if (last != null)
getShortDate(Date(last.last_read))
else
"N/A"
}
LibrarySort.UNREAD -> {
val unread = (iFlexible as LibraryItem).manga.unread
if (unread > 0)
unread.toString()
else
"Read"
}
LibrarySort.LATEST_CHAPTER -> {
val lastUpdate = (iFlexible as LibraryItem).manga.last_update
if (lastUpdate > 0)
getShortDate(Date(lastUpdate))
else
"N/A"
}
else -> {
val title = (iFlexible as LibraryItem).manga.title
if (preferences.removeArticles().getOrDefault())
title.removeArticles().substring(0, 1).toUpperCase(Locale.US)
else title.substring(0, 1).toUpperCase(Locale.US)
}
else -> ""
}
}
private fun getFirstLetter(name: String): String {
val letter = name.first()
return if (letter.isLetter()) letter.toString()
.toUpperCase(Locale.ROOT) else "#"
}
override fun onCreateBubbleText(position: Int): String {
val preferences: PreferencesHelper by injectLazy()
val db: DatabaseHelper by injectLazy()
return when (val iFlexible: IFlexible<*>? = getItem(position)) {
is LibraryHeaderItem -> iFlexible.category.name
is LibraryItem -> {
when (preferences.librarySortingMode().getOrDefault()) {
LibrarySort.DRAG_AND_DROP -> {
if (!preferences.hideCategories().getOrDefault()) {
val title = iFlexible.manga.title
if (preferences.removeArticles().getOrDefault()) title.removeArticles()
.substring(0, 1).toUpperCase(Locale.US)
else title.substring(0, 1).toUpperCase(Locale.US)
} else {
val category = db.getCategoriesForManga(iFlexible.manga)
.executeAsBlocking().firstOrNull()?.name
category?.chop(10)
?: recyclerView.context.getString(R.string.default_category)
}
}
LibrarySort.LAST_READ -> {
val id = iFlexible.manga.id ?: return ""
val history = db.getHistoryByMangaId(id).executeAsBlocking()
val last = history.maxBy { it.last_read }
if (last != null && last.last_read > 100) getShortDate(Date(last.last_read))
else "N/A"
}
LibrarySort.UNREAD -> {
val unread = iFlexible.manga.unread
if (unread > 0) getRange(unread)
else recyclerView.context.getString(R.string.action_filter_read)
}
LibrarySort.TOTAL -> {
val total = iFlexible.chapterCount
if (total > 0) getRange(total)
else "N/A"
}
LibrarySort.LATEST_CHAPTER -> {
val lastUpdate = iFlexible.manga.last_update
if (lastUpdate > 0) getShortDate(Date(lastUpdate))
else "N/A"
}
LibrarySort.DATE_ADDED -> {
val lastUpdate = iFlexible.manga.date_added
if (lastUpdate > 0) getShortDate(Date(lastUpdate))
else "N/A"
}
else -> getSectionText(position) ?: ""
}
}
else -> ""
}
}
private fun getRange(value: Int): String {
return when (value) {
in 1..99 -> "< 100"
in 100..199 -> "100-199"
in 200..299 -> "200-299"
in 300..399 -> "300-399"
in 400..499 -> "400-499"
in 500..599 -> "500-599"
in 600..699 -> "600-699"
in 700..799 -> "700-799"
in 800..899 -> "800-899"
in 900..Int.MAX_VALUE -> "900+"
else -> "None"
}
}
private fun getShorterDate(date: Date): String {
val cal = Calendar.getInstance()
cal.time = Date()
val yearNow = cal.get(Calendar.YEAR)
val cal2 = Calendar.getInstance()
cal2.time = date
val yearThen = cal2.get(Calendar.YEAR)
return if (yearNow == yearThen)
SimpleDateFormat("M", Locale.getDefault()).format(date)
else
SimpleDateFormat("''yy", Locale.getDefault()).format(date)
}
private fun getShortDate(date: Date): String {
val cal = Calendar.getInstance()
cal.time = Date()
@ -160,7 +249,7 @@ class LibraryCategoryAdapter(val libraryListener: LibraryListener) :
val yearThen = cal2.get(Calendar.YEAR)
return if (yearNow == yearThen)
SimpleDateFormat("MMM", Locale.getDefault()).format(date)
SimpleDateFormat("MMMM", Locale.getDefault()).format(date)
else
SimpleDateFormat("yyyy", Locale.getDefault()).format(date)
}

View File

@ -5,6 +5,7 @@ import android.animation.AnimatorSet
import android.animation.ValueAnimator
import android.app.Activity
import android.content.Context
import android.content.res.ColorStateList
import android.graphics.Rect
import android.os.Bundle
import android.util.TypedValue
@ -15,11 +16,13 @@ import android.view.MenuItem
import android.view.MotionEvent
import android.view.View
import android.view.ViewGroup
import android.view.ViewPropertyAnimator
import android.view.inputmethod.InputMethodManager
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.view.ActionMode
import androidx.appcompat.widget.SearchView
import androidx.core.content.ContextCompat
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.ItemTouchHelper
import androidx.recyclerview.widget.LinearLayoutManager
@ -33,6 +36,8 @@ import com.bluelinelabs.conductor.ControllerChangeType
import com.google.android.material.bottomsheet.BottomSheetBehavior
import com.google.android.material.snackbar.BaseTransientBottomBar
import com.google.android.material.snackbar.Snackbar
import com.reddit.indicatorfastscroll.FastScrollItemIndicator
import com.reddit.indicatorfastscroll.FastScrollerView
import eu.davidea.flexibleadapter.FlexibleAdapter
import eu.davidea.flexibleadapter.SelectableAdapter
import eu.davidea.flexibleadapter.items.IFlexible
@ -51,7 +56,6 @@ import eu.kanade.tachiyomi.ui.library.filter.FilterBottomSheet
import eu.kanade.tachiyomi.ui.main.MainActivity
import eu.kanade.tachiyomi.ui.main.OnTouchEventInterface
import eu.kanade.tachiyomi.ui.main.RootSearchInterface
import eu.kanade.tachiyomi.ui.main.SpinnerTitleInterface
import eu.kanade.tachiyomi.ui.main.SwipeGestureInterface
import eu.kanade.tachiyomi.ui.manga.MangaDetailsController
import eu.kanade.tachiyomi.ui.migration.manga.design.PreMigrationController
@ -59,6 +63,7 @@ import eu.kanade.tachiyomi.ui.migration.manga.process.MigrationListController
import eu.kanade.tachiyomi.ui.migration.manga.process.MigrationProcedureConfig
import eu.kanade.tachiyomi.ui.reader.ReaderActivity
import eu.kanade.tachiyomi.util.system.dpToPx
import eu.kanade.tachiyomi.util.system.getResourceColor
import eu.kanade.tachiyomi.util.system.launchUI
import eu.kanade.tachiyomi.util.system.toast
import eu.kanade.tachiyomi.util.view.applyWindowInsetsForRootController
@ -90,7 +95,7 @@ class LibraryController(
ChangeMangaCategoriesDialog.Listener,
FlexibleAdapter.OnItemClickListener, FlexibleAdapter.OnItemLongClickListener,
FlexibleAdapter.OnItemMoveListener, LibraryCategoryAdapter.LibraryListener,
SpinnerTitleInterface, OnTouchEventInterface, SwipeGestureInterface,
OnTouchEventInterface, SwipeGestureInterface,
RootSearchInterface, LibraryServiceListener {
init {
@ -112,6 +117,8 @@ class LibraryController(
private var libraryLayout: Int = preferences.libraryLayout().getOrDefault()
private var singleCategory: Boolean = false
/**
* Library search query.
*/
@ -155,11 +162,15 @@ class LibraryController(
private var isDragging = false
private val scrollDistanceTilHidden = 1000.dpToPx
private var textAnim: ViewPropertyAnimator? = null
private var scrollAnim: ViewPropertyAnimator? = null
private var autoHideScroller: Boolean = preferences.autoHideSeeker().getOrDefault()
override fun getTitle(): String? {
return if (view != null && presenter.categories.size > 1) presenter.categories.find {
it.order == activeCategory
}?.name ?: super.getTitle()
else super.getTitle()
}?.name ?: view?.context?.getString(R.string.label_library)
else view?.context?.getString(R.string.label_library)
}
private var scrollListener = object : RecyclerView.OnScrollListener() {
@ -179,14 +190,145 @@ class LibraryController(
setTitle()
}
}
override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
super.onScrollStateChanged(recyclerView, newState)
if (!autoHideScroller) return
when (newState) {
RecyclerView.SCROLL_STATE_DRAGGING -> {
scrollAnim?.cancel()
if (fast_scroller.translationX != 0f) {
fast_scroller.animate().setStartDelay(0).setDuration(100).translationX(0f)
.start()
}
}
RecyclerView.SCROLL_STATE_IDLE -> {
scrollAnim = fast_scroller.animate().setStartDelay(1000).setDuration(250)
.translationX(22f.dpToPx)
scrollAnim?.start()
}
}
}
}
private fun hideScroller() {
if (!autoHideScroller) return
scrollAnim = fast_scroller.animate()
.setStartDelay(1000)
.setDuration(250)
.translationX(22f.dpToPx)
scrollAnim?.start()
}
private fun setFastScrollBackground() {
val context = activity ?: return
fast_scroller.background = if (autoHideScroller) ContextCompat.getDrawable(
context, R.drawable.fast_scroll_background
) else null
fast_scroller.textColor = ColorStateList.valueOf(
context.getResourceColor(
if (autoHideScroller) android.R.attr.textColorPrimaryInverse else android.R.attr.textColorPrimary
)
)
}
override fun onViewCreated(view: View) {
super.onViewCreated(view)
view.applyWindowInsetsForRootController(activity!!.bottom_nav)
if (!::presenter.isInitialized) presenter = LibraryPresenter(this)
fast_scroller.translationX = 22f.dpToPx
setFastScrollBackground()
layoutView(view)
adapter = LibraryCategoryAdapter(this)
setRecyclerLayout()
recycler.manager.spanSizeLookup = (object : GridLayoutManager.SpanSizeLookup() {
override fun getSpanSize(position: Int): Int {
if (libraryLayout == 0) return 1
val item = this@LibraryController.adapter.getItem(position)
return if (item is LibraryHeaderItem) recycler.manager.spanCount
else if (item is LibraryItem && item.manga.isBlank()) recycler.manager.spanCount
else 1
}
})
recycler.setHasFixedSize(true)
recycler.adapter = adapter
fast_scroller.setupWithRecyclerView(
recycler, { position ->
val letter = adapter.getSectionText(position)
if (!singleCategory && !adapter.isHeader(adapter.getItem(position))) null
else if (letter != null) FastScrollItemIndicator.Text(letter)
else FastScrollItemIndicator.Icon(R.drawable.star)
})
fast_scroller.useDefaultScroller = false
fast_scroller.itemIndicatorSelectedCallbacks += object : FastScrollerView.ItemIndicatorSelectedCallback {
override fun onItemIndicatorSelected(
indicator: FastScrollItemIndicator,
indicatorCenterY: Int,
itemPosition: Int
) {
fast_scroller.translationX = 0f
hideScroller()
textAnim?.cancel()
textAnim = text_view_m.animate().alpha(0f).setDuration(250L).setStartDelay(1000)
textAnim?.start()
text_view_m.translationY = indicatorCenterY.toFloat() - text_view_m.height / 2
text_view_m.alpha = 1f
text_view_m.text = adapter.onCreateBubbleText(itemPosition)
val appbar = activity?.appbar
appbar?.y = 0f
(recycler.layoutManager as LinearLayoutManager).scrollToPositionWithOffset(
itemPosition,
if (singleCategory) 0 else (if (itemPosition == 0) 0 else (-40).dpToPx)
)
}
}
recycler.addOnScrollListener(scrollListener)
val tv = TypedValue()
activity!!.theme.resolveAttribute(R.attr.actionBarTintColor, tv, true)
scrollViewWith(recycler, swipeRefreshLayout = swipe_refresh) { insets ->
fast_scroller.updateLayoutParams<ViewGroup.MarginLayoutParams> {
topMargin = insets.systemWindowInsetTop
}
}
swipe_refresh.setDistanceToTriggerSync(150.dpToPx)
swipe_refresh.setOnRefreshListener {
swipe_refresh.isRefreshing = false
if (!LibraryUpdateService.isRunning()) {
when {
presenter.allCategories.size <= 1 -> updateLibrary()
preferences.updateOnRefresh().getOrDefault() == -1 -> {
MaterialDialog(activity!!).title(R.string.what_should_update)
.negativeButton(android.R.string.cancel)
.listItemsSingleChoice(items = listOf(
view.context.getString(
R.string.top_category, presenter.allCategories.first().name
), view.context.getString(
R.string.categories_in_global_update
)
), selection = { _, index, _ ->
preferences.updateOnRefresh().set(index)
when (index) {
0 -> updateLibrary(presenter.allCategories.first())
else -> updateLibrary()
}
})
.positiveButton(R.string.action_update)
.show()
}
else -> {
when (preferences.updateOnRefresh().getOrDefault()) {
0 -> updateLibrary(presenter.allCategories.first())
else -> updateLibrary()
}
}
}
}
}
if (selectedMangas.isNotEmpty()) {
createActionModeIfNeeded()
@ -201,6 +343,7 @@ class LibraryController(
FilterBottomSheet.ACTION_HIDE_FILTER_TIP -> activity?.toast(
R.string.hide_filters_tip, Toast.LENGTH_LONG
)
FilterBottomSheet.ACTION_DISPLAY -> DisplayBottomSheet(this).show()
}
}
@ -342,7 +485,7 @@ class LibraryController(
}
private fun resetScrollingValues() {
swipe_refresh.isEnabled = true
swipe_refresh.isEnabled = !isDragging
startPosX = null
startPosY = null
nextCategory = null
@ -351,8 +494,17 @@ class LibraryController(
lockedY = false
}
fun updateAutoHideScrollbar(autoHide: Boolean) {
autoHideScroller = autoHide
setFastScrollBackground()
scrollAnim?.cancel()
if (autoHide) hideScroller()
else fast_scroller.translationX = 0f
setRecyclerLayout()
}
private fun resetRecyclerY(animated: Boolean = false, time: Long = 100) {
swipe_refresh.isEnabled = true
swipe_refresh.isEnabled = !isDragging
moved = false
lockedRecycler = false
if (animated) {
@ -387,67 +539,6 @@ class LibraryController(
return inflater.inflate(R.layout.library_list_controller, container, false)
}
private fun layoutView(view: View) {
adapter = LibraryCategoryAdapter(this)
setRecyclerLayout()
recycler.manager.spanSizeLookup = (object : GridLayoutManager.SpanSizeLookup() {
override fun getSpanSize(position: Int): Int {
if (libraryLayout == 0) return 1
val item = this@LibraryController.adapter.getItem(position)
return if (item is LibraryHeaderItem) recycler.manager.spanCount
else if (item is LibraryItem && item.manga.isBlank()) recycler.manager.spanCount
else 1
}
})
recycler.setHasFixedSize(true)
recycler.adapter = adapter
adapter.fastScroller = fast_scroller
recycler.addOnScrollListener(scrollListener)
val tv = TypedValue()
activity!!.theme.resolveAttribute(R.attr.actionBarTintColor, tv, true)
scrollViewWith(recycler, swipeRefreshLayout = swipe_refresh) { insets ->
fast_scroller.updateLayoutParams<ViewGroup.MarginLayoutParams> {
topMargin = insets.systemWindowInsetTop
}
}
swipe_refresh.setOnRefreshListener {
swipe_refresh.isRefreshing = false
if (!LibraryUpdateService.isRunning()) {
when {
presenter.allCategories.size <= 1 -> updateLibrary()
preferences.updateOnRefresh().getOrDefault() == -1 -> {
MaterialDialog(activity!!).title(R.string.what_should_update)
.negativeButton(android.R.string.cancel)
.listItemsSingleChoice(items = listOf(
view.context.getString(
R.string.top_category, presenter.allCategories.first().name
), view.context.getString(
R.string.categories_in_global_update
)
), selection = { _, index, _ ->
preferences.updateOnRefresh().set(index)
when (index) {
0 -> updateLibrary(presenter.allCategories.first())
else -> updateLibrary()
}
})
.positiveButton(R.string.action_update)
.show()
}
else -> {
when (preferences.updateOnRefresh().getOrDefault()) {
0 -> updateLibrary(presenter.allCategories.first())
else -> updateLibrary()
}
}
}
}
}
}
private fun updateLibrary(category: Category? = null) {
val view = view ?: return
LibraryUpdateService.start(view.context, category)
@ -459,21 +550,24 @@ class LibraryController(
private fun setRecyclerLayout() {
if (libraryLayout == 0) {
recycler.spanCount = 1
recycler.updatePaddingRelative(start = 0, end = 0)
recycler.updatePaddingRelative(start = 0, end = if (!autoHideScroller) 10.dpToPx else 0)
} else {
recycler.columnWidth = (90 + (preferences.gridSize().getOrDefault() * 30)).dpToPx
recycler.updatePaddingRelative(start = 5.dpToPx, end = 5.dpToPx)
recycler.updatePaddingRelative(
start = (if (!autoHideScroller) 2 else 5).dpToPx,
end = (if (!autoHideScroller) 12 else 5).dpToPx
)
}
}
override fun onChangeStarted(handler: ControllerChangeHandler, type: ControllerChangeType) {
super.onChangeStarted(handler, type)
if (type.isEnter) {
if (presenter.categories.size > 1) {
/*if (presenter.categories.size > 1) {
activity?.toolbar?.showSpinner()
} else {
activity?.toolbar?.removeSpinner()
}
}*/
presenter.getLibrary()
DownloadService.callListeners()
LibraryUpdateService.setListener(this)
@ -521,8 +615,10 @@ class LibraryController(
)
}
adapter.setItems(mangaMap)
singleCategory = presenter.categories.size <= 1
val isCurrentController = router?.backstack?.lastOrNull()?.controller() == this
fast_scroller.translationX = 0f
hideScroller()
setTitle()
updateScroll = false
@ -537,21 +633,21 @@ class LibraryController(
}
adapter.isLongPressDragEnabled = canDrag()
val popupMenu = if (presenter.categories.size > 1 && isCurrentController) {
/*val popupMenu = if (presenter.categories.size > 1 && isCurrentController) {
activity?.toolbar?.showSpinner()
} else {
activity?.toolbar?.removeSpinner()
null
}
}*/
presenter.categories.forEach { category ->
/*presenter.categories.forEach { category ->
popupMenu?.menu?.add(0, category.order, max(0, category.order), category.name)
}
popupMenu?.setOnMenuItemClickListener { item ->
scrollToHeader(item.itemId)
true
}
}*/
}
private fun scrollToHeader(pos: Int) {
@ -736,6 +832,7 @@ class LibraryController(
override fun onActionStateChanged(viewHolder: RecyclerView.ViewHolder?, actionState: Int) {
val position = viewHolder?.adapterPosition ?: return
swipe_refresh.isEnabled = actionState != ItemTouchHelper.ACTION_STATE_DRAG
if (actionState == ItemTouchHelper.ACTION_STATE_DRAG) {
isDragging = true
activity?.appbar?.y = 0f
@ -995,9 +1092,6 @@ class LibraryController(
searchView.clearFocus()
}
// Mutate the filter icon because it needs to be tinted and the resource is shared.
menu.findItem(R.id.action_library_filter).icon.mutate()
setOnQueryTextChangeListener(searchView) { search(it) }
searchItem.fixExpand(onExpand = { invalidateMenuOnExpand() })
}
@ -1043,8 +1137,6 @@ class LibraryController(
override fun onCreateActionMode(mode: ActionMode, menu: Menu): Boolean {
mode.menuInflater.inflate(R.menu.library_selection, menu)
val selectItem = menu.findItem(R.id.action_select_all)
selectItem.isVisible = false
return true
}

View File

@ -47,7 +47,7 @@ class LibraryItem(
val parent = adapter.recyclerView
return if (parent is AutofitRecyclerView) {
val libraryLayout = libraryLayout.getOrDefault()
val isFixedSize = fixedSize.getOrDefault()
val isFixedSize = true // fixedSize.getOrDefault()
if (libraryLayout == 0 || manga.isBlank()) {
LibraryListHolder(view, adapter as LibraryCategoryAdapter)
} else {

View File

@ -346,7 +346,7 @@ class LibraryPresenter(
manga1TotalChapter.compareTo(mange2TotalChapter)
}
sortingMode == LibrarySort.DATE_ADDED -> {
i1.manga.date_added.compareTo(i2.manga.date_added)
i2.manga.date_added.compareTo(i1.manga.date_added)
}
else -> 0
}
@ -421,13 +421,13 @@ class LibraryPresenter(
i2.chapterCount = totalChapters!![i2.manga.id!!] ?: 0
manga1TotalChapter.compareTo(mange2TotalChapter)
}
LibrarySort.DATE_ADDED -> i1.manga.date_added.compareTo(i2.manga.date_added)
LibrarySort.DATE_ADDED -> i2.manga.date_added.compareTo(i1.manga.date_added)
else -> sortAlphabetical(i1, i2)
}
if (!category.isAscending()) sort *= -1
sort
}
category?.mangaOrder?.isEmpty() == false -> {
category.mangaOrder.isNotEmpty() -> {
val order = category.mangaOrder
val index1 = order.indexOf(i1.manga.id!!)
val index2 = order.indexOf(i2.manga.id!!)
@ -441,7 +441,7 @@ class LibraryPresenter(
else -> 0
}
if (compare == 0) {
if (category?.isAscending() != false) sortAlphabetical(i1, i2)
if (category.isAscending()) sortAlphabetical(i1, i2)
else sortAlphabetical(i2, i1)
} else compare
} else {
@ -560,7 +560,7 @@ class LibraryPresenter(
}
}
suspend fun updateView(
private suspend fun updateView(
categories: List<Category>,
mangaMap: LibraryMap,
freshStart: Boolean =

View File

@ -98,6 +98,9 @@ class FilterBottomSheet @JvmOverloads constructor(context: Context, attrs: Attri
if (isChecked)
onGroupClicked(ACTION_HIDE_FILTER_TIP)
}
view_options.setOnClickListener {
onGroupClicked(ACTION_DISPLAY)
}
val activeFilters = hasActiveFiltersFromPref()
sheetBehavior?.isHideable = !activeFilters
@ -334,6 +337,7 @@ class FilterBottomSheet @JvmOverloads constructor(context: Context, attrs: Attri
const val ACTION_REFRESH = 0
const val ACTION_FILTER = 1
const val ACTION_HIDE_FILTER_TIP = 2
const val ACTION_DISPLAY = 3
var FILTER_TRACKER = ""
private set
}

View File

@ -21,6 +21,7 @@ import eu.kanade.tachiyomi.ui.base.holder.BaseFlexibleViewHolder
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.resetStrokeColor
import eu.kanade.tachiyomi.util.view.updateLayoutParams
import eu.kanade.tachiyomi.util.view.visible
import eu.kanade.tachiyomi.util.view.visibleIf
@ -233,13 +234,7 @@ class MangaHeaderHolder(
)
strokeColor = ColorStateList.valueOf(Color.TRANSPARENT)
} else {
strokeColor = ColorStateList.valueOf(
ColorUtils.setAlphaComponent(
itemView.context.getResourceColor(
R.attr.colorOnSurface
), 31
)
)
resetStrokeColor()
backgroundTintList =
ContextCompat.getColorStateList(context, android.R.color.transparent)
}

View File

@ -11,6 +11,7 @@ import android.view.ViewGroup
import androidx.appcompat.widget.SearchView
import androidx.recyclerview.widget.ItemTouchHelper
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.bluelinelabs.conductor.Controller
import com.bluelinelabs.conductor.ControllerChangeHandler
import com.bluelinelabs.conductor.ControllerChangeType
@ -51,6 +52,7 @@ import kotlin.math.max
class RecentsController(bundle: Bundle? = null) : BaseController(bundle),
RecentMangaAdapter.RecentsInterface,
FlexibleAdapter.OnItemClickListener,
FlexibleAdapter.OnItemMoveListener,
RootSearchInterface {
init {
@ -101,7 +103,7 @@ class RecentsController(bundle: Bundle? = null) : BaseController(bundle),
val array = view.context.obtainStyledAttributes(attrsArray)
val appBarHeight = array.getDimensionPixelSize(0, 0)
array.recycle()
scrollViewWith(recycler, skipFirstSnap = true) {
scrollViewWith(recycler, skipFirstSnap = true, swipeRefreshLayout = swipe_refresh) {
headerHeight = it.systemWindowInsetTop + appBarHeight
}
@ -154,12 +156,32 @@ class RecentsController(bundle: Bundle? = null) : BaseController(bundle),
}
})
swipe_refresh.setOnRefreshListener {
if (!LibraryUpdateService.isRunning()) {
LibraryUpdateService.start(view.context)
snack = view.snack(R.string.updating_library) {
anchorView = (activity as? MainActivity)?.bottom_nav
}
}
}
if (showingDownloads) {
dl_bottom_sheet.sheetBehavior?.state = BottomSheetBehavior.STATE_EXPANDED
}
setPadding(dl_bottom_sheet.sheetBehavior?.isHideable == true)
}
override fun onItemMove(fromPosition: Int, toPosition: Int) {
}
override fun shouldMoveItem(fromPosition: Int, toPosition: Int): Boolean {
return true
}
override fun onActionStateChanged(viewHolder: RecyclerView.ViewHolder?, actionState: Int) {
swipe_refresh.isEnabled = actionState != ItemTouchHelper.ACTION_STATE_SWIPE
}
override fun handleRootBack(): Boolean {
if (dl_bottom_sheet.sheetBehavior?.state == BottomSheetBehavior.STATE_EXPANDED) {
dl_bottom_sheet.dismiss()

View File

@ -39,7 +39,7 @@ class SettingsSourcesController : SettingsController(),
private var sorting = SourcesSort.Alpha
override fun setupPreferenceScreen(screen: PreferenceScreen) = with(screen) {
titleRes = R.string.pref_category_sources
titleRes = R.string.action_filter
sorting = SourcesSort.from(preferences.sourceSorting().getOrDefault()) ?: SourcesSort.Alpha
activity?.invalidateOptionsMenu()
// Get the list of active language codes.

View File

@ -4,6 +4,7 @@ package eu.kanade.tachiyomi.util.view
import android.app.Activity
import android.content.Context
import android.content.res.ColorStateList
import android.content.res.Configuration
import android.graphics.Color
import android.graphics.Point
@ -20,6 +21,7 @@ import android.widget.ImageView
import android.widget.TextView
import androidx.annotation.Px
import androidx.appcompat.widget.SearchView
import androidx.core.graphics.ColorUtils
import androidx.core.math.MathUtils.clamp
import androidx.core.view.ViewCompat
import androidx.recyclerview.widget.LinearLayoutManager
@ -29,6 +31,7 @@ import com.amulyakhare.textdrawable.TextDrawable
import com.amulyakhare.textdrawable.util.ColorGenerator
import com.bluelinelabs.conductor.Controller
import com.google.android.material.bottomsheet.BottomSheetDialog
import com.google.android.material.button.MaterialButton
import com.google.android.material.snackbar.Snackbar
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
@ -436,3 +439,13 @@ fun setBottomEdge(view: View, activity: Activity) {
bottomMargin = marginB + activity.window.decorView.rootWindowInsets.systemWindowInsetBottom
}
}
fun MaterialButton.resetStrokeColor() {
strokeColor = ColorStateList.valueOf(
ColorUtils.setAlphaComponent(
context.getResourceColor(
R.attr.colorOnSurface
), 31
)
)
}

View File

@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:left="4dp"
android:right="4dp"
android:bottom="4dp"
android:top="4dp">
<shape android:shape="rectangle">
<corners android:radius="40dp" />
<size
android:width="25dp"
android:height="25dp" />
<solid android:color="@color/gray_button" />
</shape>
</item>
<item
android:left="10dp"
android:bottom="4dp"
android:top="4dp">
<shape android:shape="rectangle">
<size
android:width="0dp"
android:height="25dp" />
<solid android:color="@color/gray_button" />
</shape>
</item>
</layer-list>

View File

@ -0,0 +1,6 @@
<vector android:height="24dp"
android:viewportHeight="24.0" android:viewportWidth="24.0"
android:alpha=".38"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#FF000000" android:pathData="M20,9H4v2h16V9zM4,15h16v-2H4v2z"/>
</vector>

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="13dp"/>
<corners android:radius="25dp"/>
<size
android:height="25dp"
android:width="25dp" />

View File

@ -17,7 +17,7 @@
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/ic_reorder_grey_24dp" />
app:srcCompat="@drawable/ic_drag_handle_black_24dp" />
<ImageView

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/diplay_bottom_sheet"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/diplay_bottom_sheet"
android:layout_width="match_parent"
android:layout_height="wrap_content">
@ -32,23 +32,25 @@
android:id="@+id/display_group"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:orientation="horizontal"
android:paddingStart="12dp"
android:paddingEnd="12dp">
<com.google.android.material.radiobutton.MaterialRadioButton
android:layout_width="match_parent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/action_display_list" />
<com.google.android.material.radiobutton.MaterialRadioButton
android:layout_width="match_parent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:text="@string/action_display_grid" />
<com.google.android.material.radiobutton.MaterialRadioButton
android:layout_width="match_parent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:text="@string/action_display_comfy_grid" />
</RadioGroup>
@ -90,6 +92,7 @@
<com.google.android.material.checkbox.MaterialCheckBox
android:id="@+id/uniform_grid"
android:layout_width="match_parent"
android:visibility="gone"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:layout_marginEnd="12dp"
@ -102,7 +105,45 @@
android:layout_marginTop="12dp"
android:paddingStart="16dp"
android:paddingEnd="12dp"
android:text="@string/badges" />
android:text="@string/action_display_unread_badge" />
<RadioGroup
android:id="@+id/unread_badge_group"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:paddingStart="12dp"
android:paddingEnd="12dp">
<com.google.android.material.radiobutton.MaterialRadioButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxLines="2"
android:text="@string/hide_badges" />
<com.google.android.material.radiobutton.MaterialRadioButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:maxLines="2"
android:text="@string/show_badges" />
<com.google.android.material.radiobutton.MaterialRadioButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:maxLines="2"
android:text="@string/show_count" />
</RadioGroup>
<com.google.android.material.textview.MaterialTextView
style="@style/TextAppearance.MaterialComponents.Headline6"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:paddingStart="16dp"
android:paddingEnd="12dp"
android:text="@string/more" />
<com.google.android.material.checkbox.MaterialCheckBox
android:id="@+id/download_badge"
@ -112,31 +153,21 @@
android:layout_marginEnd="12dp"
android:text="@string/action_display_download_badge" />
<RadioGroup
android:id="@+id/unread_badge_group"
<com.google.android.material.checkbox.MaterialCheckBox
android:id="@+id/autohide_seeker"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingStart="12dp"
android:paddingEnd="12dp">
<com.google.android.material.radiobutton.MaterialRadioButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxLines="2"
android:text="@string/hide_unread" />
<com.google.android.material.radiobutton.MaterialRadioButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/show_unread" />
<com.google.android.material.radiobutton.MaterialRadioButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/show_unread_count" />
</RadioGroup>
android:layout_marginStart="12dp"
android:layout_marginEnd="12dp"
android:text="@string/auto_hide_category_seeker" />
<com.google.android.material.checkbox.MaterialCheckBox
android:id="@+id/hide_filters"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:layout_marginEnd="12dp"
android:text="@string/action_start_filters_hidden" />
</LinearLayout>
</androidx.core.widget.NestedScrollView>
@ -144,10 +175,10 @@
android:id="@+id/close_button"
android:layout_width="32dp"
android:layout_height="32dp"
android:background="@drawable/round_ripple"
android:layout_gravity="end"
android:layout_marginTop="12dp"
android:layout_marginEnd="12dp"
android:background="@drawable/round_ripple"
android:clickable="true"
android:contentDescription="@string/action_close"
android:focusable="true"

View File

@ -57,7 +57,7 @@
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/ic_reorder_grey_24dp" />
app:srcCompat="@drawable/ic_drag_handle_black_24dp" />
<TextView
android:id="@+id/manga_full_title"

View File

@ -64,7 +64,7 @@
app:layout_constraintStart_toEndOf="@id/lang"
tools:text="Version" />
<Button
<com.google.android.material.button.MaterialButton
android:id="@+id/ext_button"
style="@style/Widget.MaterialComponents.Button.OutlinedButton"
android:layout_width="wrap_content"

View File

@ -29,10 +29,10 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="2dp"
android:requiresFadingEdge="horizontal"
android:fadingEdgeLength="20dp"
android:clipToPadding="false"
android:paddingStart="10dp"
android:paddingTop="8dp"
android:paddingEnd="20dp"
android:paddingBottom="6dp"
android:scrollbars="none">
@ -41,6 +41,8 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:paddingStart="10dp"
android:paddingEnd="20dp"
android:orientation="horizontal">
<ImageView
@ -73,11 +75,22 @@
android:layout_marginEnd="20dp"
android:text="@string/action_hide_categories" />
<com.google.android.material.button.MaterialButton
android:id="@+id/view_options"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="@style/Theme.Widget.Button.TextButton"
android:text="@string/action_view_options"
android:textColor="?android:attr/textColorPrimary"
app:icon="@drawable/ic_tune_white_24dp"
app:iconTint="?android:attr/textColorPrimary"
/>
<com.google.android.material.checkbox.MaterialCheckBox
android:id="@+id/hide_filters"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone"
android:layout_marginEnd="20dp"
android:text="@string/action_start_filters_hidden" />
</LinearLayout>

View File

@ -1,31 +1,61 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/library_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:id="@+id/swipe_refresh"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:id="@+id/recycler_layout"
<FrameLayout
android:id="@+id/recycler_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<include layout="@layout/library_grid_recycler" />
</FrameLayout>
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<include layout="@layout/library_grid_recycler"/>
</FrameLayout>
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
<com.reddit.indicatorfastscroll.FastScrollerView
android:id="@+id/fast_scroller"
android:textColor="?android:attr/textColorPrimaryInverse"
android:layout_width="22dp"
android:layout_height="wrap_content"
android:elevation="10dp"
android:layout_gravity="end"
android:background="@drawable/fast_scroll_background"
android:paddingTop="8dp"
android:paddingBottom="8dp"
android:paddingStart="3dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:visibility="visible" />
<com.google.android.material.textview.MaterialTextView
android:id="@+id/text_view_m"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:alpha="0"
tools:alpha="1"
android:layout_marginEnd="50dp"
android:background="@drawable/round_textview_background"
android:backgroundTint="@color/md_grey_800_50"
android:padding="12dp"
android:textColor="@android:color/white"
app:layout_constraintEnd_toStartOf="@id/fast_scroller"
app:layout_constraintTop_toTopOf="@id/fast_scroller"
tools:text="sdfsdf" />
</androidx.constraintlayout.widget.ConstraintLayout>
<eu.davidea.fastscroller.FastScroller
android:id="@+id/fast_scroller"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="end"
app:fastScrollerIgnoreTouchesOutsideHandle="true"
app:fastScrollerBubbleEnabled="false"
tools:visibility="visible" />
<eu.kanade.tachiyomi.widget.EmptyView
android:id="@+id/empty_view"
@ -33,6 +63,7 @@
android:layout_height="wrap_content"
android:layout_gravity="center"
android:visibility="gone" />
<View
android:id="@+id/shadow"
android:layout_width="match_parent"
@ -40,11 +71,11 @@
android:alpha="0.5"
android:background="@drawable/shape_gradient_top_shadow"
android:paddingBottom="10dp"
app:layout_anchorGravity="top"
app:layout_anchor="@id/bottom_sheet" />
app:layout_anchor="@id/bottom_sheet"
app:layout_anchorGravity="top" />
<!-- Adding bottom sheet after main content -->
<include layout="@layout/filter_bottom_sheet"/>
<include layout="@layout/filter_bottom_sheet" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/fab"
@ -54,8 +85,8 @@
android:focusable="false"
android:scaleX="0"
android:scaleY="0"
app:layout_anchor="@id/bottom_sheet"
android:visibility="gone"
app:layout_anchor="@id/bottom_sheet"
app:layout_anchorGravity="end|top"
app:srcCompat="@drawable/ic_file_download_white_24dp" />

View File

@ -62,6 +62,7 @@
android:id="@+id/dropdown"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_gravity="center"
android:layout_marginStart="4dp"
android:background="@drawable/round_ripple"

View File

@ -1,14 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="center"
android:textAppearance="@style/TextAppearance.AppCompat.Body2"
android:background="@drawable/round_textview_background"
android:textColor="#FFFFFF"
android:layout_marginTop="12dp"
android:layout_marginBottom="12dp"
android:textStyle="bold"
android:layout_marginStart="12dp"
android:paddingStart="4dp"
android:paddingEnd="4dp"/>

View File

@ -37,7 +37,7 @@
android:layout_height="@dimen/material_component_lists_single_line_with_avatar_height"
android:scaleType="center"
android:layout_gravity="end"
app:srcCompat="@drawable/ic_reorder_grey_24dp"
app:srcCompat="@drawable/ic_drag_handle_black_24dp"
android:tint="?android:attr/textColorPrimary"/>
</FrameLayout>

View File

@ -1,25 +1,31 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/recents_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">
android:layout_height="match_parent">
<FrameLayout
android:id="@+id/frame_layout"
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:id="@+id/swipe_refresh"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?android:attr/colorBackground">
android:layout_height="match_parent">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler"
<FrameLayout
android:id="@+id/frame_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false"
tools:listitem="@layout/catalogue_main_controller_card" />
android:background="?android:attr/colorBackground">
</FrameLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false"
tools:listitem="@layout/catalogue_main_controller_card" />
</FrameLayout>
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
<View
android:id="@+id/shadow"
@ -28,10 +34,10 @@
android:alpha="0.5"
android:background="@drawable/shape_gradient_top_shadow"
android:paddingBottom="10dp"
app:layout_anchorGravity="top"
app:layout_anchor="@id/dl_bottom_sheet" />
app:layout_anchor="@id/dl_bottom_sheet"
app:layout_anchorGravity="top" />
<!-- Adding bottom sheet after main content -->
<include layout="@layout/download_bottom_sheet"/>
<include layout="@layout/download_bottom_sheet" />
<View
android:id="@+id/shadow2"

View File

@ -17,7 +17,8 @@
<item
android:id="@+id/action_open_in_web_view"
android:icon="@drawable/ic_open_in_webview_white_24dp"
android:title="@string/action_open_in_web_view"
app:showAsAction="never" />
app:showAsAction="ifRoom" />
</menu>

View File

@ -11,14 +11,14 @@
app:actionViewClass="androidx.appcompat.widget.SearchView"/>
<item android:id="@+id/action_filter"
android:title="@string/action_change_sources"
android:title="@string/action_filter"
android:icon="@drawable/ic_filter_list_white_24dp"
app:showAsAction="never"/>
app:showAsAction="ifRoom"/>
<item
android:id="@+id/action_settings"
android:icon="@drawable/ic_settings_white_24dp"
android:title="@string/label_settings"
app:showAsAction="never"
app:showAsAction="ifRoom"
/>
</menu>

View File

@ -1,5 +1,10 @@
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/action_filter"
android:title="@string/action_filter"
android:icon="@drawable/ic_filter_list_white_24dp"
app:showAsAction="always"/>
<item
android:id="@+id/action_search"
@ -8,12 +13,6 @@
app:actionViewClass="androidx.appcompat.widget.SearchView"
app:showAsAction="collapseActionView|ifRoom" />
<item
android:id="@+id/action_filter"
android:title="@string/action_filter"
android:icon="@drawable/ic_filter_list_white_24dp"
app:showAsAction="always"/>
<item
android:id="@+id/action_auto_check"
android:title="@string/action_auto_check_extensions"

View File

@ -12,25 +12,19 @@
app:actionViewClass="androidx.appcompat.widget.SearchView"
app:showAsAction="collapseActionView|ifRoom" />
<item
android:id="@+id/action_library_filter"
android:icon="@drawable/ic_filter_list_white_24dp"
android:visible="false"
android:title="@string/action_filter"
app:showAsAction="ifRoom"/>
<item
android:id="@+id/action_library_display"
android:icon="@drawable/ic_tune_white_24dp"
android:visible="false"
android:title="@string/action_view_options"
app:showAsAction="never"
app:showAsAction="ifRoom"
/>
<item
android:id="@+id/action_settings"
android:icon="@drawable/ic_settings_white_24dp"
android:title="@string/label_settings"
app:showAsAction="never"
app:showAsAction="ifRoom"
/>
</menu>

View File

@ -13,11 +13,6 @@
android:icon="@drawable/ic_delete_white_24dp"
app:showAsAction="ifRoom"/>
<item android:id="@+id/action_select_all"
android:title="@string/action_select_all"
android:icon="@drawable/ic_select_all_white_24dp"
app:showAsAction="ifRoom"/>
<item
android:id="@+id/action_migrate"
android:icon="@drawable/ic_swap_calls_white_24dp"

View File

@ -26,14 +26,14 @@
android:title="@string/action_sort_total"
android:icon="@drawable/ic_blank_24dp"/>
<item
android:id="@+id/action_drag_and_drop"
android:title="@string/action_sort_drag_and_drop"
android:icon="@drawable/ic_blank_24dp"/>
<item
android:id="@+id/action_date_added"
android:title="@string/action_date_added"
android:icon="@drawable/ic_blank_24dp"/>
<item
android:id="@+id/action_drag_and_drop"
android:title="@string/action_sort_drag_and_drop"
android:icon="@drawable/ic_blank_24dp"/>
</menu>

View File

@ -12,6 +12,7 @@
<item
android:id="@+id/action_refresh"
android:icon="@drawable/ic_refresh_white_24dp"
android:visible="false"
android:title="@string/action_update_library"
app:showAsAction="never" />
@ -19,5 +20,5 @@
android:id="@+id/action_settings"
android:icon="@drawable/ic_settings_white_24dp"
android:title="@string/label_settings"
app:showAsAction="never" />
app:showAsAction="ifRoom" />
</menu>

View File

@ -71,6 +71,7 @@
<color name="md_grey_50">#FAFAFA</color>
<color name="md_grey_200">#CCCCCC</color>
<color name="md_grey_800">#424242</color>
<color name="md_grey_800_50">#CF424242</color>
<color name="md_blue_A200_50">#80448AFF</color>

View File

@ -46,7 +46,7 @@
<!-- Actions -->
<string name="action_filter">Filter</string>
<string name="action_change_sources">Change sources</string>
<string name="action_view_options">View options</string>
<string name="action_view_options">Display options</string>
<string name="action_filter_downloaded">Downloaded</string>
<string name="action_filter_not_downloaded">Not downloaded</string>
<string name="action_filter_bookmarked">Bookmarked</string>
@ -57,7 +57,7 @@
<string name="action_filter_tracked">Tracked</string>
<string name="action_filter_not_tracked">Not tracked</string>
<string name="action_hide_categories">Hide categories</string>
<string name="action_start_filters_hidden">Start hidden</string>
<string name="action_start_filters_hidden">Start with filters hidden</string>
<string name="hiding_categories">Hiding categories</string>
<string name="manga_only">Manga only</string>
<string name="manhwa_only">Manhwa only</string>
@ -121,6 +121,7 @@
<string name="action_display_grid">Compact Grid</string>
<string name="action_display_list">List</string>
<string name="action_display_download_badge">Download badges</string>
<string name="auto_hide_category_seeker">Auto-hide category seeker</string>
<string name="action_display_unread_badge">Unread badges</string>
<string name="action_set_filter">Set filter</string>
<string name="action_cancel">Cancel</string>
@ -483,9 +484,9 @@
<string name="large">Large</string>
<string name="grid_options">Grid options</string>
<string name="badges">Badges</string>
<string name="hide_unread">Hide unread badges</string>
<string name="show_unread">Show unread badges</string>
<string name="show_unread_count">Show unread count</string>
<string name="hide_badges">Hide badges</string>
<string name="show_badges">Show badges</string>
<string name="show_count">Show count</string>
<string name="hide_filters_tip">To show filters again, tap the Library icon</string>
<!-- Catalogue fragment -->