craft-native 0.0.206 → 0.0.209

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -578,6 +578,11 @@ internal class CraftNativeChrome(context: Context, private val tabs: List<CraftN
578
578
  private val largeTitleView = TextView(context)
579
579
  private val buttons = LinearLayout(context)
580
580
  private val tabBar = LinearLayout(context)
581
+ private val tabRow = LinearLayout(context)
582
+ private val accessory = FrameLayout(context)
583
+ private val accessoryIcon = ImageView(context)
584
+ private val accessoryBadge = TextView(context)
585
+ private var accessorySpec: JSONObject? = null
581
586
  private val tabViews = mutableListOf<Pair<TextView, TextView>>()
582
587
  private val tabIconText = mutableMapOf<String, String>()
583
588
  private val tabImageURLs = mutableMapOf<String, String>()
@@ -596,6 +601,7 @@ internal class CraftNativeChrome(context: Context, private val tabs: List<CraftN
596
601
  var onBack: (() -> Unit)? = null
597
602
  var onButton: ((String) -> Unit)? = null
598
603
  var onTab: ((Int) -> Unit)? = null
604
+ var onAccessory: ((String) -> Unit)? = null
599
605
  var onTabSwipeStart: ((Float, Float, Float) -> Boolean)? = null
600
606
  var onTabSwipeMove: ((Float) -> Unit)? = null
601
607
  var onTabSwipeEnd: ((Float, Boolean) -> Unit)? = null
@@ -660,8 +666,22 @@ internal class CraftNativeChrome(context: Context, private val tabs: List<CraftN
660
666
  tabBar.addView(cell, LayoutParams(0, ViewGroup.LayoutParams.MATCH_PARENT, 1f))
661
667
  tabViews.add(icon to label)
662
668
  }
663
- addView(tabBar, LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, dp(64)))
664
- tabBar.visibility = if (tabs.isEmpty()) View.GONE else View.VISIBLE
669
+ tabRow.orientation = HORIZONTAL
670
+ tabRow.gravity = Gravity.CENTER_VERTICAL
671
+ tabRow.setPadding(dp(12), dp(4), dp(12), dp(4))
672
+ tabRow.addView(tabBar, LayoutParams(0, dp(64), 1f))
673
+ accessory.addView(accessoryIcon, FrameLayout.LayoutParams(dp(26), dp(26), Gravity.CENTER))
674
+ accessoryBadge.textSize = 10f
675
+ accessoryBadge.gravity = Gravity.CENTER
676
+ accessoryBadge.setTextColor(Color.WHITE)
677
+ accessoryBadge.setPadding(dp(4), 0, dp(4), 0)
678
+ accessoryBadge.background = GradientDrawable().apply { setColor(Color.RED); cornerRadius = dp(9).toFloat() }
679
+ accessory.addView(accessoryBadge, FrameLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, dp(18), Gravity.TOP or Gravity.END))
680
+ accessory.setOnClickListener { accessorySpec?.optString("path")?.let { onAccessory?.invoke(it) } }
681
+ accessory.visibility = View.GONE
682
+ tabRow.addView(accessory, LayoutParams(dp(64), dp(64)).apply { marginStart = dp(8) })
683
+ addView(tabRow, LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, dp(72)))
684
+ tabRow.visibility = if (tabs.isEmpty()) View.GONE else View.VISIBLE
665
685
  refreshColors()
666
686
  }
667
687
 
@@ -671,7 +691,7 @@ internal class CraftNativeChrome(context: Context, private val tabs: List<CraftN
671
691
  val overHorizontalScroll = onTabSwipeShouldDefer?.invoke(event.x, event.y) == true
672
692
  horizontalScrollDeferred = overHorizontalScroll
673
693
  if (overHorizontalScroll) parent?.requestDisallowInterceptTouchEvent(true)
674
- swipeTracking = tabs.size > 1 && tabSwipeEnabled && !overHorizontalScroll && tabBar.visibility == View.VISIBLE && event.y < tabBar.top
694
+ swipeTracking = tabs.size > 1 && tabSwipeEnabled && !overHorizontalScroll && tabRow.visibility == View.VISIBLE && event.y < tabRow.top
675
695
  swipeIntercepted = false
676
696
  swipeDownX = event.x
677
697
  swipeDownY = event.y
@@ -742,7 +762,17 @@ internal class CraftNativeChrome(context: Context, private val tabs: List<CraftN
742
762
  buttons.addView(navButton(button))
743
763
  }
744
764
  val tabBarHidden = options.optBoolean("tabBarHidden", false) || depth > 0 && options.optBoolean("tabBarHiddenWhenPushed", false)
745
- tabBar.visibility = if (tabs.isEmpty() || tabBarHidden) View.GONE else View.VISIBLE
765
+ tabRow.visibility = if (tabs.isEmpty() || tabBarHidden) View.GONE else View.VISIBLE
766
+ accessorySpec = options.optJSONObject("tabAccessory")?.takeIf {
767
+ val path = it.optString("path")
768
+ path.startsWith("/") && !path.startsWith("//") && it.has("title")
769
+ }
770
+ accessory.visibility = if (accessorySpec == null) View.GONE else View.VISIBLE
771
+ accessorySpec?.let {
772
+ accessory.contentDescription = it.optString("accessibilityLabel").ifBlank { it.optString("title") } + it.optString("badge").takeIf { badge -> badge.isNotBlank() && badge != "null" }?.let { badge -> ", $badge" }.orEmpty()
773
+ accessoryBadge.text = it.optString("badge").takeUnless { badge -> badge == "null" }.orEmpty().take(8)
774
+ accessoryBadge.visibility = if (accessoryBadge.text.isEmpty()) View.GONE else View.VISIBLE
775
+ }
746
776
  tabSwipeEnabled = options.optBoolean("tabSwipeEnabled", true)
747
777
  refreshColors()
748
778
  }
@@ -801,13 +831,10 @@ internal class CraftNativeChrome(context: Context, private val tabs: List<CraftN
801
831
  titleView.setTextColor(text)
802
832
  largeTitleView.setTextColor(text)
803
833
  backButton.imageTintList = ColorStateList.valueOf(accent)
804
- tabBar.setBackgroundColor(if (dark) Color.parseColor("#121212") else Color.parseColor("#F9F9F9"))
805
- val divider = GradientDrawable().apply { setColor(if (dark) Color.parseColor("#262626") else Color.parseColor("#D8D8DC")) }
806
- tabBar.foreground = null
807
- tabBar.background = android.graphics.drawable.LayerDrawable(arrayOf(
808
- divider,
809
- GradientDrawable().apply { setColor(if (dark) Color.parseColor("#121212") else Color.parseColor("#F9F9F9")) },
810
- )).apply { setLayerInset(1, 0, maxOf(1, (density / 2).toInt()), 0, 0) }
834
+ val surface = if (dark) Color.parseColor("#1C1C1E") else Color.parseColor("#F9F9F9")
835
+ tabBar.background = GradientDrawable().apply { setColor(surface); cornerRadius = dp(32).toFloat() }
836
+ accessory.background = GradientDrawable().apply { setColor(surface); cornerRadius = dp(32).toFloat() }
837
+ accessorySpec?.let { accessoryIcon.setImageDrawable(CraftNativeIcons.drawable(context, null, it.optString("symbol"), text)) }
811
838
  tabViews.forEachIndexed { index, (icon, label) ->
812
839
  val color = if (index == selectedTab) accent else muted
813
840
  val number = tabIconText[tabs[index].id]