Refactor: change window insets handling approach

This commit is contained in:
Koitharu
2025-02-26 08:06:57 +02:00
parent a7caf9848e
commit b27d6dbe9a
66 changed files with 399 additions and 743 deletions

View File

@@ -1,11 +1,10 @@
package org.koitharu.kotatsu.alternatives.ui package org.koitharu.kotatsu.alternatives.ui
import android.os.Bundle import android.os.Bundle
import android.view.Gravity
import android.view.View import android.view.View
import android.widget.Toast import android.widget.Toast
import androidx.activity.viewModels import androidx.activity.viewModels
import androidx.core.graphics.Insets
import androidx.core.view.updatePadding
import coil3.ImageLoader import coil3.ImageLoader
import dagger.hilt.android.AndroidEntryPoint import dagger.hilt.android.AndroidEntryPoint
import org.koitharu.kotatsu.R import org.koitharu.kotatsu.R
@@ -16,6 +15,7 @@ import org.koitharu.kotatsu.core.ui.BaseActivity
import org.koitharu.kotatsu.core.ui.BaseListAdapter import org.koitharu.kotatsu.core.ui.BaseListAdapter
import org.koitharu.kotatsu.core.ui.dialog.buildAlertDialog import org.koitharu.kotatsu.core.ui.dialog.buildAlertDialog
import org.koitharu.kotatsu.core.ui.list.OnListItemClickListener import org.koitharu.kotatsu.core.ui.list.OnListItemClickListener
import org.koitharu.kotatsu.core.util.ext.consumeInsetsAsPadding
import org.koitharu.kotatsu.core.util.ext.observe import org.koitharu.kotatsu.core.util.ext.observe
import org.koitharu.kotatsu.core.util.ext.observeEvent import org.koitharu.kotatsu.core.util.ext.observeEvent
import org.koitharu.kotatsu.databinding.ActivityAlternativesBinding import org.koitharu.kotatsu.databinding.ActivityAlternativesBinding
@@ -50,6 +50,7 @@ class AlternativesActivity : BaseActivity<ActivityAlternativesBinding>(),
.addDelegate(ListItemType.FOOTER_LOADING, loadingFooterAD()) .addDelegate(ListItemType.FOOTER_LOADING, loadingFooterAD())
.addDelegate(ListItemType.STATE_LOADING, loadingStateAD()) .addDelegate(ListItemType.STATE_LOADING, loadingStateAD())
with(viewBinding.recyclerView) { with(viewBinding.recyclerView) {
consumeInsetsAsPadding(Gravity.START or Gravity.END or Gravity.BOTTOM)
setHasFixedSize(true) setHasFixedSize(true)
addItemDecoration(TypedListSpacingDecoration(context, addHorizontalPadding = false)) addItemDecoration(TypedListSpacingDecoration(context, addHorizontalPadding = false))
adapter = listAdapter adapter = listAdapter
@@ -64,16 +65,6 @@ class AlternativesActivity : BaseActivity<ActivityAlternativesBinding>(),
} }
} }
override fun onWindowInsetsChanged(insets: Insets) {
viewBinding.root.updatePadding(
left = insets.left,
right = insets.right,
)
viewBinding.recyclerView.updatePadding(
bottom = insets.bottom + viewBinding.recyclerView.paddingTop,
)
}
override fun onItemClick(item: MangaAlternativeModel, view: View) { override fun onItemClick(item: MangaAlternativeModel, view: View) {
when (view.id) { when (view.id) {
R.id.chip_source -> router.openSearch(item.manga.source, viewModel.manga.title) R.id.chip_source -> router.openSearch(item.manga.source, viewModel.manga.title)

View File

@@ -2,8 +2,6 @@ package org.koitharu.kotatsu.bookmarks.ui
import android.os.Bundle import android.os.Bundle
import androidx.coordinatorlayout.widget.CoordinatorLayout import androidx.coordinatorlayout.widget.CoordinatorLayout
import androidx.core.graphics.Insets
import androidx.core.view.updatePadding
import androidx.fragment.app.commit import androidx.fragment.app.commit
import com.google.android.material.appbar.AppBarLayout import com.google.android.material.appbar.AppBarLayout
import dagger.hilt.android.AndroidEntryPoint import dagger.hilt.android.AndroidEntryPoint
@@ -37,11 +35,4 @@ class AllBookmarksActivity :
} }
} }
} }
override fun onWindowInsetsChanged(insets: Insets) {
viewBinding.root.updatePadding(
left = insets.left,
right = insets.right,
)
}
} }

View File

@@ -1,6 +1,7 @@
package org.koitharu.kotatsu.bookmarks.ui package org.koitharu.kotatsu.bookmarks.ui
import android.os.Bundle import android.os.Bundle
import android.view.Gravity
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.Menu import android.view.Menu
import android.view.MenuInflater import android.view.MenuInflater
@@ -9,9 +10,6 @@ import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.Toast import android.widget.Toast
import androidx.appcompat.view.ActionMode import androidx.appcompat.view.ActionMode
import androidx.core.graphics.Insets
import androidx.core.view.updateLayoutParams
import androidx.core.view.updatePadding
import androidx.fragment.app.viewModels import androidx.fragment.app.viewModels
import androidx.recyclerview.widget.GridLayoutManager import androidx.recyclerview.widget.GridLayoutManager
import coil3.ImageLoader import coil3.ImageLoader
@@ -28,6 +26,7 @@ import org.koitharu.kotatsu.core.ui.list.ListSelectionController
import org.koitharu.kotatsu.core.ui.list.OnListItemClickListener import org.koitharu.kotatsu.core.ui.list.OnListItemClickListener
import org.koitharu.kotatsu.core.ui.list.fastscroll.FastScroller import org.koitharu.kotatsu.core.ui.list.fastscroll.FastScroller
import org.koitharu.kotatsu.core.ui.util.ReversibleActionObserver import org.koitharu.kotatsu.core.ui.util.ReversibleActionObserver
import org.koitharu.kotatsu.core.util.ext.consumeInsetsAsPadding
import org.koitharu.kotatsu.core.util.ext.findAppCompatDelegate import org.koitharu.kotatsu.core.util.ext.findAppCompatDelegate
import org.koitharu.kotatsu.core.util.ext.observe import org.koitharu.kotatsu.core.util.ext.observe
import org.koitharu.kotatsu.core.util.ext.observeEvent import org.koitharu.kotatsu.core.util.ext.observeEvent
@@ -86,6 +85,7 @@ class AllBookmarksFragment :
) )
val spanSizeLookup = SpanSizeLookup() val spanSizeLookup = SpanSizeLookup()
with(binding.recyclerView) { with(binding.recyclerView) {
consumeInsetsAsPadding(Gravity.BOTTOM or Gravity.START or Gravity.END)
setHasFixedSize(true) setHasFixedSize(true)
val spanResolver = GridSpanResolver(resources) val spanResolver = GridSpanResolver(resources)
addItemDecoration(TypedListSpacingDecoration(context, false)) addItemDecoration(TypedListSpacingDecoration(context, false))
@@ -177,16 +177,6 @@ class AllBookmarksFragment :
} }
} }
override fun onWindowInsetsChanged(insets: Insets) {
val rv = requireViewBinding().recyclerView
rv.updatePadding(
bottom = insets.bottom + rv.paddingTop,
)
rv.fastScroller.updateLayoutParams<ViewGroup.MarginLayoutParams> {
bottomMargin = insets.bottom
}
}
private inner class SpanSizeLookup : GridLayoutManager.SpanSizeLookup(), Runnable { private inner class SpanSizeLookup : GridLayoutManager.SpanSizeLookup(), Runnable {
init { init {

View File

@@ -1,11 +1,10 @@
package org.koitharu.kotatsu.browser package org.koitharu.kotatsu.browser
import android.os.Bundle import android.os.Bundle
import android.view.Gravity
import android.view.Menu import android.view.Menu
import android.view.MenuItem import android.view.MenuItem
import androidx.core.graphics.Insets
import androidx.core.view.isVisible import androidx.core.view.isVisible
import androidx.core.view.updatePadding
import com.google.android.material.snackbar.Snackbar import com.google.android.material.snackbar.Snackbar
import dagger.hilt.android.AndroidEntryPoint import dagger.hilt.android.AndroidEntryPoint
import org.koitharu.kotatsu.R import org.koitharu.kotatsu.R
@@ -17,6 +16,7 @@ import org.koitharu.kotatsu.core.parser.MangaRepository
import org.koitharu.kotatsu.core.parser.ParserMangaRepository import org.koitharu.kotatsu.core.parser.ParserMangaRepository
import org.koitharu.kotatsu.core.ui.BaseActivity import org.koitharu.kotatsu.core.ui.BaseActivity
import org.koitharu.kotatsu.core.util.ext.configureForParser import org.koitharu.kotatsu.core.util.ext.configureForParser
import org.koitharu.kotatsu.core.util.ext.consumeInsetsAsPadding
import org.koitharu.kotatsu.databinding.ActivityBrowserBinding import org.koitharu.kotatsu.databinding.ActivityBrowserBinding
import javax.inject.Inject import javax.inject.Inject
import com.google.android.material.R as materialR import com.google.android.material.R as materialR
@@ -42,6 +42,7 @@ class BrowserActivity : BaseActivity<ActivityBrowserBinding>(), BrowserCallback
val repository = mangaRepositoryFactory.create(mangaSource) as? ParserMangaRepository val repository = mangaRepositoryFactory.create(mangaSource) as? ParserMangaRepository
val userAgent = repository?.getRequestHeaders()?.get(CommonHeaders.USER_AGENT) val userAgent = repository?.getRequestHeaders()?.get(CommonHeaders.USER_AGENT)
viewBinding.webView.configureForParser(userAgent) viewBinding.webView.configureForParser(userAgent)
viewBinding.webView.consumeInsetsAsPadding(Gravity.START or Gravity.END or Gravity.BOTTOM)
viewBinding.webView.webViewClient = BrowserClient(this) viewBinding.webView.webViewClient = BrowserClient(this)
viewBinding.webView.webChromeClient = ProgressChromeClient(viewBinding.progressBar) viewBinding.webView.webChromeClient = ProgressChromeClient(viewBinding.progressBar)
onBackPressedCallback = WebViewBackPressedCallback(viewBinding.webView) onBackPressedCallback = WebViewBackPressedCallback(viewBinding.webView)
@@ -114,15 +115,4 @@ class BrowserActivity : BaseActivity<ActivityBrowserBinding>(), BrowserCallback
override fun onHistoryChanged() { override fun onHistoryChanged() {
onBackPressedCallback.onHistoryChanged() onBackPressedCallback.onHistoryChanged()
} }
override fun onWindowInsetsChanged(insets: Insets) {
viewBinding.appbar.updatePadding(
top = insets.top,
)
viewBinding.root.updatePadding(
left = insets.left,
right = insets.right,
bottom = insets.bottom,
)
}
} }

View File

@@ -3,13 +3,12 @@ package org.koitharu.kotatsu.browser.cloudflare
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.os.Bundle import android.os.Bundle
import android.view.Gravity
import android.view.Menu import android.view.Menu
import android.view.MenuItem import android.view.MenuItem
import androidx.activity.result.contract.ActivityResultContract import androidx.activity.result.contract.ActivityResultContract
import androidx.core.graphics.Insets
import androidx.core.view.isInvisible import androidx.core.view.isInvisible
import androidx.core.view.isVisible import androidx.core.view.isVisible
import androidx.core.view.updatePadding
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import dagger.hilt.android.AndroidEntryPoint import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
@@ -26,6 +25,7 @@ import org.koitharu.kotatsu.core.nav.AppRouter
import org.koitharu.kotatsu.core.network.cookies.MutableCookieJar import org.koitharu.kotatsu.core.network.cookies.MutableCookieJar
import org.koitharu.kotatsu.core.ui.BaseActivity import org.koitharu.kotatsu.core.ui.BaseActivity
import org.koitharu.kotatsu.core.util.ext.configureForParser import org.koitharu.kotatsu.core.util.ext.configureForParser
import org.koitharu.kotatsu.core.util.ext.consumeInsetsAsPadding
import org.koitharu.kotatsu.databinding.ActivityBrowserBinding import org.koitharu.kotatsu.databinding.ActivityBrowserBinding
import org.koitharu.kotatsu.parsers.network.CloudFlareHelper import org.koitharu.kotatsu.parsers.network.CloudFlareHelper
import javax.inject.Inject import javax.inject.Inject
@@ -58,6 +58,7 @@ class CloudFlareActivity : BaseActivity<ActivityBrowserBinding>(), CloudFlareCal
} }
cfClient = CloudFlareClient(cookieJar, this, url) cfClient = CloudFlareClient(cookieJar, this, url)
viewBinding.webView.configureForParser(intent?.getStringExtra(AppRouter.KEY_USER_AGENT)) viewBinding.webView.configureForParser(intent?.getStringExtra(AppRouter.KEY_USER_AGENT))
viewBinding.webView.consumeInsetsAsPadding(Gravity.START or Gravity.END or Gravity.BOTTOM)
viewBinding.webView.webViewClient = cfClient viewBinding.webView.webViewClient = cfClient
onBackPressedCallback = WebViewBackPressedCallback(viewBinding.webView).also { onBackPressedCallback = WebViewBackPressedCallback(viewBinding.webView).also {
onBackPressedDispatcher.addCallback(it) onBackPressedDispatcher.addCallback(it)
@@ -83,17 +84,6 @@ class CloudFlareActivity : BaseActivity<ActivityBrowserBinding>(), CloudFlareCal
return super.onCreateOptionsMenu(menu) return super.onCreateOptionsMenu(menu)
} }
override fun onWindowInsetsChanged(insets: Insets) {
viewBinding.appbar.updatePadding(
top = insets.top,
)
viewBinding.root.updatePadding(
left = insets.left,
right = insets.right,
bottom = insets.bottom,
)
}
override fun onOptionsItemSelected(item: MenuItem): Boolean = when (item.itemId) { override fun onOptionsItemSelected(item: MenuItem): Boolean = when (item.itemId) {
android.R.id.home -> { android.R.id.home -> {
viewBinding.webView.stopLoading() viewBinding.webView.stopLoading()

View File

@@ -8,13 +8,13 @@ import android.os.Bundle
import android.view.KeyEvent import android.view.KeyEvent
import android.view.View import android.view.View
import android.widget.Toast import android.widget.Toast
import androidx.activity.enableEdgeToEdge
import androidx.annotation.CallSuper import androidx.annotation.CallSuper
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.app.AppCompatDelegate import androidx.appcompat.app.AppCompatDelegate
import androidx.appcompat.view.ActionMode import androidx.appcompat.view.ActionMode
import androidx.appcompat.widget.Toolbar import androidx.appcompat.widget.Toolbar
import androidx.core.app.ActivityCompat import androidx.core.app.ActivityCompat
import androidx.core.view.WindowCompat
import androidx.fragment.app.FragmentManager import androidx.fragment.app.FragmentManager
import androidx.viewbinding.ViewBinding import androidx.viewbinding.ViewBinding
import dagger.hilt.android.EntryPointAccessors import dagger.hilt.android.EntryPointAccessors
@@ -25,15 +25,13 @@ import org.koitharu.kotatsu.R
import org.koitharu.kotatsu.core.exceptions.resolve.ExceptionResolver import org.koitharu.kotatsu.core.exceptions.resolve.ExceptionResolver
import org.koitharu.kotatsu.core.nav.AppRouter import org.koitharu.kotatsu.core.nav.AppRouter
import org.koitharu.kotatsu.core.ui.util.ActionModeDelegate import org.koitharu.kotatsu.core.ui.util.ActionModeDelegate
import org.koitharu.kotatsu.core.ui.util.WindowInsetsDelegate
import org.koitharu.kotatsu.core.util.ext.isWebViewUnavailable import org.koitharu.kotatsu.core.util.ext.isWebViewUnavailable
import org.koitharu.kotatsu.main.ui.protect.ScreenshotPolicyHelper import org.koitharu.kotatsu.main.ui.protect.ScreenshotPolicyHelper
abstract class BaseActivity<B : ViewBinding> : abstract class BaseActivity<B : ViewBinding> :
AppCompatActivity(), AppCompatActivity(),
ExceptionResolver.Host, ExceptionResolver.Host,
ScreenshotPolicyHelper.ContentContainer, ScreenshotPolicyHelper.ContentContainer {
WindowInsetsDelegate.WindowInsetsListener {
private var isAmoledTheme = false private var isAmoledTheme = false
@@ -43,9 +41,6 @@ abstract class BaseActivity<B : ViewBinding> :
protected lateinit var exceptionResolver: ExceptionResolver protected lateinit var exceptionResolver: ExceptionResolver
private set private set
@JvmField
protected val insetsDelegate = WindowInsetsDelegate()
@JvmField @JvmField
val actionModeDelegate = ActionModeDelegate() val actionModeDelegate = ActionModeDelegate()
@@ -68,10 +63,8 @@ abstract class BaseActivity<B : ViewBinding> :
} }
putDataToExtras(intent) putDataToExtras(intent)
exceptionResolver = entryPoint.exceptionResolverFactory.create(this) exceptionResolver = entryPoint.exceptionResolverFactory.create(this)
enableEdgeToEdge()
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
WindowCompat.setDecorFitsSystemWindows(window, false)
insetsDelegate.handleImeInsets = true
insetsDelegate.addInsetsListener(this)
} }
override fun onPostCreate(savedInstanceState: Bundle?) { override fun onPostCreate(savedInstanceState: Bundle?) {
@@ -105,7 +98,6 @@ abstract class BaseActivity<B : ViewBinding> :
super.setContentView(binding.root) super.setContentView(binding.root)
val toolbar = (binding.root.findViewById<View>(R.id.toolbar) as? Toolbar) val toolbar = (binding.root.findViewById<View>(R.id.toolbar) as? Toolbar)
toolbar?.let(this::setSupportActionBar) toolbar?.let(this::setSupportActionBar)
insetsDelegate.onViewCreated(binding.root)
} }
override fun onSupportNavigateUp(): Boolean { override fun onSupportNavigateUp(): Boolean {

View File

@@ -10,12 +10,10 @@ import androidx.viewbinding.ViewBinding
import dagger.hilt.android.EntryPointAccessors import dagger.hilt.android.EntryPointAccessors
import org.koitharu.kotatsu.core.exceptions.resolve.ExceptionResolver import org.koitharu.kotatsu.core.exceptions.resolve.ExceptionResolver
import org.koitharu.kotatsu.core.ui.util.ActionModeDelegate import org.koitharu.kotatsu.core.ui.util.ActionModeDelegate
import org.koitharu.kotatsu.core.ui.util.WindowInsetsDelegate
abstract class BaseFragment<B : ViewBinding> : abstract class BaseFragment<B : ViewBinding> :
Fragment(), Fragment(),
ExceptionResolver.Host, ExceptionResolver.Host {
WindowInsetsDelegate.WindowInsetsListener {
var viewBinding: B? = null var viewBinding: B? = null
private set private set
@@ -23,9 +21,6 @@ abstract class BaseFragment<B : ViewBinding> :
protected lateinit var exceptionResolver: ExceptionResolver protected lateinit var exceptionResolver: ExceptionResolver
private set private set
@JvmField
protected val insetsDelegate = WindowInsetsDelegate()
protected val actionModeDelegate: ActionModeDelegate protected val actionModeDelegate: ActionModeDelegate
get() = (requireActivity() as BaseActivity<*>).actionModeDelegate get() = (requireActivity() as BaseActivity<*>).actionModeDelegate
@@ -47,15 +42,11 @@ abstract class BaseFragment<B : ViewBinding> :
final override fun onViewCreated(view: View, savedInstanceState: Bundle?) { final override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
insetsDelegate.onViewCreated(view)
insetsDelegate.addInsetsListener(this)
onViewBindingCreated(requireViewBinding(), savedInstanceState) onViewBindingCreated(requireViewBinding(), savedInstanceState)
} }
override fun onDestroyView() { override fun onDestroyView() {
viewBinding = null viewBinding = null
insetsDelegate.removeInsetsListener(this)
insetsDelegate.onDestroyView()
super.onDestroyView() super.onDestroyView()
} }

View File

@@ -2,11 +2,9 @@ package org.koitharu.kotatsu.core.ui
import android.content.Context import android.content.Context
import android.os.Bundle import android.os.Bundle
import android.view.Gravity
import android.view.View import android.view.View
import androidx.annotation.CallSuper
import androidx.annotation.StringRes import androidx.annotation.StringRes
import androidx.core.graphics.Insets
import androidx.core.view.updatePadding
import androidx.preference.Preference import androidx.preference.Preference
import androidx.preference.PreferenceFragmentCompat import androidx.preference.PreferenceFragmentCompat
import androidx.preference.PreferenceScreen import androidx.preference.PreferenceScreen
@@ -17,7 +15,7 @@ import dagger.hilt.android.EntryPointAccessors
import org.koitharu.kotatsu.core.exceptions.resolve.ExceptionResolver import org.koitharu.kotatsu.core.exceptions.resolve.ExceptionResolver
import org.koitharu.kotatsu.core.prefs.AppSettings import org.koitharu.kotatsu.core.prefs.AppSettings
import org.koitharu.kotatsu.core.ui.util.RecyclerViewOwner import org.koitharu.kotatsu.core.ui.util.RecyclerViewOwner
import org.koitharu.kotatsu.core.ui.util.WindowInsetsDelegate import org.koitharu.kotatsu.core.util.ext.consumeInsetsAsPadding
import org.koitharu.kotatsu.core.util.ext.getThemeColor import org.koitharu.kotatsu.core.util.ext.getThemeColor
import org.koitharu.kotatsu.core.util.ext.getThemeDrawable import org.koitharu.kotatsu.core.util.ext.getThemeDrawable
import org.koitharu.kotatsu.core.util.ext.parentView import org.koitharu.kotatsu.core.util.ext.parentView
@@ -28,7 +26,6 @@ import com.google.android.material.R as materialR
@AndroidEntryPoint @AndroidEntryPoint
abstract class BasePreferenceFragment(@StringRes private val titleId: Int) : abstract class BasePreferenceFragment(@StringRes private val titleId: Int) :
PreferenceFragmentCompat(), PreferenceFragmentCompat(),
WindowInsetsDelegate.WindowInsetsListener,
RecyclerViewOwner, RecyclerViewOwner,
ExceptionResolver.Host { ExceptionResolver.Host {
@@ -38,9 +35,6 @@ abstract class BasePreferenceFragment(@StringRes private val titleId: Int) :
@Inject @Inject
lateinit var settings: AppSettings lateinit var settings: AppSettings
@JvmField
protected val insetsDelegate = WindowInsetsDelegate()
override val recyclerView: RecyclerView override val recyclerView: RecyclerView
get() = listView get() = listView
@@ -55,14 +49,7 @@ abstract class BasePreferenceFragment(@StringRes private val titleId: Int) :
val themedContext = (view.parentView ?: view).context val themedContext = (view.parentView ?: view).context
view.setBackgroundColor(themedContext.getThemeColor(android.R.attr.colorBackground)) view.setBackgroundColor(themedContext.getThemeColor(android.R.attr.colorBackground))
listView.clipToPadding = false listView.clipToPadding = false
insetsDelegate.onViewCreated(view) listView.consumeInsetsAsPadding(Gravity.BOTTOM or Gravity.START or Gravity.END)
insetsDelegate.addInsetsListener(this)
}
override fun onDestroyView() {
insetsDelegate.removeInsetsListener(this)
insetsDelegate.onDestroyView()
super.onDestroyView()
} }
override fun onResume() { override fun onResume() {
@@ -74,13 +61,6 @@ abstract class BasePreferenceFragment(@StringRes private val titleId: Int) :
} }
} }
@CallSuper
override fun onWindowInsetsChanged(insets: Insets) {
listView.updatePadding(
bottom = insets.bottom,
)
}
protected open fun setTitle(title: CharSequence?) { protected open fun setTitle(title: CharSequence?) {
(activity as? SettingsActivity)?.setSectionTitle(title) (activity as? SettingsActivity)?.setSectionTitle(title)
} }

View File

@@ -1,8 +1,5 @@
package org.koitharu.kotatsu.core.ui.dialog package org.koitharu.kotatsu.core.ui.dialog
import android.content.ClipData
import android.content.ClipboardManager
import android.content.Context
import android.os.Bundle import android.os.Bundle
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.ViewGroup import android.view.ViewGroup
@@ -14,6 +11,7 @@ import com.google.android.material.dialog.MaterialAlertDialogBuilder
import org.koitharu.kotatsu.R import org.koitharu.kotatsu.R
import org.koitharu.kotatsu.core.nav.AppRouter import org.koitharu.kotatsu.core.nav.AppRouter
import org.koitharu.kotatsu.core.ui.AlertDialogFragment import org.koitharu.kotatsu.core.ui.AlertDialogFragment
import org.koitharu.kotatsu.core.util.ext.copyToClipboard
import org.koitharu.kotatsu.core.util.ext.getCauseUrl import org.koitharu.kotatsu.core.util.ext.getCauseUrl
import org.koitharu.kotatsu.core.util.ext.isReportable import org.koitharu.kotatsu.core.util.ext.isReportable
import org.koitharu.kotatsu.core.util.ext.report import org.koitharu.kotatsu.core.util.ext.report
@@ -53,7 +51,7 @@ class ErrorDetailsDialog : AlertDialogFragment<DialogErrorDetailsBinding>() {
.setNegativeButton(android.R.string.cancel, null) .setNegativeButton(android.R.string.cancel, null)
.setTitle(R.string.error_occurred) .setTitle(R.string.error_occurred)
.setNeutralButton(androidx.preference.R.string.copy) { _, _ -> .setNeutralButton(androidx.preference.R.string.copy) { _, _ ->
copyToClipboard() context?.copyToClipboard(getString(R.string.error), exception.stackTraceToString())
} }
if (exception.isReportable()) { if (exception.isReportable()) {
builder.setPositiveButton(R.string.report) { _, _ -> builder.setPositiveButton(R.string.report) { _, _ ->
@@ -63,12 +61,4 @@ class ErrorDetailsDialog : AlertDialogFragment<DialogErrorDetailsBinding>() {
} }
return builder return builder
} }
private fun copyToClipboard() {
val clipboardManager = context?.getSystemService(Context.CLIPBOARD_SERVICE) as? ClipboardManager
?: return
clipboardManager.setPrimaryClip(
ClipData.newPlainText(getString(R.string.error), exception.stackTraceToString()),
)
}
} }

View File

@@ -0,0 +1,39 @@
package org.koitharu.kotatsu.core.ui.util
import android.view.Gravity
import android.view.View
import android.view.ViewGroup
import androidx.annotation.GravityInt
import androidx.core.view.OnApplyWindowInsetsListener
import androidx.core.view.WindowInsetsCompat
import androidx.core.view.updateLayoutParams
import org.koitharu.kotatsu.core.util.ext.consumeRelative
import org.koitharu.kotatsu.core.util.ext.end
import org.koitharu.kotatsu.core.util.ext.start
class InsetsToMarginsListener(
@GravityInt
private val sides: Int,
) : OnApplyWindowInsetsListener {
override fun onApplyWindowInsets(v: View, insets: WindowInsetsCompat): WindowInsetsCompat {
val barsInsets = insets.getInsets(WindowInsetsCompat.Type.systemBars())
v.updateLayoutParams<ViewGroup.MarginLayoutParams> {
if (sides and Gravity.START == Gravity.START) marginStart = barsInsets.start(v)
if (sides and Gravity.TOP == Gravity.TOP) topMargin = barsInsets.top
if (sides and Gravity.END == Gravity.END) marginEnd = barsInsets.end(v)
if (sides and Gravity.BOTTOM == Gravity.BOTTOM) bottomMargin = barsInsets.bottom
}
return WindowInsetsCompat.Builder(insets)
.setInsets(
WindowInsetsCompat.Type.systemBars(),
barsInsets.consumeRelative(
v,
start = sides and Gravity.START == Gravity.START,
top = sides and Gravity.TOP == Gravity.TOP,
end = sides and Gravity.END == Gravity.END,
bottom = sides and Gravity.BOTTOM == Gravity.BOTTOM,
),
).build()
}
}

View File

@@ -0,0 +1,37 @@
package org.koitharu.kotatsu.core.ui.util
import android.view.Gravity
import android.view.View
import androidx.annotation.GravityInt
import androidx.core.view.OnApplyWindowInsetsListener
import androidx.core.view.WindowInsetsCompat
import org.koitharu.kotatsu.core.util.ext.consumeRelative
import org.koitharu.kotatsu.core.util.ext.end
import org.koitharu.kotatsu.core.util.ext.start
class InsetsToPaddingListener(
@GravityInt
private val sides: Int,
) : OnApplyWindowInsetsListener {
override fun onApplyWindowInsets(v: View, insets: WindowInsetsCompat): WindowInsetsCompat {
val barsInsets = insets.getInsets(WindowInsetsCompat.Type.systemBars())
v.setPaddingRelative(
/* start = */ if (sides and Gravity.START == Gravity.START) barsInsets.start(v) else v.paddingStart,
/* top = */ if (sides and Gravity.TOP == Gravity.TOP) barsInsets.top else v.paddingTop,
/* end = */ if (sides and Gravity.END == Gravity.END) barsInsets.end(v) else v.paddingEnd,
/* bottom = */ if (sides and Gravity.BOTTOM == Gravity.BOTTOM) barsInsets.bottom else v.paddingBottom,
)
return WindowInsetsCompat.Builder(insets)
.setInsets(
WindowInsetsCompat.Type.systemBars(),
barsInsets.consumeRelative(
v,
start = sides and Gravity.START == Gravity.START,
top = sides and Gravity.TOP == Gravity.TOP,
end = sides and Gravity.END == Gravity.END,
bottom = sides and Gravity.BOTTOM == Gravity.BOTTOM,
),
).build()
}
}

View File

@@ -1,78 +0,0 @@
package org.koitharu.kotatsu.core.ui.util
import android.view.View
import androidx.core.graphics.Insets
import androidx.core.view.OnApplyWindowInsetsListener
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import java.util.LinkedList
@Deprecated("")
class WindowInsetsDelegate : OnApplyWindowInsetsListener, View.OnLayoutChangeListener {
@JvmField
var handleImeInsets: Boolean = false
@JvmField
var interceptingWindowInsetsListener: OnApplyWindowInsetsListener? = null
private val listeners = LinkedList<WindowInsetsListener>()
private var lastInsets: Insets? = null
override fun onApplyWindowInsets(v: View, insets: WindowInsetsCompat): WindowInsetsCompat {
val handledInsets = interceptingWindowInsetsListener?.onApplyWindowInsets(v, insets) ?: insets
val newInsets = if (handleImeInsets) {
Insets.max(
handledInsets.getInsets(WindowInsetsCompat.Type.systemBars()),
handledInsets.getInsets(WindowInsetsCompat.Type.ime()),
)
} else {
handledInsets.getInsets(WindowInsetsCompat.Type.systemBars())
}
if (newInsets != lastInsets) {
listeners.forEach { it.onWindowInsetsChanged(newInsets) }
lastInsets = newInsets
}
return handledInsets
}
override fun onLayoutChange(
view: View,
left: Int,
top: Int,
right: Int,
bottom: Int,
oldLeft: Int,
oldTop: Int,
oldRight: Int,
oldBottom: Int,
) {
view.removeOnLayoutChangeListener(this)
if (lastInsets == null) { // Listener may not be called
onApplyWindowInsets(view, ViewCompat.getRootWindowInsets(view) ?: return)
}
}
fun addInsetsListener(listener: WindowInsetsListener) {
listeners.add(listener)
lastInsets?.let { listener.onWindowInsetsChanged(it) }
}
fun removeInsetsListener(listener: WindowInsetsListener) {
listeners.remove(listener)
}
fun onViewCreated(view: View) {
ViewCompat.setOnApplyWindowInsetsListener(view, this)
view.addOnLayoutChangeListener(this)
}
fun onDestroyView() {
lastInsets = null
}
fun interface WindowInsetsListener {
fun onWindowInsetsChanged(insets: Insets)
}
}

View File

@@ -6,6 +6,8 @@ import android.app.Activity
import android.app.ActivityManager import android.app.ActivityManager
import android.app.ActivityManager.MemoryInfo import android.app.ActivityManager.MemoryInfo
import android.app.LocaleConfig import android.app.LocaleConfig
import android.content.ClipData
import android.content.ClipboardManager
import android.content.ComponentName import android.content.ComponentName
import android.content.Context import android.content.Context
import android.content.Context.ACTIVITY_SERVICE import android.content.Context.ACTIVITY_SERVICE
@@ -247,3 +249,8 @@ private fun PowerManager?.newPartialWakeLock(tag: String): PowerManager.WakeLock
null null
} }
} }
fun Context.copyToClipboard(label: String, content: String) {
val clipboardManager = getSystemService(Context.CLIPBOARD_SERVICE) as? ClipboardManager ?: return
clipboardManager.setPrimaryClip(ClipData.newPlainText(label, content))
}

View File

@@ -10,3 +10,29 @@ fun Insets.end(view: View): Int {
fun Insets.start(view: View): Int { fun Insets.start(view: View): Int {
return if (view.isRtl) right else left return if (view.isRtl) right else left
} }
fun Insets.consume(
left: Boolean = false,
top: Boolean = false,
right: Boolean = false,
bottom: Boolean = false,
): Insets = Insets.of(
/* left = */ if (left) 0 else this.left,
/* top = */ if (top) 0 else this.top,
/* right = */ if (right) 0 else this.right,
/* bottom = */ if (bottom) 0 else this.bottom,
)
fun Insets.consumeRelative(
view: View,
start: Boolean = false,
top: Boolean = false,
end: Boolean = false,
bottom: Boolean = false,
): Insets = Insets.of(
/* left = */ if (if (view.isRtl) end else start) 0 else this.left,
/* top = */ if (top) 0 else this.top,
/* right = */ if (if (view.isRtl) start else end) 0 else this.right,
/* bottom = */ if (bottom) 0 else this.bottom,
)

View File

@@ -6,8 +6,10 @@ import android.view.View
import android.view.View.MeasureSpec import android.view.View.MeasureSpec
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.Checkable import android.widget.Checkable
import androidx.annotation.GravityInt
import androidx.appcompat.widget.ActionMenuView import androidx.appcompat.widget.ActionMenuView
import androidx.appcompat.widget.Toolbar import androidx.appcompat.widget.Toolbar
import androidx.core.view.ViewCompat
import androidx.core.view.children import androidx.core.view.children
import androidx.core.view.descendants import androidx.core.view.descendants
import androidx.core.view.isVisible import androidx.core.view.isVisible
@@ -22,6 +24,8 @@ import com.google.android.material.slider.RangeSlider
import com.google.android.material.slider.Slider import com.google.android.material.slider.Slider
import com.google.android.material.tabs.TabLayout import com.google.android.material.tabs.TabLayout
import org.koitharu.kotatsu.core.ui.OnContextClickListenerCompat import org.koitharu.kotatsu.core.ui.OnContextClickListenerCompat
import org.koitharu.kotatsu.core.ui.util.InsetsToMarginsListener
import org.koitharu.kotatsu.core.ui.util.InsetsToPaddingListener
import kotlin.math.roundToInt import kotlin.math.roundToInt
fun View.hasGlobalPoint(x: Int, y: Int): Boolean { fun View.hasGlobalPoint(x: Int, y: Int): Boolean {
@@ -182,3 +186,13 @@ fun Chip.setProgressIcon() {
chipIcon = progressDrawable chipIcon = progressDrawable
progressDrawable.start() progressDrawable.start()
} }
fun View.consumeInsetsAsPadding(@GravityInt sides: Int) = ViewCompat.setOnApplyWindowInsetsListener(
this,
InsetsToPaddingListener(sides),
)
fun View.consumeInsetsAsMargins(@GravityInt sides: Int) = ViewCompat.setOnApplyWindowInsetsListener(
this,
InsetsToMarginsListener(sides),
)

View File

@@ -6,17 +6,20 @@ import android.transition.TransitionManager
import android.view.Gravity import android.view.Gravity
import android.view.MenuItem import android.view.MenuItem
import android.view.View import android.view.View
import android.view.ViewGroup.MarginLayoutParams import android.view.ViewGroup
import android.view.ViewTreeObserver import android.view.ViewTreeObserver
import android.widget.Toast import android.widget.Toast
import androidx.activity.viewModels import androidx.activity.viewModels
import androidx.appcompat.widget.PopupMenu import androidx.appcompat.widget.PopupMenu
import androidx.core.graphics.Insets
import androidx.core.text.method.LinkMovementMethodCompat import androidx.core.text.method.LinkMovementMethodCompat
import androidx.core.view.OnApplyWindowInsetsListener
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import androidx.core.view.isGone import androidx.core.view.isGone
import androidx.core.view.isVisible import androidx.core.view.isVisible
import androidx.core.view.updateLayoutParams import androidx.core.view.updateLayoutParams
import androidx.core.view.updatePadding import androidx.core.view.updatePadding
import androidx.core.view.updatePaddingRelative
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
import coil3.ImageLoader import coil3.ImageLoader
import coil3.request.ImageRequest import coil3.request.ImageRequest
@@ -57,6 +60,7 @@ import org.koitharu.kotatsu.core.parser.favicon.faviconUri
import org.koitharu.kotatsu.core.ui.BaseActivity import org.koitharu.kotatsu.core.ui.BaseActivity
import org.koitharu.kotatsu.core.ui.BaseListAdapter import org.koitharu.kotatsu.core.ui.BaseListAdapter
import org.koitharu.kotatsu.core.ui.OnContextClickListenerCompat import org.koitharu.kotatsu.core.ui.OnContextClickListenerCompat
import org.koitharu.kotatsu.core.ui.dialog.buildAlertDialog
import org.koitharu.kotatsu.core.ui.image.CoverSizeResolver import org.koitharu.kotatsu.core.ui.image.CoverSizeResolver
import org.koitharu.kotatsu.core.ui.image.FaviconDrawable import org.koitharu.kotatsu.core.ui.image.FaviconDrawable
import org.koitharu.kotatsu.core.ui.image.TextDrawable import org.koitharu.kotatsu.core.ui.image.TextDrawable
@@ -68,10 +72,13 @@ import org.koitharu.kotatsu.core.ui.util.ReversibleActionObserver
import org.koitharu.kotatsu.core.ui.widgets.ChipsView import org.koitharu.kotatsu.core.ui.widgets.ChipsView
import org.koitharu.kotatsu.core.util.FileSize import org.koitharu.kotatsu.core.util.FileSize
import org.koitharu.kotatsu.core.util.LocaleUtils import org.koitharu.kotatsu.core.util.LocaleUtils
import org.koitharu.kotatsu.core.util.ext.consumeRelative
import org.koitharu.kotatsu.core.util.ext.copyToClipboard
import org.koitharu.kotatsu.core.util.ext.crossfade import org.koitharu.kotatsu.core.util.ext.crossfade
import org.koitharu.kotatsu.core.util.ext.defaultPlaceholders import org.koitharu.kotatsu.core.util.ext.defaultPlaceholders
import org.koitharu.kotatsu.core.util.ext.drawable import org.koitharu.kotatsu.core.util.ext.drawable
import org.koitharu.kotatsu.core.util.ext.drawableStart import org.koitharu.kotatsu.core.util.ext.drawableStart
import org.koitharu.kotatsu.core.util.ext.end
import org.koitharu.kotatsu.core.util.ext.enqueueWith import org.koitharu.kotatsu.core.util.ext.enqueueWith
import org.koitharu.kotatsu.core.util.ext.getQuantityStringSafe import org.koitharu.kotatsu.core.util.ext.getQuantityStringSafe
import org.koitharu.kotatsu.core.util.ext.isTextTruncated import org.koitharu.kotatsu.core.util.ext.isTextTruncated
@@ -80,6 +87,7 @@ import org.koitharu.kotatsu.core.util.ext.mangaSourceExtra
import org.koitharu.kotatsu.core.util.ext.observe import org.koitharu.kotatsu.core.util.ext.observe
import org.koitharu.kotatsu.core.util.ext.observeEvent import org.koitharu.kotatsu.core.util.ext.observeEvent
import org.koitharu.kotatsu.core.util.ext.parentView import org.koitharu.kotatsu.core.util.ext.parentView
import org.koitharu.kotatsu.core.util.ext.start
import org.koitharu.kotatsu.core.util.ext.textAndVisible import org.koitharu.kotatsu.core.util.ext.textAndVisible
import org.koitharu.kotatsu.databinding.ActivityDetailsBinding import org.koitharu.kotatsu.databinding.ActivityDetailsBinding
import org.koitharu.kotatsu.databinding.LayoutDetailsTableBinding import org.koitharu.kotatsu.databinding.LayoutDetailsTableBinding
@@ -101,6 +109,7 @@ import org.koitharu.kotatsu.list.ui.size.StaticItemSizeResolver
import org.koitharu.kotatsu.parsers.model.Manga import org.koitharu.kotatsu.parsers.model.Manga
import org.koitharu.kotatsu.parsers.model.MangaTag import org.koitharu.kotatsu.parsers.model.MangaTag
import org.koitharu.kotatsu.parsers.util.ifNullOrEmpty import org.koitharu.kotatsu.parsers.util.ifNullOrEmpty
import org.koitharu.kotatsu.parsers.util.nullIfEmpty
import org.koitharu.kotatsu.scrobbling.common.domain.model.ScrobblingInfo import org.koitharu.kotatsu.scrobbling.common.domain.model.ScrobblingInfo
import org.koitharu.kotatsu.search.domain.SearchKind import org.koitharu.kotatsu.search.domain.SearchKind
import javax.inject.Inject import javax.inject.Inject
@@ -110,7 +119,7 @@ import com.google.android.material.R as materialR
@AndroidEntryPoint @AndroidEntryPoint
class DetailsActivity : class DetailsActivity :
BaseActivity<ActivityDetailsBinding>(), BaseActivity<ActivityDetailsBinding>(),
View.OnClickListener, View.OnClickListener, OnApplyWindowInsetsListener,
View.OnLongClickListener, PopupMenu.OnMenuItemClickListener, View.OnLayoutChangeListener, View.OnLongClickListener, PopupMenu.OnMenuItemClickListener, View.OnLayoutChangeListener,
ViewTreeObserver.OnDrawListener, ChipsView.OnChipClickListener, OnListItemClickListener<Bookmark>, ViewTreeObserver.OnDrawListener, ChipsView.OnChipClickListener, OnListItemClickListener<Bookmark>,
OnContextClickListenerCompat, SwipeRefreshLayout.OnRefreshListener { OnContextClickListenerCompat, SwipeRefreshLayout.OnRefreshListener {
@@ -141,6 +150,7 @@ class DetailsActivity :
infoBinding.textViewAuthor.setOnClickListener(this) infoBinding.textViewAuthor.setOnClickListener(this)
infoBinding.textViewSource.setOnClickListener(this) infoBinding.textViewSource.setOnClickListener(this)
viewBinding.imageViewCover.setOnClickListener(this) viewBinding.imageViewCover.setOnClickListener(this)
viewBinding.textViewTitle.setOnClickListener(this)
viewBinding.buttonDescriptionMore.setOnClickListener(this) viewBinding.buttonDescriptionMore.setOnClickListener(this)
viewBinding.buttonScrobblingMore.setOnClickListener(this) viewBinding.buttonScrobblingMore.setOnClickListener(this)
viewBinding.buttonRelatedMore.setOnClickListener(this) viewBinding.buttonRelatedMore.setOnClickListener(this)
@@ -151,12 +161,13 @@ class DetailsActivity :
viewBinding.chipsTags.onChipClickListener = this viewBinding.chipsTags.onChipClickListener = this
TitleScrollCoordinator(viewBinding.textViewTitle).attach(viewBinding.scrollView) TitleScrollCoordinator(viewBinding.textViewTitle).attach(viewBinding.scrollView)
viewBinding.containerBottomSheet?.let { sheet -> viewBinding.containerBottomSheet?.let { sheet ->
sheet.addOnLayoutChangeListener(this)
onBackPressedDispatcher.addCallback(BottomSheetCollapseCallback(sheet)) onBackPressedDispatcher.addCallback(BottomSheetCollapseCallback(sheet))
BottomSheetBehavior.from(sheet).addBottomSheetCallback( BottomSheetBehavior.from(sheet).addBottomSheetCallback(
DetailsBottomSheetCallback(viewBinding.swipeRefreshLayout, checkNotNull(viewBinding.navbarDim)), DetailsBottomSheetCallback(viewBinding.swipeRefreshLayout, checkNotNull(viewBinding.navbarDim)),
) )
} }
TitleExpandListener(viewBinding.textViewTitle).attach() ViewCompat.setOnApplyWindowInsetsListener(viewBinding.root, this)
val appRouter = router val appRouter = router
viewModel.mangaDetails.filterNotNull().observe(this, ::onMangaUpdated) viewModel.mangaDetails.filterNotNull().observe(this, ::onMangaUpdated)
@@ -253,6 +264,17 @@ class DetailsActivity :
val manga = viewModel.manga.value ?: return val manga = viewModel.manga.value ?: return
router.openRelated(manga) router.openRelated(manga)
} }
R.id.textView_title -> {
val title = viewModel.manga.value?.title?.nullIfEmpty() ?: return
buildAlertDialog(this) {
setMessage(title)
setNegativeButton(R.string.close, null)
setPositiveButton(androidx.preference.R.string.copy) { _, _ ->
copyToClipboard(getString(R.string.content_type_manga), title)
}
}.show()
}
} }
} }
@@ -324,6 +346,38 @@ class DetailsActivity :
) { ) {
with(viewBinding) { with(viewBinding) {
buttonDescriptionMore.isVisible = textViewDescription.isTextTruncated buttonDescriptionMore.isVisible = textViewDescription.isTextTruncated
containerBottomSheet?.let { sheet ->
val peekHeight = BottomSheetBehavior.from(sheet).peekHeight
if (scrollView.paddingBottom != peekHeight) {
scrollView.updatePadding(bottom = peekHeight)
}
}
}
}
override fun onApplyWindowInsets(v: View, insets: WindowInsetsCompat): WindowInsetsCompat {
val barsInsets = insets.getInsets(WindowInsetsCompat.Type.systemBars())
if (viewBinding.cardChapters != null) {
// landscape
viewBinding.cardChapters?.updateLayoutParams<ViewGroup.MarginLayoutParams> {
topMargin = barsInsets.top + resources.getDimensionPixelOffset(R.dimen.grid_spacing_outer)
marginEnd = barsInsets.end(v) + resources.getDimensionPixelOffset(R.dimen.side_card_offset)
bottomMargin = barsInsets.bottom + resources.getDimensionPixelOffset(R.dimen.side_card_offset)
}
viewBinding.scrollView.updatePaddingRelative(
bottom = barsInsets.bottom,
start = barsInsets.start(v),
)
viewBinding.appbar.updatePaddingRelative(
start = barsInsets.start(v),
)
return WindowInsetsCompat.Builder(insets)
.setInsets(
WindowInsetsCompat.Type.systemBars(),
barsInsets.consumeRelative(v, end = true, bottom = true),
).build()
} else {
return insets
} }
} }
@@ -452,21 +506,6 @@ class DetailsActivity :
finishAfterTransition() finishAfterTransition()
} }
override fun onWindowInsetsChanged(insets: Insets) {
viewBinding.root.updatePadding(
left = insets.left,
right = insets.right,
)
viewBinding.cardChapters?.updateLayoutParams<MarginLayoutParams> {
val baseOffset = leftMargin
bottomMargin = insets.bottom + baseOffset
topMargin = insets.bottom + baseOffset
}
viewBinding.scrollView.updatePadding(
bottom = insets.bottom,
)
}
private fun onHistoryChanged(info: HistoryInfo, isLoading: Boolean) = with(infoBinding) { private fun onHistoryChanged(info: HistoryInfo, isLoading: Boolean) = with(infoBinding) {
textViewChapters.text = when { textViewChapters.text = when {
isLoading -> getString(R.string.loading_) isLoading -> getString(R.string.loading_)

View File

@@ -1,45 +0,0 @@
package org.koitharu.kotatsu.details.ui
import android.annotation.SuppressLint
import android.transition.TransitionManager
import android.view.GestureDetector
import android.view.MotionEvent
import android.view.View
import android.view.View.OnTouchListener
import android.view.ViewGroup
import org.koitharu.kotatsu.R
import org.koitharu.kotatsu.core.ui.widgets.SelectableTextView
import org.koitharu.kotatsu.core.util.ext.isAnimationsEnabled
@SuppressLint("ClickableViewAccessibility")
class TitleExpandListener(
private val textView: SelectableTextView,
) : GestureDetector.SimpleOnGestureListener(), OnTouchListener {
private val gestureDetector = GestureDetector(textView.context, this)
private val linesExpanded = textView.resources.getInteger(R.integer.details_description_lines)
private val linesCollapsed = textView.resources.getInteger(R.integer.details_title_lines)
override fun onTouch(v: View?, event: MotionEvent) = gestureDetector.onTouchEvent(event)
override fun onSingleTapConfirmed(e: MotionEvent): Boolean {
if (textView.context.isAnimationsEnabled) {
TransitionManager.beginDelayedTransition(textView.parent as ViewGroup)
}
if (textView.maxLines in 1 until Integer.MAX_VALUE) {
textView.maxLines = Integer.MAX_VALUE
} else {
textView.maxLines = linesCollapsed
}
return true
}
override fun onLongPress(e: MotionEvent) {
textView.maxLines = Integer.MAX_VALUE
textView.selectAll()
}
fun attach() {
textView.setOnTouchListener(this)
}
}

View File

@@ -1,6 +1,7 @@
package org.koitharu.kotatsu.details.ui.pager.bookmarks package org.koitharu.kotatsu.details.ui.pager.bookmarks
import android.os.Bundle import android.os.Bundle
import android.view.Gravity
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.Menu import android.view.Menu
import android.view.MenuInflater import android.view.MenuInflater
@@ -8,8 +9,6 @@ import android.view.MenuItem
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.appcompat.view.ActionMode import androidx.appcompat.view.ActionMode
import androidx.core.graphics.Insets
import androidx.core.view.updatePadding
import androidx.fragment.app.viewModels import androidx.fragment.app.viewModels
import androidx.recyclerview.widget.GridLayoutManager import androidx.recyclerview.widget.GridLayoutManager
import coil3.ImageLoader import coil3.ImageLoader
@@ -28,6 +27,7 @@ import org.koitharu.kotatsu.core.ui.list.ListSelectionController
import org.koitharu.kotatsu.core.ui.list.OnListItemClickListener import org.koitharu.kotatsu.core.ui.list.OnListItemClickListener
import org.koitharu.kotatsu.core.ui.util.PagerNestedScrollHelper import org.koitharu.kotatsu.core.ui.util.PagerNestedScrollHelper
import org.koitharu.kotatsu.core.ui.util.ReversibleActionObserver import org.koitharu.kotatsu.core.ui.util.ReversibleActionObserver
import org.koitharu.kotatsu.core.util.ext.consumeInsetsAsPadding
import org.koitharu.kotatsu.core.util.ext.findAppCompatDelegate import org.koitharu.kotatsu.core.util.ext.findAppCompatDelegate
import org.koitharu.kotatsu.core.util.ext.findParentCallback import org.koitharu.kotatsu.core.util.ext.findParentCallback
import org.koitharu.kotatsu.core.util.ext.observe import org.koitharu.kotatsu.core.util.ext.observe
@@ -42,7 +42,8 @@ import javax.inject.Inject
@AndroidEntryPoint @AndroidEntryPoint
class BookmarksFragment : BaseFragment<FragmentMangaBookmarksBinding>(), class BookmarksFragment : BaseFragment<FragmentMangaBookmarksBinding>(),
OnListItemClickListener<Bookmark>, ListSelectionController.Callback { OnListItemClickListener<Bookmark>,
ListSelectionController.Callback {
private val activityViewModel by ChaptersPagesViewModel.ActivityVMLazy(this) private val activityViewModel by ChaptersPagesViewModel.ActivityVMLazy(this)
private val viewModel by viewModels<BookmarksViewModel>() private val viewModel by viewModels<BookmarksViewModel>()
@@ -87,6 +88,7 @@ class BookmarksFragment : BaseFragment<FragmentMangaBookmarksBinding>(),
headerClickListener = null, headerClickListener = null,
) )
viewModel.gridScale.observe(viewLifecycleOwner, ::onGridScaleChanged) // before rv initialization viewModel.gridScale.observe(viewLifecycleOwner, ::onGridScaleChanged) // before rv initialization
binding.recyclerView.consumeInsetsAsPadding(Gravity.START or Gravity.BOTTOM or Gravity.END)
with(binding.recyclerView) { with(binding.recyclerView) {
addItemDecoration(TypedListSpacingDecoration(context, false)) addItemDecoration(TypedListSpacingDecoration(context, false))
setHasFixedSize(true) setHasFixedSize(true)
@@ -116,14 +118,6 @@ class BookmarksFragment : BaseFragment<FragmentMangaBookmarksBinding>(),
super.onDestroyView() super.onDestroyView()
} }
override fun onWindowInsetsChanged(insets: Insets) {
with (viewBinding ?: return) {
recyclerView.updatePadding(
bottom = insets.bottom
)
}
}
override fun onItemClick(item: Bookmark, view: View) { override fun onItemClick(item: Bookmark, view: View) {
if (selectionController?.onItemClick(item.pageId) == true) { if (selectionController?.onItemClick(item.pageId) == true) {
return return

View File

@@ -4,7 +4,9 @@ import android.os.Bundle
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.core.graphics.Insets import androidx.core.view.OnApplyWindowInsetsListener
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import androidx.core.view.isGone import androidx.core.view.isGone
import androidx.core.view.isVisible import androidx.core.view.isVisible
import androidx.core.view.updatePadding import androidx.core.view.updatePadding
@@ -44,7 +46,9 @@ import kotlin.math.roundToInt
@AndroidEntryPoint @AndroidEntryPoint
class ChaptersFragment : class ChaptersFragment :
BaseFragment<FragmentChaptersBinding>(), BaseFragment<FragmentChaptersBinding>(),
OnListItemClickListener<ChapterListItem>, ChipsView.OnChipClickListener { OnListItemClickListener<ChapterListItem>,
OnApplyWindowInsetsListener,
ChipsView.OnChipClickListener {
private val viewModel by ChaptersPagesViewModel.ActivityVMLazy(this) private val viewModel by ChaptersPagesViewModel.ActivityVMLazy(this)
@@ -74,6 +78,7 @@ class ChaptersFragment :
LinearLayoutManager(context) LinearLayoutManager(context)
} }
} }
ViewCompat.setOnApplyWindowInsetsListener(binding.root, this)
with(binding.recyclerViewChapters) { with(binding.recyclerViewChapters) {
addItemDecoration(TypedListSpacingDecoration(context, true)) addItemDecoration(TypedListSpacingDecoration(context, true))
checkNotNull(selectionController).attachToRecyclerView(this) checkNotNull(selectionController).attachToRecyclerView(this)
@@ -130,12 +135,23 @@ class ChaptersFragment :
viewModel.setSelectedBranch(data.titleText) viewModel.setSelectedBranch(data.titleText)
} }
override fun onWindowInsetsChanged(insets: Insets) { override fun onApplyWindowInsets(
with (viewBinding ?: return) { v: View,
insets: WindowInsetsCompat
): WindowInsetsCompat {
viewBinding?.run {
val bars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
recyclerViewChapters.updatePadding( recyclerViewChapters.updatePadding(
bottom = insets.bottom left = bars.left,
right = bars.right,
bottom = bars.bottom,
)
chipsFilter.updatePadding(
left = bars.left,
right = bars.right,
) )
} }
return WindowInsetsCompat.CONSUMED
} }
private fun onChaptersChanged(list: List<ListModel>) { private fun onChaptersChanged(list: List<ListModel>) {

View File

@@ -1,6 +1,7 @@
package org.koitharu.kotatsu.details.ui.pager.pages package org.koitharu.kotatsu.details.ui.pager.pages
import android.os.Bundle import android.os.Bundle
import android.view.Gravity
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.Menu import android.view.Menu
import android.view.MenuInflater import android.view.MenuInflater
@@ -9,10 +10,8 @@ import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.appcompat.view.ActionMode import androidx.appcompat.view.ActionMode
import androidx.collection.ArraySet import androidx.collection.ArraySet
import androidx.core.graphics.Insets
import androidx.core.view.isInvisible import androidx.core.view.isInvisible
import androidx.core.view.isVisible import androidx.core.view.isVisible
import androidx.core.view.updatePadding
import androidx.fragment.app.viewModels import androidx.fragment.app.viewModels
import androidx.recyclerview.widget.GridLayoutManager import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
@@ -33,6 +32,7 @@ import org.koitharu.kotatsu.core.ui.list.ListSelectionController
import org.koitharu.kotatsu.core.ui.list.OnListItemClickListener import org.koitharu.kotatsu.core.ui.list.OnListItemClickListener
import org.koitharu.kotatsu.core.ui.util.PagerNestedScrollHelper import org.koitharu.kotatsu.core.ui.util.PagerNestedScrollHelper
import org.koitharu.kotatsu.core.util.RecyclerViewScrollCallback import org.koitharu.kotatsu.core.util.RecyclerViewScrollCallback
import org.koitharu.kotatsu.core.util.ext.consumeInsetsAsPadding
import org.koitharu.kotatsu.core.util.ext.findAppCompatDelegate import org.koitharu.kotatsu.core.util.ext.findAppCompatDelegate
import org.koitharu.kotatsu.core.util.ext.findParentCallback import org.koitharu.kotatsu.core.util.ext.findParentCallback
import org.koitharu.kotatsu.core.util.ext.observe import org.koitharu.kotatsu.core.util.ext.observe
@@ -54,7 +54,8 @@ import kotlin.math.roundToInt
@AndroidEntryPoint @AndroidEntryPoint
class PagesFragment : class PagesFragment :
BaseFragment<FragmentPagesBinding>(), BaseFragment<FragmentPagesBinding>(),
OnListItemClickListener<PageThumbnail>, ListSelectionController.Callback { OnListItemClickListener<PageThumbnail>,
ListSelectionController.Callback {
@Inject @Inject
lateinit var coil: ImageLoader lateinit var coil: ImageLoader
@@ -112,6 +113,7 @@ class PagesFragment :
clickListener = this@PagesFragment, clickListener = this@PagesFragment,
) )
viewModel.gridScale.observe(viewLifecycleOwner, ::onGridScaleChanged) // before rv initialization viewModel.gridScale.observe(viewLifecycleOwner, ::onGridScaleChanged) // before rv initialization
binding.recyclerView.consumeInsetsAsPadding(Gravity.START or Gravity.BOTTOM or Gravity.END)
with(binding.recyclerView) { with(binding.recyclerView) {
addItemDecoration(TypedListSpacingDecoration(context, false)) addItemDecoration(TypedListSpacingDecoration(context, false))
checkNotNull(selectionController).attachToRecyclerView(this) checkNotNull(selectionController).attachToRecyclerView(this)
@@ -143,14 +145,6 @@ class PagesFragment :
super.onDestroyView() super.onDestroyView()
} }
override fun onWindowInsetsChanged(insets: Insets) {
with (viewBinding ?: return) {
recyclerView.updatePadding(
bottom = insets.bottom
)
}
}
override fun onItemClick(item: PageThumbnail, view: View) { override fun onItemClick(item: PageThumbnail, view: View) {
if (selectionController?.onItemClick(item.page.id) == true) { if (selectionController?.onItemClick(item.page.id) == true) {
return return

View File

@@ -1,8 +1,6 @@
package org.koitharu.kotatsu.details.ui.related package org.koitharu.kotatsu.details.ui.related
import android.os.Bundle import android.os.Bundle
import androidx.core.graphics.Insets
import androidx.core.view.updatePadding
import androidx.fragment.app.commit import androidx.fragment.app.commit
import com.google.android.material.appbar.AppBarLayout import com.google.android.material.appbar.AppBarLayout
import dagger.hilt.android.AndroidEntryPoint import dagger.hilt.android.AndroidEntryPoint
@@ -29,11 +27,4 @@ class RelatedMangaActivity : BaseActivity<ActivityContainerBinding>(), AppBarOwn
} }
} }
} }
override fun onWindowInsetsChanged(insets: Insets) {
viewBinding.root.updatePadding(
left = insets.left,
right = insets.right,
)
}
} }

View File

@@ -1,14 +1,13 @@
package org.koitharu.kotatsu.download.ui.list package org.koitharu.kotatsu.download.ui.list
import android.os.Bundle import android.os.Bundle
import android.view.Gravity
import android.view.Menu import android.view.Menu
import android.view.MenuInflater import android.view.MenuInflater
import android.view.MenuItem import android.view.MenuItem
import android.view.View import android.view.View
import androidx.activity.viewModels import androidx.activity.viewModels
import androidx.appcompat.view.ActionMode import androidx.appcompat.view.ActionMode
import androidx.core.graphics.Insets
import androidx.core.view.updatePadding
import coil3.ImageLoader import coil3.ImageLoader
import dagger.hilt.android.AndroidEntryPoint import dagger.hilt.android.AndroidEntryPoint
import org.koitharu.kotatsu.R import org.koitharu.kotatsu.R
@@ -18,6 +17,7 @@ import org.koitharu.kotatsu.core.ui.list.ListSelectionController
import org.koitharu.kotatsu.core.ui.list.RecyclerScrollKeeper import org.koitharu.kotatsu.core.ui.list.RecyclerScrollKeeper
import org.koitharu.kotatsu.core.ui.util.MenuInvalidator import org.koitharu.kotatsu.core.ui.util.MenuInvalidator
import org.koitharu.kotatsu.core.ui.util.ReversibleActionObserver import org.koitharu.kotatsu.core.ui.util.ReversibleActionObserver
import org.koitharu.kotatsu.core.util.ext.consumeInsetsAsPadding
import org.koitharu.kotatsu.core.util.ext.observe import org.koitharu.kotatsu.core.util.ext.observe
import org.koitharu.kotatsu.core.util.ext.observeEvent import org.koitharu.kotatsu.core.util.ext.observeEvent
import org.koitharu.kotatsu.databinding.ActivityDownloadsBinding import org.koitharu.kotatsu.databinding.ActivityDownloadsBinding
@@ -52,6 +52,7 @@ class DownloadsActivity : BaseActivity<ActivityDownloadsBinding>(),
callback = this, callback = this,
) )
with(viewBinding.recyclerView) { with(viewBinding.recyclerView) {
consumeInsetsAsPadding(Gravity.START or Gravity.END or Gravity.BOTTOM)
setHasFixedSize(true) setHasFixedSize(true)
addItemDecoration(decoration) addItemDecoration(decoration)
adapter = downloadsAdapter adapter = downloadsAdapter
@@ -67,19 +68,6 @@ class DownloadsActivity : BaseActivity<ActivityDownloadsBinding>(),
viewModel.hasCancellableWorks.observe(this, menuInvalidator) viewModel.hasCancellableWorks.observe(this, menuInvalidator)
} }
override fun onWindowInsetsChanged(insets: Insets) {
val rv = viewBinding.recyclerView
rv.updatePadding(
left = insets.left + rv.paddingTop,
right = insets.right + rv.paddingTop,
bottom = insets.bottom,
)
viewBinding.toolbar.updatePadding(
left = insets.left,
right = insets.right,
)
}
override fun onItemClick(item: DownloadItemModel, view: View) { override fun onItemClick(item: DownloadItemModel, view: View) {
if (selectionController.onItemClick(item.id.mostSignificantBits)) { if (selectionController.onItemClick(item.id.mostSignificantBits)) {
return return

View File

@@ -5,6 +5,7 @@ import android.content.Intent
import android.net.Uri import android.net.Uri
import android.os.Build import android.os.Build
import android.os.Bundle import android.os.Bundle
import android.view.Gravity
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.Menu import android.view.Menu
import android.view.MenuInflater import android.view.MenuInflater
@@ -12,8 +13,6 @@ import android.view.MenuItem
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.appcompat.view.ActionMode import androidx.appcompat.view.ActionMode
import androidx.core.graphics.Insets
import androidx.core.view.updatePadding
import androidx.fragment.app.viewModels import androidx.fragment.app.viewModels
import androidx.recyclerview.widget.GridLayoutManager import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
@@ -33,6 +32,7 @@ import org.koitharu.kotatsu.core.ui.util.RecyclerViewOwner
import org.koitharu.kotatsu.core.ui.util.ReversibleActionObserver import org.koitharu.kotatsu.core.ui.util.ReversibleActionObserver
import org.koitharu.kotatsu.core.ui.util.SpanSizeResolver import org.koitharu.kotatsu.core.ui.util.SpanSizeResolver
import org.koitharu.kotatsu.core.util.ext.addMenuProvider import org.koitharu.kotatsu.core.util.ext.addMenuProvider
import org.koitharu.kotatsu.core.util.ext.consumeInsetsAsPadding
import org.koitharu.kotatsu.core.util.ext.findAppCompatDelegate import org.koitharu.kotatsu.core.util.ext.findAppCompatDelegate
import org.koitharu.kotatsu.core.util.ext.observe import org.koitharu.kotatsu.core.util.ext.observe
import org.koitharu.kotatsu.core.util.ext.observeEvent import org.koitharu.kotatsu.core.util.ext.observeEvent
@@ -79,6 +79,7 @@ class ExploreFragment :
callback = this, callback = this,
) )
with(binding.recyclerView) { with(binding.recyclerView) {
consumeInsetsAsPadding(Gravity.BOTTOM or Gravity.START or Gravity.END)
adapter = exploreAdapter adapter = exploreAdapter
setHasFixedSize(true) setHasFixedSize(true)
SpanSizeResolver(this, resources.getDimensionPixelSize(R.dimen.explore_grid_width)).attach() SpanSizeResolver(this, resources.getDimensionPixelSize(R.dimen.explore_grid_width)).attach()
@@ -102,13 +103,6 @@ class ExploreFragment :
exploreAdapter = null exploreAdapter = null
} }
override fun onWindowInsetsChanged(insets: Insets) {
val rv = requireViewBinding().recyclerView
rv.updatePadding(
bottom = insets.bottom + rv.paddingTop,
)
}
override fun onListHeaderClick(item: ListHeader, view: View) { override fun onListHeaderClick(item: ListHeader, view: View) {
if (item.payload == R.id.nav_suggestions) { if (item.payload == R.id.nav_suggestions) {
router.openSuggestions() router.openSuggestions()

View File

@@ -1,8 +1,6 @@
package org.koitharu.kotatsu.favourites.ui package org.koitharu.kotatsu.favourites.ui
import android.os.Bundle import android.os.Bundle
import androidx.core.graphics.Insets
import androidx.core.view.updatePadding
import androidx.fragment.app.commit import androidx.fragment.app.commit
import dagger.hilt.android.AndroidEntryPoint import dagger.hilt.android.AndroidEntryPoint
import org.koitharu.kotatsu.R import org.koitharu.kotatsu.R
@@ -32,11 +30,4 @@ class FavouritesActivity : BaseActivity<ActivityContainerBinding>() {
} }
} }
} }
override fun onWindowInsetsChanged(insets: Insets) {
viewBinding.root.updatePadding(
left = insets.left,
right = insets.right,
)
}
} }

View File

@@ -1,13 +1,10 @@
package org.koitharu.kotatsu.favourites.ui.categories package org.koitharu.kotatsu.favourites.ui.categories
import android.os.Bundle import android.os.Bundle
import android.view.Gravity
import android.view.View import android.view.View
import android.view.ViewGroup
import androidx.activity.viewModels import androidx.activity.viewModels
import androidx.appcompat.view.ActionMode import androidx.appcompat.view.ActionMode
import androidx.core.graphics.Insets
import androidx.core.view.updateLayoutParams
import androidx.core.view.updatePadding
import androidx.recyclerview.widget.ItemTouchHelper import androidx.recyclerview.widget.ItemTouchHelper
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import coil3.ImageLoader import coil3.ImageLoader
@@ -18,6 +15,7 @@ import org.koitharu.kotatsu.core.model.FavouriteCategory
import org.koitharu.kotatsu.core.nav.router import org.koitharu.kotatsu.core.nav.router
import org.koitharu.kotatsu.core.ui.BaseActivity import org.koitharu.kotatsu.core.ui.BaseActivity
import org.koitharu.kotatsu.core.ui.list.ListSelectionController import org.koitharu.kotatsu.core.ui.list.ListSelectionController
import org.koitharu.kotatsu.core.util.ext.consumeInsetsAsPadding
import org.koitharu.kotatsu.core.util.ext.observe import org.koitharu.kotatsu.core.util.ext.observe
import org.koitharu.kotatsu.core.util.ext.observeEvent import org.koitharu.kotatsu.core.util.ext.observeEvent
import org.koitharu.kotatsu.databinding.ActivityCategoriesBinding import org.koitharu.kotatsu.databinding.ActivityCategoriesBinding
@@ -55,6 +53,7 @@ class FavouriteCategoriesActivity :
callback = CategoriesSelectionCallback(viewBinding.recyclerView, viewModel), callback = CategoriesSelectionCallback(viewBinding.recyclerView, viewModel),
) )
selectionController.attachToRecyclerView(viewBinding.recyclerView) selectionController.attachToRecyclerView(viewBinding.recyclerView)
viewBinding.recyclerView.consumeInsetsAsPadding(Gravity.START or Gravity.END or Gravity.BOTTOM)
viewBinding.recyclerView.setHasFixedSize(true) viewBinding.recyclerView.setHasFixedSize(true)
viewBinding.recyclerView.adapter = adapter viewBinding.recyclerView.adapter = adapter
viewBinding.recyclerView.addItemDecoration(TypedListSpacingDecoration(this, false)) viewBinding.recyclerView.addItemDecoration(TypedListSpacingDecoration(this, false))
@@ -127,21 +126,6 @@ class FavouriteCategoriesActivity :
override fun onEmptyActionClick() = Unit override fun onEmptyActionClick() = Unit
override fun onWindowInsetsChanged(insets: Insets) {
viewBinding.fabAdd.updateLayoutParams<ViewGroup.MarginLayoutParams> {
rightMargin = topMargin + insets.right
leftMargin = topMargin + insets.left
bottomMargin = topMargin + insets.bottom
}
viewBinding.root.updatePadding(
left = insets.left,
right = insets.right,
)
viewBinding.recyclerView.updatePadding(
bottom = insets.bottom + viewBinding.recyclerView.paddingTop,
)
}
private suspend fun onCategoriesChanged(categories: List<ListModel>) { private suspend fun onCategoriesChanged(categories: List<ListModel>) {
adapter.emit(categories) adapter.emit(categories)
invalidateOptionsMenu() invalidateOptionsMenu()

View File

@@ -4,15 +4,11 @@ import android.content.Context
import android.os.Bundle import android.os.Bundle
import android.text.Editable import android.text.Editable
import android.view.View import android.view.View
import android.view.ViewGroup
import android.widget.AdapterView import android.widget.AdapterView
import android.widget.ArrayAdapter import android.widget.ArrayAdapter
import android.widget.Filter import android.widget.Filter
import androidx.activity.viewModels import androidx.activity.viewModels
import androidx.core.graphics.Insets
import androidx.core.view.isVisible import androidx.core.view.isVisible
import androidx.core.view.updateLayoutParams
import androidx.core.view.updatePadding
import dagger.hilt.android.AndroidEntryPoint import dagger.hilt.android.AndroidEntryPoint
import org.koitharu.kotatsu.R import org.koitharu.kotatsu.R
import org.koitharu.kotatsu.core.model.FavouriteCategory import org.koitharu.kotatsu.core.model.FavouriteCategory
@@ -87,19 +83,6 @@ class FavouritesCategoryEditActivity :
viewBinding.buttonDone.isEnabled = !s.isNullOrBlank() viewBinding.buttonDone.isEnabled = !s.isNullOrBlank()
} }
override fun onWindowInsetsChanged(insets: Insets) {
viewBinding.root.updatePadding(
left = insets.left,
right = insets.right,
)
viewBinding.scrollView.updatePadding(
bottom = insets.bottom,
)
viewBinding.toolbar.updateLayoutParams<ViewGroup.MarginLayoutParams> {
topMargin = insets.top
}
}
override fun onItemClick(parent: AdapterView<*>?, view: View?, position: Int, id: Long) { override fun onItemClick(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
selectedSortOrder = sortOrders.getOrNull(position) selectedSortOrder = sortOrders.getOrNull(position)
} }

View File

@@ -6,10 +6,8 @@ import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.view.ViewStub import android.view.ViewStub
import androidx.appcompat.view.ActionMode import androidx.appcompat.view.ActionMode
import androidx.core.graphics.Insets
import androidx.core.view.isGone import androidx.core.view.isGone
import androidx.core.view.isVisible import androidx.core.view.isVisible
import androidx.core.view.updatePadding
import androidx.fragment.app.viewModels import androidx.fragment.app.viewModels
import coil3.ImageLoader import coil3.ImageLoader
import com.google.android.material.tabs.TabLayoutMediator import com.google.android.material.tabs.TabLayoutMediator
@@ -69,13 +67,6 @@ class FavouritesContainerFragment : BaseFragment<FragmentFavouritesContainerBind
super.onDestroyView() super.onDestroyView()
} }
override fun onWindowInsetsChanged(insets: Insets) {
viewBinding?.tabs?.updatePadding(
left = insets.left,
right = insets.right,
)
}
override fun onActionModeStarted(mode: ActionMode) { override fun onActionModeStarted(mode: ActionMode) {
viewBinding?.run { viewBinding?.run {
pager.isUserInputEnabled = false pager.isUserInputEnabled = false

View File

@@ -3,7 +3,6 @@ package org.koitharu.kotatsu.filter.ui
import android.os.Bundle import android.os.Bundle
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.ViewGroup import android.view.ViewGroup
import androidx.core.graphics.Insets
import androidx.core.view.isVisible import androidx.core.view.isVisible
import com.google.android.material.chip.Chip import com.google.android.material.chip.Chip
import dagger.hilt.android.AndroidEntryPoint import dagger.hilt.android.AndroidEntryPoint
@@ -48,8 +47,6 @@ class FilterHeaderFragment : BaseFragment<FragmentFilterHeaderBinding>(), ChipsV
.observe(viewLifecycleOwner, ::onDataChanged) .observe(viewLifecycleOwner, ::onDataChanged)
} }
override fun onWindowInsetsChanged(insets: Insets) = Unit
override fun onChipClick(chip: Chip, data: Any?) { override fun onChipClick(chip: Chip, data: Any?) {
when (data) { when (data) {
is MangaTag -> filter.toggleTag(data, !chip.isChecked) is MangaTag -> filter.toggleTag(data, !chip.isChecked)
@@ -65,6 +62,7 @@ class FilterHeaderFragment : BaseFragment<FragmentFilterHeaderBinding>(), ChipsV
} else { } else {
filter.setQuery(null) filter.setQuery(null)
} }
is ContentRating -> filter.toggleContentRating(data, false) is ContentRating -> filter.toggleContentRating(data, false)
is Demographic -> filter.toggleDemographic(data, false) is Demographic -> filter.toggleDemographic(data, false)
is ContentType -> filter.toggleContentType(data, false) is ContentType -> filter.toggleContentType(data, false)

View File

@@ -1,8 +1,6 @@
package org.koitharu.kotatsu.history.ui package org.koitharu.kotatsu.history.ui
import android.os.Bundle import android.os.Bundle
import androidx.core.graphics.Insets
import androidx.core.view.updatePadding
import androidx.fragment.app.commit import androidx.fragment.app.commit
import com.google.android.material.appbar.AppBarLayout import com.google.android.material.appbar.AppBarLayout
import dagger.hilt.android.AndroidEntryPoint import dagger.hilt.android.AndroidEntryPoint
@@ -32,11 +30,4 @@ class HistoryActivity :
} }
} }
} }
override fun onWindowInsetsChanged(insets: Insets) {
viewBinding.root.updatePadding(
left = insets.left,
right = insets.right,
)
}
} }

View File

@@ -6,8 +6,10 @@ import android.os.Bundle
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.activity.viewModels import androidx.activity.viewModels
import androidx.core.graphics.Insets
import androidx.core.graphics.drawable.toBitmap import androidx.core.graphics.drawable.toBitmap
import androidx.core.view.OnApplyWindowInsetsListener
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import androidx.core.view.isVisible import androidx.core.view.isVisible
import androidx.core.view.updateLayoutParams import androidx.core.view.updateLayoutParams
import androidx.swiperefreshlayout.widget.CircularProgressDrawable import androidx.swiperefreshlayout.widget.CircularProgressDrawable
@@ -31,6 +33,7 @@ import org.koitharu.kotatsu.core.nav.AppRouter
import org.koitharu.kotatsu.core.ui.BaseActivity import org.koitharu.kotatsu.core.ui.BaseActivity
import org.koitharu.kotatsu.core.ui.util.PopupMenuMediator import org.koitharu.kotatsu.core.ui.util.PopupMenuMediator
import org.koitharu.kotatsu.core.util.ShareHelper import org.koitharu.kotatsu.core.util.ShareHelper
import org.koitharu.kotatsu.core.util.ext.end
import org.koitharu.kotatsu.core.util.ext.enqueueWith import org.koitharu.kotatsu.core.util.ext.enqueueWith
import org.koitharu.kotatsu.core.util.ext.getDisplayIcon import org.koitharu.kotatsu.core.util.ext.getDisplayIcon
import org.koitharu.kotatsu.core.util.ext.getDisplayMessage import org.koitharu.kotatsu.core.util.ext.getDisplayMessage
@@ -38,13 +41,17 @@ import org.koitharu.kotatsu.core.util.ext.getThemeColor
import org.koitharu.kotatsu.core.util.ext.mangaSourceExtra import org.koitharu.kotatsu.core.util.ext.mangaSourceExtra
import org.koitharu.kotatsu.core.util.ext.observe import org.koitharu.kotatsu.core.util.ext.observe
import org.koitharu.kotatsu.core.util.ext.observeEvent import org.koitharu.kotatsu.core.util.ext.observeEvent
import org.koitharu.kotatsu.core.util.ext.start
import org.koitharu.kotatsu.databinding.ActivityImageBinding import org.koitharu.kotatsu.databinding.ActivityImageBinding
import org.koitharu.kotatsu.databinding.ItemErrorStateBinding import org.koitharu.kotatsu.databinding.ItemErrorStateBinding
import javax.inject.Inject import javax.inject.Inject
import com.google.android.material.R as materialR import com.google.android.material.R as materialR
@AndroidEntryPoint @AndroidEntryPoint
class ImageActivity : BaseActivity<ActivityImageBinding>(), ImageRequest.Listener, View.OnClickListener { class ImageActivity : BaseActivity<ActivityImageBinding>(),
ImageRequest.Listener,
OnApplyWindowInsetsListener,
View.OnClickListener {
@Inject @Inject
lateinit var coil: ImageLoader lateinit var coil: ImageLoader
@@ -56,6 +63,7 @@ class ImageActivity : BaseActivity<ActivityImageBinding>(), ImageRequest.Listene
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
setContentView(ActivityImageBinding.inflate(layoutInflater)) setContentView(ActivityImageBinding.inflate(layoutInflater))
ViewCompat.setOnApplyWindowInsetsListener(viewBinding.root, this)
viewBinding.buttonBack.setOnClickListener(this) viewBinding.buttonBack.setOnClickListener(this)
viewBinding.buttonMenu.setOnClickListener(this) viewBinding.buttonMenu.setOnClickListener(this)
val imageUrl = requireNotNull(intent.data) val imageUrl = requireNotNull(intent.data)
@@ -72,19 +80,6 @@ class ImageActivity : BaseActivity<ActivityImageBinding>(), ImageRequest.Listene
loadImage(imageUrl) loadImage(imageUrl)
} }
override fun onWindowInsetsChanged(insets: Insets) {
viewBinding.buttonBack.updateLayoutParams<ViewGroup.MarginLayoutParams> {
topMargin = insets.top + bottomMargin
leftMargin = insets.left + bottomMargin
rightMargin = insets.right + bottomMargin
}
viewBinding.buttonMenu.updateLayoutParams<ViewGroup.MarginLayoutParams> {
topMargin = insets.top + bottomMargin
leftMargin = insets.left + bottomMargin
rightMargin = insets.right + bottomMargin
}
}
override fun onClick(v: View) { override fun onClick(v: View) {
when (v.id) { when (v.id) {
R.id.button_back -> dispatchNavigateUp() R.id.button_back -> dispatchNavigateUp()
@@ -115,6 +110,19 @@ class ImageActivity : BaseActivity<ActivityImageBinding>(), ImageRequest.Listene
(errorBinding?.root ?: viewBinding.stubError).isVisible = false (errorBinding?.root ?: viewBinding.stubError).isVisible = false
} }
override fun onApplyWindowInsets(v: View, insets: WindowInsetsCompat): WindowInsetsCompat {
val barsInsets = insets.getInsets(WindowInsetsCompat.Type.systemBars())
viewBinding.buttonMenu.updateLayoutParams<ViewGroup.MarginLayoutParams> {
marginEnd = barsInsets.end(v)
topMargin = barsInsets.top
}
viewBinding.buttonBack.updateLayoutParams<ViewGroup.MarginLayoutParams> {
marginStart = barsInsets.start(v)
topMargin = barsInsets.top
}
return insets
}
private fun loadImage(url: Uri?) { private fun loadImage(url: Uri?) {
ImageRequest.Builder(this) ImageRequest.Builder(this)
.data(url) .data(url)

View File

@@ -1,19 +1,16 @@
package org.koitharu.kotatsu.list.ui package org.koitharu.kotatsu.list.ui
import android.os.Bundle import android.os.Bundle
import android.view.Gravity
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.Menu import android.view.Menu
import android.view.MenuInflater import android.view.MenuInflater
import android.view.MenuItem import android.view.MenuItem
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.view.ViewGroup.MarginLayoutParams
import androidx.annotation.CallSuper import androidx.annotation.CallSuper
import androidx.appcompat.view.ActionMode import androidx.appcompat.view.ActionMode
import androidx.collection.ArraySet import androidx.collection.ArraySet
import androidx.core.graphics.Insets
import androidx.core.view.updateLayoutParams
import androidx.core.view.updatePadding
import androidx.recyclerview.widget.GridLayoutManager import androidx.recyclerview.widget.GridLayoutManager
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
import coil3.ImageLoader import coil3.ImageLoader
@@ -38,11 +35,10 @@ import org.koitharu.kotatsu.core.ui.util.ReversibleActionObserver
import org.koitharu.kotatsu.core.ui.widgets.TipView import org.koitharu.kotatsu.core.ui.widgets.TipView
import org.koitharu.kotatsu.core.util.ShareHelper import org.koitharu.kotatsu.core.util.ShareHelper
import org.koitharu.kotatsu.core.util.ext.addMenuProvider import org.koitharu.kotatsu.core.util.ext.addMenuProvider
import org.koitharu.kotatsu.core.util.ext.consumeInsetsAsPadding
import org.koitharu.kotatsu.core.util.ext.findAppCompatDelegate import org.koitharu.kotatsu.core.util.ext.findAppCompatDelegate
import org.koitharu.kotatsu.core.util.ext.measureHeight
import org.koitharu.kotatsu.core.util.ext.observe import org.koitharu.kotatsu.core.util.ext.observe
import org.koitharu.kotatsu.core.util.ext.observeEvent import org.koitharu.kotatsu.core.util.ext.observeEvent
import org.koitharu.kotatsu.core.util.ext.resolveDp
import org.koitharu.kotatsu.core.util.ext.viewLifecycleScope import org.koitharu.kotatsu.core.util.ext.viewLifecycleScope
import org.koitharu.kotatsu.databinding.FragmentListBinding import org.koitharu.kotatsu.databinding.FragmentListBinding
import org.koitharu.kotatsu.list.domain.ListFilterOption import org.koitharu.kotatsu.list.domain.ListFilterOption
@@ -55,7 +51,6 @@ import org.koitharu.kotatsu.list.ui.model.ListHeader
import org.koitharu.kotatsu.list.ui.model.ListModel import org.koitharu.kotatsu.list.ui.model.ListModel
import org.koitharu.kotatsu.list.ui.model.MangaListModel import org.koitharu.kotatsu.list.ui.model.MangaListModel
import org.koitharu.kotatsu.list.ui.size.DynamicItemSizeResolver import org.koitharu.kotatsu.list.ui.size.DynamicItemSizeResolver
import org.koitharu.kotatsu.main.ui.MainActivity
import org.koitharu.kotatsu.main.ui.owners.AppBarOwner import org.koitharu.kotatsu.main.ui.owners.AppBarOwner
import org.koitharu.kotatsu.parsers.model.Manga import org.koitharu.kotatsu.parsers.model.Manga
import org.koitharu.kotatsu.parsers.model.MangaTag import org.koitharu.kotatsu.parsers.model.MangaTag
@@ -109,6 +104,7 @@ abstract class MangaListFragment :
) )
paginationListener = PaginationScrollListener(4, this) paginationListener = PaginationScrollListener(4, this)
with(binding.recyclerView) { with(binding.recyclerView) {
consumeInsetsAsPadding(Gravity.START or Gravity.BOTTOM or Gravity.END)
setHasFixedSize(true) setHasFixedSize(true)
adapter = listAdapter adapter = listAdapter
checkNotNull(selectionController).attachToRecyclerView(this) checkNotNull(selectionController).attachToRecyclerView(this)
@@ -212,24 +208,6 @@ abstract class MangaListFragment :
) )
} }
override fun onWindowInsetsChanged(insets: Insets) {
val rv = requireViewBinding().recyclerView
rv.updatePadding(
bottom = insets.bottom + rv.paddingTop,
)
rv.fastScroller.updateLayoutParams<MarginLayoutParams> {
bottomMargin = insets.bottom
}
if (activity is MainActivity) {
val headerHeight = (activity as? AppBarOwner)?.appBar?.measureHeight() ?: insets.top
requireViewBinding().swipeRefreshLayout.setProgressViewOffset(
true,
headerHeight + resources.resolveDp(-72),
headerHeight + resources.resolveDp(10),
)
}
}
override fun onFilterOptionClick(option: ListFilterOption) { override fun onFilterOptionClick(option: ListFilterOption) {
selectionController?.clear() selectionController?.clear()
(viewModel as? QuickFilterListener)?.toggleFilterOption(option) (viewModel as? QuickFilterListener)?.toggleFilterOption(option)

View File

@@ -5,7 +5,6 @@ import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.TextView import android.widget.TextView
import androidx.core.graphics.Insets
import androidx.core.text.method.LinkMovementMethodCompat import androidx.core.text.method.LinkMovementMethodCompat
import androidx.core.view.isVisible import androidx.core.view.isVisible
import androidx.fragment.app.viewModels import androidx.fragment.app.viewModels
@@ -89,8 +88,6 @@ class PreviewFragment : BaseFragment<FragmentPreviewBinding>(), View.OnClickList
} }
} }
override fun onWindowInsetsChanged(insets: Insets) = Unit
override fun onChipClick(chip: Chip, data: Any?) { override fun onChipClick(chip: Chip, data: Any?) {
val tag = data as? MangaTag ?: return val tag = data as? MangaTag ?: return
val filter = (activity as? FilterCoordinator.Owner)?.filterCoordinator val filter = (activity as? FilterCoordinator.Owner)?.filterCoordinator

View File

@@ -14,9 +14,11 @@ import androidx.activity.viewModels
import androidx.appcompat.view.ActionMode import androidx.appcompat.view.ActionMode
import androidx.core.app.ActivityCompat import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import androidx.core.graphics.Insets
import androidx.core.net.toUri import androidx.core.net.toUri
import androidx.core.view.OnApplyWindowInsetsListener
import androidx.core.view.SoftwareKeyboardControllerCompat import androidx.core.view.SoftwareKeyboardControllerCompat
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import androidx.core.view.children import androidx.core.view.children
import androidx.core.view.inputmethod.EditorInfoCompat import androidx.core.view.inputmethod.EditorInfoCompat
import androidx.core.view.isInvisible import androidx.core.view.isInvisible
@@ -50,8 +52,11 @@ import org.koitharu.kotatsu.core.ui.util.FadingAppbarMediator
import org.koitharu.kotatsu.core.ui.util.MenuInvalidator import org.koitharu.kotatsu.core.ui.util.MenuInvalidator
import org.koitharu.kotatsu.core.ui.util.OptionsMenuBadgeHelper import org.koitharu.kotatsu.core.ui.util.OptionsMenuBadgeHelper
import org.koitharu.kotatsu.core.ui.widgets.SlidingBottomNavigationView import org.koitharu.kotatsu.core.ui.widgets.SlidingBottomNavigationView
import org.koitharu.kotatsu.core.util.ext.consumeRelative
import org.koitharu.kotatsu.core.util.ext.end
import org.koitharu.kotatsu.core.util.ext.observe import org.koitharu.kotatsu.core.util.ext.observe
import org.koitharu.kotatsu.core.util.ext.observeEvent import org.koitharu.kotatsu.core.util.ext.observeEvent
import org.koitharu.kotatsu.core.util.ext.start
import org.koitharu.kotatsu.databinding.ActivityMainBinding import org.koitharu.kotatsu.databinding.ActivityMainBinding
import org.koitharu.kotatsu.details.service.MangaPrefetchService import org.koitharu.kotatsu.details.service.MangaPrefetchService
import org.koitharu.kotatsu.favourites.ui.container.FavouritesContainerFragment import org.koitharu.kotatsu.favourites.ui.container.FavouritesContainerFragment
@@ -76,8 +81,11 @@ private const val TAG_SEARCH = "search"
@AndroidEntryPoint @AndroidEntryPoint
class MainActivity : BaseActivity<ActivityMainBinding>(), AppBarOwner, BottomNavOwner, class MainActivity : BaseActivity<ActivityMainBinding>(), AppBarOwner, BottomNavOwner,
View.OnClickListener, View.OnClickListener,
View.OnFocusChangeListener, SearchSuggestionListener, View.OnFocusChangeListener,
MainNavigationDelegate.OnFragmentChangedListener, View.OnLayoutChangeListener { SearchSuggestionListener,
OnApplyWindowInsetsListener,
MainNavigationDelegate.OnFragmentChangedListener,
View.OnLayoutChangeListener {
@Inject @Inject
lateinit var settings: AppSettings lateinit var settings: AppSettings
@@ -98,6 +106,7 @@ class MainActivity : BaseActivity<ActivityMainBinding>(), AppBarOwner, BottomNav
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
setContentView(ActivityMainBinding.inflate(layoutInflater)) setContentView(ActivityMainBinding.inflate(layoutInflater))
ViewCompat.setOnApplyWindowInsetsListener(viewBinding.root, this)
with(viewBinding.searchView) { with(viewBinding.searchView) {
onFocusChangeListener = this@MainActivity onFocusChangeListener = this@MainActivity
@@ -204,12 +213,24 @@ class MainActivity : BaseActivity<ActivityMainBinding>(), AppBarOwner, BottomNav
} }
} }
override fun onWindowInsetsChanged(insets: Insets) { override fun onApplyWindowInsets(v: View, insets: WindowInsetsCompat): WindowInsetsCompat {
viewBinding.root.updatePadding( val barsInsets = insets.getInsets(WindowInsetsCompat.Type.systemBars())
left = insets.left, viewBinding.toolbarCard.updateLayoutParams<MarginLayoutParams> {
right = insets.right, marginEnd = barsInsets.end(v)
) marginStart = if (viewBinding.navRail != null) {
viewBinding.bottomNav?.updatePadding(bottom = insets.bottom) 0
} else {
barsInsets.start(v)
}
}
return viewBinding.navRail?.let { navRail ->
navRail.updateLayoutParams<MarginLayoutParams> {
marginStart = barsInsets.start(v)
}
WindowInsetsCompat.Builder(insets)
.setInsets(WindowInsetsCompat.Type.systemBars(), barsInsets.consumeRelative(v, start = true))
.build()
} ?: insets
} }
override fun onLayoutChange( override fun onLayoutChange(

View File

@@ -15,7 +15,6 @@ import androidx.biometric.BiometricManager.Authenticators.BIOMETRIC_WEAK
import androidx.biometric.BiometricManager.BIOMETRIC_SUCCESS import androidx.biometric.BiometricManager.BIOMETRIC_SUCCESS
import androidx.biometric.BiometricPrompt import androidx.biometric.BiometricPrompt
import androidx.biometric.BiometricPrompt.AuthenticationCallback import androidx.biometric.BiometricPrompt.AuthenticationCallback
import androidx.core.graphics.Insets
import com.google.android.material.textfield.TextInputLayout import com.google.android.material.textfield.TextInputLayout
import dagger.hilt.android.AndroidEntryPoint import dagger.hilt.android.AndroidEntryPoint
import org.koitharu.kotatsu.R import org.koitharu.kotatsu.R
@@ -71,16 +70,6 @@ class ProtectActivity :
} }
} }
override fun onWindowInsetsChanged(insets: Insets) {
val basePadding = resources.getDimensionPixelOffset(R.dimen.screen_padding)
viewBinding.root.setPadding(
basePadding + insets.left,
basePadding + insets.top,
basePadding + insets.right,
basePadding + insets.bottom,
)
}
override fun onClick(v: View) { override fun onClick(v: View) {
when (v.id) { when (v.id) {
R.id.button_next -> viewModel.tryUnlock(viewBinding.editPassword.text?.toString().orEmpty()) R.id.button_next -> viewModel.tryUnlock(viewBinding.editPassword.text?.toString().orEmpty())

View File

@@ -16,6 +16,7 @@ import androidx.activity.viewModels
import androidx.core.graphics.Insets import androidx.core.graphics.Insets
import androidx.core.view.MenuHost import androidx.core.view.MenuHost
import androidx.core.view.OnApplyWindowInsetsListener import androidx.core.view.OnApplyWindowInsetsListener
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat import androidx.core.view.WindowInsetsCompat
import androidx.core.view.isGone import androidx.core.view.isGone
import androidx.core.view.isVisible import androidx.core.view.isVisible
@@ -122,10 +123,10 @@ class ReaderActivity :
viewBinding.slider.setLabelFormatter(PageLabelFormatter()) viewBinding.slider.setLabelFormatter(PageLabelFormatter())
viewBinding.zoomControl.listener = this viewBinding.zoomControl.listener = this
ReaderSliderListener(viewModel, this).attachToSlider(viewBinding.slider) ReaderSliderListener(viewModel, this).attachToSlider(viewBinding.slider)
insetsDelegate.interceptingWindowInsetsListener = this
idlingDetector.bindToLifecycle(this) idlingDetector.bindToLifecycle(this)
viewBinding.buttonPrev.setOnClickListener(controlDelegate) viewBinding.buttonPrev.setOnClickListener(controlDelegate)
viewBinding.buttonNext.setOnClickListener(controlDelegate) viewBinding.buttonNext.setOnClickListener(controlDelegate)
ViewCompat.setOnApplyWindowInsetsListener(viewBinding.root, this)
viewModel.onError.observeEvent( viewModel.onError.observeEvent(
this, this,
@@ -353,8 +354,6 @@ class ReaderActivity :
.build() .build()
} }
override fun onWindowInsetsChanged(insets: Insets) = Unit
override fun switchPageBy(delta: Int) { override fun switchPageBy(delta: Int) {
readerManager.currentReader?.switchPageBy(delta) readerManager.currentReader?.switchPageBy(delta)
} }

View File

@@ -4,12 +4,8 @@ import android.content.res.Resources
import android.graphics.Bitmap import android.graphics.Bitmap
import android.os.Bundle import android.os.Bundle
import android.view.View import android.view.View
import android.view.ViewGroup
import android.widget.CompoundButton import android.widget.CompoundButton
import androidx.activity.viewModels import androidx.activity.viewModels
import androidx.core.graphics.Insets
import androidx.core.view.updateLayoutParams
import androidx.core.view.updatePadding
import coil3.ImageLoader import coil3.ImageLoader
import coil3.request.ImageRequest import coil3.request.ImageRequest
import coil3.request.bitmapConfig import coil3.request.bitmapConfig
@@ -99,19 +95,6 @@ class ColorFilterConfigActivity :
} }
} }
override fun onWindowInsetsChanged(insets: Insets) {
viewBinding.root.updatePadding(
left = insets.left,
right = insets.right,
)
viewBinding.scrollView.updatePadding(
bottom = insets.bottom,
)
viewBinding.toolbar.updateLayoutParams<ViewGroup.MarginLayoutParams> {
topMargin = insets.top
}
}
fun showSaveConfirmation() { fun showSaveConfirmation() {
MaterialAlertDialogBuilder(this) MaterialAlertDialogBuilder(this)
.setTitle(R.string.apply) .setTitle(R.string.apply)

View File

@@ -1,7 +1,6 @@
package org.koitharu.kotatsu.reader.ui.pager package org.koitharu.kotatsu.reader.ui.pager
import android.os.Bundle import android.os.Bundle
import androidx.core.graphics.Insets
import androidx.fragment.app.activityViewModels import androidx.fragment.app.activityViewModels
import androidx.viewbinding.ViewBinding import androidx.viewbinding.ViewBinding
import org.koitharu.kotatsu.core.prefs.ReaderAnimation import org.koitharu.kotatsu.core.prefs.ReaderAnimation
@@ -51,8 +50,6 @@ abstract class BaseReaderFragment<B : ViewBinding> : BaseFragment<B>(), ZoomCont
return context?.isAnimationsEnabled == true && viewModel.pageAnimation.value != ReaderAnimation.NONE return context?.isAnimationsEnabled == true && viewModel.pageAnimation.value != ReaderAnimation.NONE
} }
override fun onWindowInsetsChanged(insets: Insets) = Unit
abstract fun switchPageBy(delta: Int) abstract fun switchPageBy(delta: Int)
abstract fun switchPageTo(position: Int, smooth: Boolean) abstract fun switchPageTo(position: Int, smooth: Boolean)

View File

@@ -2,10 +2,9 @@ package org.koitharu.kotatsu.scrobbling.common.ui.config
import android.content.Intent import android.content.Intent
import android.os.Bundle import android.os.Bundle
import android.view.Gravity
import android.view.View import android.view.View
import androidx.activity.viewModels import androidx.activity.viewModels
import androidx.core.graphics.Insets
import androidx.core.view.updatePadding
import coil3.ImageLoader import coil3.ImageLoader
import coil3.request.error import coil3.request.error
import coil3.request.fallback import coil3.request.fallback
@@ -17,6 +16,7 @@ import org.koitharu.kotatsu.core.exceptions.resolve.SnackbarErrorObserver
import org.koitharu.kotatsu.core.nav.router import org.koitharu.kotatsu.core.nav.router
import org.koitharu.kotatsu.core.ui.BaseActivity import org.koitharu.kotatsu.core.ui.BaseActivity
import org.koitharu.kotatsu.core.ui.list.OnListItemClickListener import org.koitharu.kotatsu.core.ui.list.OnListItemClickListener
import org.koitharu.kotatsu.core.util.ext.consumeInsetsAsPadding
import org.koitharu.kotatsu.core.util.ext.disposeImageRequest import org.koitharu.kotatsu.core.util.ext.disposeImageRequest
import org.koitharu.kotatsu.core.util.ext.enqueueWith import org.koitharu.kotatsu.core.util.ext.enqueueWith
import org.koitharu.kotatsu.core.util.ext.newImageRequest import org.koitharu.kotatsu.core.util.ext.newImageRequest
@@ -48,6 +48,7 @@ class ScrobblerConfigActivity : BaseActivity<ActivityScrobblerConfigBinding>(),
val listAdapter = ScrobblingMangaAdapter(this, coil, this) val listAdapter = ScrobblingMangaAdapter(this, coil, this)
with(viewBinding.recyclerView) { with(viewBinding.recyclerView) {
consumeInsetsAsPadding(Gravity.START or Gravity.END or Gravity.BOTTOM)
adapter = listAdapter adapter = listAdapter
setHasFixedSize(true) setHasFixedSize(true)
val decoration = TypedListSpacingDecoration(context, false) val decoration = TypedListSpacingDecoration(context, false)
@@ -72,15 +73,6 @@ class ScrobblerConfigActivity : BaseActivity<ActivityScrobblerConfigBinding>(),
processIntent(intent) processIntent(intent)
} }
override fun onWindowInsetsChanged(insets: Insets) {
val rv = viewBinding.recyclerView
rv.updatePadding(
left = insets.left + rv.paddingTop,
right = insets.right + rv.paddingTop,
bottom = insets.bottom + rv.paddingTop,
)
}
override fun onItemClick(item: ScrobblingInfo, view: View) { override fun onItemClick(item: ScrobblingInfo, view: View) {
router.openDetails(item.mangaId) router.openDetails(item.mangaId)
} }

View File

@@ -5,7 +5,6 @@ import android.content.Intent
import android.os.Bundle import android.os.Bundle
import android.text.Editable import android.text.Editable
import android.view.View import android.view.View
import androidx.core.graphics.Insets
import androidx.core.net.toUri import androidx.core.net.toUri
import org.koitharu.kotatsu.R import org.koitharu.kotatsu.R
import org.koitharu.kotatsu.core.ui.BaseActivity import org.koitharu.kotatsu.core.ui.BaseActivity
@@ -26,16 +25,6 @@ class KitsuAuthActivity : BaseActivity<ActivityKitsuAuthBinding>(), View.OnClick
viewBinding.editPassword.addTextChangedListener(this) viewBinding.editPassword.addTextChangedListener(this)
} }
override fun onWindowInsetsChanged(insets: Insets) {
val basePadding = resources.getDimensionPixelOffset(R.dimen.screen_padding)
viewBinding.root.setPadding(
basePadding + insets.left,
basePadding + insets.top,
basePadding + insets.right,
basePadding + insets.bottom,
)
}
override fun onClick(v: View) { override fun onClick(v: View) {
when (v.id) { when (v.id) {
R.id.button_cancel -> finish() R.id.button_cancel -> finish()

View File

@@ -2,12 +2,14 @@ package org.koitharu.kotatsu.search.ui
import android.os.Bundle import android.os.Bundle
import android.view.View import android.view.View
import android.view.ViewGroup.MarginLayoutParams import android.view.ViewGroup
import androidx.core.graphics.Insets
import androidx.core.graphics.drawable.toDrawable import androidx.core.graphics.drawable.toDrawable
import androidx.core.os.bundleOf import androidx.core.os.bundleOf
import androidx.core.view.OnApplyWindowInsetsListener
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import androidx.core.view.updateLayoutParams import androidx.core.view.updateLayoutParams
import androidx.core.view.updatePadding import androidx.core.view.updatePaddingRelative
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.fragment.app.commit import androidx.fragment.app.commit
import com.google.android.material.appbar.AppBarLayout import com.google.android.material.appbar.AppBarLayout
@@ -30,11 +32,14 @@ import org.koitharu.kotatsu.core.nav.router
import org.koitharu.kotatsu.core.ui.BaseActivity import org.koitharu.kotatsu.core.ui.BaseActivity
import org.koitharu.kotatsu.core.ui.model.titleRes import org.koitharu.kotatsu.core.ui.model.titleRes
import org.koitharu.kotatsu.core.util.ViewBadge import org.koitharu.kotatsu.core.util.ViewBadge
import org.koitharu.kotatsu.core.util.ext.consumeRelative
import org.koitharu.kotatsu.core.util.ext.end
import org.koitharu.kotatsu.core.util.ext.getParcelableExtraCompat import org.koitharu.kotatsu.core.util.ext.getParcelableExtraCompat
import org.koitharu.kotatsu.core.util.ext.getSerializableExtraCompat import org.koitharu.kotatsu.core.util.ext.getSerializableExtraCompat
import org.koitharu.kotatsu.core.util.ext.getThemeColor import org.koitharu.kotatsu.core.util.ext.getThemeColor
import org.koitharu.kotatsu.core.util.ext.observe import org.koitharu.kotatsu.core.util.ext.observe
import org.koitharu.kotatsu.core.util.ext.setTextAndVisible import org.koitharu.kotatsu.core.util.ext.setTextAndVisible
import org.koitharu.kotatsu.core.util.ext.start
import org.koitharu.kotatsu.databinding.ActivityMangaListBinding import org.koitharu.kotatsu.databinding.ActivityMangaListBinding
import org.koitharu.kotatsu.filter.ui.FilterCoordinator import org.koitharu.kotatsu.filter.ui.FilterCoordinator
import org.koitharu.kotatsu.filter.ui.FilterHeaderFragment import org.koitharu.kotatsu.filter.ui.FilterHeaderFragment
@@ -53,7 +58,10 @@ import com.google.android.material.R as materialR
@AndroidEntryPoint @AndroidEntryPoint
class MangaListActivity : class MangaListActivity :
BaseActivity<ActivityMangaListBinding>(), BaseActivity<ActivityMangaListBinding>(),
AppBarOwner, View.OnClickListener, FilterCoordinator.Owner, AppBarLayout.OnOffsetChangedListener { AppBarOwner, View.OnClickListener,
FilterCoordinator.Owner,
OnApplyWindowInsetsListener,
AppBarLayout.OnOffsetChangedListener {
override val appBar: AppBarLayout override val appBar: AppBarLayout
get() = viewBinding.appbar get() = viewBinding.appbar
@@ -74,6 +82,8 @@ class MangaListActivity :
supportActionBar?.setDisplayHomeAsUpEnabled(true) supportActionBar?.setDisplayHomeAsUpEnabled(true)
if (viewBinding.containerFilterHeader != null) { if (viewBinding.containerFilterHeader != null) {
viewBinding.appbar.addOnOffsetChangedListener(this) viewBinding.appbar.addOnOffsetChangedListener(this)
} else {
ViewCompat.setOnApplyWindowInsetsListener(viewBinding.root, this)
} }
viewBinding.buttonOrder?.setOnClickListener(this) viewBinding.buttonOrder?.setOnClickListener(this)
title = source.getTitle(this) title = source.getTitle(this)
@@ -82,17 +92,6 @@ class MangaListActivity :
override fun isNsfwContent(): Flow<Boolean> = flowOf(source.isNsfw()) override fun isNsfwContent(): Flow<Boolean> = flowOf(source.isNsfw())
override fun onWindowInsetsChanged(insets: Insets) {
viewBinding.root.updatePadding(
left = insets.left,
right = insets.right,
)
viewBinding.cardSide?.updateLayoutParams<MarginLayoutParams> {
bottomMargin = marginStart + insets.bottom
topMargin = marginStart + insets.top
}
}
override fun onOffsetChanged(appBarLayout: AppBarLayout, verticalOffset: Int) { override fun onOffsetChanged(appBarLayout: AppBarLayout, verticalOffset: Int) {
val container = viewBinding.containerFilterHeader ?: return val container = viewBinding.containerFilterHeader ?: return
container.background = if (verticalOffset.absoluteValue < appBarLayout.totalScrollRange) { container.background = if (verticalOffset.absoluteValue < appBarLayout.totalScrollRange) {
@@ -102,6 +101,31 @@ class MangaListActivity :
} }
} }
/**
* Only for landscape
*/
override fun onApplyWindowInsets(v: View, insets: WindowInsetsCompat): WindowInsetsCompat {
val barsInsets = insets.getInsets(WindowInsetsCompat.Type.systemBars())
viewBinding.cardSide?.updateLayoutParams<ViewGroup.MarginLayoutParams> {
marginEnd = barsInsets.end(v) + resources.getDimensionPixelOffset(R.dimen.side_card_offset)
topMargin = barsInsets.top + resources.getDimensionPixelOffset(R.dimen.grid_spacing_outer_double)
bottomMargin = barsInsets.bottom + resources.getDimensionPixelOffset(R.dimen.side_card_offset)
}
viewBinding.appbar.updatePaddingRelative(
top = barsInsets.top,
start = barsInsets.start(v),
)
return WindowInsetsCompat.Builder(insets)
.setInsets(
WindowInsetsCompat.Type.systemBars(),
barsInsets.consumeRelative(
v,
top = true,
end = true,
),
).build()
}
override fun onClick(v: View) { override fun onClick(v: View) {
when (v.id) { when (v.id) {
R.id.button_order -> router.showFilterSheet() R.id.button_order -> router.showFilterSheet()

View File

@@ -1,14 +1,13 @@
package org.koitharu.kotatsu.search.ui.multi package org.koitharu.kotatsu.search.ui.multi
import android.os.Bundle import android.os.Bundle
import android.view.Gravity
import android.view.Menu import android.view.Menu
import android.view.MenuInflater import android.view.MenuInflater
import android.view.MenuItem import android.view.MenuItem
import android.view.View import android.view.View
import androidx.activity.viewModels import androidx.activity.viewModels
import androidx.appcompat.view.ActionMode import androidx.appcompat.view.ActionMode
import androidx.core.graphics.Insets
import androidx.core.view.updatePadding
import coil3.ImageLoader import coil3.ImageLoader
import dagger.hilt.android.AndroidEntryPoint import dagger.hilt.android.AndroidEntryPoint
import org.koitharu.kotatsu.R import org.koitharu.kotatsu.R
@@ -20,6 +19,7 @@ import org.koitharu.kotatsu.core.ui.list.ListSelectionController
import org.koitharu.kotatsu.core.ui.list.OnListItemClickListener import org.koitharu.kotatsu.core.ui.list.OnListItemClickListener
import org.koitharu.kotatsu.core.ui.widgets.TipView import org.koitharu.kotatsu.core.ui.widgets.TipView
import org.koitharu.kotatsu.core.util.ShareHelper import org.koitharu.kotatsu.core.util.ShareHelper
import org.koitharu.kotatsu.core.util.ext.consumeInsetsAsPadding
import org.koitharu.kotatsu.core.util.ext.invalidateNestedItemDecorations import org.koitharu.kotatsu.core.util.ext.invalidateNestedItemDecorations
import org.koitharu.kotatsu.core.util.ext.observe import org.koitharu.kotatsu.core.util.ext.observe
import org.koitharu.kotatsu.core.util.ext.observeEvent import org.koitharu.kotatsu.core.util.ext.observeEvent
@@ -91,6 +91,7 @@ class SearchActivity :
selectionDecoration = selectionDecoration, selectionDecoration = selectionDecoration,
) )
viewBinding.recyclerView.adapter = adapter viewBinding.recyclerView.adapter = adapter
viewBinding.recyclerView.consumeInsetsAsPadding(Gravity.START or Gravity.END or Gravity.BOTTOM)
viewBinding.recyclerView.setHasFixedSize(true) viewBinding.recyclerView.setHasFixedSize(true)
viewBinding.recyclerView.addItemDecoration(TypedListSpacingDecoration(this, true)) viewBinding.recyclerView.addItemDecoration(TypedListSpacingDecoration(this, true))
@@ -105,16 +106,6 @@ class SearchActivity :
viewModel.onError.observeEvent(this, SnackbarErrorObserver(viewBinding.recyclerView, null)) viewModel.onError.observeEvent(this, SnackbarErrorObserver(viewBinding.recyclerView, null))
} }
override fun onWindowInsetsChanged(insets: Insets) {
viewBinding.root.updatePadding(
left = insets.left,
right = insets.right,
)
viewBinding.recyclerView.updatePadding(
bottom = insets.bottom + viewBinding.recyclerView.paddingTop,
)
}
override fun onItemClick(item: Manga, view: View) { override fun onItemClick(item: Manga, view: View) {
if (!selectionController.onItemClick(item.id)) { if (!selectionController.onItemClick(item.id)) {
router.openDetails(item) router.openDetails(item)

View File

@@ -1,18 +1,17 @@
package org.koitharu.kotatsu.search.ui.suggestion package org.koitharu.kotatsu.search.ui.suggestion
import android.os.Bundle import android.os.Bundle
import android.view.Gravity
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.ViewGroup import android.view.ViewGroup
import androidx.core.graphics.Insets
import androidx.core.view.updatePadding
import androidx.fragment.app.activityViewModels import androidx.fragment.app.activityViewModels
import androidx.recyclerview.widget.ItemTouchHelper import androidx.recyclerview.widget.ItemTouchHelper
import coil3.ImageLoader import coil3.ImageLoader
import dagger.hilt.android.AndroidEntryPoint import dagger.hilt.android.AndroidEntryPoint
import org.koitharu.kotatsu.R
import org.koitharu.kotatsu.core.os.VoiceInputContract import org.koitharu.kotatsu.core.os.VoiceInputContract
import org.koitharu.kotatsu.core.ui.BaseFragment import org.koitharu.kotatsu.core.ui.BaseFragment
import org.koitharu.kotatsu.core.util.ext.addMenuProvider import org.koitharu.kotatsu.core.util.ext.addMenuProvider
import org.koitharu.kotatsu.core.util.ext.consumeInsetsAsPadding
import org.koitharu.kotatsu.core.util.ext.observe import org.koitharu.kotatsu.core.util.ext.observe
import org.koitharu.kotatsu.databinding.FragmentSearchSuggestionBinding import org.koitharu.kotatsu.databinding.FragmentSearchSuggestionBinding
import org.koitharu.kotatsu.search.ui.suggestion.adapter.SearchSuggestionAdapter import org.koitharu.kotatsu.search.ui.suggestion.adapter.SearchSuggestionAdapter
@@ -48,21 +47,12 @@ class SearchSuggestionFragment :
addMenuProvider(SearchSuggestionMenuProvider(binding.root.context, voiceInputLauncher, viewModel)) addMenuProvider(SearchSuggestionMenuProvider(binding.root.context, voiceInputLauncher, viewModel))
binding.root.adapter = adapter binding.root.adapter = adapter
binding.root.setHasFixedSize(true) binding.root.setHasFixedSize(true)
binding.root.consumeInsetsAsPadding(Gravity.BOTTOM or Gravity.START or Gravity.END)
viewModel.suggestion.observe(viewLifecycleOwner, adapter) viewModel.suggestion.observe(viewLifecycleOwner, adapter)
ItemTouchHelper(SearchSuggestionItemCallback(this)) ItemTouchHelper(SearchSuggestionItemCallback(this))
.attachToRecyclerView(binding.root) .attachToRecyclerView(binding.root)
} }
override fun onWindowInsetsChanged(insets: Insets) {
val extraPadding = resources.getDimensionPixelOffset(R.dimen.list_spacing)
requireViewBinding().root.updatePadding(
top = extraPadding,
right = insets.right,
left = insets.left,
bottom = insets.bottom,
)
}
override fun onRemoveQuery(query: String) { override fun onRemoveQuery(query: String) {
viewModel.deleteQuery(query) viewModel.deleteQuery(query)
} }

View File

@@ -2,12 +2,8 @@ package org.koitharu.kotatsu.settings
import android.content.Intent import android.content.Intent
import android.os.Bundle import android.os.Bundle
import android.view.ViewGroup.MarginLayoutParams
import androidx.activity.viewModels import androidx.activity.viewModels
import androidx.core.graphics.Insets
import androidx.core.view.isVisible import androidx.core.view.isVisible
import androidx.core.view.updateLayoutParams
import androidx.core.view.updatePadding
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentFactory import androidx.fragment.app.FragmentFactory
import androidx.fragment.app.FragmentTransaction import androidx.fragment.app.FragmentTransaction
@@ -86,16 +82,6 @@ class SettingsActivity :
return true return true
} }
override fun onWindowInsetsChanged(insets: Insets) {
viewBinding.root.updatePadding(
left = insets.left,
right = insets.right,
)
viewBinding.textViewHeader?.updateLayoutParams<MarginLayoutParams> {
topMargin = screenPadding + insets.top
}
}
fun setSectionTitle(title: CharSequence?) { fun setSectionTitle(title: CharSequence?) {
viewBinding.textViewHeader?.apply { viewBinding.textViewHeader?.apply {
textAndVisible = title textAndVisible = title

View File

@@ -14,7 +14,6 @@ import android.widget.TextView
import androidx.activity.result.contract.ActivityResultContracts import androidx.activity.result.contract.ActivityResultContracts
import androidx.activity.viewModels import androidx.activity.viewModels
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import androidx.core.graphics.Insets
import androidx.core.text.buildSpannedString import androidx.core.text.buildSpannedString
import com.google.android.material.snackbar.Snackbar import com.google.android.material.snackbar.Snackbar
import dagger.hilt.android.AndroidEntryPoint import dagger.hilt.android.AndroidEntryPoint
@@ -91,16 +90,6 @@ class AppUpdateActivity : BaseActivity<ActivityAppUpdateBinding>(), View.OnClick
} }
} }
override fun onWindowInsetsChanged(insets: Insets) {
val basePadding = resources.getDimensionPixelOffset(R.dimen.screen_padding)
viewBinding.root.setPadding(
basePadding + insets.left,
basePadding + insets.top,
basePadding + insets.right,
basePadding + insets.bottom,
)
}
private suspend fun onNextVersionChanged(version: AppVersion?) { private suspend fun onNextVersionChanged(version: AppVersion?) {
viewBinding.buttonUpdate.isEnabled = version != null && !viewModel.isLoading.value viewBinding.buttonUpdate.isEnabled = version != null && !viewModel.isLoading.value
if (version == null) { if (version == null) {

View File

@@ -5,8 +5,6 @@ import android.os.Bundle
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.core.graphics.Insets
import androidx.core.view.updatePadding
import androidx.fragment.app.viewModels import androidx.fragment.app.viewModels
import androidx.recyclerview.widget.ItemTouchHelper import androidx.recyclerview.widget.ItemTouchHelper
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
@@ -72,14 +70,6 @@ class NavConfigFragment : BaseFragment<FragmentSettingsSourcesBinding>(), Recycl
super.onDestroyView() super.onDestroyView()
} }
override fun onWindowInsetsChanged(insets: Insets) {
requireViewBinding().recyclerView.updatePadding(
bottom = insets.bottom,
left = insets.left,
right = insets.right,
)
}
override fun onClick(v: View) { override fun onClick(v: View) {
var dialog: DialogInterface? = null var dialog: DialogInterface? = null
val listener = OnListItemClickListener<NavItem> { item, _ -> val listener = OnListItemClickListener<NavItem> { item, _ ->

View File

@@ -11,7 +11,6 @@ import android.view.inputmethod.EditorInfo
import android.widget.CompoundButton import android.widget.CompoundButton
import android.widget.TextView import android.widget.TextView
import androidx.activity.viewModels import androidx.activity.viewModels
import androidx.core.graphics.Insets
import androidx.core.view.isGone import androidx.core.view.isGone
import androidx.core.view.isVisible import androidx.core.view.isVisible
import dagger.hilt.android.AndroidEntryPoint import dagger.hilt.android.AndroidEntryPoint
@@ -58,16 +57,6 @@ class ProtectSetupActivity :
} }
} }
override fun onWindowInsetsChanged(insets: Insets) {
val basePadding = resources.getDimensionPixelOffset(R.dimen.screen_padding)
viewBinding.root.setPadding(
basePadding + insets.left,
basePadding + insets.top,
basePadding + insets.right,
basePadding + insets.bottom,
)
}
override fun onClick(v: View) { override fun onClick(v: View) {
when (v.id) { when (v.id) {
R.id.button_cancel -> finish() R.id.button_cancel -> finish()

View File

@@ -1,24 +1,24 @@
package org.koitharu.kotatsu.settings.reader package org.koitharu.kotatsu.settings.reader
import android.content.DialogInterface import android.content.DialogInterface
import android.graphics.drawable.ColorDrawable
import android.graphics.drawable.Drawable import android.graphics.drawable.Drawable
import android.graphics.drawable.LayerDrawable import android.graphics.drawable.LayerDrawable
import android.os.Bundle import android.os.Bundle
import android.view.Gravity
import android.view.Menu import android.view.Menu
import android.view.MenuItem import android.view.MenuItem
import android.view.View import android.view.View
import android.widget.TextView import android.widget.TextView
import androidx.activity.viewModels import androidx.activity.viewModels
import androidx.core.graphics.ColorUtils import androidx.core.graphics.ColorUtils
import androidx.core.graphics.Insets import androidx.core.graphics.drawable.toDrawable
import androidx.core.text.bold import androidx.core.text.bold
import androidx.core.text.buildSpannedString import androidx.core.text.buildSpannedString
import androidx.core.view.updatePadding
import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.android.material.dialog.MaterialAlertDialogBuilder
import dagger.hilt.android.AndroidEntryPoint import dagger.hilt.android.AndroidEntryPoint
import org.koitharu.kotatsu.R import org.koitharu.kotatsu.R
import org.koitharu.kotatsu.core.ui.BaseActivity import org.koitharu.kotatsu.core.ui.BaseActivity
import org.koitharu.kotatsu.core.util.ext.consumeInsetsAsPadding
import org.koitharu.kotatsu.core.util.ext.findKeyByValue import org.koitharu.kotatsu.core.util.ext.findKeyByValue
import org.koitharu.kotatsu.core.util.ext.getThemeDrawable import org.koitharu.kotatsu.core.util.ext.getThemeDrawable
import org.koitharu.kotatsu.core.util.ext.observe import org.koitharu.kotatsu.core.util.ext.observe
@@ -39,6 +39,7 @@ class ReaderTapGridConfigActivity : BaseActivity<ActivityReaderTapActionsBinding
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
setContentView(ActivityReaderTapActionsBinding.inflate(layoutInflater)) setContentView(ActivityReaderTapActionsBinding.inflate(layoutInflater))
viewBinding.root.consumeInsetsAsPadding(Gravity.START or Gravity.END or Gravity.BOTTOM or Gravity.TOP)
supportActionBar?.setDisplayHomeAsUpEnabled(true) supportActionBar?.setDisplayHomeAsUpEnabled(true)
controls[TapGridArea.TOP_LEFT] = viewBinding.textViewTopLeft controls[TapGridArea.TOP_LEFT] = viewBinding.textViewTopLeft
controls[TapGridArea.TOP_CENTER] = viewBinding.textViewTopCenter controls[TapGridArea.TOP_CENTER] = viewBinding.textViewTopCenter
@@ -79,15 +80,6 @@ class ReaderTapGridConfigActivity : BaseActivity<ActivityReaderTapActionsBinding
} }
} }
override fun onWindowInsetsChanged(insets: Insets) {
viewBinding.root.updatePadding(
left = insets.left,
top = insets.top,
right = insets.right,
bottom = insets.bottom,
)
}
override fun onClick(v: View) { override fun onClick(v: View) {
val area = controls.findKeyByValue(v) ?: return val area = controls.findKeyByValue(v) ?: return
showActionSelector(area, isLongTap = false) showActionSelector(area, isLongTap = false)
@@ -116,7 +108,8 @@ class ReaderTapGridConfigActivity : BaseActivity<ActivityReaderTapActionsBinding
view.background = createBackground(actions?.tapAction) view.background = createBackground(actions?.tapAction)
} }
} }
// lint bug
// lint bug
private fun TapAction?.getText(): String = if (this != null) { private fun TapAction?.getText(): String = if (this != null) {
getString(nameStringResId) getString(nameStringResId)
} else { } else {
@@ -157,7 +150,7 @@ class ReaderTapGridConfigActivity : BaseActivity<ActivityReaderTapActionsBinding
return if (action == null) { return if (action == null) {
ripple ripple
} else { } else {
LayerDrawable(arrayOf(ripple, ColorDrawable(ColorUtils.setAlphaComponent(action.color, 40)))) LayerDrawable(arrayOf(ripple, ColorUtils.setAlphaComponent(action.color, 40).toDrawable()))
} }
} }
} }

View File

@@ -4,13 +4,10 @@ import android.os.Bundle
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.core.graphics.Insets
import androidx.core.view.updatePadding
import androidx.fragment.app.activityViewModels import androidx.fragment.app.activityViewModels
import androidx.recyclerview.widget.AsyncListDiffer.ListListener import androidx.recyclerview.widget.AsyncListDiffer.ListListener
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import dagger.hilt.android.AndroidEntryPoint import dagger.hilt.android.AndroidEntryPoint
import org.koitharu.kotatsu.R
import org.koitharu.kotatsu.core.ui.BaseFragment import org.koitharu.kotatsu.core.ui.BaseFragment
import org.koitharu.kotatsu.core.ui.BaseListAdapter import org.koitharu.kotatsu.core.ui.BaseListAdapter
import org.koitharu.kotatsu.core.ui.list.OnListItemClickListener import org.koitharu.kotatsu.core.ui.list.OnListItemClickListener
@@ -39,16 +36,6 @@ class SettingsSearchFragment : BaseFragment<FragmentSearchSuggestionBinding>(),
viewModel.content.observe(viewLifecycleOwner, adapter) viewModel.content.observe(viewLifecycleOwner, adapter)
} }
override fun onWindowInsetsChanged(insets: Insets) {
val extraPadding = resources.getDimensionPixelOffset(R.dimen.list_spacing)
requireViewBinding().root.updatePadding(
top = extraPadding,
right = insets.right,
left = insets.left,
bottom = insets.bottom,
)
}
override fun onItemClick(item: SettingsItem, view: View) = viewModel.navigateToPreference(item) override fun onItemClick(item: SettingsItem, view: View) = viewModel.navigateToPreference(item)
override fun onCurrentListChanged( override fun onCurrentListChanged(

View File

@@ -7,9 +7,7 @@ import android.os.Bundle
import android.view.MenuItem import android.view.MenuItem
import android.widget.Toast import android.widget.Toast
import androidx.activity.result.contract.ActivityResultContract import androidx.activity.result.contract.ActivityResultContract
import androidx.core.graphics.Insets
import androidx.core.view.isVisible import androidx.core.view.isVisible
import androidx.core.view.updatePadding
import dagger.hilt.android.AndroidEntryPoint import dagger.hilt.android.AndroidEntryPoint
import org.koitharu.kotatsu.R import org.koitharu.kotatsu.R
import org.koitharu.kotatsu.browser.BrowserCallback import org.koitharu.kotatsu.browser.BrowserCallback
@@ -125,11 +123,6 @@ class SourceAuthActivity : BaseActivity<ActivityBrowserBinding>(), BrowserCallba
onBackPressedCallback.onHistoryChanged() onBackPressedCallback.onHistoryChanged()
} }
override fun onWindowInsetsChanged(insets: Insets) {
viewBinding.appbar.updatePadding(top = insets.top)
viewBinding.webView.updatePadding(bottom = insets.bottom)
}
class Contract : ActivityResultContract<MangaSource, Boolean>() { class Contract : ActivityResultContract<MangaSource, Boolean>() {
override fun createIntent(context: Context, input: MangaSource): Intent { override fun createIntent(context: Context, input: MangaSource): Intent {
return AppRouter.sourceAuthIntent(context, input) return AppRouter.sourceAuthIntent(context, input)

View File

@@ -1,14 +1,13 @@
package org.koitharu.kotatsu.settings.sources.catalog package org.koitharu.kotatsu.settings.sources.catalog
import android.os.Bundle import android.os.Bundle
import android.view.Gravity
import android.view.Menu import android.view.Menu
import android.view.MenuItem import android.view.MenuItem
import android.view.View import android.view.View
import androidx.activity.viewModels import androidx.activity.viewModels
import androidx.appcompat.widget.PopupMenu import androidx.appcompat.widget.PopupMenu
import androidx.appcompat.widget.SearchView import androidx.appcompat.widget.SearchView
import androidx.core.graphics.Insets
import androidx.core.view.updatePadding
import coil3.ImageLoader import coil3.ImageLoader
import com.google.android.material.appbar.AppBarLayout import com.google.android.material.appbar.AppBarLayout
import com.google.android.material.chip.Chip import com.google.android.material.chip.Chip
@@ -24,6 +23,7 @@ import org.koitharu.kotatsu.core.ui.util.ReversibleActionObserver
import org.koitharu.kotatsu.core.ui.widgets.ChipsView import org.koitharu.kotatsu.core.ui.widgets.ChipsView
import org.koitharu.kotatsu.core.ui.widgets.ChipsView.ChipModel import org.koitharu.kotatsu.core.ui.widgets.ChipsView.ChipModel
import org.koitharu.kotatsu.core.util.LocaleComparator import org.koitharu.kotatsu.core.util.LocaleComparator
import org.koitharu.kotatsu.core.util.ext.consumeInsetsAsPadding
import org.koitharu.kotatsu.core.util.ext.getDisplayName import org.koitharu.kotatsu.core.util.ext.getDisplayName
import org.koitharu.kotatsu.core.util.ext.observe import org.koitharu.kotatsu.core.util.ext.observe
import org.koitharu.kotatsu.core.util.ext.observeEvent import org.koitharu.kotatsu.core.util.ext.observeEvent
@@ -53,6 +53,7 @@ class SourcesCatalogActivity : BaseActivity<ActivitySourcesCatalogBinding>(),
supportActionBar?.setDisplayHomeAsUpEnabled(true) supportActionBar?.setDisplayHomeAsUpEnabled(true)
val sourcesAdapter = SourcesCatalogAdapter(this, coil, this) val sourcesAdapter = SourcesCatalogAdapter(this, coil, this)
with(viewBinding.recyclerView) { with(viewBinding.recyclerView) {
consumeInsetsAsPadding(Gravity.START or Gravity.END or Gravity.BOTTOM)
setHasFixedSize(true) setHasFixedSize(true)
addItemDecoration(TypedListSpacingDecoration(context, false)) addItemDecoration(TypedListSpacingDecoration(context, false))
adapter = sourcesAdapter adapter = sourcesAdapter
@@ -70,16 +71,6 @@ class SourcesCatalogActivity : BaseActivity<ActivitySourcesCatalogBinding>(),
addMenuProvider(SourcesCatalogMenuProvider(this, viewModel, this)) addMenuProvider(SourcesCatalogMenuProvider(this, viewModel, this))
} }
override fun onWindowInsetsChanged(insets: Insets) {
viewBinding.root.updatePadding(
left = insets.left,
right = insets.right,
)
viewBinding.recyclerView.updatePadding(
bottom = insets.bottom,
)
}
override fun onChipClick(chip: Chip, data: Any?) { override fun onChipClick(chip: Chip, data: Any?) {
when (data) { when (data) {
is ContentType -> viewModel.setContentType(data, !chip.isChecked) is ContentType -> viewModel.setContentType(data, !chip.isChecked)

View File

@@ -1,15 +1,14 @@
package org.koitharu.kotatsu.settings.sources.manage package org.koitharu.kotatsu.settings.sources.manage
import android.os.Bundle import android.os.Bundle
import android.view.Gravity
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.Menu import android.view.Menu
import android.view.MenuInflater import android.view.MenuInflater
import android.view.MenuItem import android.view.MenuItem
import android.view.ViewGroup import android.view.ViewGroup
import androidx.appcompat.widget.SearchView import androidx.appcompat.widget.SearchView
import androidx.core.graphics.Insets
import androidx.core.view.MenuProvider import androidx.core.view.MenuProvider
import androidx.core.view.updatePadding
import androidx.fragment.app.viewModels import androidx.fragment.app.viewModels
import androidx.recyclerview.widget.ItemTouchHelper import androidx.recyclerview.widget.ItemTouchHelper
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
@@ -24,6 +23,7 @@ import org.koitharu.kotatsu.core.ui.BaseFragment
import org.koitharu.kotatsu.core.ui.util.RecyclerViewOwner import org.koitharu.kotatsu.core.ui.util.RecyclerViewOwner
import org.koitharu.kotatsu.core.ui.util.ReversibleActionObserver import org.koitharu.kotatsu.core.ui.util.ReversibleActionObserver
import org.koitharu.kotatsu.core.util.ext.addMenuProvider import org.koitharu.kotatsu.core.util.ext.addMenuProvider
import org.koitharu.kotatsu.core.util.ext.consumeInsetsAsPadding
import org.koitharu.kotatsu.core.util.ext.getItem import org.koitharu.kotatsu.core.util.ext.getItem
import org.koitharu.kotatsu.core.util.ext.observe import org.koitharu.kotatsu.core.util.ext.observe
import org.koitharu.kotatsu.core.util.ext.observeEvent import org.koitharu.kotatsu.core.util.ext.observeEvent
@@ -72,6 +72,7 @@ class SourcesManageFragment :
sourcesAdapter = SourceConfigAdapter(this, coil, viewLifecycleOwner) sourcesAdapter = SourceConfigAdapter(this, coil, viewLifecycleOwner)
with(binding.recyclerView) { with(binding.recyclerView) {
setHasFixedSize(true) setHasFixedSize(true)
consumeInsetsAsPadding(Gravity.START or Gravity.END or Gravity.BOTTOM)
adapter = sourcesAdapter adapter = sourcesAdapter
reorderHelper = ItemTouchHelper(SourcesReorderCallback()).also { reorderHelper = ItemTouchHelper(SourcesReorderCallback()).also {
it.attachToRecyclerView(this) it.attachToRecyclerView(this)
@@ -96,14 +97,6 @@ class SourcesManageFragment :
super.onDestroyView() super.onDestroyView()
} }
override fun onWindowInsetsChanged(insets: Insets) {
requireViewBinding().recyclerView.updatePadding(
bottom = insets.bottom,
left = insets.left,
right = insets.right,
)
}
override fun onItemSettingsClick(item: SourceConfigItem.SourceItem) { override fun onItemSettingsClick(item: SourceConfigItem.SourceItem) {
(activity as? SettingsActivity)?.openFragment( (activity as? SettingsActivity)?.openFragment(
fragmentClass = SourceSettingsFragment::class.java, fragmentClass = SourceSettingsFragment::class.java,

View File

@@ -9,6 +9,9 @@ import android.view.ViewGroup
import androidx.activity.result.contract.ActivityResultContracts import androidx.activity.result.contract.ActivityResultContracts
import androidx.activity.viewModels import androidx.activity.viewModels
import androidx.core.graphics.Insets import androidx.core.graphics.Insets
import androidx.core.view.OnApplyWindowInsetsListener
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import androidx.core.view.isVisible import androidx.core.view.isVisible
import androidx.core.view.updateLayoutParams import androidx.core.view.updateLayoutParams
import androidx.core.view.updatePadding import androidx.core.view.updatePadding
@@ -30,7 +33,7 @@ import org.koitharu.kotatsu.settings.storage.RequestStorageManagerPermissionCont
@AndroidEntryPoint @AndroidEntryPoint
class MangaDirectoriesActivity : BaseActivity<ActivityMangaDirectoriesBinding>(), class MangaDirectoriesActivity : BaseActivity<ActivityMangaDirectoriesBinding>(),
OnListItemClickListener<DirectoryModel>, View.OnClickListener { OnListItemClickListener<DirectoryModel>, View.OnClickListener, OnApplyWindowInsetsListener {
private val viewModel: MangaDirectoriesViewModel by viewModels() private val viewModel: MangaDirectoriesViewModel by viewModels()
private val pickFileTreeLauncher = OpenDocumentTreeHelper( private val pickFileTreeLauncher = OpenDocumentTreeHelper(
@@ -61,6 +64,7 @@ class MangaDirectoriesActivity : BaseActivity<ActivityMangaDirectoriesBinding>()
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
setContentView(ActivityMangaDirectoriesBinding.inflate(layoutInflater)) setContentView(ActivityMangaDirectoriesBinding.inflate(layoutInflater))
ViewCompat.setOnApplyWindowInsetsListener(viewBinding.root, this)
supportActionBar?.setDisplayHomeAsUpEnabled(true) supportActionBar?.setDisplayHomeAsUpEnabled(true)
val adapter = AsyncListDifferDelegationAdapter(DirectoryDiffCallback(), directoryConfigAD(this)) val adapter = AsyncListDifferDelegationAdapter(DirectoryDiffCallback(), directoryConfigAD(this))
viewBinding.recyclerView.adapter = adapter viewBinding.recyclerView.adapter = adapter
@@ -87,18 +91,22 @@ class MangaDirectoriesActivity : BaseActivity<ActivityMangaDirectoriesBinding>()
} }
} }
override fun onWindowInsetsChanged(insets: Insets) { override fun onApplyWindowInsets(v: View, insets: WindowInsetsCompat): WindowInsetsCompat {
val barsInsets = insets.getInsets(WindowInsetsCompat.Type.systemBars())
viewBinding.fabAdd.updateLayoutParams<ViewGroup.MarginLayoutParams> { viewBinding.fabAdd.updateLayoutParams<ViewGroup.MarginLayoutParams> {
rightMargin = topMargin + insets.right rightMargin = topMargin + barsInsets.right
leftMargin = topMargin + insets.left leftMargin = topMargin + barsInsets.left
bottomMargin = topMargin + insets.bottom bottomMargin = topMargin + barsInsets.bottom
} }
viewBinding.root.updatePadding( viewBinding.root.updatePadding(
left = insets.left, left = barsInsets.left,
right = insets.right, right = barsInsets.right,
) )
viewBinding.recyclerView.updatePadding( viewBinding.recyclerView.updatePadding(
bottom = insets.bottom, bottom = barsInsets.bottom,
) )
return WindowInsetsCompat.Builder(insets)
.setInsets(WindowInsetsCompat.Type.systemBars(), Insets.NONE)
.build()
} }
} }

View File

@@ -8,7 +8,6 @@ import android.view.ViewStub
import android.widget.CompoundButton import android.widget.CompoundButton
import androidx.activity.viewModels import androidx.activity.viewModels
import androidx.appcompat.widget.PopupMenu import androidx.appcompat.widget.PopupMenu
import androidx.core.graphics.Insets
import androidx.core.view.isGone import androidx.core.view.isGone
import androidx.core.view.isVisible import androidx.core.view.isVisible
import androidx.recyclerview.widget.AsyncListDiffer import androidx.recyclerview.widget.AsyncListDiffer
@@ -89,8 +88,6 @@ class StatsActivity : BaseActivity<ActivityStatsBinding>(),
} }
} }
override fun onWindowInsetsChanged(insets: Insets) = Unit
override fun onClick(v: View) { override fun onClick(v: View) {
when (v.id) { when (v.id) {
R.id.chip_period -> showPeriodSelector() R.id.chip_period -> showPeriodSelector()

View File

@@ -1,8 +1,6 @@
package org.koitharu.kotatsu.suggestions.ui package org.koitharu.kotatsu.suggestions.ui
import android.os.Bundle import android.os.Bundle
import androidx.core.graphics.Insets
import androidx.core.view.updatePadding
import androidx.fragment.app.commit import androidx.fragment.app.commit
import com.google.android.material.appbar.AppBarLayout import com.google.android.material.appbar.AppBarLayout
import dagger.hilt.android.AndroidEntryPoint import dagger.hilt.android.AndroidEntryPoint
@@ -31,11 +29,4 @@ class SuggestionsActivity :
} }
} }
} }
override fun onWindowInsetsChanged(insets: Insets) {
viewBinding.root.updatePadding(
left = insets.left,
right = insets.right,
)
}
} }

View File

@@ -11,7 +11,6 @@ import android.widget.Button
import android.widget.Toast import android.widget.Toast
import androidx.activity.OnBackPressedCallback import androidx.activity.OnBackPressedCallback
import androidx.activity.viewModels import androidx.activity.viewModels
import androidx.core.graphics.Insets
import androidx.core.view.isVisible import androidx.core.view.isVisible
import androidx.fragment.app.FragmentResultListener import androidx.fragment.app.FragmentResultListener
import androidx.transition.Fade import androidx.transition.Fade
@@ -66,16 +65,6 @@ class SyncAuthActivity : BaseActivity<ActivitySyncAuthBinding>(), View.OnClickLi
pageBackCallback.update() pageBackCallback.update()
} }
override fun onWindowInsetsChanged(insets: Insets) {
val basePadding = resources.getDimensionPixelOffset(R.dimen.screen_padding)
viewBinding.root.setPadding(
basePadding + insets.left,
basePadding + insets.top,
basePadding + insets.right,
basePadding + insets.bottom,
)
}
override fun onClick(v: View) { override fun onClick(v: View) {
when (v.id) { when (v.id) {
R.id.button_cancel -> { R.id.button_cancel -> {

View File

@@ -1,16 +1,16 @@
package org.koitharu.kotatsu.tracker.ui.debug package org.koitharu.kotatsu.tracker.ui.debug
import android.os.Bundle import android.os.Bundle
import android.view.Gravity
import android.view.View import android.view.View
import androidx.activity.viewModels import androidx.activity.viewModels
import androidx.core.graphics.Insets
import androidx.core.view.updatePadding
import coil3.ImageLoader import coil3.ImageLoader
import dagger.hilt.android.AndroidEntryPoint import dagger.hilt.android.AndroidEntryPoint
import org.koitharu.kotatsu.core.nav.router import org.koitharu.kotatsu.core.nav.router
import org.koitharu.kotatsu.core.ui.BaseActivity import org.koitharu.kotatsu.core.ui.BaseActivity
import org.koitharu.kotatsu.core.ui.BaseListAdapter import org.koitharu.kotatsu.core.ui.BaseListAdapter
import org.koitharu.kotatsu.core.ui.list.OnListItemClickListener import org.koitharu.kotatsu.core.ui.list.OnListItemClickListener
import org.koitharu.kotatsu.core.util.ext.consumeInsetsAsPadding
import org.koitharu.kotatsu.core.util.ext.observe import org.koitharu.kotatsu.core.util.ext.observe
import org.koitharu.kotatsu.databinding.ActivityTrackerDebugBinding import org.koitharu.kotatsu.databinding.ActivityTrackerDebugBinding
import org.koitharu.kotatsu.list.ui.adapter.ListItemType import org.koitharu.kotatsu.list.ui.adapter.ListItemType
@@ -32,6 +32,7 @@ class TrackerDebugActivity : BaseActivity<ActivityTrackerDebugBinding>(), OnList
val tracksAdapter = BaseListAdapter<TrackDebugItem>() val tracksAdapter = BaseListAdapter<TrackDebugItem>()
.addDelegate(ListItemType.FEED, trackDebugAD(this, coil, this)) .addDelegate(ListItemType.FEED, trackDebugAD(this, coil, this))
with(viewBinding.recyclerView) { with(viewBinding.recyclerView) {
consumeInsetsAsPadding(Gravity.START or Gravity.END or Gravity.BOTTOM)
setHasFixedSize(true) setHasFixedSize(true)
adapter = tracksAdapter adapter = tracksAdapter
addItemDecoration(TypedListSpacingDecoration(context, false)) addItemDecoration(TypedListSpacingDecoration(context, false))
@@ -39,19 +40,6 @@ class TrackerDebugActivity : BaseActivity<ActivityTrackerDebugBinding>(), OnList
viewModel.content.observe(this, tracksAdapter) viewModel.content.observe(this, tracksAdapter)
} }
override fun onWindowInsetsChanged(insets: Insets) {
val rv = viewBinding.recyclerView
rv.updatePadding(
left = insets.left + rv.paddingTop,
right = insets.right + rv.paddingTop,
bottom = insets.bottom,
)
viewBinding.toolbar.updatePadding(
left = insets.left,
right = insets.right,
)
}
override fun onItemClick(item: TrackDebugItem, view: View) { override fun onItemClick(item: TrackDebugItem, view: View) {
router.openDetails(item.manga) router.openDetails(item.manga)
} }

View File

@@ -4,8 +4,6 @@ import android.os.Bundle
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.core.graphics.Insets
import androidx.core.view.updatePadding
import androidx.fragment.app.viewModels import androidx.fragment.app.viewModels
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
@@ -79,13 +77,6 @@ class FeedFragment :
viewModel.isRunning.observe(viewLifecycleOwner, this::onIsTrackerRunningChanged) viewModel.isRunning.observe(viewLifecycleOwner, this::onIsTrackerRunningChanged)
} }
override fun onWindowInsetsChanged(insets: Insets) {
val rv = requireViewBinding().recyclerView
rv.updatePadding(
bottom = insets.bottom + rv.paddingTop,
)
}
override fun onRefresh() { override fun onRefresh() {
viewModel.update() viewModel.update()
} }

View File

@@ -1,8 +1,6 @@
package org.koitharu.kotatsu.tracker.ui.updates package org.koitharu.kotatsu.tracker.ui.updates
import android.os.Bundle import android.os.Bundle
import androidx.core.graphics.Insets
import androidx.core.view.updatePadding
import androidx.fragment.app.commit import androidx.fragment.app.commit
import com.google.android.material.appbar.AppBarLayout import com.google.android.material.appbar.AppBarLayout
import dagger.hilt.android.AndroidEntryPoint import dagger.hilt.android.AndroidEntryPoint
@@ -32,11 +30,4 @@ class UpdatesActivity :
} }
} }
} }
override fun onWindowInsetsChanged(insets: Insets) {
viewBinding.root.updatePadding(
left = insets.left,
right = insets.right,
)
}
} }

View File

@@ -3,13 +3,13 @@ package org.koitharu.kotatsu.widget.recent
import android.appwidget.AppWidgetManager import android.appwidget.AppWidgetManager
import android.content.Intent import android.content.Intent
import android.os.Bundle import android.os.Bundle
import android.view.Gravity
import android.view.View import android.view.View
import androidx.core.graphics.Insets
import androidx.core.view.updatePadding
import dagger.hilt.android.AndroidEntryPoint import dagger.hilt.android.AndroidEntryPoint
import org.koitharu.kotatsu.R import org.koitharu.kotatsu.R
import org.koitharu.kotatsu.core.prefs.AppWidgetConfig import org.koitharu.kotatsu.core.prefs.AppWidgetConfig
import org.koitharu.kotatsu.core.ui.BaseActivity import org.koitharu.kotatsu.core.ui.BaseActivity
import org.koitharu.kotatsu.core.util.ext.consumeInsetsAsPadding
import org.koitharu.kotatsu.databinding.ActivityAppwidgetRecentBinding import org.koitharu.kotatsu.databinding.ActivityAppwidgetRecentBinding
import com.google.android.material.R as materialR import com.google.android.material.R as materialR
@@ -28,6 +28,7 @@ class RecentWidgetConfigActivity :
setHomeAsUpIndicator(materialR.drawable.abc_ic_clear_material) setHomeAsUpIndicator(materialR.drawable.abc_ic_clear_material)
} }
viewBinding.buttonDone.setOnClickListener(this) viewBinding.buttonDone.setOnClickListener(this)
viewBinding.root.consumeInsetsAsPadding(Gravity.START or Gravity.END or Gravity.BOTTOM or Gravity.TOP)
val appWidgetId = intent?.getIntExtra( val appWidgetId = intent?.getIntExtra(
AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.EXTRA_APPWIDGET_ID,
AppWidgetManager.INVALID_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID,
@@ -54,15 +55,6 @@ class RecentWidgetConfigActivity :
} }
} }
override fun onWindowInsetsChanged(insets: Insets) {
viewBinding.root.updatePadding(
left = insets.left,
right = insets.right,
bottom = insets.bottom,
top = insets.top,
)
}
private fun updateWidget() { private fun updateWidget() {
val intent = Intent(this, RecentWidgetProvider::class.java) val intent = Intent(this, RecentWidgetProvider::class.java)
intent.action = AppWidgetManager.ACTION_APPWIDGET_UPDATE intent.action = AppWidgetManager.ACTION_APPWIDGET_UPDATE

View File

@@ -1,21 +1,18 @@
package org.koitharu.kotatsu.widget.shelf package org.koitharu.kotatsu.widget.shelf
import android.app.Activity
import android.appwidget.AppWidgetManager import android.appwidget.AppWidgetManager
import android.content.Intent import android.content.Intent
import android.os.Bundle import android.os.Bundle
import android.view.Gravity
import android.view.View import android.view.View
import android.view.ViewGroup
import androidx.activity.viewModels import androidx.activity.viewModels
import androidx.core.graphics.Insets
import androidx.core.view.updateLayoutParams
import androidx.core.view.updatePadding
import dagger.hilt.android.AndroidEntryPoint import dagger.hilt.android.AndroidEntryPoint
import org.koitharu.kotatsu.R import org.koitharu.kotatsu.R
import org.koitharu.kotatsu.core.exceptions.resolve.SnackbarErrorObserver import org.koitharu.kotatsu.core.exceptions.resolve.SnackbarErrorObserver
import org.koitharu.kotatsu.core.prefs.AppWidgetConfig import org.koitharu.kotatsu.core.prefs.AppWidgetConfig
import org.koitharu.kotatsu.core.ui.BaseActivity import org.koitharu.kotatsu.core.ui.BaseActivity
import org.koitharu.kotatsu.core.ui.list.OnListItemClickListener import org.koitharu.kotatsu.core.ui.list.OnListItemClickListener
import org.koitharu.kotatsu.core.util.ext.consumeInsetsAsPadding
import org.koitharu.kotatsu.core.util.ext.observe import org.koitharu.kotatsu.core.util.ext.observe
import org.koitharu.kotatsu.core.util.ext.observeEvent import org.koitharu.kotatsu.core.util.ext.observeEvent
import org.koitharu.kotatsu.databinding.ActivityAppwidgetShelfBinding import org.koitharu.kotatsu.databinding.ActivityAppwidgetShelfBinding
@@ -43,6 +40,7 @@ class ShelfWidgetConfigActivity :
} }
adapter = CategorySelectAdapter(this) adapter = CategorySelectAdapter(this)
viewBinding.recyclerView.adapter = adapter viewBinding.recyclerView.adapter = adapter
viewBinding.recyclerView.consumeInsetsAsPadding(Gravity.START or Gravity.END or Gravity.BOTTOM)
viewBinding.buttonDone.setOnClickListener(this) viewBinding.buttonDone.setOnClickListener(this)
val appWidgetId = intent?.getIntExtra( val appWidgetId = intent?.getIntExtra(
AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.EXTRA_APPWIDGET_ID,
@@ -79,23 +77,6 @@ class ShelfWidgetConfigActivity :
viewModel.checkedId = item.id viewModel.checkedId = item.id
} }
override fun onWindowInsetsChanged(insets: Insets) {
viewBinding.recyclerView.updatePadding(
left = insets.left,
right = insets.right,
bottom = insets.bottom,
)
with(viewBinding.toolbar) {
updatePadding(
left = insets.left,
right = insets.right,
)
updateLayoutParams<ViewGroup.MarginLayoutParams> {
topMargin = insets.top
}
}
}
private fun updateWidget() { private fun updateWidget() {
val intent = Intent(this, ShelfWidgetProvider::class.java) val intent = Intent(this, ShelfWidgetProvider::class.java)
intent.action = AppWidgetManager.ACTION_APPWIDGET_UPDATE intent.action = AppWidgetManager.ACTION_APPWIDGET_UPDATE

View File

@@ -50,7 +50,8 @@
<androidx.constraintlayout.widget.ConstraintLayout <androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent"
android:paddingBottom="@dimen/margin_normal">
<com.google.android.material.imageview.ShapeableImageView <com.google.android.material.imageview.ShapeableImageView
android:id="@+id/imageView_cover" android:id="@+id/imageView_cover"
@@ -328,7 +329,7 @@
android:id="@+id/card_chapters" android:id="@+id/card_chapters"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="0dp" android:layout_height="0dp"
android:layout_marginTop="2dp" android:layout_marginTop="@dimen/grid_spacing_outer"
android:layout_marginEnd="@dimen/side_card_offset" android:layout_marginEnd="@dimen/side_card_offset"
android:layout_marginBottom="@dimen/side_card_offset" android:layout_marginBottom="@dimen/side_card_offset"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"

View File

@@ -34,18 +34,17 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:clipToPadding="false" android:clipToPadding="false"
android:fitsSystemWindows="false" android:fitsSystemWindows="false"
android:paddingLeft="16dp" android:paddingHorizontal="@dimen/margin_normal"
android:paddingRight="16dp"
android:stateListAnimator="@null" android:stateListAnimator="@null"
app:liftOnScrollColor="@null" app:liftOnScroll="false"
app:liftOnScroll="false"> app:liftOnScrollColor="@null">
<org.koitharu.kotatsu.core.ui.widgets.WindowInsetHolder <org.koitharu.kotatsu.core.ui.widgets.WindowInsetHolder
android:id="@+id/insetsHolder" android:id="@+id/insetsHolder"
android:fitsSystemWindows="true"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="top" android:layout_gravity="top"
android:fitsSystemWindows="true"
app:layout_scrollFlags="scroll|enterAlways|snap" /> app:layout_scrollFlags="scroll|enterAlways|snap" />
<FrameLayout <FrameLayout

View File

@@ -10,7 +10,6 @@
android:id="@+id/appbar" android:id="@+id/appbar"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:fitsSystemWindows="true"
app:layout_constraintEnd_toEndOf="@id/container" app:layout_constraintEnd_toEndOf="@id/container"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"> app:layout_constraintTop_toTopOf="parent">

View File

@@ -31,6 +31,7 @@
android:id="@+id/appbar" android:id="@+id/appbar"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:fitsSystemWindows="true"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"> app:layout_constraintTop_toTopOf="parent">

View File

@@ -43,7 +43,7 @@
<androidx.constraintlayout.widget.ConstraintLayout <androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:paddingBottom="@dimen/details_bs_peek_height"> android:paddingBottom="@dimen/margin_normal">
<com.google.android.material.imageview.ShapeableImageView <com.google.android.material.imageview.ShapeableImageView
android:id="@+id/imageView_cover" android:id="@+id/imageView_cover"

View File

@@ -20,7 +20,7 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:clipToPadding="false" android:clipToPadding="false"
android:fitsSystemWindows="false" android:fitsSystemWindows="false"
android:paddingHorizontal="16dp" android:paddingHorizontal="@dimen/margin_normal"
android:stateListAnimator="@null" android:stateListAnimator="@null"
app:liftOnScroll="false" app:liftOnScroll="false"
app:liftOnScrollColor="@null"> app:liftOnScrollColor="@null">
@@ -37,8 +37,8 @@
android:id="@+id/toolbar_card" android:id="@+id/toolbar_card"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="56dp" android:layout_height="56dp"
android:layout_marginTop="16dp" android:layout_marginTop="@dimen/margin_normal"
android:layout_marginBottom="8dp" android:layout_marginBottom="@dimen/margin_small"
android:background="@drawable/search_bar_background" android:background="@drawable/search_bar_background"
android:theme="@style/ThemeOverlay.Kotatsu.MainToolbar" android:theme="@style/ThemeOverlay.Kotatsu.MainToolbar"
app:layout_scrollFlags="scroll|enterAlways|snap"> app:layout_scrollFlags="scroll|enterAlways|snap">