Bottom sheet header bar view
This commit is contained in:
@@ -0,0 +1,187 @@
|
||||
package org.koitharu.kotatsu.base.ui.widgets
|
||||
|
||||
import android.animation.LayoutTransition
|
||||
import android.content.Context
|
||||
import android.util.AttributeSet
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.annotation.AttrRes
|
||||
import androidx.appcompat.widget.Toolbar
|
||||
import androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||
import androidx.core.content.withStyledAttributes
|
||||
import androidx.core.view.ViewCompat
|
||||
import androidx.core.view.WindowInsetsCompat
|
||||
import androidx.core.view.isGone
|
||||
import com.google.android.material.R as materialR
|
||||
import com.google.android.material.appbar.AppBarLayout
|
||||
import com.google.android.material.appbar.MaterialToolbar
|
||||
import com.google.android.material.bottomsheet.BottomSheetBehavior
|
||||
import java.util.*
|
||||
import org.koitharu.kotatsu.R
|
||||
import org.koitharu.kotatsu.databinding.LayoutSheetHeaderBinding
|
||||
import org.koitharu.kotatsu.utils.ext.getAnimationDuration
|
||||
import org.koitharu.kotatsu.utils.ext.getThemeDrawable
|
||||
import org.koitharu.kotatsu.utils.ext.parents
|
||||
|
||||
class BottomSheetHeaderBar @JvmOverloads constructor(
|
||||
context: Context,
|
||||
attrs: AttributeSet? = null,
|
||||
@AttrRes defStyleAttr: Int = materialR.attr.appBarLayoutStyle,
|
||||
) : AppBarLayout(context, attrs, defStyleAttr) {
|
||||
|
||||
private val binding = LayoutSheetHeaderBinding.inflate(LayoutInflater.from(context), this)
|
||||
private val closeDrawable = context.getThemeDrawable(materialR.attr.actionModeCloseDrawable)
|
||||
private val bottomSheetCallback = Callback()
|
||||
private var bottomSheetBehavior: BottomSheetBehavior<*>? = null
|
||||
private val locationBuffer = IntArray(2)
|
||||
private val expansionListeners = LinkedList<OnExpansionChangeListener>()
|
||||
|
||||
val toolbar: MaterialToolbar
|
||||
get() = binding.toolbar
|
||||
|
||||
init {
|
||||
setBackgroundResource(R.drawable.sheet_toolbar_background)
|
||||
layoutTransition = LayoutTransition().apply {
|
||||
setDuration(context.getAnimationDuration(R.integer.config_tinyAnimTime))
|
||||
}
|
||||
context.withStyledAttributes(attrs, R.styleable.BottomSheetHeaderBar, defStyleAttr) {
|
||||
binding.toolbar.title = getString(R.styleable.BottomSheetHeaderBar_title)
|
||||
val menuResId = getResourceId(R.styleable.BottomSheetHeaderBar_menu, 0)
|
||||
if (menuResId != 0) {
|
||||
binding.toolbar.inflateMenu(menuResId)
|
||||
}
|
||||
}
|
||||
binding.toolbar.setNavigationOnClickListener(bottomSheetCallback)
|
||||
}
|
||||
|
||||
override fun onAttachedToWindow() {
|
||||
super.onAttachedToWindow()
|
||||
setBottomSheetBehavior(findParentBottomSheetBehavior())
|
||||
}
|
||||
|
||||
override fun onDetachedFromWindow() {
|
||||
setBottomSheetBehavior(null)
|
||||
super.onDetachedFromWindow()
|
||||
}
|
||||
|
||||
override fun addView(child: View?, index: Int) {
|
||||
if (shouldAddView(child)) {
|
||||
super.addView(child, index)
|
||||
} else {
|
||||
binding.toolbar.addView(child, index)
|
||||
}
|
||||
}
|
||||
|
||||
override fun addView(child: View?, width: Int, height: Int) {
|
||||
if (shouldAddView(child)) {
|
||||
super.addView(child, width, height)
|
||||
} else {
|
||||
binding.toolbar.addView(child, width, height)
|
||||
}
|
||||
}
|
||||
|
||||
override fun addView(child: View?, index: Int, params: ViewGroup.LayoutParams?) {
|
||||
if (shouldAddView(child)) {
|
||||
super.addView(child, index, params)
|
||||
} else {
|
||||
binding.toolbar.addView(child, index, convertLayoutParams(params))
|
||||
}
|
||||
}
|
||||
|
||||
fun setNavigationOnClickListener(onClickListener: OnClickListener) {
|
||||
binding.toolbar.setNavigationOnClickListener(onClickListener)
|
||||
}
|
||||
|
||||
fun addOnExpansionChangeListener(listener: OnExpansionChangeListener) {
|
||||
expansionListeners.add(listener)
|
||||
}
|
||||
|
||||
fun removeOnExpansionChangeListener(listener: OnExpansionChangeListener) {
|
||||
expansionListeners.remove(listener)
|
||||
}
|
||||
|
||||
private fun setBottomSheetBehavior(behavior: BottomSheetBehavior<*>?) {
|
||||
bottomSheetBehavior?.removeBottomSheetCallback(bottomSheetCallback)
|
||||
bottomSheetBehavior = behavior
|
||||
if (behavior != null) {
|
||||
onBottomSheetStateChanged(behavior.state)
|
||||
behavior.addBottomSheetCallback(bottomSheetCallback)
|
||||
}
|
||||
}
|
||||
|
||||
private fun onBottomSheetStateChanged(newState: Int) {
|
||||
val isExpanded = newState == BottomSheetBehavior.STATE_EXPANDED && isOnTopOfScreen()
|
||||
if (isExpanded == binding.dragHandle.isGone) {
|
||||
return
|
||||
}
|
||||
binding.toolbar.navigationIcon = (if (isExpanded) closeDrawable else null)
|
||||
binding.dragHandle.isGone = isExpanded
|
||||
expansionListeners.forEach { it.onExpansionStateChanged(this, isExpanded) }
|
||||
}
|
||||
|
||||
private fun findParentBottomSheetBehavior(): BottomSheetBehavior<*>? {
|
||||
for (p in parents) {
|
||||
val layoutParams = (p as? View)?.layoutParams
|
||||
if (layoutParams is CoordinatorLayout.LayoutParams) {
|
||||
val behavior = layoutParams.behavior
|
||||
if (behavior is BottomSheetBehavior<*>) {
|
||||
return behavior
|
||||
}
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
private fun isOnTopOfScreen(): Boolean {
|
||||
getLocationInWindow(locationBuffer)
|
||||
val topInset = ViewCompat.getRootWindowInsets(this)
|
||||
?.getInsets(WindowInsetsCompat.Type.systemBars())?.top ?: 0
|
||||
val zeroTop = (layoutParams as? MarginLayoutParams)?.topMargin ?: 0
|
||||
return (locationBuffer[1] - topInset) <= zeroTop
|
||||
}
|
||||
|
||||
private fun dismissBottomSheet() {
|
||||
bottomSheetBehavior?.state = BottomSheetBehavior.STATE_HIDDEN
|
||||
}
|
||||
|
||||
private fun shouldAddView(child: View?): Boolean {
|
||||
if (child == null) {
|
||||
return true
|
||||
}
|
||||
val viewId = child.id
|
||||
return viewId == R.id.dragHandle || viewId == R.id.toolbar
|
||||
}
|
||||
|
||||
private fun convertLayoutParams(params: ViewGroup.LayoutParams?): Toolbar.LayoutParams? {
|
||||
return when (params) {
|
||||
null -> null
|
||||
is MarginLayoutParams -> {
|
||||
val lp = Toolbar.LayoutParams(params)
|
||||
if (params is LayoutParams) {
|
||||
lp.gravity = params.gravity
|
||||
}
|
||||
lp
|
||||
}
|
||||
else -> Toolbar.LayoutParams(params)
|
||||
}
|
||||
}
|
||||
|
||||
private inner class Callback : BottomSheetBehavior.BottomSheetCallback(), View.OnClickListener {
|
||||
|
||||
override fun onStateChanged(bottomSheet: View, newState: Int) {
|
||||
onBottomSheetStateChanged(newState)
|
||||
}
|
||||
|
||||
override fun onSlide(bottomSheet: View, slideOffset: Float) = Unit
|
||||
|
||||
override fun onClick(v: View?) {
|
||||
dismissBottomSheet()
|
||||
}
|
||||
}
|
||||
|
||||
fun interface OnExpansionChangeListener {
|
||||
|
||||
fun onExpansionStateChanged(headerBar: BottomSheetHeaderBar, isExpanded: Boolean)
|
||||
}
|
||||
}
|
||||
@@ -44,7 +44,7 @@ class FavouriteCategoriesBottomSheet :
|
||||
adapter = MangaCategoriesAdapter(this)
|
||||
binding.recyclerViewCategories.adapter = adapter
|
||||
binding.buttonDone.setOnClickListener(this)
|
||||
binding.toolbar.setOnMenuItemClickListener(this)
|
||||
binding.headerBar.toolbar.setOnMenuItemClickListener(this)
|
||||
|
||||
viewModel.content.observe(viewLifecycleOwner, this::onContentChanged)
|
||||
viewModel.onError.observe(viewLifecycleOwner, ::onError)
|
||||
|
||||
@@ -12,7 +12,6 @@ import org.koitharu.kotatsu.base.ui.BaseBottomSheet
|
||||
import org.koitharu.kotatsu.base.ui.list.OnListItemClickListener
|
||||
import org.koitharu.kotatsu.core.model.FavouriteCategory
|
||||
import org.koitharu.kotatsu.databinding.SheetBaseBinding
|
||||
import org.koitharu.kotatsu.utils.BottomSheetToolbarController
|
||||
|
||||
class LibraryCategoriesConfigSheet :
|
||||
BaseBottomSheet<SheetBaseBinding>(),
|
||||
@@ -27,14 +26,9 @@ class LibraryCategoriesConfigSheet :
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
binding.toolbar.setNavigationOnClickListener { dismiss() }
|
||||
binding.toolbar.setTitle(R.string.favourites_categories)
|
||||
binding.headerBar.toolbar.setTitle(R.string.favourites_categories)
|
||||
binding.buttonDone.isVisible = true
|
||||
binding.buttonDone.setOnClickListener(this)
|
||||
behavior?.addBottomSheetCallback(BottomSheetToolbarController(binding.toolbar))
|
||||
if (!resources.getBoolean(R.bool.is_tablet)) {
|
||||
binding.toolbar.navigationIcon = null
|
||||
}
|
||||
val adapter = LibraryCategoriesConfigAdapter(this)
|
||||
binding.recyclerView.adapter = adapter
|
||||
|
||||
|
||||
@@ -11,7 +11,6 @@ import org.koitharu.kotatsu.R
|
||||
import org.koitharu.kotatsu.base.ui.BaseBottomSheet
|
||||
import org.koitharu.kotatsu.databinding.SheetFilterBinding
|
||||
import org.koitharu.kotatsu.remotelist.ui.RemoteListViewModel
|
||||
import org.koitharu.kotatsu.utils.BottomSheetToolbarController
|
||||
|
||||
class FilterBottomSheet :
|
||||
BaseBottomSheet<SheetFilterBinding>(),
|
||||
@@ -20,7 +19,7 @@ class FilterBottomSheet :
|
||||
DialogInterface.OnKeyListener {
|
||||
|
||||
private val viewModel by sharedViewModel<RemoteListViewModel>(
|
||||
owner = { requireParentFragment() }
|
||||
owner = { requireParentFragment() },
|
||||
)
|
||||
|
||||
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
|
||||
@@ -35,11 +34,6 @@ class FilterBottomSheet :
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
binding.toolbar.setNavigationOnClickListener { dismiss() }
|
||||
behavior?.addBottomSheetCallback(BottomSheetToolbarController(binding.toolbar))
|
||||
if (!resources.getBoolean(R.bool.is_tablet)) {
|
||||
binding.toolbar.navigationIcon = null
|
||||
}
|
||||
val adapter = FilterAdapter(viewModel)
|
||||
binding.recyclerView.adapter = adapter
|
||||
viewModel.filterItems.observe(viewLifecycleOwner, adapter::setItems)
|
||||
@@ -67,7 +61,7 @@ class FilterBottomSheet :
|
||||
|
||||
override fun onKey(dialog: DialogInterface?, keyCode: Int, event: KeyEvent?): Boolean {
|
||||
if (keyCode == KeyEvent.KEYCODE_BACK) {
|
||||
val menuItem = binding.toolbar.menu.findItem(R.id.action_search) ?: return false
|
||||
val menuItem = binding.headerBar.toolbar.menu.findItem(R.id.action_search) ?: return false
|
||||
if (menuItem.isActionViewExpanded) {
|
||||
if (event?.action == KeyEvent.ACTION_UP) {
|
||||
menuItem.collapseActionView()
|
||||
@@ -79,8 +73,8 @@ class FilterBottomSheet :
|
||||
}
|
||||
|
||||
private fun initOptionsMenu() {
|
||||
binding.toolbar.inflateMenu(R.menu.opt_filter)
|
||||
val searchMenuItem = binding.toolbar.menu.findItem(R.id.action_search)
|
||||
binding.headerBar.toolbar.inflateMenu(R.menu.opt_filter)
|
||||
val searchMenuItem = binding.headerBar.toolbar.menu.findItem(R.id.action_search)
|
||||
searchMenuItem.setOnActionExpandListener(this)
|
||||
val searchView = searchMenuItem.actionView as SearchView
|
||||
searchView.setOnQueryTextListener(this)
|
||||
@@ -94,4 +88,4 @@ class FilterBottomSheet :
|
||||
|
||||
fun show(fm: FragmentManager) = FilterBottomSheet().show(fm, TAG)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.fragment.app.FragmentManager
|
||||
import kotlin.math.roundToInt
|
||||
import org.koin.android.ext.android.get
|
||||
import org.koitharu.kotatsu.R
|
||||
import org.koitharu.kotatsu.base.ui.BaseBottomSheet
|
||||
@@ -16,10 +17,8 @@ import org.koitharu.kotatsu.details.ui.adapter.ChaptersAdapter
|
||||
import org.koitharu.kotatsu.details.ui.model.ChapterListItem
|
||||
import org.koitharu.kotatsu.details.ui.model.toListItem
|
||||
import org.koitharu.kotatsu.parsers.model.MangaChapter
|
||||
import org.koitharu.kotatsu.utils.BottomSheetToolbarController
|
||||
import org.koitharu.kotatsu.utils.RecyclerViewScrollCallback
|
||||
import org.koitharu.kotatsu.utils.ext.withArgs
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
class ChaptersBottomSheet : BaseBottomSheet<SheetChaptersBinding>(), OnListItemClickListener<ChapterListItem> {
|
||||
|
||||
@@ -29,11 +28,6 @@ class ChaptersBottomSheet : BaseBottomSheet<SheetChaptersBinding>(), OnListItemC
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
binding.toolbar.setNavigationOnClickListener { dismiss() }
|
||||
behavior?.addBottomSheetCallback(BottomSheetToolbarController(binding.toolbar))
|
||||
if (!resources.getBoolean(R.bool.is_tablet)) {
|
||||
binding.toolbar.navigationIcon = null
|
||||
}
|
||||
val chapters = arguments?.getParcelable<ParcelableMangaChapters>(ARG_CHAPTERS)?.chapters
|
||||
if (chapters.isNullOrEmpty()) {
|
||||
dismissAllowingStateLoss()
|
||||
@@ -90,9 +84,5 @@ class ChaptersBottomSheet : BaseBottomSheet<SheetChaptersBinding>(), OnListItemC
|
||||
putParcelable(ARG_CHAPTERS, ParcelableMangaChapters(chapters))
|
||||
putLong(ARG_CURRENT_ID, currentId)
|
||||
}.show(fm, TAG)
|
||||
|
||||
private fun <T> List<T>.asArrayList(): ArrayList<T> {
|
||||
return this as? ArrayList<T> ?: ArrayList(this)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,14 +20,15 @@ import org.koitharu.kotatsu.databinding.SheetReaderConfigBinding
|
||||
import org.koitharu.kotatsu.reader.ui.PageSaveContract
|
||||
import org.koitharu.kotatsu.reader.ui.ReaderViewModel
|
||||
import org.koitharu.kotatsu.settings.SettingsActivity
|
||||
import org.koitharu.kotatsu.utils.BottomSheetToolbarController
|
||||
import org.koitharu.kotatsu.utils.ScreenOrientationHelper
|
||||
import org.koitharu.kotatsu.utils.ext.viewLifecycleScope
|
||||
import org.koitharu.kotatsu.utils.ext.withArgs
|
||||
|
||||
class ReaderConfigBottomSheet : BaseBottomSheet<SheetReaderConfigBinding>(),
|
||||
class ReaderConfigBottomSheet :
|
||||
BaseBottomSheet<SheetReaderConfigBinding>(),
|
||||
CheckableButtonGroup.OnCheckedChangeListener,
|
||||
ActivityResultCallback<Uri?>, View.OnClickListener {
|
||||
ActivityResultCallback<Uri?>,
|
||||
View.OnClickListener {
|
||||
|
||||
private val viewModel by sharedViewModel<ReaderViewModel>()
|
||||
private val savePageRequest = registerForActivityResult(PageSaveContract(), this)
|
||||
@@ -48,11 +49,6 @@ class ReaderConfigBottomSheet : BaseBottomSheet<SheetReaderConfigBinding>(),
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
observeScreenOrientation()
|
||||
binding.toolbar.setNavigationOnClickListener { dismiss() }
|
||||
behavior?.addBottomSheetCallback(BottomSheetToolbarController(binding.toolbar))
|
||||
if (!resources.getBoolean(R.bool.is_tablet)) {
|
||||
binding.toolbar.navigationIcon = null
|
||||
}
|
||||
binding.buttonStandard.isChecked = mode == ReaderMode.STANDARD
|
||||
binding.buttonReversed.isChecked = mode == ReaderMode.REVERSED
|
||||
binding.buttonWebtoon.isChecked = mode == ReaderMode.WEBTOON
|
||||
@@ -61,7 +57,6 @@ class ReaderConfigBottomSheet : BaseBottomSheet<SheetReaderConfigBinding>(),
|
||||
binding.buttonSavePage.setOnClickListener(this)
|
||||
binding.buttonScreenRotate.setOnClickListener(this)
|
||||
binding.buttonSettings.setOnClickListener(this)
|
||||
|
||||
}
|
||||
|
||||
override fun onClick(v: View) {
|
||||
|
||||
@@ -4,16 +4,15 @@ import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.appcompat.widget.Toolbar
|
||||
import androidx.fragment.app.FragmentManager
|
||||
import androidx.recyclerview.widget.GridLayoutManager
|
||||
import com.google.android.material.bottomsheet.BottomSheetBehavior
|
||||
import org.koin.android.ext.android.get
|
||||
import org.koin.androidx.viewmodel.ext.android.getViewModel
|
||||
import org.koitharu.kotatsu.R
|
||||
import org.koitharu.kotatsu.base.ui.BaseBottomSheet
|
||||
import org.koitharu.kotatsu.base.ui.list.OnListItemClickListener
|
||||
import org.koitharu.kotatsu.base.ui.list.decor.SpacingItemDecoration
|
||||
import org.koitharu.kotatsu.base.ui.widgets.BottomSheetHeaderBar
|
||||
import org.koitharu.kotatsu.core.model.parcelable.ParcelableMangaPages
|
||||
import org.koitharu.kotatsu.core.parser.MangaRepository
|
||||
import org.koitharu.kotatsu.core.prefs.AppSettings
|
||||
@@ -24,13 +23,13 @@ import org.koitharu.kotatsu.reader.domain.PageLoader
|
||||
import org.koitharu.kotatsu.reader.ui.ReaderActivity
|
||||
import org.koitharu.kotatsu.reader.ui.ReaderViewModel
|
||||
import org.koitharu.kotatsu.reader.ui.thumbnails.adapter.PageThumbnailAdapter
|
||||
import org.koitharu.kotatsu.utils.BottomSheetToolbarController
|
||||
import org.koitharu.kotatsu.utils.ext.viewLifecycleScope
|
||||
import org.koitharu.kotatsu.utils.ext.withArgs
|
||||
|
||||
class PagesThumbnailsSheet :
|
||||
BaseBottomSheet<SheetPagesBinding>(),
|
||||
OnListItemClickListener<MangaPage> {
|
||||
OnListItemClickListener<MangaPage>,
|
||||
BottomSheetHeaderBar.OnExpansionChangeListener {
|
||||
|
||||
private lateinit var thumbnails: List<PageThumbnail>
|
||||
private var spanResolver: MangaListSpanResolver? = null
|
||||
@@ -64,16 +63,10 @@ class PagesThumbnailsSheet :
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
val title = arguments?.getString(ARG_TITLE)
|
||||
binding.toolbar.title = title
|
||||
binding.toolbar.setNavigationOnClickListener { dismiss() }
|
||||
binding.toolbar.subtitle = null
|
||||
behavior?.addBottomSheetCallback(ToolbarController(binding.toolbar))
|
||||
|
||||
if (!resources.getBoolean(R.bool.is_tablet)) {
|
||||
binding.toolbar.navigationIcon = null
|
||||
} else {
|
||||
binding.toolbar.subtitle =
|
||||
resources.getQuantityString(R.plurals.pages, thumbnails.size, thumbnails.size)
|
||||
with(binding.headerBar) {
|
||||
toolbar.title = title
|
||||
toolbar.subtitle = null
|
||||
addOnExpansionChangeListener(this@PagesThumbnailsSheet)
|
||||
}
|
||||
|
||||
with(binding.recyclerView) {
|
||||
@@ -113,26 +106,23 @@ class PagesThumbnailsSheet :
|
||||
}
|
||||
}
|
||||
|
||||
override fun onExpansionStateChanged(headerBar: BottomSheetHeaderBar, isExpanded: Boolean) {
|
||||
if (isExpanded) {
|
||||
headerBar.toolbar.subtitle = resources.getQuantityString(
|
||||
R.plurals.pages,
|
||||
thumbnails.size,
|
||||
thumbnails.size,
|
||||
)
|
||||
} else {
|
||||
headerBar.toolbar.subtitle = null
|
||||
}
|
||||
}
|
||||
|
||||
private fun getPageLoader(): PageLoader {
|
||||
val viewModel = (activity as? ReaderActivity)?.getViewModel<ReaderViewModel>()
|
||||
return viewModel?.pageLoader ?: PageLoader().also { pageLoader = it }
|
||||
}
|
||||
|
||||
private inner class ToolbarController(toolbar: Toolbar) : BottomSheetToolbarController(toolbar) {
|
||||
override fun onStateChanged(bottomSheet: View, newState: Int) {
|
||||
super.onStateChanged(bottomSheet, newState)
|
||||
if (newState == BottomSheetBehavior.STATE_EXPANDED) {
|
||||
toolbar.subtitle = resources.getQuantityString(
|
||||
R.plurals.pages,
|
||||
thumbnails.size,
|
||||
thumbnails.size,
|
||||
)
|
||||
} else {
|
||||
toolbar.subtitle = null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
private const val ARG_PAGES = "pages"
|
||||
|
||||
@@ -21,7 +21,6 @@ import org.koitharu.kotatsu.parsers.model.Manga
|
||||
import org.koitharu.kotatsu.scrobbling.domain.model.ScrobblerManga
|
||||
import org.koitharu.kotatsu.scrobbling.ui.selector.adapter.ShikiMangaSelectionDecoration
|
||||
import org.koitharu.kotatsu.scrobbling.ui.selector.adapter.ShikimoriSelectorAdapter
|
||||
import org.koitharu.kotatsu.utils.BottomSheetToolbarController
|
||||
import org.koitharu.kotatsu.utils.ext.getDisplayMessage
|
||||
import org.koitharu.kotatsu.utils.ext.withArgs
|
||||
|
||||
@@ -50,8 +49,6 @@ class ScrobblingSelectorBottomSheet :
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
binding.toolbar.setNavigationOnClickListener { dismiss() }
|
||||
addBottomSheetCallback(BottomSheetToolbarController(binding.toolbar))
|
||||
val listAdapter = ShikimoriSelectorAdapter(viewLifecycleOwner, get(), this)
|
||||
val decoration = ShikiMangaSelectionDecoration(view.context)
|
||||
with(binding.recyclerView) {
|
||||
@@ -72,7 +69,7 @@ class ScrobblingSelectorBottomSheet :
|
||||
dismiss()
|
||||
}
|
||||
viewModel.searchQuery.observe(viewLifecycleOwner) {
|
||||
binding.toolbar.subtitle = it
|
||||
binding.headerBar.toolbar.subtitle = it
|
||||
}
|
||||
}
|
||||
|
||||
@@ -107,7 +104,7 @@ class ScrobblingSelectorBottomSheet :
|
||||
return false
|
||||
}
|
||||
viewModel.search(query)
|
||||
binding.toolbar.menu.findItem(R.id.action_search)?.collapseActionView()
|
||||
binding.headerBar.toolbar.menu.findItem(R.id.action_search)?.collapseActionView()
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -115,7 +112,7 @@ class ScrobblingSelectorBottomSheet :
|
||||
|
||||
override fun onKey(dialog: DialogInterface?, keyCode: Int, event: KeyEvent?): Boolean {
|
||||
if (keyCode == KeyEvent.KEYCODE_BACK) {
|
||||
val menuItem = binding.toolbar.menu.findItem(R.id.action_search) ?: return false
|
||||
val menuItem = binding.headerBar.toolbar.menu.findItem(R.id.action_search) ?: return false
|
||||
if (menuItem.isActionViewExpanded) {
|
||||
if (event?.action == KeyEvent.ACTION_UP) {
|
||||
menuItem.collapseActionView()
|
||||
@@ -134,8 +131,8 @@ class ScrobblingSelectorBottomSheet :
|
||||
}
|
||||
|
||||
private fun initOptionsMenu() {
|
||||
binding.toolbar.inflateMenu(R.menu.opt_shiki_selector)
|
||||
val searchMenuItem = binding.toolbar.menu.findItem(R.id.action_search)
|
||||
binding.headerBar.toolbar.inflateMenu(R.menu.opt_shiki_selector)
|
||||
val searchMenuItem = binding.headerBar.toolbar.menu.findItem(R.id.action_search)
|
||||
searchMenuItem.setOnActionExpandListener(this)
|
||||
val searchView = searchMenuItem.actionView as SearchView
|
||||
searchView.setOnQueryTextListener(this)
|
||||
@@ -152,4 +149,4 @@ class ScrobblingSelectorBottomSheet :
|
||||
putParcelable(MangaIntent.KEY_MANGA, ParcelableManga(manga, withChapters = false))
|
||||
}.show(fm, TAG)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
package org.koitharu.kotatsu.utils
|
||||
|
||||
import android.view.View
|
||||
import androidx.appcompat.widget.Toolbar
|
||||
import com.google.android.material.bottomsheet.BottomSheetBehavior
|
||||
import com.google.android.material.R as materialR
|
||||
|
||||
open class BottomSheetToolbarController(
|
||||
protected val toolbar: Toolbar,
|
||||
) : BottomSheetBehavior.BottomSheetCallback() {
|
||||
|
||||
override fun onStateChanged(bottomSheet: View, newState: Int) {
|
||||
val isExpanded = newState == BottomSheetBehavior.STATE_EXPANDED && bottomSheet.top <= 0
|
||||
if (isExpanded) {
|
||||
toolbar.setNavigationIcon(materialR.drawable.abc_ic_clear_material)
|
||||
} else {
|
||||
toolbar.navigationIcon = null
|
||||
}
|
||||
}
|
||||
|
||||
override fun onSlide(bottomSheet: View, slideOffset: Float) = Unit
|
||||
}
|
||||
@@ -10,7 +10,6 @@ import android.content.SyncResult
|
||||
import android.content.pm.ResolveInfo
|
||||
import android.database.SQLException
|
||||
import android.graphics.Color
|
||||
|
||||
import android.net.ConnectivityManager
|
||||
import android.net.Network
|
||||
import android.net.NetworkRequest
|
||||
@@ -22,14 +21,16 @@ import android.view.ViewGroup
|
||||
import android.view.ViewPropertyAnimator
|
||||
import android.view.Window
|
||||
import androidx.activity.result.ActivityResultLauncher
|
||||
import androidx.annotation.IntegerRes
|
||||
import androidx.core.app.ActivityOptionsCompat
|
||||
import androidx.core.content.ContextCompat.getSystemService
|
||||
import androidx.core.view.children
|
||||
import androidx.core.view.descendants
|
||||
import androidx.lifecycle.Lifecycle
|
||||
import androidx.lifecycle.coroutineScope
|
||||
import androidx.work.CoroutineWorker
|
||||
import com.google.android.material.elevation.ElevationOverlayProvider
|
||||
import kotlin.coroutines.resume
|
||||
import kotlin.math.roundToLong
|
||||
import kotlinx.coroutines.channels.awaitClose
|
||||
import kotlinx.coroutines.channels.trySendBlocking
|
||||
import kotlinx.coroutines.delay
|
||||
@@ -43,7 +44,6 @@ import okio.IOException
|
||||
import org.json.JSONException
|
||||
import org.koitharu.kotatsu.BuildConfig
|
||||
import org.koitharu.kotatsu.utils.InternalResourceHelper
|
||||
import kotlin.coroutines.resume
|
||||
|
||||
val Context.activityManager: ActivityManager?
|
||||
get() = getSystemService(ACTIVITY_SERVICE) as? ActivityManager
|
||||
@@ -122,7 +122,8 @@ fun SyncResult.onError(error: Throwable) {
|
||||
when (error) {
|
||||
is IOException -> stats.numIoExceptions++
|
||||
is OperationApplicationException,
|
||||
is SQLException -> databaseError = true
|
||||
is SQLException,
|
||||
-> databaseError = true
|
||||
is JSONException -> stats.numParseExceptions++
|
||||
else -> if (BuildConfig.DEBUG) throw error
|
||||
}
|
||||
@@ -150,6 +151,10 @@ fun ViewPropertyAnimator.applySystemAnimatorScale(context: Context): ViewPropert
|
||||
this.duration = (this.duration * context.animatorDurationScale).toLong()
|
||||
}
|
||||
|
||||
fun Context.getAnimationDuration(@IntegerRes resId: Int): Long {
|
||||
return (resources.getInteger(resId) * animatorDurationScale).roundToLong()
|
||||
}
|
||||
|
||||
inline fun <reified T> ViewGroup.findChild(): T? {
|
||||
return children.find { it is T } as? T
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user