mirror of
https://github.com/tachiyomiorg/tachiyomi.git
synced 2024-11-09 20:15:05 +01:00
Added sorting/display options to bottom sheet
Edge to edge on the pre migration bottom sheet
This commit is contained in:
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
|
||||
}
|
||||
}
|
@ -19,6 +19,7 @@ import eu.kanade.tachiyomi.data.library.LibraryUpdateService
|
||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||
import eu.kanade.tachiyomi.data.preference.getOrDefault
|
||||
import eu.kanade.tachiyomi.ui.category.CategoryAdapter
|
||||
import eu.kanade.tachiyomi.ui.main.MainActivity
|
||||
import eu.kanade.tachiyomi.util.system.launchUI
|
||||
import eu.kanade.tachiyomi.util.view.doOnApplyWindowInsets
|
||||
import eu.kanade.tachiyomi.util.view.inflate
|
||||
@ -26,6 +27,7 @@ import eu.kanade.tachiyomi.util.view.snack
|
||||
import eu.kanade.tachiyomi.util.view.updateLayoutParams
|
||||
import eu.kanade.tachiyomi.util.view.updatePaddingRelative
|
||||
import eu.kanade.tachiyomi.util.lang.plusAssign
|
||||
import eu.kanade.tachiyomi.util.system.dpToPx
|
||||
import eu.kanade.tachiyomi.widget.AutofitRecyclerView
|
||||
import kotlinx.android.synthetic.main.library_category.view.*
|
||||
import kotlinx.coroutines.delay
|
||||
@ -98,14 +100,26 @@ class LibraryCategoryView @JvmOverloads constructor(context: Context, attrs: Att
|
||||
swipe_refresh.addView(recycler)
|
||||
adapter.fastScroller = fast_scroller
|
||||
|
||||
fast_scroller.addOnScrollStateChangeListener {
|
||||
controller.lockFilterBar(it)
|
||||
}
|
||||
recycler.doOnApplyWindowInsets { v, insets, padding ->
|
||||
v.updatePaddingRelative(bottom = padding.bottom + insets.systemWindowInsetBottom)
|
||||
|
||||
fast_scroller?.updateLayoutParams<MarginLayoutParams> {
|
||||
bottomMargin = insets.systemWindowInsetBottom
|
||||
if (!MainActivity.bottomNav) {
|
||||
fast_scroller.addOnScrollStateChangeListener {
|
||||
controller.lockFilterBar(it)
|
||||
}
|
||||
}
|
||||
else {
|
||||
fast_scroller.setIgnoreTouchesOutsideHandle(false)
|
||||
}
|
||||
if (MainActivity.bottomNav) {
|
||||
val height = context.resources.getDimensionPixelSize(R.dimen.rounder_radius) + 5.dpToPx
|
||||
recycler.updatePaddingRelative(bottom = height)
|
||||
}
|
||||
else {
|
||||
recycler.doOnApplyWindowInsets { v, insets, padding ->
|
||||
v.updatePaddingRelative(bottom = padding.bottom + insets.systemWindowInsetBottom)
|
||||
|
||||
fast_scroller?.updateLayoutParams<MarginLayoutParams> {
|
||||
bottomMargin = insets.systemWindowInsetBottom
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -23,8 +23,6 @@ import com.afollestad.materialdialogs.MaterialDialog
|
||||
import com.bluelinelabs.conductor.ControllerChangeHandler
|
||||
import com.bluelinelabs.conductor.ControllerChangeType
|
||||
import com.f2prateek.rx.preferences.Preference
|
||||
import com.google.android.material.bottomsheet.BottomSheetBehavior
|
||||
import com.google.android.material.bottomsheet.BottomSheetDialog
|
||||
import com.google.android.material.snackbar.BaseTransientBottomBar
|
||||
import com.google.android.material.snackbar.Snackbar
|
||||
import com.google.android.material.tabs.TabLayout
|
||||
@ -46,6 +44,7 @@ import eu.kanade.tachiyomi.ui.base.controller.TabbedController
|
||||
import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction
|
||||
import eu.kanade.tachiyomi.ui.category.CategoryController
|
||||
import eu.kanade.tachiyomi.ui.download.DownloadController
|
||||
import eu.kanade.tachiyomi.ui.library.filter.FilterBottomSheet
|
||||
import eu.kanade.tachiyomi.ui.main.MainActivity
|
||||
import eu.kanade.tachiyomi.ui.manga.MangaController
|
||||
import eu.kanade.tachiyomi.ui.migration.MigrationController
|
||||
@ -217,7 +216,7 @@ class LibraryController(
|
||||
}
|
||||
|
||||
if (MainActivity.bottomNav) {
|
||||
bottom_sheet.onCreate(library_pager)
|
||||
bottom_sheet.onCreate(pager_layout)
|
||||
|
||||
bottom_sheet?.onGroupClicked = {
|
||||
when (it) {
|
||||
@ -241,11 +240,13 @@ class LibraryController(
|
||||
}
|
||||
|
||||
fun enableReorderItems(category: Category) {
|
||||
if (MainActivity.bottomNav) return
|
||||
adapter?.categories?.getOrNull(library_pager.currentItem)?.mangaSort = category.mangaSort
|
||||
enableReorderItems(sortType = category.mangaSort)
|
||||
}
|
||||
|
||||
private fun enableReorderItems(position: Int? = null, sortType: Char? = null) {
|
||||
if (MainActivity.bottomNav) return
|
||||
val pos = position ?: library_pager.currentItem
|
||||
val orderOfCat = sortType ?: adapter?.categories?.getOrNull(pos)?.mangaSort
|
||||
if (reorderMenuItem?.isVisible != true) return
|
||||
@ -302,7 +303,8 @@ class LibraryController(
|
||||
super.onDetach(view)
|
||||
}
|
||||
|
||||
override fun createSecondaryDrawer(drawer: DrawerLayout): ViewGroup {
|
||||
override fun createSecondaryDrawer(drawer: DrawerLayout): ViewGroup? {
|
||||
if (MainActivity.bottomNav) return null
|
||||
val view = drawer.inflate(R.layout.library_drawer) as LibraryNavigationView
|
||||
navView = view
|
||||
drawer.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED, GravityCompat.END)
|
||||
@ -384,6 +386,7 @@ class LibraryController(
|
||||
|
||||
bottom_sheet.lastCategory = adapter.categories.getOrNull(activeCat)
|
||||
bottom_sheet.updateTitle()
|
||||
bottom_sheet.setMainSortText()
|
||||
|
||||
tabsVisibilityRelay.call(categories.size > 1)
|
||||
|
||||
@ -481,8 +484,10 @@ class LibraryController(
|
||||
|
||||
val reorganizeItem = menu.findItem(R.id.action_reorganize)
|
||||
reorganizeItem.isVisible =
|
||||
!MainActivity.bottomNav
|
||||
preferences.librarySortingMode().getOrDefault() == LibrarySort.DRAG_AND_DROP &&
|
||||
!preferences.hideCategories().getOrDefault()
|
||||
menu.findItem(R.id.action_filter).isVisible = !MainActivity.bottomNav
|
||||
reorderMenuItem = reorganizeItem
|
||||
enableReorderItems()
|
||||
|
||||
@ -726,7 +731,8 @@ class LibraryController(
|
||||
presenter.removeMangaFromLibrary(mangas)
|
||||
destroyActionModeIfNeeded()
|
||||
snack?.dismiss()
|
||||
snack = view?.snack(activity?.getString(R.string.manga_removed_library) ?: "", Snackbar.LENGTH_INDEFINITE) {
|
||||
snack = pager_layout?.snack(activity?.getString(R.string.manga_removed_library) ?: "", Snackbar
|
||||
.LENGTH_INDEFINITE) {
|
||||
var undoing = false
|
||||
setAction(R.string.action_undo) {
|
||||
presenter.addMangas(mangas)
|
||||
|
@ -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
|
||||
}
|
||||
}
|
@ -1,12 +1,9 @@
|
||||
package eu.kanade.tachiyomi.ui.library
|
||||
package eu.kanade.tachiyomi.ui.library.filter
|
||||
|
||||
import android.content.Context
|
||||
import android.util.AttributeSet
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.HorizontalScrollView
|
||||
import android.widget.LinearLayout
|
||||
import androidx.transition.Transition
|
||||
import com.f2prateek.rx.preferences.Preference
|
||||
import eu.kanade.tachiyomi.data.preference.getOrDefault
|
||||
import eu.kanade.tachiyomi.util.system.dpToPx
|
||||
@ -17,7 +14,7 @@ import kotlinx.android.synthetic.main.filter_buttons.view.*
|
||||
class FilterTagGroup@JvmOverloads constructor(context: Context, attrs: AttributeSet? = null): LinearLayout
|
||||
(context, attrs) {
|
||||
|
||||
private var listener:FilterTagGroupListener? = null
|
||||
private var listener: FilterTagGroupListener? = null
|
||||
|
||||
var itemCount = 0
|
||||
private set
|
@ -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()
|
||||
}
|
@ -2,12 +2,22 @@ package eu.kanade.tachiyomi.ui.migration.manga.design
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.res.Configuration
|
||||
import android.graphics.Color
|
||||
import android.graphics.drawable.ColorDrawable
|
||||
import android.graphics.drawable.GradientDrawable
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.view.Gravity
|
||||
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
|
||||
@ -17,6 +27,8 @@ 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
|
||||
@ -24,9 +36,10 @@ import kotlinx.android.synthetic.main.migration_bottom_sheet.extra_search_param_
|
||||
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 kotlinx.android.synthetic.main.migration_bottom_sheet.view.*
|
||||
import uy.kohesive.injekt.injectLazy
|
||||
|
||||
class MigrationBottomSheetDialog(activity: Activity, theme: Int, private val listener:
|
||||
class MigrationBottomSheetDialog(private val activity: Activity, theme: Int, private val listener:
|
||||
StartMigrationListener) :
|
||||
BottomSheetDialog(activity,
|
||||
theme) {
|
||||
@ -45,6 +58,28 @@ StartMigrationListener) :
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -55,6 +90,16 @@ StartMigrationListener) :
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fab.setOnClickListener {
|
||||
preferences.skipPreMigration().set(skip_step.isChecked)
|
||||
listener.startMigration(
|
||||
|
@ -72,7 +72,8 @@ class PreMigrationController(bundle: Bundle? = null) : BaseController(bundle), F
|
||||
|
||||
fab.setOnClickListener {
|
||||
if (dialog?.isShowing != true) {
|
||||
dialog = MigrationBottomSheetDialog(activity!!, R.style.SheetDialog, this)
|
||||
dialog = MigrationBottomSheetDialog(activity!!, R.style.BottomSheetDialogTheme,
|
||||
this)
|
||||
dialog?.show()
|
||||
val bottomSheet = dialog?.findViewById<FrameLayout>(
|
||||
com.google.android.material.R.id.design_bottom_sheet
|
||||
|
@ -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>
|
10
app/src/main/res/drawable/ic_arrow_down_white_24dp.xml
Normal file
10
app/src/main/res/drawable/ic_arrow_down_white_24dp.xml
Normal file
@ -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>
|
9
app/src/main/res/drawable/ic_arrow_up_white_24dp.xml
Normal file
9
app/src/main/res/drawable/ic_arrow_up_white_24dp.xml
Normal file
@ -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,21 +1,23 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<eu.kanade.tachiyomi.ui.library.FilterBottomSheet xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<eu.kanade.tachiyomi.ui.library.filter.FilterBottomSheet 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/bottom_sheet"
|
||||
android:layout_width="match_parent"
|
||||
style="@style/BottomSheetDialogTheme"
|
||||
android:background="@drawable/bg_bottom_sheet_dialog_fragment"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?android:attr/colorBackground"
|
||||
android:orientation="vertical"
|
||||
android:clickable="true"
|
||||
app:layout_behavior="com.google.android.material.bottomsheet.BottomSheetBehavior"
|
||||
android:focusable="true">
|
||||
android:focusable="true"
|
||||
android:orientation="vertical"
|
||||
app:layout_behavior="com.google.android.material.bottomsheet.BottomSheetBehavior">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:id="@+id/topbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/topbar"
|
||||
android:background="?android:attr/colorPrimary">
|
||||
android:backgroundTint="?android:attr/colorPrimary"
|
||||
android:background="@drawable/bg_bottom_sheet_dialog_fragment">
|
||||
|
||||
|
||||
<ImageView
|
||||
@ -33,39 +35,30 @@
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:layout_marginTop="15dp"
|
||||
android:textColor="?attr/actionBarTintColor"
|
||||
android:text="Filter & Sort"
|
||||
android:layout_marginBottom="15dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:text="@string/filter_and_sort"
|
||||
android:textAlignment="textStart"
|
||||
android:textAppearance="@style/TextAppearance.MaterialComponents.Body1"
|
||||
app:layout_constraintStart_toEndOf="@+id/imageView2"
|
||||
android:textColor="?attr/actionBarTintColor"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@+id/imageView2"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/title"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="?attr/actionBarTintColor"
|
||||
android:text="Filter & Sort"
|
||||
android:textAlignment="textStart"
|
||||
android:textAppearance="@style/TextAppearance.MaterialComponents.Body1"
|
||||
app:layout_constraintTop_toTopOf="@+id/sortText"
|
||||
android:textColor="?attr/actionBarTintColor"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/sortText"
|
||||
app:layout_constraintEnd_toEndOf="@+id/sortText"
|
||||
app:layout_constraintStart_toStartOf="@+id/sortText" />
|
||||
|
||||
<View
|
||||
android:id="@+id/line"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="1dp"
|
||||
android:layout_marginTop="15dp"
|
||||
android:background="?attr/actionBarTintColor"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/sortText" />
|
||||
app:layout_constraintStart_toStartOf="@+id/sortText"
|
||||
app:layout_constraintTop_toTopOf="@+id/sortText" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
|
||||
@ -73,38 +66,134 @@
|
||||
android:id="@+id/scrollView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
|
||||
android:orientation="vertical">
|
||||
<HorizontalScrollView
|
||||
android:layout_marginTop="6dp"
|
||||
android:paddingTop="10dp"
|
||||
android:paddingBottom="10dp"
|
||||
android:id="@+id/filterScrollView"
|
||||
android:layout_width="wrap_content"
|
||||
android:scrollbars="none"
|
||||
android:paddingStart="20dp"
|
||||
android:paddingEnd="20dp"
|
||||
android:clipToPadding="false"
|
||||
android:layout_height="wrap_content">
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/filterLayout"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal">
|
||||
|
||||
</LinearLayout>
|
||||
</HorizontalScrollView>
|
||||
<HorizontalScrollView
|
||||
android:id="@+id/filterScrollView"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="6dp"
|
||||
android:clipToPadding="false"
|
||||
android:paddingStart="20dp"
|
||||
android:paddingTop="10dp"
|
||||
android:paddingEnd="20dp"
|
||||
android:paddingBottom="10dp"
|
||||
android:scrollbars="none">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="8dp"
|
||||
android:drawablePadding="16dp"
|
||||
android:text="For sorting later" />
|
||||
<LinearLayout
|
||||
android:id="@+id/filterLayout"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal">
|
||||
|
||||
</LinearLayout>
|
||||
</HorizontalScrollView>
|
||||
|
||||
<HorizontalScrollView
|
||||
android:id="@+id/sortScrollView"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="6dp"
|
||||
android:clipToPadding="false"
|
||||
android:paddingStart="30dp"
|
||||
android:paddingTop="10dp"
|
||||
android:paddingEnd="20dp"
|
||||
android:paddingBottom="10dp"
|
||||
android:scrollbars="none">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/sortLayout"
|
||||
android:layout_width="wrap_content"
|
||||
android:baselineAligned="true"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center|start"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/mainSortTextView"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="20dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_marginBottom="20dp"
|
||||
android:clickable="true"
|
||||
android:drawablePadding="16dp"
|
||||
android:focusable="true"
|
||||
android:gravity="center"
|
||||
android:text="srgdg"
|
||||
android:textAppearance="@style/TextAppearance.MaterialComponents.Body2"
|
||||
android:textColor="?android:attr/textColorPrimary"
|
||||
android:textSize="15sp"
|
||||
android:textStyle="normal" />
|
||||
|
||||
|
||||
<TextView
|
||||
android:id="@+id/catSortTextView"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="20dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_marginBottom="20dp"
|
||||
android:clickable="true"
|
||||
android:drawablePadding="16dp"
|
||||
android:gravity="center"
|
||||
android:focusable="true"
|
||||
android:text="srgdg"
|
||||
android:textAppearance="@style/TextAppearance.MaterialComponents.Body2"
|
||||
android:textColor="?android:attr/textColorPrimary"
|
||||
android:textSize="15sp"
|
||||
android:textStyle="normal" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/displayLayout"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center|start"
|
||||
android:layout_weight="1"
|
||||
android:baselineAligned="false"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:clickable="true"
|
||||
android:layout_marginEnd="14dp"
|
||||
android:focusable="true"
|
||||
android:text="@string/display_as"
|
||||
android:textAppearance="@style/TextAppearance.MaterialComponents.Body2"
|
||||
android:textColor="?android:attr/textColorPrimary"
|
||||
android:textSize="15sp"
|
||||
android:textStyle="normal" />
|
||||
|
||||
|
||||
<RadioGroup
|
||||
android:id="@+id/displayGroup"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<RadioButton
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingStart="0dp"
|
||||
android:paddingEnd="8dp"
|
||||
android:text="@string/action_display_grid" />
|
||||
|
||||
<RadioButton
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="24dp"
|
||||
android:text="@string/action_display_list" />
|
||||
</RadioGroup>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
</HorizontalScrollView>
|
||||
</LinearLayout>
|
||||
</androidx.core.widget.NestedScrollView>
|
||||
</eu.kanade.tachiyomi.ui.library.FilterBottomSheet>
|
||||
</eu.kanade.tachiyomi.ui.library.filter.FilterBottomSheet>
|
@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<eu.kanade.tachiyomi.ui.library.FilterTagGroup xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<eu.kanade.tachiyomi.ui.library.filter.FilterTagGroup xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:orientation="horizontal" android:layout_width="wrap_content"
|
||||
android:background="@drawable/round_textview_border"
|
||||
android:layout_marginStart="5dp"
|
||||
@ -64,4 +64,4 @@
|
||||
android:text="112"
|
||||
android:paddingStart="20dp"
|
||||
android:paddingEnd="20dp"/>
|
||||
</eu.kanade.tachiyomi.ui.library.FilterTagGroup>
|
||||
</eu.kanade.tachiyomi.ui.library.filter.FilterTagGroup>
|
@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<eu.kanade.tachiyomi.ui.library.FilterTagGroup xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<eu.kanade.tachiyomi.ui.library.filter.FilterTagGroup xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/textView"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
|
@ -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>
|
||||
|
@ -6,6 +6,7 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@android:color/transparent"
|
||||
android:fitsSystemWindows="true"
|
||||
android:orientation="vertical">
|
||||
|
||||
|
||||
@ -13,7 +14,7 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="32dp"
|
||||
android:background="@drawable/dialog_rounded_background"
|
||||
android:background="@drawable/bg_bottom_sheet_dialog_fragment"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
|
27
app/src/main/res/menu/cat_sort.xml
Normal file
27
app/src/main/res/menu/cat_sort.xml
Normal file
@ -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>
|
@ -19,18 +19,21 @@
|
||||
|
||||
<item
|
||||
android:id="@+id/action_edit_categories"
|
||||
android:icon="@drawable/ic_label_outline_white_24dp"
|
||||
android:title="@string/action_edit_categories"
|
||||
app:showAsAction="never"/>
|
||||
app:showAsAction="ifRoom"/>
|
||||
|
||||
<item
|
||||
android:id="@+id/action_source_migration"
|
||||
android:icon="@drawable/ic_swap_calls_white_24dp"
|
||||
android:title="@string/label_migration"
|
||||
app:showAsAction="never"/>
|
||||
|
||||
<item
|
||||
android:id="@+id/action_reorganize"
|
||||
android:icon="@drawable/ic_swap_vert_white_24dp"
|
||||
android:title="@string/action_sort_by"
|
||||
app:showAsAction="never">
|
||||
app:showAsAction="ifRoom">
|
||||
<menu>
|
||||
<group android:id="@+id/reorder_group"
|
||||
android:checkableBehavior="single">
|
||||
|
@ -24,8 +24,6 @@
|
||||
android:title="@string/label_migration"
|
||||
app:showAsAction="ifRoom" />
|
||||
|
||||
|
||||
|
||||
<item
|
||||
android:id="@+id/action_move_manga"
|
||||
android:icon="@drawable/ic_swap_vert_white_24dp"
|
||||
|
35
app/src/main/res/menu/main_sort.xml
Normal file
35
app/src/main/res/menu/main_sort.xml
Normal file
@ -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>
|
@ -1,6 +1,7 @@
|
||||
<resources>
|
||||
<!-- Default screen margins, per the Android Design guidelines. -->
|
||||
<dimen name="space_between_cards">4dp</dimen>
|
||||
<dimen name="rounder_radius">14dp</dimen>
|
||||
|
||||
<dimen name="fab_size">56dp</dimen>
|
||||
<dimen name="fab_margin">16dp</dimen>
|
||||
|
@ -50,6 +50,9 @@
|
||||
<string name="manwha_only">Manwha only</string>
|
||||
|
||||
<string name="sorting_by_">Sorting by %1$s</string>
|
||||
<string name="sort_by_">Sort by: %1$s</string>
|
||||
<string name="sort_library_by_">Sort library by: %1$s</string>
|
||||
<string name="sort_category_by_">Sort category by: %1$s</string>
|
||||
<string name="action_filter_empty">Remove filter</string>
|
||||
<string name="action_sort_alpha">Alphabetically</string>
|
||||
<string name="action_sort_enabled">Enabled</string>
|
||||
@ -628,5 +631,7 @@
|
||||
<string name="skip_this_step_next_time">Skip this step next time</string>
|
||||
<string name="pre_migration_skip_toast">To show this screen again, go to Settings -> Library.</string>
|
||||
<string name="reset_tags">Reset Tags</string>
|
||||
<string name="filter_and_sort"><![CDATA[Filter & Sort]]></string>
|
||||
<string name="display_as">Display as:</string>
|
||||
|
||||
</resources>
|
||||
|
@ -191,6 +191,19 @@
|
||||
<item name="android:background">?attr/selectable_list_drawable</item>
|
||||
</style>
|
||||
|
||||
<!-- set the rounded drawable as background to your bottom sheet -->
|
||||
<style name="BottomSheet" parent="@style/Widget.Design.BottomSheet.Modal">
|
||||
<item name="android:background">@drawable/bg_bottom_sheet_dialog_fragment</item>
|
||||
</style>
|
||||
|
||||
<style name="RoundedBottomSheetDialogTheme" parent="@style/Theme.MaterialComponents.BottomSheetDialog">
|
||||
<item name="android:background">@android:color/transparent</item>
|
||||
</style>
|
||||
|
||||
<style name="BottomSheetDialogTheme" parent="@style/Theme.MaterialComponents.BottomSheetDialog">
|
||||
<item name="android:colorBackground">@android:color/transparent</item>
|
||||
</style>
|
||||
|
||||
<!--==============-->
|
||||
<!--Widgets.Button-->
|
||||
<!--==============-->
|
||||
|
Loading…
Reference in New Issue
Block a user