Attach some FABs and snackbars to root CoordinatorLayout

Fixes some issues around snackbars sometimes being out of view.

(cherry picked from commit 479eb1ba71e5dc0529f521a9cc4268eb731dc83a)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/browse/BrowseSourceController.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/main/MainActivity.kt
This commit is contained in:
arkon 2020-07-10 10:44:54 -04:00 committed by Jobobby04
parent 04749a8fce
commit 27ad39b6ce
12 changed files with 212 additions and 99 deletions

View File

@ -0,0 +1,10 @@
package eu.kanade.tachiyomi.ui.base.controller
import com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
interface FabController {
fun configureFab(fab: ExtendedFloatingActionButton) {}
fun cleanupFab(fab: ExtendedFloatingActionButton) {}
}

View File

@ -18,6 +18,7 @@ import com.afollestad.materialdialogs.MaterialDialog
import com.afollestad.materialdialogs.input.input import com.afollestad.materialdialogs.input.input
import com.afollestad.materialdialogs.list.listItems import com.afollestad.materialdialogs.list.listItems
import com.elvishew.xlog.XLog import com.elvishew.xlog.XLog
import com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
import com.google.android.material.snackbar.Snackbar import com.google.android.material.snackbar.Snackbar
import com.tfcporciuncula.flow.Preference import com.tfcporciuncula.flow.Preference
import eu.davidea.flexibleadapter.FlexibleAdapter import eu.davidea.flexibleadapter.FlexibleAdapter
@ -34,13 +35,13 @@ import eu.kanade.tachiyomi.source.ConfigurableSource
import eu.kanade.tachiyomi.source.LocalSource import eu.kanade.tachiyomi.source.LocalSource
import eu.kanade.tachiyomi.source.model.FilterList import eu.kanade.tachiyomi.source.model.FilterList
import eu.kanade.tachiyomi.source.online.HttpSource import eu.kanade.tachiyomi.source.online.HttpSource
import eu.kanade.tachiyomi.ui.base.controller.FabController
import eu.kanade.tachiyomi.ui.base.controller.NucleusController import eu.kanade.tachiyomi.ui.base.controller.NucleusController
import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction
import eu.kanade.tachiyomi.ui.browse.extension.details.SourcePreferencesController import eu.kanade.tachiyomi.ui.browse.extension.details.SourcePreferencesController
import eu.kanade.tachiyomi.ui.browse.source.SourceController import eu.kanade.tachiyomi.ui.browse.source.SourceController
import eu.kanade.tachiyomi.ui.browse.source.browse.SourceFilterSheet.FilterNavigationView.Companion.MAX_SAVED_SEARCHES import eu.kanade.tachiyomi.ui.browse.source.browse.SourceFilterSheet.FilterNavigationView.Companion.MAX_SAVED_SEARCHES
import eu.kanade.tachiyomi.ui.library.ChangeMangaCategoriesDialog import eu.kanade.tachiyomi.ui.library.ChangeMangaCategoriesDialog
import eu.kanade.tachiyomi.ui.main.offsetAppbarHeight
import eu.kanade.tachiyomi.ui.manga.MangaAllInOneController import eu.kanade.tachiyomi.ui.manga.MangaAllInOneController
import eu.kanade.tachiyomi.ui.manga.MangaController import eu.kanade.tachiyomi.ui.manga.MangaController
import eu.kanade.tachiyomi.ui.webview.WebViewActivity import eu.kanade.tachiyomi.ui.webview.WebViewActivity
@ -72,6 +73,7 @@ import uy.kohesive.injekt.injectLazy
*/ */
open class BrowseSourceController(bundle: Bundle) : open class BrowseSourceController(bundle: Bundle) :
NucleusController<SourceControllerBinding, BrowseSourcePresenter>(bundle), NucleusController<SourceControllerBinding, BrowseSourcePresenter>(bundle),
FabController,
FlexibleAdapter.OnItemClickListener, FlexibleAdapter.OnItemClickListener,
FlexibleAdapter.OnItemLongClickListener, FlexibleAdapter.OnItemLongClickListener,
FlexibleAdapter.EndlessScrollListener, FlexibleAdapter.EndlessScrollListener,
@ -113,6 +115,9 @@ open class BrowseSourceController(bundle: Bundle) :
*/ */
private var adapter: FlexibleAdapter<IFlexible<*>>? = null private var adapter: FlexibleAdapter<IFlexible<*>>? = null
private var actionFab: ExtendedFloatingActionButton? = null
private var actionFabScrollListener: RecyclerView.OnScrollListener? = null
/** /**
* Snackbar containing an error message when a request fails. * Snackbar containing an error message when a request fails.
*/ */
@ -189,7 +194,7 @@ open class BrowseSourceController(bundle: Bundle) :
if (presenter.sourceFilters.isEmpty()) { if (presenter.sourceFilters.isEmpty()) {
// SY --> // SY -->
binding.fabFilter.text = activity!!.getString(R.string.eh_saved_searches) actionFab?.text = activity!!.getString(R.string.eh_saved_searches)
// SY <-- // SY <--
} }
@ -303,13 +308,27 @@ open class BrowseSourceController(bundle: Bundle) :
filterSheet?.setFilters(presenter.filterItems) filterSheet?.setFilters(presenter.filterItems)
// TODO: [ExtendedFloatingActionButton] hide/show methods don't work properly // TODO: [ExtendedFloatingActionButton] hide/show methods don't work properly
filterSheet?.setOnShowListener { binding.fabFilter.gone() } filterSheet?.setOnShowListener { actionFab?.gone() }
filterSheet?.setOnDismissListener { binding.fabFilter.visible() } filterSheet?.setOnDismissListener { actionFab?.visible() }
binding.fabFilter.setOnClickListener { filterSheet?.show() } actionFab?.setOnClickListener { filterSheet?.show() }
binding.fabFilter.offsetAppbarHeight(activity!!) actionFab?.visible()
binding.fabFilter.visible() }
override fun configureFab(fab: ExtendedFloatingActionButton) {
actionFab = fab
// Controlled by initFilterSheet()
fab.gone()
fab.setText(R.string.action_filter)
fab.setIconResource(R.drawable.ic_filter_list_24dp)
}
override fun cleanupFab(fab: ExtendedFloatingActionButton) {
actionFabScrollListener?.let { recycler?.removeOnScrollListener(it) }
actionFab = null
} }
override fun onDestroyView(view: View) { override fun onDestroyView(view: View) {
@ -369,7 +388,7 @@ open class BrowseSourceController(bundle: Bundle) :
) )
recycler.clipToPadding = false recycler.clipToPadding = false
binding.fabFilter.shrinkOnScroll(recycler) actionFab?.shrinkOnScroll(recycler)
} }
recycler.setHasFixedSize(true) recycler.setHasFixedSize(true)

View File

@ -9,6 +9,7 @@ import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.view.ActionMode import androidx.appcompat.view.ActionMode
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
import com.google.android.material.snackbar.Snackbar import com.google.android.material.snackbar.Snackbar
import eu.davidea.flexibleadapter.FlexibleAdapter import eu.davidea.flexibleadapter.FlexibleAdapter
import eu.davidea.flexibleadapter.SelectableAdapter import eu.davidea.flexibleadapter.SelectableAdapter
@ -16,9 +17,10 @@ import eu.davidea.flexibleadapter.helpers.UndoHelper
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.database.models.Category import eu.kanade.tachiyomi.data.database.models.Category
import eu.kanade.tachiyomi.databinding.CategoriesControllerBinding import eu.kanade.tachiyomi.databinding.CategoriesControllerBinding
import eu.kanade.tachiyomi.ui.base.controller.FabController
import eu.kanade.tachiyomi.ui.base.controller.NucleusController import eu.kanade.tachiyomi.ui.base.controller.NucleusController
import eu.kanade.tachiyomi.ui.main.offsetAppbarHeight
import eu.kanade.tachiyomi.util.system.toast import eu.kanade.tachiyomi.util.system.toast
import eu.kanade.tachiyomi.util.view.shrinkOnScroll
import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.onEach
import reactivecircus.flowbinding.android.view.clicks import reactivecircus.flowbinding.android.view.clicks
@ -28,6 +30,7 @@ import reactivecircus.flowbinding.android.view.clicks
*/ */
class CategoryController : class CategoryController :
NucleusController<CategoriesControllerBinding, CategoryPresenter>(), NucleusController<CategoriesControllerBinding, CategoryPresenter>(),
FabController,
ActionMode.Callback, ActionMode.Callback,
FlexibleAdapter.OnItemClickListener, FlexibleAdapter.OnItemClickListener,
FlexibleAdapter.OnItemLongClickListener, FlexibleAdapter.OnItemLongClickListener,
@ -46,6 +49,9 @@ class CategoryController :
*/ */
private var adapter: CategoryAdapter? = null private var adapter: CategoryAdapter? = null
private var actionFab: ExtendedFloatingActionButton? = null
private var actionFabScrollListener: RecyclerView.OnScrollListener? = null
/** /**
* Undo helper used for restoring a deleted category. * Undo helper used for restoring a deleted category.
*/ */
@ -89,13 +95,23 @@ class CategoryController :
adapter?.isHandleDragEnabled = true adapter?.isHandleDragEnabled = true
adapter?.isPermanentDelete = false adapter?.isPermanentDelete = false
binding.fab.clicks() actionFabScrollListener = actionFab?.shrinkOnScroll(binding.recycler)
}
override fun configureFab(fab: ExtendedFloatingActionButton) {
actionFab = fab
fab.setText(R.string.action_add)
fab.setIconResource(R.drawable.ic_add_24dp)
fab.clicks()
.onEach { .onEach {
CategoryCreateDialog(this@CategoryController).showDialog(router, null) CategoryCreateDialog(this@CategoryController).showDialog(router, null)
} }
.launchIn(scope) .launchIn(scope)
}
binding.fab.offsetAppbarHeight(activity!!) override fun cleanupFab(fab: ExtendedFloatingActionButton) {
actionFabScrollListener?.let { binding.recycler.removeOnScrollListener(it) }
actionFab = null
} }
/** /**
@ -181,7 +197,7 @@ class CategoryController :
R.id.action_delete -> { R.id.action_delete -> {
undoHelper = UndoHelper(adapter, this) undoHelper = UndoHelper(adapter, this)
undoHelper?.start( undoHelper?.start(
adapter.selectedPositions, view!!, adapter.selectedPositions, activity!!.findViewById(R.id.root_coordinator),
R.string.snack_categories_deleted, R.string.action_undo, 3000 R.string.snack_categories_deleted, R.string.action_undo, 3000
) )

View File

@ -9,15 +9,17 @@ import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.view.ActionMode import androidx.appcompat.view.ActionMode
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
import com.google.android.material.snackbar.Snackbar import com.google.android.material.snackbar.Snackbar
import eu.davidea.flexibleadapter.FlexibleAdapter import eu.davidea.flexibleadapter.FlexibleAdapter
import eu.davidea.flexibleadapter.SelectableAdapter import eu.davidea.flexibleadapter.SelectableAdapter
import eu.davidea.flexibleadapter.helpers.UndoHelper import eu.davidea.flexibleadapter.helpers.UndoHelper
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.databinding.CategoriesControllerBinding import eu.kanade.tachiyomi.databinding.CategoriesControllerBinding
import eu.kanade.tachiyomi.ui.base.controller.FabController
import eu.kanade.tachiyomi.ui.base.controller.NucleusController import eu.kanade.tachiyomi.ui.base.controller.NucleusController
import eu.kanade.tachiyomi.ui.main.offsetAppbarHeight
import eu.kanade.tachiyomi.util.system.toast import eu.kanade.tachiyomi.util.system.toast
import eu.kanade.tachiyomi.util.view.shrinkOnScroll
import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.onEach
import reactivecircus.flowbinding.android.view.clicks import reactivecircus.flowbinding.android.view.clicks
@ -28,6 +30,7 @@ import reactivecircus.flowbinding.android.view.clicks
class SourceCategoryController : class SourceCategoryController :
NucleusController<CategoriesControllerBinding, SourceCategoryPresenter>(), NucleusController<CategoriesControllerBinding, SourceCategoryPresenter>(),
ActionMode.Callback, ActionMode.Callback,
FabController,
FlexibleAdapter.OnItemClickListener, FlexibleAdapter.OnItemClickListener,
FlexibleAdapter.OnItemLongClickListener, FlexibleAdapter.OnItemLongClickListener,
SourceCategoryCreateDialog.Listener, SourceCategoryCreateDialog.Listener,
@ -44,6 +47,9 @@ class SourceCategoryController :
*/ */
private var adapter: SourceCategoryAdapter? = null private var adapter: SourceCategoryAdapter? = null
private var actionFab: ExtendedFloatingActionButton? = null
private var actionFabScrollListener: RecyclerView.OnScrollListener? = null
/** /**
* Undo helper used for restoring a deleted category. * Undo helper used for restoring a deleted category.
*/ */
@ -86,13 +92,23 @@ class SourceCategoryController :
binding.recycler.adapter = adapter binding.recycler.adapter = adapter
adapter?.isPermanentDelete = false adapter?.isPermanentDelete = false
binding.fab.clicks() actionFabScrollListener = actionFab?.shrinkOnScroll(binding.recycler)
}
override fun configureFab(fab: ExtendedFloatingActionButton) {
actionFab = fab
fab.setText(R.string.action_add)
fab.setIconResource(R.drawable.ic_add_24dp)
fab.clicks()
.onEach { .onEach {
SourceCategoryCreateDialog(this@SourceCategoryController).showDialog(router, null) SourceCategoryCreateDialog(this@SourceCategoryController).showDialog(router, null)
} }
.launchIn(scope) .launchIn(scope)
}
binding.fab.offsetAppbarHeight(activity!!) override fun cleanupFab(fab: ExtendedFloatingActionButton) {
actionFabScrollListener?.let { binding.recycler.removeOnScrollListener(it) }
actionFab = null
} }
/** /**
@ -178,7 +194,7 @@ class SourceCategoryController :
R.id.action_delete -> { R.id.action_delete -> {
undoHelper = UndoHelper(adapter, this) undoHelper = UndoHelper(adapter, this)
undoHelper?.start( undoHelper?.start(
adapter.selectedPositions, view!!, adapter.selectedPositions, activity!!.findViewById(R.id.root_coordinator),
R.string.snack_categories_deleted, R.string.action_undo, 3000 R.string.snack_categories_deleted, R.string.action_undo, 3000
) )

View File

@ -7,13 +7,18 @@ import android.view.MenuItem
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.download.DownloadService import eu.kanade.tachiyomi.data.download.DownloadService
import eu.kanade.tachiyomi.data.download.model.Download import eu.kanade.tachiyomi.data.download.model.Download
import eu.kanade.tachiyomi.databinding.DownloadControllerBinding import eu.kanade.tachiyomi.databinding.DownloadControllerBinding
import eu.kanade.tachiyomi.source.model.Page import eu.kanade.tachiyomi.source.model.Page
import eu.kanade.tachiyomi.ui.base.controller.FabController
import eu.kanade.tachiyomi.ui.base.controller.NucleusController import eu.kanade.tachiyomi.ui.base.controller.NucleusController
import eu.kanade.tachiyomi.ui.main.offsetAppbarHeight import eu.kanade.tachiyomi.util.view.gone
import eu.kanade.tachiyomi.util.view.shrinkOnScroll
import eu.kanade.tachiyomi.util.view.visible
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.onEach
@ -28,6 +33,7 @@ import rx.android.schedulers.AndroidSchedulers
*/ */
class DownloadController : class DownloadController :
NucleusController<DownloadControllerBinding, DownloadPresenter>(), NucleusController<DownloadControllerBinding, DownloadPresenter>(),
FabController,
DownloadAdapter.DownloadItemListener { DownloadAdapter.DownloadItemListener {
/** /**
@ -35,6 +41,9 @@ class DownloadController :
*/ */
private var adapter: DownloadAdapter? = null private var adapter: DownloadAdapter? = null
private var actionFab: ExtendedFloatingActionButton? = null
private var actionFabScrollListener: RecyclerView.OnScrollListener? = null
/** /**
* Map of subscriptions for active downloads. * Map of subscriptions for active downloads.
*/ */
@ -78,22 +87,7 @@ class DownloadController :
binding.recycler.layoutManager = LinearLayoutManager(view.context) binding.recycler.layoutManager = LinearLayoutManager(view.context)
binding.recycler.setHasFixedSize(true) binding.recycler.setHasFixedSize(true)
binding.fab.clicks() actionFabScrollListener = actionFab?.shrinkOnScroll(binding.recycler)
.onEach {
val context = applicationContext ?: return@onEach
if (isRunning) {
DownloadService.stop(context)
presenter.pauseDownloads()
} else {
DownloadService.start(context)
}
setInformationView()
}
.launchIn(scope)
binding.fab.offsetAppbarHeight(activity!!)
// Subscribe to changes // Subscribe to changes
DownloadService.runningRelay DownloadService.runningRelay
@ -109,6 +103,29 @@ class DownloadController :
.subscribeUntilDestroy { onUpdateDownloadedPages(it) } .subscribeUntilDestroy { onUpdateDownloadedPages(it) }
} }
override fun configureFab(fab: ExtendedFloatingActionButton) {
actionFab = fab
fab.clicks()
.onEach {
val context = applicationContext ?: return@onEach
if (isRunning) {
DownloadService.stop(context)
presenter.pauseDownloads()
} else {
DownloadService.start(context)
}
setInformationView()
}
.launchIn(scope)
}
override fun cleanupFab(fab: ExtendedFloatingActionButton) {
actionFabScrollListener?.let { binding.recycler.removeOnScrollListener(it) }
actionFab = null
}
override fun onDestroyView(view: View) { override fun onDestroyView(view: View) {
for (subscription in progressSubscriptions.values) { for (subscription in progressSubscriptions.values) {
subscription.unsubscribe() subscription.unsubscribe()
@ -267,12 +284,21 @@ class DownloadController :
private fun setInformationView() { private fun setInformationView() {
if (presenter.downloadQueue.isEmpty()) { if (presenter.downloadQueue.isEmpty()) {
binding.emptyView.show(R.string.information_no_downloads) binding.emptyView.show(R.string.information_no_downloads)
binding.fab.hide() actionFab?.gone()
} else { } else {
binding.emptyView.hide() binding.emptyView.hide()
binding.fab.show() actionFab?.apply {
visible()
binding.fab.setImageResource( setText(
if (isRunning) {
R.string.action_pause
} else {
R.string.action_resume
}
)
setIconResource(
if (isRunning) { if (isRunning) {
R.drawable.ic_pause_24dp R.drawable.ic_pause_24dp
} else { } else {
@ -281,6 +307,7 @@ class DownloadController :
) )
} }
} }
}
/** /**
* Called when an item is released from a drag. * Called when an item is released from a drag.

View File

@ -3,8 +3,10 @@ package eu.kanade.tachiyomi.ui.main
import android.app.Activity import android.app.Activity
import android.app.SearchManager import android.app.SearchManager
import android.content.Intent import android.content.Intent
import android.net.Uri
import android.os.Bundle import android.os.Bundle
import android.os.Looper import android.os.Looper
import android.view.Gravity
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.Toast import android.widget.Toast
@ -16,13 +18,16 @@ import com.bluelinelabs.conductor.Router
import com.bluelinelabs.conductor.RouterTransaction import com.bluelinelabs.conductor.RouterTransaction
import com.google.android.material.appbar.AppBarLayout import com.google.android.material.appbar.AppBarLayout
import com.google.android.material.behavior.HideBottomViewOnScrollBehavior import com.google.android.material.behavior.HideBottomViewOnScrollBehavior
import com.google.android.material.snackbar.Snackbar
import com.google.android.material.tabs.TabLayout import com.google.android.material.tabs.TabLayout
import eu.kanade.tachiyomi.BuildConfig
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.notification.NotificationReceiver import eu.kanade.tachiyomi.data.notification.NotificationReceiver
import eu.kanade.tachiyomi.databinding.MainActivityBinding import eu.kanade.tachiyomi.databinding.MainActivityBinding
import eu.kanade.tachiyomi.extension.api.ExtensionGithubApi import eu.kanade.tachiyomi.extension.api.ExtensionGithubApi
import eu.kanade.tachiyomi.ui.base.activity.BaseActivity import eu.kanade.tachiyomi.ui.base.activity.BaseActivity
import eu.kanade.tachiyomi.ui.base.controller.DialogController import eu.kanade.tachiyomi.ui.base.controller.DialogController
import eu.kanade.tachiyomi.ui.base.controller.FabController
import eu.kanade.tachiyomi.ui.base.controller.NoToolbarElevationController import eu.kanade.tachiyomi.ui.base.controller.NoToolbarElevationController
import eu.kanade.tachiyomi.ui.base.controller.RootController import eu.kanade.tachiyomi.ui.base.controller.RootController
import eu.kanade.tachiyomi.ui.base.controller.TabbedController import eu.kanade.tachiyomi.ui.base.controller.TabbedController
@ -38,6 +43,10 @@ import eu.kanade.tachiyomi.ui.recent.history.HistoryController
import eu.kanade.tachiyomi.ui.recent.updates.UpdatesController import eu.kanade.tachiyomi.ui.recent.updates.UpdatesController
import eu.kanade.tachiyomi.util.lang.launchIO import eu.kanade.tachiyomi.util.lang.launchIO
import eu.kanade.tachiyomi.util.lang.launchUI import eu.kanade.tachiyomi.util.lang.launchUI
import eu.kanade.tachiyomi.util.system.toast
import eu.kanade.tachiyomi.util.view.gone
import eu.kanade.tachiyomi.util.view.snack
import eu.kanade.tachiyomi.util.view.visible
import exh.EH_SOURCE_ID import exh.EH_SOURCE_ID
import exh.EIGHTMUSES_SOURCE_ID import exh.EIGHTMUSES_SOURCE_ID
import exh.EXHMigrations import exh.EXHMigrations
@ -176,10 +185,10 @@ class MainActivity : BaseActivity<MainActivityBinding>() {
syncActivityViewWithController(router.backstack.lastOrNull()?.controller()) syncActivityViewWithController(router.backstack.lastOrNull()?.controller())
if (savedInstanceState == null) { if (savedInstanceState == null) {
// Show changelog if needed // Show changelog prompt on update
// TODO // TODO
// if (Migrations.upgrade(preferences)) { // if (Migrations.upgrade(preferences) && !BuildConfig.DEBUG) {
// ChangelogDialogController().showDialog(router) // showUpdateInfoSnackbar()
// } // }
// EXH --> // EXH -->
@ -427,6 +436,15 @@ class MainActivity : BaseActivity<MainActivityBinding>() {
binding.tabs.setupWithViewPager(null) binding.tabs.setupWithViewPager(null)
} }
if (from is FabController) {
binding.rootFab.gone()
from.cleanupFab(binding.rootFab)
}
if (to is FabController) {
binding.rootFab.visible()
to.configureFab(binding.rootFab)
}
if (to is NoToolbarElevationController) { if (to is NoToolbarElevationController) {
binding.appbar.disableElevation() binding.appbar.disableElevation()
} else { } else {
@ -452,6 +470,32 @@ class MainActivity : BaseActivity<MainActivityBinding>() {
} }
} }
private fun showUpdateInfoSnackbar() {
val snack = binding.rootCoordinator.snack(
getString(R.string.updated_version, BuildConfig.VERSION_NAME),
Snackbar.LENGTH_INDEFINITE
) {
setAction(R.string.whats_new) {
val url = "https://github.com/inorichi/tachiyomi/releases/tag/v${BuildConfig.VERSION_NAME}"
val intent = Intent(Intent.ACTION_VIEW, Uri.parse(url))
startActivity(intent)
}
// Ensure the snackbar sits above the bottom nav
val layoutParams = view.layoutParams as CoordinatorLayout.LayoutParams
layoutParams.anchorId = binding.bottomNav.id
layoutParams.anchorGravity = Gravity.TOP
layoutParams.gravity = Gravity.TOP
view.layoutParams = layoutParams
}
// Manually handle dismiss delay since Snackbar.LENGTH_LONG is a too short
launchIO {
delay(5000)
snack.dismiss()
}
}
companion object { companion object {
// Shortcut actions // Shortcut actions
const val SHORTCUT_LIBRARY = "eu.kanade.tachiyomi.SHOW_LIBRARY" const val SHORTCUT_LIBRARY = "eu.kanade.tachiyomi.SHOW_LIBRARY"

View File

@ -82,8 +82,8 @@ inline fun View.toggle() {
* *
* @param recycler [RecyclerView] that the FAB should shrink/extend in response to. * @param recycler [RecyclerView] that the FAB should shrink/extend in response to.
*/ */
fun ExtendedFloatingActionButton.shrinkOnScroll(recycler: RecyclerView) { fun ExtendedFloatingActionButton.shrinkOnScroll(recycler: RecyclerView): RecyclerView.OnScrollListener {
recycler.addOnScrollListener(object : RecyclerView.OnScrollListener() { val listener = object : RecyclerView.OnScrollListener() {
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) { override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
if (dy <= 0) { if (dy <= 0) {
extend() extend()
@ -91,7 +91,9 @@ fun ExtendedFloatingActionButton.shrinkOnScroll(recycler: RecyclerView) {
shrink() shrink()
} }
} }
}) }
recycler.addOnScrollListener(listener)
return listener
} }
/** /**

View File

@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android" <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent">
@ -14,12 +13,6 @@
android:paddingBottom="@dimen/fab_list_padding" android:paddingBottom="@dimen/fab_list_padding"
tools:listitem="@layout/categories_item" /> tools:listitem="@layout/categories_item" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/fab"
style="@style/Theme.Widget.FAB"
app:layout_anchor="@id/recycler"
app:srcCompat="@drawable/ic_add_24dp" />
<eu.kanade.tachiyomi.widget.EmptyView <eu.kanade.tachiyomi.widget.EmptyView
android:id="@+id/empty_view" android:id="@+id/empty_view"
android:layout_width="wrap_content" android:layout_width="wrap_content"
@ -27,4 +20,4 @@
android:layout_gravity="center" android:layout_gravity="center"
android:visibility="gone" /> android:visibility="gone" />
</androidx.coordinatorlayout.widget.CoordinatorLayout> </FrameLayout>

View File

@ -22,13 +22,6 @@
app:fastScrollerBubbleEnabled="false" app:fastScrollerBubbleEnabled="false"
tools:visibility="visible" /> tools:visibility="visible" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/fab"
style="@style/Theme.Widget.FAB"
android:visibility="gone"
app:layout_anchor="@id/recycler"
app:srcCompat="@drawable/ic_pause_24dp" />
<eu.kanade.tachiyomi.widget.EmptyView <eu.kanade.tachiyomi.widget.EmptyView
android:id="@+id/empty_view" android:id="@+id/empty_view"
android:layout_width="wrap_content" android:layout_width="wrap_content"

View File

@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android" <androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/root_coordinator"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:orientation="vertical"> android:orientation="vertical">
@ -32,6 +33,11 @@
android:layout_height="match_parent" android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior" /> app:layout_behavior="@string/appbar_scrolling_view_behavior" />
<com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
android:id="@+id/root_fab"
style="@style/Theme.Widget.FAB"
android:visibility="gone" />
<com.google.android.material.bottomnavigation.BottomNavigationView <com.google.android.material.bottomnavigation.BottomNavigationView
android:id="@+id/bottom_nav" android:id="@+id/bottom_nav"
style="@style/Widget.MaterialComponents.BottomNavigationView.Colored" style="@style/Widget.MaterialComponents.BottomNavigationView.Colored"

View File

@ -1,14 +1,9 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android" <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout <LinearLayout
android:id="@+id/catalogue_view" android:id="@+id/catalogue_view"
android:layout_width="match_parent" android:layout_width="match_parent"
@ -26,14 +21,6 @@
</LinearLayout> </LinearLayout>
<com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
android:id="@+id/fab_filter"
style="@style/Theme.Widget.FAB"
android:text="@string/action_filter"
android:visibility="gone"
app:icon="@drawable/ic_filter_list_24dp"
app:layout_anchor="@id/catalogue_view" />
<eu.kanade.tachiyomi.widget.EmptyView <eu.kanade.tachiyomi.widget.EmptyView
android:id="@+id/empty_view" android:id="@+id/empty_view"
android:layout_width="match_parent" android:layout_width="match_parent"
@ -41,6 +28,4 @@
android:gravity="center" android:gravity="center"
android:visibility="gone" /> android:visibility="gone" />
</FrameLayout> </FrameLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>

View File

@ -388,9 +388,11 @@
<string name="version">Version</string> <string name="version">Version</string>
<string name="build_time">Build time</string> <string name="build_time">Build time</string>
<string name="changelog">Changelog</string> <string name="changelog">Changelog</string>
<string name="whats_new">What\'s new</string>
<string name="notices">Preview build notices</string> <string name="notices">Preview build notices</string>
<string name="licenses">Open source licenses</string> <string name="licenses">Open source licenses</string>
<string name="check_for_updates">Check for updates</string> <string name="check_for_updates">Check for updates</string>
<string name="updated_version">Updated to v%1$s</string>
<!-- ACRA --> <!-- ACRA -->
<string name="pref_enable_acra">Send crash reports</string> <string name="pref_enable_acra">Send crash reports</string>