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:
parent
04749a8fce
commit
27ad39b6ce
@ -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) {}
|
||||||
|
}
|
@ -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)
|
||||||
|
@ -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
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -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
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -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,18 +284,28 @@ 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) {
|
if (isRunning) {
|
||||||
R.drawable.ic_pause_24dp
|
R.string.action_pause
|
||||||
} else {
|
} else {
|
||||||
R.drawable.ic_play_arrow_24dp
|
R.string.action_resume
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
setIconResource(
|
||||||
|
if (isRunning) {
|
||||||
|
R.drawable.ic_pause_24dp
|
||||||
|
} else {
|
||||||
|
R.drawable.ic_play_arrow_24dp
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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"
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -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>
|
||||||
|
@ -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"
|
||||||
|
@ -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"
|
||||||
|
@ -1,46 +1,31 @@
|
|||||||
<?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
|
<LinearLayout
|
||||||
|
android:id="@+id/catalogue_view"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent">
|
android:layout_height="match_parent"
|
||||||
|
android:orientation="vertical"
|
||||||
|
tools:context=".ui.browse.source.browse.BrowseSourceController">
|
||||||
|
|
||||||
<LinearLayout
|
<ProgressBar
|
||||||
android:id="@+id/catalogue_view"
|
android:id="@+id/progress"
|
||||||
android:layout_width="match_parent"
|
style="?android:attr/progressBarStyleLarge"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:orientation="vertical"
|
android:layout_gravity="center"
|
||||||
tools:context=".ui.browse.source.browse.BrowseSourceController">
|
|
||||||
|
|
||||||
<ProgressBar
|
|
||||||
android:id="@+id/progress"
|
|
||||||
style="?android:attr/progressBarStyleLarge"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:layout_gravity="center"
|
|
||||||
android:visibility="gone" />
|
|
||||||
|
|
||||||
</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
|
|
||||||
android:id="@+id/empty_view"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:gravity="center"
|
|
||||||
android:visibility="gone" />
|
android:visibility="gone" />
|
||||||
|
|
||||||
</FrameLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
<eu.kanade.tachiyomi.widget.EmptyView
|
||||||
|
android:id="@+id/empty_view"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:gravity="center"
|
||||||
|
android:visibility="gone" />
|
||||||
|
|
||||||
|
</FrameLayout>
|
||||||
|
@ -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>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user