Skip to content

Commit

Permalink
Implement helper methods for displaying snackbars
Browse files Browse the repository at this point in the history
  • Loading branch information
oakkitten committed Dec 28, 2024
1 parent e39e9b5 commit 9c4a92e
Show file tree
Hide file tree
Showing 3 changed files with 121 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,8 @@ import com.ubergeek42.WeechatAndroid.views.DrawerToggleFix
import com.ubergeek42.WeechatAndroid.views.ToolbarController
import com.ubergeek42.WeechatAndroid.views.WeechatActivityFullScreenController
import com.ubergeek42.WeechatAndroid.views.hideSoftwareKeyboard
import com.ubergeek42.WeechatAndroid.views.snackbar.BaseSnackbarBuilderProvider
import com.ubergeek42.WeechatAndroid.views.snackbar.SnackbarBuilder
import com.ubergeek42.WeechatAndroid.views.snackbar.SnackbarPositionController
import com.ubergeek42.WeechatAndroid.views.snackbar.setOrScheduleSettingAnchorAfterPagerChange
import com.ubergeek42.WeechatAndroid.views.solidColor
Expand All @@ -114,7 +116,7 @@ import kotlin.system.exitProcess


class WeechatActivity : AppCompatActivity(), CutePageChangeListener,
BufferListClickListener, BufferFragmentContainer {
BufferListClickListener, BufferFragmentContainer, BaseSnackbarBuilderProvider {
private var uiMenu: Menu? = null

private lateinit var pagerAdapter: MainPagerAdapter
Expand Down Expand Up @@ -156,7 +158,7 @@ class WeechatActivity : AppCompatActivity(), CutePageChangeListener,

setContentView(R.layout.main_screen)
uiDrawer = findViewById(R.id.bufferlist_fragment)
uiWeasel = findViewById(R.id.weasel) // ui.weasel for some reason returns a wrong view
uiWeasel = findViewById(R.id.coordinator_layout) // ui.weasel for some reason returns a wrong view
ui = WeaselBinding.bind(uiWeasel)

setSupportActionBar(ui.toolbar)
Expand Down Expand Up @@ -509,6 +511,10 @@ class WeechatActivity : AppCompatActivity(), CutePageChangeListener,

val snackbarPositionController = SnackbarPositionController()

override val baseSnackbarBuilder: SnackbarBuilder = {
snackbarPositionController.setSnackbar(this)
}

@MainThread @Cat("Menu") override fun onOptionsItemSelected(item: MenuItem): Boolean {
when (item.itemId) {
android.R.id.home -> if (slidy) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
package com.ubergeek42.WeechatAndroid.views.snackbar

import android.app.Activity
import android.view.View
import android.widget.TextView
import androidx.annotation.StringRes
import androidx.coordinatorlayout.widget.CoordinatorLayout
import com.google.android.material.snackbar.Snackbar
import com.ubergeek42.WeechatAndroid.BuildConfig
import com.ubergeek42.WeechatAndroid.R
import com.ubergeek42.WeechatAndroid.utils.Toaster
import com.ubergeek42.cats.Kitty
import com.ubergeek42.cats.Root


@Root private val kitty = Kitty.make("Snackbars")


// Create snackbars by calling `showSnackbar` on either an activity or a view.
// As `CoordinatorLayout` is responsible for proper placement and animation of snackbars,
//
// * if calling on an activity, the activity **MUST** have a `CoordinatorLayout`
// with id `coordinator_layout`;
//
// * if calling on a view, the view **MUST** be either a `CoordinatorLayout`,
// or a (possibly indirect) child of `CoordinatorLayout`.
//
// Additional configuration can be done in the configuration block, e.g.
//
// showSnackbar(text) {
// addCallback(callback)
// }
//
// If an activity wants to alter behavior for all snackbars,
// it can extend `BaseSnackbarBuilderProvider`.


typealias SnackbarBuilder = Snackbar.() -> Unit

interface BaseSnackbarBuilderProvider {
val baseSnackbarBuilder: SnackbarBuilder
}


fun Activity.showSnackbar(
@StringRes textResource: Int,
duration: Int = Snackbar.LENGTH_LONG,
snackbarBuilder: SnackbarBuilder? = null,
) {
val text = getText(textResource)
showSnackbar(text, duration, snackbarBuilder)
}


fun Activity.showSnackbar(
text: CharSequence,
duration: Int = Snackbar.LENGTH_LONG,
snackbarBuilder: SnackbarBuilder? = null,
) {
val view: View? = findViewById(R.id.coordinator_layout) as? CoordinatorLayout

if (view != null) {
val baseSnackbarBuilder = (this as? BaseSnackbarBuilderProvider)?.baseSnackbarBuilder
view.showSnackbar(text, duration) {
baseSnackbarBuilder?.invoke(this)
snackbarBuilder?.invoke(this)
}
} else {
val errorMessage = "While trying to show a snackbar, could not find a view with id coordinator_layout in $this"

if (BuildConfig.DEBUG) {
throw IllegalArgumentException(errorMessage)
} else {
kitty.error(errorMessage)
Toaster.InfoToast.show(errorMessage)
}
}
}


fun View.showSnackbar(
@StringRes textResource: Int,
duration: Int = Snackbar.LENGTH_LONG,
snackbarBuilder: SnackbarBuilder? = null,
) {
val text = resources.getText(textResource)
showSnackbar(text, duration, snackbarBuilder)
}


fun View.showSnackbar(
text: CharSequence,
duration: Int = Snackbar.LENGTH_LONG,
snackbarBuilder: SnackbarBuilder? = null,
) {
val snackbar = Snackbar.make(this, text, duration)
snackbar.setMaxLines(4)
snackbar.behavior = SwipeDismissBehaviorFix()

if (snackbarBuilder != null) {
snackbar.snackbarBuilder()
}

kitty.info("Showing a snackbar: '%s'", text)

snackbar.show()
}


fun Snackbar.setMaxLines(maxLines: Int) {
view.findViewById<TextView>(com.google.android.material.R.id.snackbar_text)?.maxLines = maxLines
}
2 changes: 1 addition & 1 deletion app/src/main/res/layout/weasel.xml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/weasel"
android:id="@+id/coordinator_layout"
android:background="?attr/colorPrimary"
android:layout_width="match_parent"
android:layout_height="match_parent">
Expand Down

0 comments on commit 9c4a92e

Please sign in to comment.