More snack

This commit is contained in:
Jay 2019-10-30 01:19:30 -07:00
parent 1d0f6e8bce
commit d719cae942
11 changed files with 110 additions and 31 deletions

View File

@ -79,14 +79,12 @@ class CoverCache(private val context: Context) {
// Check if url is empty.
if (thumbnailUrl.isNullOrEmpty()) return
launchUI {
if (delayBy > 0) {
delay(delayBy)
if (manga.favorite) cancel()
delay(delayBy)
if (!manga.favorite) {
// Remove file.
val file = getCoverFile(thumbnailUrl)
if (file.exists()) file.delete()
}
// Remove file.
val file = getCoverFile(thumbnailUrl)
if (file.exists())
file.delete()
}
}

View File

@ -516,7 +516,7 @@ open class BrowseCatalogueController(bundle: Bundle) :
} else {
addManga(manga, position)
snack =
catalogue_view?.snack(activity.getString(R.string.manga_added_library), Snackbar.LENGTH_SHORT)
catalogue_view?.snack(activity.getString(R.string.manga_added_library))
}
}

View File

@ -95,7 +95,7 @@ class LibraryCategoryView @JvmOverloads constructor(context: Context, attrs: Att
swipe_refresh.setOnRefreshListener {
if (!LibraryUpdateService.isRunning(context)) {
LibraryUpdateService.start(context, category)
context.toast(R.string.updating_category)
swipe_refresh.snack(R.string.updating_category)
}
// It can be a very long operation, so we disable swipe refresh and show a toast.
swipe_refresh.isRefreshing = false

View File

@ -157,13 +157,6 @@ class LibraryController(
if (selectedMangas.isNotEmpty()) {
createActionModeIfNeeded()
}
view.doOnApplyWindowInsets { view, insets, psdding ->
val contextView = activity?.window?.decorView?.findViewById<View>(R.id.action_mode_bar)
if (Build.VERSION.SDK_INT >= 23) contextView?.updateLayoutParams<ViewGroup.MarginLayoutParams> {
leftMargin = view.rootWindowInsets.systemWindowInsetLeft
rightMargin = view.rootWindowInsets.systemWindowInsetRight
}
}
}
override fun onChangeStarted(handler: ControllerChangeHandler, type: ControllerChangeType) {

View File

@ -44,6 +44,7 @@ import eu.kanade.tachiyomi.util.doOnApplyWindowInsets
import eu.kanade.tachiyomi.util.marginBottom
import eu.kanade.tachiyomi.util.marginTop
import eu.kanade.tachiyomi.util.openInBrowser
import eu.kanade.tachiyomi.util.updateLayoutParams
import eu.kanade.tachiyomi.util.updatePadding
import eu.kanade.tachiyomi.util.updatePaddingRelative
import kotlinx.android.synthetic.main.chapters_controller.view.*
@ -153,7 +154,11 @@ class MainActivity : BaseActivity() {
val drawerContainer: FrameLayout = findViewById(R.id.drawer_container)
drawerContainer.setOnApplyWindowInsetsListener { v, insets ->
val contextView = window?.decorView?.findViewById<View>(R.id.action_mode_bar)
contextView?.updateLayoutParams<ViewGroup.MarginLayoutParams> {
leftMargin = insets.systemWindowInsetLeft
rightMargin = insets.systemWindowInsetRight
}
// Consume any horizontal insets and pad all content in. There's not much we can do
// with horizontal insets
v.updatePadding(

View File

@ -5,12 +5,15 @@ import android.animation.AnimatorListenerAdapter
import android.annotation.SuppressLint
import android.app.Activity
import android.content.Intent
import android.os.Build
import com.google.android.material.snackbar.Snackbar
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.view.ActionMode
import androidx.recyclerview.widget.DividerItemDecoration
import androidx.recyclerview.widget.LinearLayoutManager
import android.view.*
import androidx.coordinatorlayout.widget.CoordinatorLayout
import com.google.android.material.snackbar.BaseTransientBottomBar
import com.jakewharton.rxbinding.support.v4.widget.refreshes
import com.jakewharton.rxbinding.view.clicks
import eu.davidea.flexibleadapter.FlexibleAdapter
@ -26,6 +29,11 @@ import eu.kanade.tachiyomi.ui.reader.ReaderActivity
import eu.kanade.tachiyomi.util.*
import kotlinx.android.synthetic.main.chapters_controller.*
import timber.log.Timber
import com.google.android.material.floatingactionbutton.FloatingActionButton
import android.content.Context
import android.util.AttributeSet
import androidx.core.view.ViewCompat
import kotlin.math.*
class ChaptersController : NucleusController<ChaptersPresenter>(),
ActionMode.Callback,
@ -48,6 +56,7 @@ class ChaptersController : NucleusController<ChaptersPresenter>(),
*/
private var actionMode: ActionMode? = null
private var snack:Snackbar? = null
/**
* Selected items. Used to restore selections after a rotation.
*/
@ -83,6 +92,11 @@ class ChaptersController : NucleusController<ChaptersPresenter>(),
val fabBaseMarginBottom = fab?.marginBottom ?: 0
recycler.doOnApplyWindowInsets { v, insets, padding ->
v.updatePaddingRelative(bottom = padding.bottom + insets.systemWindowInsetBottom)
//if (snack == null) {
//fab?.translationY = -insets.systemWindowInsetBottom.toFloat()
/*}
else
fab?.translationY = 0f*/
fab?.updateLayoutParams<ViewGroup.MarginLayoutParams> {
bottomMargin = fabBaseMarginBottom + insets.systemWindowInsetBottom
}
@ -108,7 +122,14 @@ class ChaptersController : NucleusController<ChaptersPresenter>(),
openChapter(item.chapter)
}
} else {
view.context.toast(R.string.no_next_chapter)
snack = view.snack(R.string.no_next_chapter, Snackbar.LENGTH_LONG) {
addCallback(object : BaseTransientBottomBar.BaseCallback<Snackbar>() {
override fun onDismissed(transientBottomBar: Snackbar?, event: Int) {
super.onDismissed(transientBottomBar, event)
if (snack == transientBottomBar) snack = null
}
})
}
}
}
}
@ -373,11 +394,17 @@ class ChaptersController : NucleusController<ChaptersPresenter>(),
destroyActionModeIfNeeded()
presenter.downloadChapters(chapters)
if (view != null && !presenter.manga.favorite) {
val snack = view.snack(view.context.getString(R.string.snack_add_to_library), Snackbar
snack = view.snack(view.context.getString(R.string.snack_add_to_library), Snackbar
.LENGTH_INDEFINITE) {
setAction(R.string.action_add) {
presenter.addToLibrary()
}
addCallback(object : BaseTransientBottomBar.BaseCallback<Snackbar>() {
override fun onDismissed(transientBottomBar: Snackbar?, event: Int) {
super.onDismissed(transientBottomBar, event)
if (snack == transientBottomBar) snack = null
}
})
}
}
}
@ -493,3 +520,7 @@ class ChaptersController : NucleusController<ChaptersPresenter>(),
}
}
}
class ShrinkBehavior(context: Context, attrs: AttributeSet) :
CoordinatorLayout.Behavior<FloatingActionButton>(context, attrs) {
}

View File

@ -421,7 +421,7 @@ class MangaInfoController : NucleusController<MangaInfoPresenter>(),
private fun showAddedSnack() {
val view = container
snack?.dismiss()
snack = view?.snack(view.context.getString(R.string.manga_added_library), Snackbar.LENGTH_SHORT)
snack = view?.snack(view.context.getString(R.string.manga_added_library))
}
private fun showRemovedSnack() {

View File

@ -20,6 +20,7 @@ import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction
import eu.kanade.tachiyomi.ui.manga.MangaController
import eu.kanade.tachiyomi.ui.reader.ReaderActivity
import eu.kanade.tachiyomi.util.RecyclerWindowInsetsListener
import eu.kanade.tachiyomi.util.snack
import eu.kanade.tachiyomi.util.toast
import kotlinx.android.synthetic.main.recent_chapters_controller.*
import timber.log.Timber
@ -86,9 +87,9 @@ class RecentChaptersController : NucleusController<RecentChaptersPresenter>(),
swipe_refresh.refreshes().subscribeUntilDestroy {
if (!LibraryUpdateService.isRunning(view.context)) {
LibraryUpdateService.start(view.context)
view.context.toast(R.string.action_update_library)
view.snack(R.string.action_update_library)
}
// It can be a very long operation, so we disable swipe refresh and show a toast.
// It can be a very long operation, so we disable swipe refresh and show a snackbar.
swipe_refresh.isRefreshing = false
}
recycler.setOnApplyWindowInsetsListener(RecyclerWindowInsetsListener)

View File

@ -17,6 +17,7 @@ import android.view.ViewGroup
import android.view.Window
import android.view.WindowInsets
import android.widget.TextView
import androidx.coordinatorlayout.widget.CoordinatorLayout
import com.amulyakhare.textdrawable.TextDrawable
import com.amulyakhare.textdrawable.util.ColorGenerator
import eu.kanade.tachiyomi.R
@ -36,28 +37,45 @@ fun View.getCoordinates() = Point((left + right) / 2, (top + bottom) / 2)
* @param length the duration of the snack.
* @param f a function to execute in the snack, allowing for example to define a custom action.
*/
fun View.snack(message: String, length: Int = Snackbar.LENGTH_LONG, f: (Snackbar.() ->
fun View.snack(message: String, length: Int = Snackbar.LENGTH_SHORT, f: (Snackbar.() ->
Unit)? = null): Snackbar {
val snack = Snackbar.make(this, message, length)
val textView: TextView = snack.view.findViewById(com.google.android.material.R.id.snackbar_text)
textView.setTextColor(context.getResourceColor(android.R.attr.textColorPrimaryInverse))
when {
Build.VERSION.SDK_INT >= 23 -> snack.config(context, rootWindowInsets.systemWindowInsetBottom)
Build.VERSION.SDK_INT >= 23 -> {
val leftM = if (this is CoordinatorLayout) 0 else rootWindowInsets.systemWindowInsetLeft
val rightM = if (this is CoordinatorLayout) 0
else rootWindowInsets.systemWindowInsetRight
snack.config(context, rootWindowInsets
.systemWindowInsetBottom, rightM, leftM)
}
else -> snack.config(context)
}
if (f != null) {
snack.f()
}
snack.view.doOnApplyWindowInsets { v, _, padding ->
v.setPadding(padding.left,0,padding.right,0)
snack.view.doOnApplyWindowInsets { v, insets, padding ->
//v.setPadding(padding.left, 0, padding.right, 0)
v.updateLayoutParams<ViewGroup.MarginLayoutParams> {
if (Build.VERSION.SDK_INT < 23) {
bottomMargin = 12 + insets.systemWindowInsetBottom
}
}
}
snack.show()
return snack
}
fun Snackbar.config(context: Context, bottomMargin: Int = 0) {
fun View.snack(resource: Int, length: Int = Snackbar.LENGTH_SHORT, f: (Snackbar.() ->
Unit)? = null): Snackbar {
return snack(context.getString(resource), length, f)
}
fun Snackbar.config(context: Context, bottomMargin: Int = 0, rightMargin: Int = 0, leftMargin:
Int = 0) {
val params = this.view.layoutParams as ViewGroup.MarginLayoutParams
params.setMargins(12, 12, 12, 12 + bottomMargin)
params.setMargins(12 + leftMargin, 12, 12 + rightMargin, 12 + bottomMargin)
this.view.layoutParams = params
this.view.background = context.getDrawable(R.drawable.bg_snackbar)

View File

@ -7,10 +7,14 @@ import android.util.AttributeSet
import android.view.View
import android.view.animation.Animation
import android.view.animation.AnimationUtils
import androidx.coordinatorlayout.widget.CoordinatorLayout
import com.google.android.material.snackbar.Snackbar
import eu.kanade.tachiyomi.R
import kotlin.math.min
@Suppress("unused", "UNUSED_PARAMETER")
class FABAnimationUpDown @JvmOverloads constructor(ctx: Context, attrs: AttributeSet? = null) : FABAnimationBase() {
class FABAnimationUpDown @JvmOverloads constructor(ctx: Context, attrs: AttributeSet? = null) :
FABAnimationBase() {
private val INTERPOLATOR = FastOutSlowInInterpolator()
@ -48,4 +52,31 @@ class FABAnimationUpDown @JvmOverloads constructor(ctx: Context, attrs: Attribut
button.visibility = View.VISIBLE
button.startAnimation(inAnimation)
}
override fun layoutDependsOn(parent: CoordinatorLayout, child: FloatingActionButton, dependency: View): Boolean {
return dependency is Snackbar.SnackbarLayout
}
override fun onDependentViewChanged(parent: CoordinatorLayout, child: FloatingActionButton, dependency: View): Boolean {
val translationY = getFabTranslationYForSnackbar(parent, child)
val percentComplete = -translationY / dependency.height
val scaleFactor = 1 - percentComplete
child.translationY = -translationY
return false
}
private fun getFabTranslationYForSnackbar(parent: CoordinatorLayout, fab:
FloatingActionButton): Float {
var minOffset = 0f
val dependencies = parent.getDependencies(fab)
for (i in 0 until dependencies.size) {
val view = dependencies[i]
if (view is Snackbar.SnackbarLayout) {
minOffset = min(minOffset, view.translationY - view.height)
}
}
return minOffset
}
}

View File

@ -5,6 +5,7 @@
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false"
android:orientation="vertical">
<eu.kanade.tachiyomi.widget.RevealAnimationView
@ -12,6 +13,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?attr/colorAccent"
android:clipToPadding="false"
android:elevation="5dp"
android:visibility="invisible"/>
@ -20,6 +22,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="@+id/toolbar_bottom"
android:clipToPadding="false"
android:orientation="vertical">
<androidx.recyclerview.widget.RecyclerView
@ -37,8 +40,6 @@
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
<eu.davidea.fastscroller.FastScroller
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/fast_scroller"
android:layout_width="wrap_content"
android:layout_height="match_parent"
@ -51,6 +52,7 @@
android:id="@+id/fab"
style="@style/Theme.Widget.FAB"
app:layout_anchor="@id/recycler"
app:layout_anchorGravity="bottom|right|end"
app:srcCompat="@drawable/ic_play_arrow_white_24dp"/>
</androidx.coordinatorlayout.widget.CoordinatorLayout>