Edge to edge on the pre migration bottom sheetpull/3117/head
parent
7f1f2b7863
commit
0cc96ef585
@ -1,317 +0,0 @@
|
||||
package eu.kanade.tachiyomi.ui.library
|
||||
|
||||
import android.content.Context
|
||||
import android.util.AttributeSet
|
||||
import android.view.View
|
||||
import android.widget.LinearLayout
|
||||
import com.google.android.material.bottomsheet.BottomSheetBehavior
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.data.database.DatabaseHelper
|
||||
import eu.kanade.tachiyomi.data.database.models.Category
|
||||
import eu.kanade.tachiyomi.data.database.models.LibraryManga
|
||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||
import eu.kanade.tachiyomi.data.preference.getOrDefault
|
||||
import eu.kanade.tachiyomi.data.track.TrackManager
|
||||
import eu.kanade.tachiyomi.util.system.dpToPx
|
||||
import eu.kanade.tachiyomi.util.system.launchUI
|
||||
import eu.kanade.tachiyomi.util.view.inflate
|
||||
import kotlinx.android.synthetic.main.filter_bottom_sheet.view.*
|
||||
import kotlinx.coroutines.CoroutineStart
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.launch
|
||||
import uy.kohesive.injekt.Injekt
|
||||
import uy.kohesive.injekt.api.get
|
||||
import uy.kohesive.injekt.injectLazy
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
class FilterBottomSheet @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null)
|
||||
: LinearLayout(context, attrs),
|
||||
FilterTagGroupListener {
|
||||
|
||||
/**
|
||||
* Preferences helper.
|
||||
*/
|
||||
private val preferences: PreferencesHelper by injectLazy()
|
||||
|
||||
private lateinit var downloaded:FilterTagGroup
|
||||
|
||||
private lateinit var unread:FilterTagGroup
|
||||
|
||||
private lateinit var completed:FilterTagGroup
|
||||
|
||||
private lateinit var tracked:FilterTagGroup
|
||||
|
||||
private lateinit var categories:FilterTagGroup
|
||||
|
||||
private var mangaType:FilterTagGroup? = null
|
||||
|
||||
var lastCategory:Category? = null
|
||||
|
||||
private val filterItems:MutableList<FilterTagGroup> by lazy {
|
||||
val list = mutableListOf<FilterTagGroup>()
|
||||
if (Injekt.get<DatabaseHelper>().getCategories().executeAsBlocking().isNotEmpty())
|
||||
list.add(categories)
|
||||
list.add(downloaded)
|
||||
list.add(unread)
|
||||
list.add(completed)
|
||||
if (Injekt.get<TrackManager>().hasLoggedServices())
|
||||
list.add(tracked)
|
||||
list
|
||||
}
|
||||
|
||||
var onGroupClicked: (Int) -> Unit = { _ -> }
|
||||
val recycler = androidx.recyclerview.widget.RecyclerView(context)
|
||||
var pager:View? = null
|
||||
|
||||
fun onCreate(pagerView:View) {
|
||||
val sheetBehavior = BottomSheetBehavior.from(this)
|
||||
topbar.setOnClickListener {
|
||||
if (sheetBehavior.state != BottomSheetBehavior.STATE_EXPANDED) {
|
||||
sheetBehavior.state = BottomSheetBehavior.STATE_EXPANDED
|
||||
} else {
|
||||
sheetBehavior.state = BottomSheetBehavior.STATE_COLLAPSED
|
||||
}
|
||||
}
|
||||
line.alpha = 0f
|
||||
|
||||
|
||||
|
||||
sortText.alpha = if (sheetBehavior.state != BottomSheetBehavior.STATE_EXPANDED) 1f else 0f
|
||||
title.alpha = if (sheetBehavior.state == BottomSheetBehavior.STATE_EXPANDED) 1f else 0f
|
||||
|
||||
pager = pagerView
|
||||
pager?.setPadding(0, 0, 0, topbar.height)
|
||||
updateTitle()
|
||||
sheetBehavior.setBottomSheetCallback(object : BottomSheetBehavior.BottomSheetCallback() {
|
||||
override fun onSlide(bottomSheet: View, progress: Float) {
|
||||
updateRootPadding(progress)
|
||||
sortText.alpha = 1 - progress
|
||||
title.alpha = progress
|
||||
}
|
||||
|
||||
override fun onStateChanged(p0: View, state: Int) {
|
||||
if (state == BottomSheetBehavior.STATE_COLLAPSED) {
|
||||
reSortViews()
|
||||
}
|
||||
}
|
||||
})
|
||||
topbar.viewTreeObserver.addOnGlobalLayoutListener {
|
||||
sheetBehavior.peekHeight = topbar.height
|
||||
if (sheetBehavior.state == BottomSheetBehavior.STATE_COLLAPSED) {
|
||||
pager?.setPadding(0, 0, 0, topbar.height)
|
||||
sortText.alpha = 1f
|
||||
title.alpha = 0f
|
||||
}
|
||||
else {
|
||||
updateRootPadding()
|
||||
}
|
||||
}
|
||||
createTags()
|
||||
}
|
||||
|
||||
fun updateTitle() {
|
||||
val filters = getFilters().toMutableList()
|
||||
if (filters.isEmpty()) {
|
||||
sortText.text = context.getString(
|
||||
R.string.sorting_by_, context.getString(
|
||||
when (sorting()) {
|
||||
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
|
||||
else -> R.string.title
|
||||
}
|
||||
)
|
||||
)
|
||||
}
|
||||
else {
|
||||
filters.add(0, when (sorting()) {
|
||||
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
|
||||
else -> R.string.action_sort_alpha
|
||||
})
|
||||
sortText.text = filters.joinToString(", ") { context.getString(it) }
|
||||
}
|
||||
}
|
||||
|
||||
fun adjustTitleMargin(downloading: Boolean) {
|
||||
val params = sortText.layoutParams as? MarginLayoutParams ?: return
|
||||
params.rightMargin = (if (downloading) 80 else 8).dpToPx
|
||||
sortText.layoutParams = params
|
||||
}
|
||||
|
||||
fun updateRootPadding(progress: Float? = null) {
|
||||
val sheetBehavior = BottomSheetBehavior.from(this)
|
||||
val minHeight = sheetBehavior.peekHeight
|
||||
val maxHeight = height
|
||||
val trueProgress = progress ?: if (sheetBehavior.state == BottomSheetBehavior.STATE_EXPANDED) 1f else 0f
|
||||
val percent = (trueProgress * 100).roundToInt()
|
||||
val value = (percent * (maxHeight - minHeight) / 100) + minHeight
|
||||
pager?.setPadding(0, 0, 0, value)
|
||||
}
|
||||
|
||||
fun sorting(): Int {
|
||||
val sortingMode = preferences.librarySortingMode().getOrDefault()
|
||||
return if (sortingMode == LibrarySort.DRAG_AND_DROP &&
|
||||
lastCategory != null &&
|
||||
preferences.showCategories().getOrDefault()) {
|
||||
when (lastCategory?.mangaSort) {
|
||||
'a', 'b' -> LibrarySort.ALPHA
|
||||
'c', 'd' -> LibrarySort.LAST_UPDATED
|
||||
'e', 'f' -> LibrarySort.UNREAD
|
||||
'g', 'h' -> LibrarySort.LAST_READ
|
||||
else -> LibrarySort.DRAG_AND_DROP
|
||||
}
|
||||
}
|
||||
else {
|
||||
preferences.librarySortingMode().getOrDefault()
|
||||
}
|
||||
}
|
||||
|
||||
private fun getFilters(): List<Int> {
|
||||
val filters = mutableListOf<Int>()
|
||||
val categoriesOn = preferences.showCategories().getOrDefault()
|
||||
if (!categoriesOn) {
|
||||
filters.add(R.string.hiding_categories)
|
||||
}
|
||||
var filter = preferences.filterDownloaded().getOrDefault()
|
||||
if (filter > 0) {
|
||||
filters.add(if (filter == 1) R.string.action_filter_downloaded else R.string
|
||||
.action_filter_not_downloaded)
|
||||
}
|
||||
filter = preferences.filterUnread().getOrDefault()
|
||||
if (filter > 0) {
|
||||
filters.add(when (filter) {
|
||||
3 -> R.string.action_filter_read
|
||||
2 -> R.string.action_filter_in_progress
|
||||
else -> R.string.action_filter_not_started
|
||||
})
|
||||
}
|
||||
filter = preferences.filterCompleted().getOrDefault()
|
||||
if (filter > 0) {
|
||||
filters.add(if (filter == 1) R.string.completed else R.string
|
||||
.ongoing)
|
||||
}
|
||||
filter = preferences.filterTracked().getOrDefault()
|
||||
if (filter > 0) {
|
||||
filters.add(if (filter == 1) R.string.action_filter_tracked else R.string
|
||||
.action_filter_not_tracked)
|
||||
}
|
||||
filter = preferences.filterMangaType().getOrDefault()
|
||||
if (filter > 0) {
|
||||
filters.add(if (filter == 1) R.string.manga_only else R.string.manwha_only)
|
||||
}
|
||||
return filters
|
||||
}
|
||||
|
||||
|
||||
fun createTags() {
|
||||
categories = inflate(R.layout.filter_buttons) as FilterTagGroup
|
||||
categories.setup(this, R.string.hide_categories)
|
||||
|
||||
downloaded = inflate(R.layout.filter_buttons) as FilterTagGroup
|
||||
downloaded.setup(this, R.string.action_filter_downloaded, R.string.action_filter_not_downloaded)
|
||||
|
||||
completed = inflate(R.layout.filter_buttons) as FilterTagGroup
|
||||
completed.setup(this, R.string.completed, R.string.ongoing)
|
||||
|
||||
unread = inflate(R.layout.filter_buttons) as FilterTagGroup
|
||||
unread.setup(this, R.string.action_filter_not_started, R.string.action_filter_in_progress,
|
||||
R.string.action_filter_read)
|
||||
|
||||
tracked = inflate(R.layout.filter_buttons) as FilterTagGroup
|
||||
tracked.setup(this, R.string.action_filter_tracked, R.string.action_filter_not_tracked)
|
||||
|
||||
filterItems.forEach {
|
||||
filterLayout.addView(it)
|
||||
}
|
||||
|
||||
checkForManwha()
|
||||
}
|
||||
|
||||
private fun checkForManwha() {
|
||||
GlobalScope.launch(Dispatchers.IO, CoroutineStart.DEFAULT) {
|
||||
val db:DatabaseHelper by injectLazy()
|
||||
val librryManga = db.getLibraryMangas().executeAsBlocking()
|
||||
if (librryManga.any { it.mangaType() == LibraryManga.MANWHA }) {
|
||||
launchUI {
|
||||
val mangaType = inflate(R.layout.filter_buttons) as FilterTagGroup
|
||||
mangaType.setup(
|
||||
this@FilterBottomSheet,
|
||||
R.string.manga,
|
||||
R.string.manwha
|
||||
)
|
||||
this@FilterBottomSheet.mangaType = mangaType
|
||||
filterLayout.addView(mangaType)
|
||||
filterItems.add(mangaType)
|
||||
}
|
||||
}
|
||||
launchUI {
|
||||
categories.setState(!preferences.showCategories().getOrDefault())
|
||||
downloaded.setState(preferences.filterDownloaded())
|
||||
completed.setState(preferences.filterCompleted())
|
||||
unread.setState(preferences.filterUnread())
|
||||
tracked.setState(preferences.filterTracked())
|
||||
mangaType?.setState(preferences.filterMangaType())
|
||||
reSortViews()
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
override fun onFilterClicked(view: FilterTagGroup, index: Int, updatePreference:Boolean) {
|
||||
if (updatePreference) {
|
||||
when (view) {
|
||||
categories -> {
|
||||
preferences.showCategories().set(index != 0)
|
||||
onGroupClicked(ACTION_REFRESH)
|
||||
}
|
||||
downloaded -> {
|
||||
preferences.filterDownloaded().set(index + 1)
|
||||
onGroupClicked(ACTION_FILTER)
|
||||
}
|
||||
unread -> {
|
||||
preferences.filterUnread().set(index + 1)
|
||||
onGroupClicked(ACTION_FILTER)
|
||||
}
|
||||
completed -> {
|
||||
preferences.filterCompleted().set(index + 1)
|
||||
onGroupClicked(ACTION_FILTER)
|
||||
}
|
||||
tracked -> {
|
||||
preferences.filterTracked().set(index + 1)
|
||||
onGroupClicked(ACTION_FILTER)
|
||||
}
|
||||
mangaType -> {
|
||||
preferences.filterMangaType().set(index + 1)
|
||||
onGroupClicked(ACTION_FILTER)
|
||||
}
|
||||
}
|
||||
updateTitle()
|
||||
}
|
||||
}
|
||||
|
||||
fun reSortViews() {
|
||||
filterLayout.removeAllViews()
|
||||
filterItems.filter { it.isActivated }.forEach {
|
||||
filterLayout.addView(it)
|
||||
}
|
||||
filterItems.filterNot { it.isActivated }.forEach {
|
||||
filterLayout.addView(it)
|
||||
}
|
||||
filterScrollView.scrollTo(0, 0)
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val ACTION_REFRESH = 0
|
||||
const val ACTION_SORT = 1
|
||||
const val ACTION_FILTER = 2
|
||||
const val ACTION_DISPLAY = 3
|
||||
const val ACTION_BADGE = 4
|
||||
}
|
||||
}
|
@ -0,0 +1,519 @@
|
||||
package eu.kanade.tachiyomi.ui.library.filter
|
||||
|
||||
import android.content.Context
|
||||
import android.content.res.Configuration
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.util.AttributeSet
|
||||
import android.view.MenuItem
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.LinearLayout
|
||||
import android.widget.RadioButton
|
||||
import android.widget.RadioGroup
|
||||
import androidx.appcompat.widget.PopupMenu
|
||||
import androidx.core.content.ContextCompat
|
||||
import com.f2prateek.rx.preferences.Preference
|
||||
import com.google.android.material.bottomsheet.BottomSheetBehavior
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.data.database.DatabaseHelper
|
||||
import eu.kanade.tachiyomi.data.database.models.Category
|
||||
import eu.kanade.tachiyomi.data.database.models.LibraryManga
|
||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||
import eu.kanade.tachiyomi.data.preference.getOrDefault
|
||||
import eu.kanade.tachiyomi.data.track.TrackManager
|
||||
import eu.kanade.tachiyomi.ui.library.LibrarySort
|
||||
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.view.gone
|
||||
import eu.kanade.tachiyomi.util.view.inflate
|
||||
import eu.kanade.tachiyomi.util.view.marginBottom
|
||||
import eu.kanade.tachiyomi.util.view.marginTop
|
||||
import eu.kanade.tachiyomi.util.view.updateLayoutParams
|
||||
import eu.kanade.tachiyomi.util.view.updatePadding
|
||||
import eu.kanade.tachiyomi.util.view.visible
|
||||
import kotlinx.android.synthetic.main.filter_bottom_sheet.view.*
|
||||
import kotlinx.coroutines.CoroutineStart
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import uy.kohesive.injekt.Injekt
|
||||
import uy.kohesive.injekt.api.get
|
||||
import uy.kohesive.injekt.injectLazy
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
class FilterBottomSheet @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null)
|
||||
: LinearLayout(context, attrs),
|
||||
FilterTagGroupListener {
|
||||
|
||||
/**
|
||||
* Preferences helper.
|
||||
*/
|
||||
private val preferences: PreferencesHelper by injectLazy()
|
||||
|
||||
private lateinit var downloaded: FilterTagGroup
|
||||
|
||||
private lateinit var unread: FilterTagGroup
|
||||
|
||||
private lateinit var completed: FilterTagGroup
|
||||
|
||||
private lateinit var tracked: FilterTagGroup
|
||||
|
||||
private lateinit var categories: FilterTagGroup
|
||||
|
||||
private var mangaType: FilterTagGroup? = null
|
||||
|
||||
var lastCategory:Category? = null
|
||||
|
||||
var sheetBehavior:BottomSheetBehavior<View>? = null
|
||||
|
||||
private val filterItems:MutableList<FilterTagGroup> by lazy {
|
||||
val list = mutableListOf<FilterTagGroup>()
|
||||
if (Injekt.get<DatabaseHelper>().getCategories().executeAsBlocking().isNotEmpty())
|
||||
list.add(categories)
|
||||
list.add(downloaded)
|
||||
list.add(unread)
|
||||
list.add(completed)
|
||||
if (Injekt.get<TrackManager>().hasLoggedServices())
|
||||
list.add(tracked)
|
||||
list
|
||||
}
|
||||
|
||||
var onGroupClicked: (Int) -> Unit = { _ -> }
|
||||
val recycler = androidx.recyclerview.widget.RecyclerView(context)
|
||||
var pager:View? = null
|
||||
|
||||
fun onCreate(pagerView:View) {
|
||||
if (context.resources.configuration?.orientation == Configuration.ORIENTATION_LANDSCAPE) {
|
||||
sortLayout.orientation = HORIZONTAL
|
||||
val marginValue = 10.dpToPx
|
||||
arrayListOf(mainSortTextView, catSortTextView, displayLayout).forEach {
|
||||
it.updateLayoutParams<MarginLayoutParams> {
|
||||
bottomMargin = 0
|
||||
topMargin = 0
|
||||
}
|
||||
}
|
||||
sortScrollView.updatePadding(
|
||||
bottom = marginValue,
|
||||
top = 0
|
||||
)
|
||||
}
|
||||
sheetBehavior = BottomSheetBehavior.from(this)
|
||||
topbar.setOnClickListener {
|
||||
if (sheetBehavior?.state != BottomSheetBehavior.STATE_EXPANDED) {
|
||||
sheetBehavior?.state = BottomSheetBehavior.STATE_EXPANDED
|
||||
} else {
|
||||
sheetBehavior?.state = BottomSheetBehavior.STATE_COLLAPSED
|
||||
}
|
||||
}
|
||||
|
||||
sortText.alpha = if (sheetBehavior?.state != BottomSheetBehavior.STATE_EXPANDED) 1f else 0f
|
||||
title.alpha = if (sheetBehavior?.state == BottomSheetBehavior.STATE_EXPANDED) 1f else 0f
|
||||
|
||||
pager = pagerView
|
||||
pager?.setPadding(0, 0, 0, topbar.height)
|
||||
updateTitle()
|
||||
sheetBehavior?.addBottomSheetCallback(object : BottomSheetBehavior.BottomSheetCallback() {
|
||||
override fun onSlide(bottomSheet: View, progress: Float) {
|
||||
updateRootPadding(progress)
|
||||
val newProg = when {
|
||||
progress > 0.9f -> 1f
|
||||
progress < 0.1f -> 0f
|
||||
else -> progress
|
||||
}
|
||||
sortText.alpha = 1 - newProg
|
||||
title.alpha = newProg
|
||||
}
|
||||
|
||||
override fun onStateChanged(p0: View, state: Int) {
|
||||
if (state == BottomSheetBehavior.STATE_COLLAPSED) reSortViews()
|
||||
else setMainSortText()
|
||||
}
|
||||
})
|
||||
topbar.viewTreeObserver.addOnGlobalLayoutListener {
|
||||
sheetBehavior?.peekHeight = topbar.height
|
||||
if (sheetBehavior?.state == BottomSheetBehavior.STATE_COLLAPSED) {
|
||||
val height = context.resources.getDimensionPixelSize(R.dimen.rounder_radius)
|
||||
pager?.setPadding(0, 0, 0, topbar.height - height)
|
||||
sortText.alpha = 1f
|
||||
title.alpha = 0f
|
||||
}
|
||||
else {
|
||||
updateRootPadding()
|
||||
}
|
||||
}
|
||||
createTags()
|
||||
|
||||
mainSortTextView.setOnClickListener { showMainSortOptions() }
|
||||
catSortTextView.setOnClickListener { showCatSortOptions() }
|
||||
|
||||
displayGroup.bindToPreference(preferences.libraryAsList())
|
||||
}
|
||||
|
||||
fun updateTitle() {
|
||||
launchUI {
|
||||
val text = withContext(Dispatchers.IO) {
|
||||
val filters = getFilters().toMutableList()
|
||||
if (filters.isEmpty()) {
|
||||
context.getString(
|
||||
R.string.sorting_by_, context.getString(
|
||||
when (sorting()) {
|
||||
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
|
||||
else -> R.string.title
|
||||
}
|
||||
)
|
||||
)
|
||||
} else {
|
||||
filters.add(
|
||||
0, when (sorting()) {
|
||||
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
|
||||
else -> R.string.action_sort_alpha
|
||||
}
|
||||
)
|
||||
filters.joinToString(", ") { context.getString(it) }
|
||||
}
|
||||
}
|
||||
sortText.text = text
|
||||
setMainSortText()
|
||||
}
|
||||
}
|
||||
|
||||
fun adjustTitleMargin(downloading: Boolean) {
|
||||
val params = sortText.layoutParams as? MarginLayoutParams ?: return
|
||||
params.rightMargin = (if (downloading) 80 else 8).dpToPx
|
||||
sortText.layoutParams = params
|
||||
}
|
||||
|
||||
fun updateRootPadding(progress: Float? = null) {
|
||||
val minHeight = sheetBehavior?.peekHeight ?: 0
|
||||
val maxHeight = height
|
||||
val trueProgress = progress ?:
|
||||
if (sheetBehavior?.state == BottomSheetBehavior.STATE_EXPANDED) 1f else 0f
|
||||
val percent = (trueProgress * 100).roundToInt()
|
||||
val value = (percent * (maxHeight - minHeight) / 100) + minHeight
|
||||
val height = context.resources.getDimensionPixelSize(R.dimen.rounder_radius)
|
||||
pager?.setPadding(0, 0, 0, value - height)
|
||||
}
|
||||
|
||||
fun sorting(trueSort:Boolean = false): Int {
|
||||
val sortingMode = preferences.librarySortingMode().getOrDefault()
|
||||
return if (!trueSort && sortingMode == LibrarySort.DRAG_AND_DROP &&
|
||||
lastCategory != null &&
|
||||
preferences.showCategories().getOrDefault()) {
|
||||
when (lastCategory?.mangaSort) {
|
||||
'a', 'b' -> LibrarySort.ALPHA
|
||||
'c', 'd' -> LibrarySort.LAST_UPDATED
|
||||
'e', 'f' -> LibrarySort.UNREAD
|
||||
'g', 'h' -> LibrarySort.LAST_READ
|
||||
else -> LibrarySort.DRAG_AND_DROP
|
||||
}
|
||||
}
|
||||
else {
|
||||
sortingMode
|
||||
}
|
||||
}
|
||||
|
||||
private fun getFilters(): List<Int> {
|
||||
val filters = mutableListOf<Int>()
|
||||
val categoriesOn = preferences.showCategories().getOrDefault()
|
||||
if (!categoriesOn) {
|
||||
filters.add(R.string.hiding_categories)
|
||||
}
|
||||
var filter = preferences.filterDownloaded().getOrDefault()
|
||||
if (filter > 0) {
|
||||
filters.add(if (filter == 1) R.string.action_filter_downloaded else R.string
|
||||
.action_filter_not_downloaded)
|
||||
}
|
||||
filter = preferences.filterUnread().getOrDefault()
|
||||
if (filter > 0) {
|
||||
filters.add(when (filter) {
|
||||
3 -> R.string.action_filter_read
|
||||
2 -> R.string.action_filter_in_progress
|
||||
else -> R.string.action_filter_not_started
|
||||
})
|
||||
}
|
||||
filter = preferences.filterCompleted().getOrDefault()
|
||||
if (filter > 0) {
|
||||
filters.add(if (filter == 1) R.string.completed else R.string
|
||||
.ongoing)
|
||||
}
|
||||
filter = preferences.filterTracked().getOrDefault()
|
||||
if (filter > 0) {
|
||||
filters.add(if (filter == 1) R.string.action_filter_tracked else R.string
|
||||
.action_filter_not_tracked)
|
||||
}
|
||||
filter = preferences.filterMangaType().getOrDefault()
|
||||
if (filter > 0) {
|
||||
filters.add(if (filter == 1) R.string.manga_only else R.string.manwha_only)
|
||||
}
|
||||
return filters
|
||||
}
|
||||
|
||||
|
||||
fun createTags() {
|
||||
categories = inflate(R.layout.filter_buttons) as FilterTagGroup
|
||||
categories.setup(this, R.string.hide_categories)
|
||||
|
||||
downloaded = inflate(R.layout.filter_buttons) as FilterTagGroup
|
||||
downloaded.setup(this, R.string.action_filter_downloaded, R.string.action_filter_not_downloaded)
|
||||
|
||||
completed = inflate(R.layout.filter_buttons) as FilterTagGroup
|
||||
completed.setup(this, R.string.completed, R.string.ongoing)
|
||||
|
||||
unread = inflate(R.layout.filter_buttons) as FilterTagGroup
|
||||
unread.setup(this, R.string.action_filter_not_started, R.string.action_filter_in_progress,
|
||||
R.string.action_filter_read)
|
||||
|
||||
tracked = inflate(R.layout.filter_buttons) as FilterTagGroup
|
||||
tracked.setup(this, R.string.action_filter_tracked, R.string.action_filter_not_tracked)
|
||||
|
||||
filterItems.forEach {
|
||||
filterLayout.addView(it)
|
||||
}
|
||||
|
||||
checkForManwha()
|
||||
}
|
||||
|
||||
private fun checkForManwha() {
|
||||
GlobalScope.launch(Dispatchers.IO, CoroutineStart.DEFAULT) {
|
||||
val db:DatabaseHelper by injectLazy()
|
||||
val librryManga = db.getLibraryMangas().executeAsBlocking()
|
||||
if (librryManga.any { it.mangaType() == LibraryManga.MANWHA }) {
|
||||
launchUI {
|
||||
val mangaType = inflate(R.layout.filter_buttons) as FilterTagGroup
|
||||
mangaType.setup(
|
||||
this@FilterBottomSheet,
|
||||
R.string.manga,
|
||||
R.string.manwha
|
||||
)
|
||||
this@FilterBottomSheet.mangaType = mangaType
|
||||
filterLayout.addView(mangaType)
|
||||
filterItems.add(mangaType)
|
||||
}
|
||||
}
|
||||
launchUI {
|
||||
categories.setState(!preferences.showCategories().getOrDefault())
|
||||
downloaded.setState(preferences.filterDownloaded())
|
||||
completed.setState(preferences.filterCompleted())
|
||||
unread.setState(preferences.filterUnread())
|
||||
tracked.setState(preferences.filterTracked())
|
||||
mangaType?.setState(preferences.filterMangaType())
|
||||
reSortViews()
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private fun showMainSortOptions() {
|
||||
// Create a PopupMenu, giving it the clicked view for an anchor
|
||||
val popup = PopupMenu(context, mainSortTextView)
|
||||
|
||||
// Inflate our menu resource into the PopupMenu's Menu
|
||||
popup.menuInflater.inflate(R.menu.main_sort, popup.menu)
|
||||
|
||||
// Set a listener so we are notified if a menu item is clicked
|
||||
popup.setOnMenuItemClickListener { menuItem ->
|
||||
onMainSortClicked(menuItem)
|
||||
true
|
||||
}
|
||||
popup.menu.findItem(R.id.action_reverse).isVisible =
|
||||
preferences.librarySortingMode().getOrDefault() != LibrarySort.DRAG_AND_DROP
|
||||
|
||||
// Finally show the PopupMenu
|
||||
popup.show()
|
||||
}
|
||||
|
||||
private fun showCatSortOptions() {
|
||||
// Create a PopupMenu, giving it the clicked view for an anchor
|
||||
val popup = PopupMenu(context, catSortTextView)
|
||||
|
||||
// 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 ->
|
||||
onMainSortClicked(menuItem)
|
||||
true
|
||||
}*/
|
||||
popup.menu.findItem(R.id.action_reverse).isVisible = lastCategory?.mangaSort != null
|
||||
|
||||
// Finally show the PopupMenu
|
||||
popup.show()
|
||||
}
|
||||
|
||||
private fun onMainSortClicked(menu: MenuItem) {
|
||||
if (menu.itemId == R.id.action_reverse) {
|
||||
preferences.librarySortingAscending().set(
|
||||
!preferences.librarySortingAscending().getOrDefault())
|
||||
}
|
||||
else {
|
||||
preferences.librarySortingMode().set(
|
||||
when (menu.itemId) {
|
||||
R.id.action_update -> LibrarySort.LAST_UPDATED
|
||||
R.id.action_unread -> LibrarySort.UNREAD
|
||||
R.id.action_total_chaps -> LibrarySort.TOTAL
|
||||
R.id.action_last_read -> LibrarySort.LAST_READ
|
||||
R.id.action_drag_and_drop -> LibrarySort.DRAG_AND_DROP
|
||||
else -> LibrarySort.ALPHA
|
||||
}
|
||||
)
|
||||
preferences.librarySortingAscending().set(true)
|
||||
}
|
||||
setMainSortText()
|
||||
onGroupClicked(ACTION_SORT)
|
||||
}
|
||||
|
||||
fun setMainSortText() {
|
||||
if (sheetBehavior?.state == BottomSheetBehavior.STATE_COLLAPSED) return
|
||||
launchUI {
|
||||
val sortId = withContext(Dispatchers.IO) { sorting(true) }
|
||||
val drawable = withContext(Dispatchers.IO) {
|
||||
tintVector(
|
||||
when {
|
||||
sortId == LibrarySort.DRAG_AND_DROP -> R.drawable.ic_sort_white_24dp
|
||||
preferences.librarySortingAscending().getOrDefault() -> R.drawable
|
||||
.ic_arrow_up_white_24dp
|
||||
else -> R.drawable.ic_arrow_down_white_24dp
|
||||
}
|
||||
)
|
||||
}
|
||||
mainSortTextView.setCompoundDrawablesRelativeWithIntrinsicBounds(
|
||||
drawable, null, null, null
|
||||
)
|
||||
mainSortTextView.text = withContext(Dispatchers.IO) {
|
||||
context.getString(
|
||||
if (sortId == LibrarySort.DRAG_AND_DROP) R.string.sort_library_by_
|
||||
else R.string.sort_by_
|
||||
, context.getString(
|
||||
when (sortId) {
|
||||
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
|
||||
else -> R.string.title
|
||||
}
|
||||
)
|
||||
)
|
||||
}
|
||||
setCatSortText()
|
||||
}
|
||||
}
|
||||
|
||||
private fun setCatSortText() {
|
||||
launchUI {
|
||||
if (preferences.librarySortingMode().getOrDefault() == LibrarySort.DRAG_AND_DROP && preferences.showCategories().getOrDefault() && lastCategory != null) {
|
||||
val sortId = withContext(Dispatchers.IO) { sorting() }
|
||||
val drawable = withContext(Dispatchers.IO) {
|
||||
tintVector(
|
||||
when {
|
||||
sortId == LibrarySort.DRAG_AND_DROP -> R.drawable.ic_sort_white_24dp
|
||||
preferences.librarySortingAscending().getOrDefault() -> R.drawable
|
||||
.ic_arrow_up_white_24dp
|
||||
else -> R.drawable.ic_arrow_down_white_24dp
|
||||
}
|
||||
)
|
||||
}
|
||||
catSortTextView.setCompoundDrawablesRelativeWithIntrinsicBounds(
|
||||
drawable, null, null, null
|
||||
)
|
||||
catSortTextView.text = withContext(Dispatchers.IO) {
|
||||
context.getString(
|
||||
R.string.sort_category_by_, context.getString(
|
||||
when (sortId) {
|
||||
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
|
||||
else -> R.string.title
|
||||
}
|
||||
)
|
||||
)
|
||||
}
|
||||
if (catSortTextView.visibility != View.VISIBLE) catSortTextView.visible()
|
||||
} else if (catSortTextView.visibility == View.VISIBLE) catSortTextView.gone()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Binds a radio group with a boolean preference.
|
||||
*/
|
||||
private fun RadioGroup.bindToPreference(pref: Preference<Boolean>) {
|
||||
(getChildAt(pref.getOrDefault().toInt()) as RadioButton).isChecked = true
|
||||
setOnCheckedChangeListener { _, value ->
|
||||
val index = indexOfChild(findViewById(value))
|
||||
pref.set(index == 1)
|
||||
onGroupClicked(ACTION_DISPLAY)
|
||||
}
|
||||
}
|
||||
|
||||
private fun Boolean.toInt() = if (this) 1 else 0
|
||||
|
||||
private fun tintVector(resId: Int): Drawable? {
|
||||
return ContextCompat.getDrawable(context, resId)?.mutate()?.apply {
|
||||
setTint(context.getResourceColor(R.attr.actionBarTintColor))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
override fun onFilterClicked(view: FilterTagGroup, index: Int, updatePreference:Boolean) {
|
||||
if (updatePreference) {
|
||||
when (view) {
|
||||
categories -> {
|
||||
preferences.showCategories().set(index != 0)
|
||||
onGroupClicked(ACTION_REFRESH)
|
||||
}
|
||||
downloaded -> {
|
||||
preferences.filterDownloaded().set(index + 1)
|
||||
onGroupClicked(ACTION_FILTER)
|
||||
}
|
||||
unread -> {
|
||||
preferences.filterUnread().set(index + 1)
|
||||
onGroupClicked(ACTION_FILTER)
|
||||
}
|
||||
completed -> {
|
||||
preferences.filterCompleted().set(index + 1)
|
||||
onGroupClicked(ACTION_FILTER)
|
||||
}
|
||||
tracked -> {
|
||||
preferences.filterTracked().set(index + 1)
|
||||
onGroupClicked(ACTION_FILTER)
|
||||
}
|
||||
mangaType -> {
|
||||
preferences.filterMangaType().set(index + 1)
|
||||
onGroupClicked(ACTION_FILTER)
|
||||
}
|
||||
}
|
||||
updateTitle()
|
||||
}
|
||||
}
|
||||
|
||||
fun reSortViews() {
|
||||
filterLayout.removeAllViews()
|
||||
filterItems.filter { it.isActivated }.forEach {
|
||||
filterLayout.addView(it)
|
||||
}
|
||||
filterItems.filterNot { it.isActivated }.forEach {
|
||||
filterLayout.addView(it)
|
||||
}
|
||||
filterScrollView.scrollTo(0, 0)
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val ACTION_REFRESH = 0
|
||||
const val ACTION_SORT = 1
|
||||
const val ACTION_FILTER = 2
|
||||
const val ACTION_DISPLAY = 3
|
||||
const val ACTION_BADGE = 4
|
||||
}
|
||||
}
|
@ -0,0 +1,168 @@
|
||||
package eu.kanade.tachiyomi.ui.library.filter
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.res.Configuration
|
||||
import android.graphics.Color
|
||||
import android.graphics.drawable.GradientDrawable
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.view.WindowManager
|
||||
import android.widget.CompoundButton
|
||||
import android.widget.LinearLayout
|
||||
import android.widget.RadioButton
|
||||
import android.widget.RadioGroup
|
||||
import android.widget.Toast
|
||||
import androidx.constraintlayout.widget.ConstraintLayout
|
||||
import androidx.core.graphics.ColorUtils
|
||||
import com.bluelinelabs.conductor.Controller
|
||||
import com.f2prateek.rx.preferences.Preference
|
||||
import com.google.android.material.bottomsheet.BottomSheetDialog
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||
import eu.kanade.tachiyomi.data.preference.getOrDefault
|
||||
import eu.kanade.tachiyomi.ui.migration.MigrationFlags
|
||||
import eu.kanade.tachiyomi.util.view.gone
|
||||
import eu.kanade.tachiyomi.util.system.toast
|
||||
import eu.kanade.tachiyomi.util.view.marginBottom
|
||||
import eu.kanade.tachiyomi.util.view.updateLayoutParams
|
||||
import eu.kanade.tachiyomi.util.view.visible
|
||||
import kotlinx.android.synthetic.main.migration_bottom_sheet.*
|
||||
import kotlinx.android.synthetic.main.migration_bottom_sheet.extra_search_param
|
||||
import kotlinx.android.synthetic.main.migration_bottom_sheet.extra_search_param_text
|
||||
import kotlinx.android.synthetic.main.migration_bottom_sheet.mig_categories
|
||||
import kotlinx.android.synthetic.main.migration_bottom_sheet.mig_chapters
|
||||
import kotlinx.android.synthetic.main.migration_bottom_sheet.mig_tracking
|
||||
import uy.kohesive.injekt.injectLazy
|
||||
|
||||
class SortBottomSheet(private val activity: Activity, theme: Int, private val listener:
|
||||
SortBottomSheetListener) :
|
||||
BottomSheetDialog(activity,
|
||||
theme) {
|
||||
/**
|
||||
* Preferences helper.
|
||||
*/
|
||||
private val preferences by injectLazy<PreferencesHelper>()
|
||||
|
||||
init {
|
||||
// Use activity theme for this layout
|
||||
val view = activity.layoutInflater.inflate(R.layout.migration_bottom_sheet, null)
|
||||
//val scroll = NestedScrollView(context)
|
||||
// scroll.addView(view)
|
||||
|
||||
setContentView(view)
|
||||
if (activity.resources.configuration?.orientation == Configuration.ORIENTATION_LANDSCAPE)
|
||||
sourceGroup.orientation = LinearLayout.HORIZONTAL
|
||||
window?.setBackgroundDrawable(null)
|
||||
val currentNightMode = activity.resources.configuration.uiMode and Configuration
|
||||
.UI_MODE_NIGHT_MASK
|
||||
if (currentNightMode == Configuration.UI_MODE_NIGHT_NO)
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
|
||||
window?.decorView?.systemUiVisibility = View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR
|
||||
else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
val nView = View(context)
|
||||
val height = activity.window.decorView.rootWindowInsets.systemWindowInsetBottom
|
||||
val params = ConstraintLayout.LayoutParams(
|
||||
ViewGroup.LayoutParams.MATCH_PARENT, height
|
||||
)
|
||||
params.bottomToBottom = constraintLayout.id
|
||||
params.startToStart = constraintLayout.id
|
||||
params.endToEnd = constraintLayout.id
|
||||
nView.layoutParams = params
|
||||
nView.background = GradientDrawable(
|
||||
GradientDrawable.Orientation.BOTTOM_TOP, intArrayOf(
|
||||
ColorUtils.setAlphaComponent(Color.BLACK, 179), Color.TRANSPARENT
|
||||
)
|
||||
)
|
||||
constraintLayout.addView(nView)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the sheet is created. It initializes the listeners and values of the preferences.
|
||||
*/
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
initPreferences()
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
window?.addFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS)
|
||||
val marginB = skip_step.marginBottom
|
||||
skip_step.updateLayoutParams<ViewGroup.MarginLayoutParams> {
|
||||
bottomMargin = marginB +
|
||||
activity.window.decorView.rootWindowInsets.systemWindowInsetBottom
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Init general reader preferences.
|
||||
*/
|
||||
private fun initPreferences() {
|
||||
val flags = preferences.migrateFlags().getOrDefault()
|
||||
|
||||
mig_chapters.isChecked = MigrationFlags.hasChapters(flags)
|
||||
mig_categories.isChecked = MigrationFlags.hasCategories(flags)
|
||||
mig_tracking.isChecked = MigrationFlags.hasTracks(flags)
|
||||
|
||||
mig_chapters.setOnCheckedChangeListener { _, _ -> setFlags() }
|
||||
mig_categories.setOnCheckedChangeListener { _, _ -> setFlags() }
|
||||
mig_tracking.setOnCheckedChangeListener { _, _ -> setFlags() }
|
||||
|
||||
extra_search_param_text.gone()
|
||||
extra_search_param.setOnCheckedChangeListener { _, isChecked ->
|
||||
if (isChecked) {
|
||||
extra_search_param_text.visible()
|
||||
} else {
|
||||
extra_search_param_text.gone()
|
||||
}
|
||||
}
|
||||
sourceGroup.bindToPreference(preferences.useSourceWithMost())
|
||||
|
||||
skip_step.isChecked = preferences.skipPreMigration().getOrDefault()
|
||||
skip_step.setOnCheckedChangeListener { _, isChecked ->
|
||||
if (isChecked)
|
||||
(listener as? Controller)?.activity?.toast(R.string.pre_migration_skip_toast,
|
||||
Toast.LENGTH_LONG)
|
||||
}
|
||||
}
|
||||
|
||||
private fun setFlags() {
|
||||
var flags = 0
|
||||
if(mig_chapters.isChecked) flags = flags or MigrationFlags.CHAPTERS
|
||||
if(mig_categories.isChecked) flags = flags or MigrationFlags.CATEGORIES
|
||||
if(mig_tracking.isChecked) flags = flags or MigrationFlags.TRACK
|
||||
preferences.migrateFlags().set(flags)
|
||||
}
|
||||
|
||||
/**
|
||||
* Binds a checkbox or switch view with a boolean preference.
|
||||
*/
|
||||
private fun CompoundButton.bindToPreference(pref: Preference<Boolean>) {
|
||||
isChecked = pref.getOrDefault()
|
||||
setOnCheckedChangeListener { _, isChecked -> pref.set(isChecked) }
|
||||
}
|
||||
|
||||
/**
|
||||
* Binds a radio group with a boolean preference.
|
||||
*/
|
||||
private fun RadioGroup.bindToPreference(pref: Preference<Boolean>) {
|
||||
(getChildAt(pref.getOrDefault().toInt()) as RadioButton).isChecked = true
|
||||
setOnCheckedChangeListener { _, value ->
|
||||
val index = indexOfChild(findViewById(value))
|
||||
pref.set(index == 1)
|
||||
}
|
||||
}
|
||||
|
||||
private fun Boolean.toInt() = if (this) 1 else 0
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
interface SortBottomSheetListener {
|
||||
fun onApplySort()
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
<corners
|
||||
android:topLeftRadius="14dp"
|
||||
android:topRightRadius="14dp" />
|
||||
<solid android:color="?android:attr/colorBackground" />
|
||||
</shape>
|
@ -0,0 +1,10 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportHeight="24"
|
||||
android:viewportWidth="24"
|
||||
android:tint="?attr/actionBarTintColor">
|
||||
<path
|
||||
android:fillColor="#FFFFFF"
|
||||
android:pathData="M11,4H13V16L18.5,10.5L19.92,11.92L12,19.84L4.08,11.92L5.5,10.5L11,16V4Z"/>
|
||||
</vector>
|
@ -0,0 +1,9 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportHeight="24"
|
||||
android:viewportWidth="24">
|
||||
<path
|
||||
android:fillColor="#FFFFFF"
|
||||
android:pathData="M13,20H11V8L5.5,13.5L4.08,12.08L12,4.16L19.92,12.08L18.5,13.5L13,8V20Z"/>
|
||||
</vector>
|
@ -0,0 +1,5 @@
|
||||
<vector android:height="24dp" android:tint="?attr/actionBarTintColor"
|
||||
android:viewportHeight="24.0" android:viewportWidth="24.0"
|
||||
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path android:fillColor="#FF000000" android:pathData="M17.63,5.84C17.27,5.33 16.67,5 16,5L5,5.01C3.9,5.01 3,5.9 3,7v10c0,1.1 0.9,1.99 2,1.99L16,19c0.67,0 1.27,-0.33 1.63,-0.84L22,12l-4.37,-6.16zM16,17H5V7h11l3.55,5L16,17z"/>
|
||||
</vector>
|
@ -1,48 +1,56 @@
|
||||
<?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"
|
||||
android:layout_height="match_parent"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<androidx.viewpager.widget.ViewPager
|
||||
<androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||
android:id="@+id/pager_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:id="@+id/library_pager"/>
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<androidx.viewpager.widget.ViewPager
|
||||
android:id="@+id/library_pager"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||
|
||||
<eu.kanade.tachiyomi.widget.EmptyView
|
||||
android:id="@+id/empty_view"
|
||||
android:visibility="gone"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:layout_height="wrap_content"/>
|
||||
android:visibility="gone" />
|
||||
|
||||
<View
|
||||
android:id="@+id/shadow"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="16dp"
|
||||
android:backgroundTint="@color/md_black_1000_54"
|
||||
android:layout_height="20dp"
|
||||
android:background="@drawable/shape_gradient_top_shadow"
|
||||
android:backgroundTint="@color/md_black_1000_54"
|
||||
android:paddingBottom="10dp"
|
||||
app:layout_anchorGravity="top"
|
||||
app:layout_anchor="@id/bottom_sheet" />
|
||||
<!-- Adding bottom sheet after main content -->
|
||||
<include layout="@layout/filter_bottom_sheet" />
|
||||
|
||||
<com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||
android:id="@+id/fab"
|
||||
android:scaleX="0"
|
||||
android:scaleY="0"
|
||||
style="@style/Theme.Widget.FABFixed"
|
||||
android:layout_gravity="center"
|
||||
android:clickable="false"
|
||||
android:focusable="false"
|
||||
android:scaleX="0"
|
||||
android:scaleY="0"
|
||||
app:layout_anchor="@id/bottom_sheet"
|
||||
style="@style/Theme.Widget.FABFixed"
|
||||
app:layout_anchorGravity="end|top"
|
||||
android:layout_gravity="center"
|
||||
app:srcCompat="@drawable/ic_file_download_white_24dp"/>
|
||||
app:srcCompat="@drawable/ic_file_download_white_24dp" />
|
||||
|
||||
<View
|
||||
android:id="@+id/shadow2"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="8dp"
|
||||
android:layout_gravity="bottom"
|
||||
android:alpha="0.25"
|
||||
android:background="@drawable/shape_gradient_top_shadow"
|
||||
android:layout_gravity="bottom" />
|
||||
android:background="@drawable/shape_gradient_top_shadow" />
|
||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||
|
@ -0,0 +1,27 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
tools:context=".MainActivity">
|
||||
<group android:id="@+id/reorder_group"
|
||||
android:checkableBehavior="single">
|
||||
<item
|
||||
android:id="@+id/action_alpha"
|
||||
android:title="@string/title"/>
|
||||
|
||||
<item
|
||||
android:id="@+id/action_last_read"
|
||||
android:title="@string/action_sort_last_read"/>
|
||||
|
||||
<item
|
||||
android:id="@+id/action_update"
|
||||
android:title="@string/action_sort_last_updated"/>
|
||||
<item
|
||||
android:id="@+id/action_unread"
|
||||
android:title="@string/action_filter_unread"/>
|
||||
|
||||
</group>
|
||||
|
||||
<item
|
||||
android:id="@+id/action_reverse"
|
||||
android:title="@string/action_reverse_order"/>
|
||||
</menu>
|
@ -0,0 +1,35 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
tools:context=".MainActivity">
|
||||
<group android:id="@+id/reorder_group"
|
||||
android:checkableBehavior="single">
|
||||
<item
|
||||
android:id="@+id/action_alpha"
|
||||
android:title="@string/title"/>
|
||||
|
||||
<item
|
||||
android:id="@+id/action_last_read"
|
||||
android:title="@string/action_sort_last_read"/>
|
||||
|
||||
<item
|
||||
android:id="@+id/action_update"
|
||||
android:title="@string/action_sort_last_updated"/>
|
||||
<item
|
||||
android:id="@+id/action_unread"
|
||||
android:title="@string/action_filter_unread"/>
|
||||
|
||||
<item
|
||||
android:id="@+id/action_total_chaps"
|
||||
android:title="@string/action_sort_total"/>
|
||||
|
||||
<item
|
||||
android:id="@+id/action_drag_and_drop"
|
||||
android:title="@string/action_sort_drag_and_drop"/>
|
||||
|
||||
</group>
|
||||
|
||||
<item
|
||||
android:id="@+id/action_reverse"
|
||||
android:title="@string/action_reverse_order"/>
|
||||
</menu>
|
Loading…
Reference in new issue