From 36634414bc7e73d5f5437f8e7d4e631bdafb4086 Mon Sep 17 00:00:00 2001 From: Koitharu Date: Sun, 24 Jul 2022 18:36:35 +0300 Subject: [PATCH] Bottom sheet header bar view --- .../base/ui/widgets/BottomSheetHeaderBar.kt | 187 ++++++++++++++++++ .../select/FavouriteCategoriesBottomSheet.kt | 2 +- .../LibraryCategoriesConfigSheet.kt | 8 +- .../list/ui/filter/FilterBottomSheet.kt | 16 +- .../kotatsu/reader/ui/ChaptersBottomSheet.kt | 14 +- .../ui/config/ReaderConfigBottomSheet.kt | 13 +- .../ui/thumbnails/PagesThumbnailsSheet.kt | 48 ++--- .../selector/ScrobblingSelectorBottomSheet.kt | 15 +- .../utils/BottomSheetToolbarController.kt | 22 --- .../koitharu/kotatsu/utils/ext/AndroidExt.kt | 13 +- .../main/res/layout/layout_sheet_header.xml | 24 +++ app/src/main/res/layout/sheet_base.xml | 47 ++--- app/src/main/res/layout/sheet_chapters.xml | 34 +--- .../res/layout/sheet_favorite_categories.xml | 20 +- app/src/main/res/layout/sheet_filter.xml | 26 +-- app/src/main/res/layout/sheet_pages.xml | 24 +-- .../main/res/layout/sheet_reader_config.xml | 26 +-- app/src/main/res/layout/sheet_scrobbling.xml | 25 +-- .../res/layout/sheet_scrobbling_selector.xml | 49 ++--- app/src/main/res/values/attrs.xml | 7 +- app/src/main/res/values/integers.xml | 3 +- 21 files changed, 321 insertions(+), 302 deletions(-) create mode 100644 app/src/main/java/org/koitharu/kotatsu/base/ui/widgets/BottomSheetHeaderBar.kt delete mode 100644 app/src/main/java/org/koitharu/kotatsu/utils/BottomSheetToolbarController.kt create mode 100644 app/src/main/res/layout/layout_sheet_header.xml diff --git a/app/src/main/java/org/koitharu/kotatsu/base/ui/widgets/BottomSheetHeaderBar.kt b/app/src/main/java/org/koitharu/kotatsu/base/ui/widgets/BottomSheetHeaderBar.kt new file mode 100644 index 000000000..66d9ed580 --- /dev/null +++ b/app/src/main/java/org/koitharu/kotatsu/base/ui/widgets/BottomSheetHeaderBar.kt @@ -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() + + 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) + } +} diff --git a/app/src/main/java/org/koitharu/kotatsu/favourites/ui/categories/select/FavouriteCategoriesBottomSheet.kt b/app/src/main/java/org/koitharu/kotatsu/favourites/ui/categories/select/FavouriteCategoriesBottomSheet.kt index 1afe10c8a..d55d66cea 100644 --- a/app/src/main/java/org/koitharu/kotatsu/favourites/ui/categories/select/FavouriteCategoriesBottomSheet.kt +++ b/app/src/main/java/org/koitharu/kotatsu/favourites/ui/categories/select/FavouriteCategoriesBottomSheet.kt @@ -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) diff --git a/app/src/main/java/org/koitharu/kotatsu/library/ui/config/categories/LibraryCategoriesConfigSheet.kt b/app/src/main/java/org/koitharu/kotatsu/library/ui/config/categories/LibraryCategoriesConfigSheet.kt index 67c4b9f01..4352f07a2 100644 --- a/app/src/main/java/org/koitharu/kotatsu/library/ui/config/categories/LibraryCategoriesConfigSheet.kt +++ b/app/src/main/java/org/koitharu/kotatsu/library/ui/config/categories/LibraryCategoriesConfigSheet.kt @@ -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(), @@ -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 diff --git a/app/src/main/java/org/koitharu/kotatsu/list/ui/filter/FilterBottomSheet.kt b/app/src/main/java/org/koitharu/kotatsu/list/ui/filter/FilterBottomSheet.kt index 7583b2e8c..0cf07b393 100644 --- a/app/src/main/java/org/koitharu/kotatsu/list/ui/filter/FilterBottomSheet.kt +++ b/app/src/main/java/org/koitharu/kotatsu/list/ui/filter/FilterBottomSheet.kt @@ -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(), @@ -20,7 +19,7 @@ class FilterBottomSheet : DialogInterface.OnKeyListener { private val viewModel by sharedViewModel( - 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) } -} \ No newline at end of file +} diff --git a/app/src/main/java/org/koitharu/kotatsu/reader/ui/ChaptersBottomSheet.kt b/app/src/main/java/org/koitharu/kotatsu/reader/ui/ChaptersBottomSheet.kt index 99f173aeb..963ec3029 100644 --- a/app/src/main/java/org/koitharu/kotatsu/reader/ui/ChaptersBottomSheet.kt +++ b/app/src/main/java/org/koitharu/kotatsu/reader/ui/ChaptersBottomSheet.kt @@ -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(), OnListItemClickListener { @@ -29,11 +28,6 @@ class ChaptersBottomSheet : BaseBottomSheet(), 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(ARG_CHAPTERS)?.chapters if (chapters.isNullOrEmpty()) { dismissAllowingStateLoss() @@ -90,9 +84,5 @@ class ChaptersBottomSheet : BaseBottomSheet(), OnListItemC putParcelable(ARG_CHAPTERS, ParcelableMangaChapters(chapters)) putLong(ARG_CURRENT_ID, currentId) }.show(fm, TAG) - - private fun List.asArrayList(): ArrayList { - return this as? ArrayList ?: ArrayList(this) - } } -} \ No newline at end of file +} diff --git a/app/src/main/java/org/koitharu/kotatsu/reader/ui/config/ReaderConfigBottomSheet.kt b/app/src/main/java/org/koitharu/kotatsu/reader/ui/config/ReaderConfigBottomSheet.kt index 17c48d283..46a6663af 100644 --- a/app/src/main/java/org/koitharu/kotatsu/reader/ui/config/ReaderConfigBottomSheet.kt +++ b/app/src/main/java/org/koitharu/kotatsu/reader/ui/config/ReaderConfigBottomSheet.kt @@ -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(), +class ReaderConfigBottomSheet : + BaseBottomSheet(), CheckableButtonGroup.OnCheckedChangeListener, - ActivityResultCallback, View.OnClickListener { + ActivityResultCallback, + View.OnClickListener { private val viewModel by sharedViewModel() private val savePageRequest = registerForActivityResult(PageSaveContract(), this) @@ -48,11 +49,6 @@ class ReaderConfigBottomSheet : BaseBottomSheet(), 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(), binding.buttonSavePage.setOnClickListener(this) binding.buttonScreenRotate.setOnClickListener(this) binding.buttonSettings.setOnClickListener(this) - } override fun onClick(v: View) { diff --git a/app/src/main/java/org/koitharu/kotatsu/reader/ui/thumbnails/PagesThumbnailsSheet.kt b/app/src/main/java/org/koitharu/kotatsu/reader/ui/thumbnails/PagesThumbnailsSheet.kt index cfa66962d..a85c10a5c 100644 --- a/app/src/main/java/org/koitharu/kotatsu/reader/ui/thumbnails/PagesThumbnailsSheet.kt +++ b/app/src/main/java/org/koitharu/kotatsu/reader/ui/thumbnails/PagesThumbnailsSheet.kt @@ -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(), - OnListItemClickListener { + OnListItemClickListener, + BottomSheetHeaderBar.OnExpansionChangeListener { private lateinit var thumbnails: List 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() 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" diff --git a/app/src/main/java/org/koitharu/kotatsu/scrobbling/ui/selector/ScrobblingSelectorBottomSheet.kt b/app/src/main/java/org/koitharu/kotatsu/scrobbling/ui/selector/ScrobblingSelectorBottomSheet.kt index 276502ec7..cf2d70bb3 100644 --- a/app/src/main/java/org/koitharu/kotatsu/scrobbling/ui/selector/ScrobblingSelectorBottomSheet.kt +++ b/app/src/main/java/org/koitharu/kotatsu/scrobbling/ui/selector/ScrobblingSelectorBottomSheet.kt @@ -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) } -} \ No newline at end of file +} diff --git a/app/src/main/java/org/koitharu/kotatsu/utils/BottomSheetToolbarController.kt b/app/src/main/java/org/koitharu/kotatsu/utils/BottomSheetToolbarController.kt deleted file mode 100644 index ae40b41f6..000000000 --- a/app/src/main/java/org/koitharu/kotatsu/utils/BottomSheetToolbarController.kt +++ /dev/null @@ -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 -} \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/utils/ext/AndroidExt.kt b/app/src/main/java/org/koitharu/kotatsu/utils/ext/AndroidExt.kt index 8818d607f..54fc9a4c1 100644 --- a/app/src/main/java/org/koitharu/kotatsu/utils/ext/AndroidExt.kt +++ b/app/src/main/java/org/koitharu/kotatsu/utils/ext/AndroidExt.kt @@ -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 ViewGroup.findChild(): T? { return children.find { it is T } as? T } diff --git a/app/src/main/res/layout/layout_sheet_header.xml b/app/src/main/res/layout/layout_sheet_header.xml new file mode 100644 index 000000000..157e6e2ce --- /dev/null +++ b/app/src/main/res/layout/layout_sheet_header.xml @@ -0,0 +1,24 @@ + + + + + + + + diff --git a/app/src/main/res/layout/sheet_base.xml b/app/src/main/res/layout/sheet_base.xml index 8aab8eb2b..52f79f0f2 100644 --- a/app/src/main/res/layout/sheet_base.xml +++ b/app/src/main/res/layout/sheet_base.xml @@ -7,42 +7,23 @@ android:layout_height="wrap_content" android:orientation="vertical"> - - - + android:layout_height="wrap_content"> - +