diff --git a/catalog/src/main/java/com/telefonica/mistica/catalog/ui/classic/components/ListsCatalogFragment.kt b/catalog/src/main/java/com/telefonica/mistica/catalog/ui/classic/components/ListsCatalogFragment.kt index c0e962739..c99ad2108 100644 --- a/catalog/src/main/java/com/telefonica/mistica/catalog/ui/classic/components/ListsCatalogFragment.kt +++ b/catalog/src/main/java/com/telefonica/mistica/catalog/ui/classic/components/ListsCatalogFragment.kt @@ -168,7 +168,7 @@ class ListsCatalogFragment : Fragment() { @SuppressLint("SetTextI18n") - @Suppress("LongMethod", "CyclomaticComplexMethod") + @Suppress("CyclomaticComplexMethod") private fun ListRowView.configureView( withLongTitle: Boolean = false, withTitleMaxLines: Int? = null, @@ -249,11 +249,7 @@ class ListsCatalogFragment : Fragment() { isClickable = false } - when { - withBadge -> setBadge(true, withBadgeDescription) - withBadgeNumeric > 0 -> setNumericBadge(withBadgeNumeric, withBadgeDescription) - else -> setBadge(false, withBadgeDescription) - } + setBadge(withBadge, withBadgeDescription, withBadgeNumeric) } private fun getAssetResource(withAsset: Boolean, @AssetType withAssetType: Int): Int? = @@ -271,6 +267,14 @@ class ListsCatalogFragment : Fragment() { } else { null } + + private fun ListRowView.setBadge(withBadge: Boolean, withBadgeDescription: String?, withBadgeNumeric: Int) { + when { + withBadge -> setBadge(true, withBadgeDescription) + withBadgeNumeric > 0 -> setNumericBadge(withBadgeNumeric, withBadgeDescription) + else -> setBadge(false, withBadgeDescription) + } + } } class ListViewHolder(val rowView: ListRowView) : ViewHolder(rowView) diff --git a/library/src/main/java/com/telefonica/mistica/button/ProgressButton.kt b/library/src/main/java/com/telefonica/mistica/button/ProgressButton.kt index e4405f708..e071ca0a3 100644 --- a/library/src/main/java/com/telefonica/mistica/button/ProgressButton.kt +++ b/library/src/main/java/com/telefonica/mistica/button/ProgressButton.kt @@ -66,8 +66,72 @@ class ProgressButton : FrameLayout { } @SuppressLint("ClickableViewAccessibility") - @Suppress("LongMethod") private fun init(attrs: AttributeSet? = null, defStyleAttr: Int = 0) { + setupAttributes(attrs, defStyleAttr) + setupViewProperties() + setupButtonNormal() + setupButtonLoading() + setupProgressBar() + setButtonBackground() + addViews() + setVisibilityAndColors() + } + + fun getText(): CharSequence = + buttonBackground.text + + fun setText(text: CharSequence) { + buttonNormal.text = text + if (!isLoading) { + buttonBackground.text = text + } + } + + fun setText(@StringRes textId: Int) { + setText(context.getString(textId)) + } + + fun setLoadingText(text: CharSequence) { + buttonLoading.text = text + if (isLoading) { + buttonBackground.text = text + } + } + + override fun setOnClickListener(l: OnClickListener?) { + buttonBackground.setOnClickListener(l) + } + + override fun setEnabled(enabled: Boolean) { + super.setEnabled(enabled) + setAlpha(enabled) + buttonBackground.isEnabled = enabled + buttonNormal.isEnabled = enabled + buttonLoading.isEnabled = enabled + progressBar.isEnabled = enabled + } + + fun setIsLoading(loading: Boolean) { + if (loading) { + showLoading() + } else { + hideLoading() + } + } + + fun showLoading() { + if (!isLoading) { + switchState() + } + } + + fun hideLoading() { + if (isLoading) { + switchState() + } + } + + private fun setupAttributes(attrs: AttributeSet?, defStyleAttr: Int) { if (attrs != null) { val theme = context.theme val styledAttrs = @@ -78,13 +142,17 @@ class ProgressButton : FrameLayout { styledAttrs.recycle() } } + } + private fun setupViewProperties() { this.importantForAccessibility = IMPORTANT_FOR_ACCESSIBILITY_NO isClickable = false setPadding(0, 0, 0, 0) setBackgroundColor(Color.TRANSPARENT) originalTextColors = buttonNormal.textColors + } + private fun setupButtonNormal() { buttonNormal.apply { id = NO_ID importantForAccessibility = IMPORTANT_FOR_ACCESSIBILITY_NO @@ -94,7 +162,9 @@ class ProgressButton : FrameLayout { ) showTextOnly() } + } + private fun setupButtonLoading() { buttonLoading.apply { id = NO_ID importantForAccessibility = IMPORTANT_FOR_ACCESSIBILITY_NO @@ -106,7 +176,9 @@ class ProgressButton : FrameLayout { icon = AppCompatResources.getDrawable(context, R.drawable.empty_material_button_icon) text = "" } + } + private fun setupProgressBar() { progressBar.apply { layoutParams = LayoutParams(buttonLoading.iconSize, buttonLoading.iconSize) .apply { @@ -115,9 +187,11 @@ class ProgressButton : FrameLayout { importantForAccessibility = IMPORTANT_FOR_ACCESSIBILITY_NO isIndeterminate = true indeterminateTintMode = PorterDuff.Mode.SRC_IN - visibility = View.INVISIBLE + visibility = INVISIBLE } + } + private fun setButtonBackground() { buttonBackground.apply { id = NO_ID importantForAccessibility = IMPORTANT_FOR_ACCESSIBILITY_YES @@ -127,88 +201,37 @@ class ProgressButton : FrameLayout { ) icon = null setTextColor(Color.TRANSPARENT) - visibility = View.VISIBLE + visibility = VISIBLE setOnTouchListener { view, event -> when (event.action) { MotionEvent.ACTION_DOWN -> { buttonNormal.isPressed = true buttonLoading.isPressed = true } + MotionEvent.ACTION_MOVE -> { val outsideBounds = event.x < 0 || event.y < 0 || event.x > view.measuredWidth || event.y > view.measuredHeight buttonNormal.isPressed = !outsideBounds buttonLoading.isPressed = !outsideBounds } + MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> { buttonNormal.isPressed = false buttonLoading.isPressed = false + view.performClick() } } false } } + } + private fun addViews() { addView(buttonBackground) addView(buttonNormal) addView(buttonLoading) addView(progressBar) - - setVisibilityAndColors() - } - - fun getText(): CharSequence = - buttonBackground.text - - fun setText(text: CharSequence) { - buttonNormal.text = text - if (!isLoading) { - buttonBackground.text = text - } - } - - fun setText(@StringRes textId: Int) { - setText(context.getString(textId)) - } - - fun setLoadingText(text: CharSequence) { - buttonLoading.text = text - if (isLoading) { - buttonBackground.text = text - } - } - - override fun setOnClickListener(l: OnClickListener?) { - buttonBackground.setOnClickListener(l) - } - - override fun setEnabled(enabled: Boolean) { - super.setEnabled(enabled) - setAlpha(enabled) - buttonBackground.isEnabled = enabled - buttonNormal.isEnabled = enabled - buttonLoading.isEnabled = enabled - progressBar.isEnabled = enabled - } - - fun setIsLoading(loading: Boolean) { - if (loading) { - showLoading() - } else { - hideLoading() - } - } - - fun showLoading() { - if (!isLoading) { - switchState() - } - } - - fun hideLoading() { - if (isLoading) { - switchState() - } } private fun switchState() { diff --git a/library/src/main/java/com/telefonica/mistica/compose/carousel/CarouselPagerIndicator.kt b/library/src/main/java/com/telefonica/mistica/compose/carousel/CarouselPagerIndicator.kt index 962f6f21c..a58a4b737 100644 --- a/library/src/main/java/com/telefonica/mistica/compose/carousel/CarouselPagerIndicator.kt +++ b/library/src/main/java/com/telefonica/mistica/compose/carousel/CarouselPagerIndicator.kt @@ -22,7 +22,6 @@ import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.IntOffset import androidx.compose.ui.unit.dp -import com.google.accompanist.pager.ExperimentalPagerApi import com.telefonica.mistica.compose.carousel.CarouselPagerIndicator.MAX_WINDOW_SIZE import com.telefonica.mistica.compose.carousel.CarouselPagerIndicator.indicatorSelectedHeight import com.telefonica.mistica.compose.carousel.CarouselPagerIndicator.indicatorSelectedWidth @@ -44,7 +43,6 @@ import com.telefonica.mistica.compose.carousel.MovementDirection.INCREASE import com.telefonica.mistica.compose.carousel.MovementDirection.NO_MOVEMENT import com.telefonica.mistica.compose.theme.MisticaTheme -@OptIn(ExperimentalPagerApi::class) @SuppressLint("MutableCollectionMutableState") @Composable fun CarouselPagerIndicator( @@ -156,8 +154,6 @@ fun CarouselPagerIndicator( indicatorShape = indicatorShape) } -@ExperimentalPagerApi -@Suppress("LongMethod", "CyclomaticComplexMethod") internal fun calculateItems( items: MutableList, visibleWindowState: VisibleWindowState, @@ -172,76 +168,27 @@ internal fun calculateItems( log("item-$index is outside the window") item.type = INVISIBLE } + //The current selected index == visibleWindowState.currentSelected -> { log("item-$index is the currently selected") item.type = SELECTED } - //The adjacent to the lower edge may be small + visibleWindowState.window.isTheAdjacentToTheLowerEdge(index) -> { - val thereAreNoMoreItems = visibleWindowState.window.first == 0 - when { - thereAreNoMoreItems -> { - log("item-$index is unselected, because it's the adjacent to the edge, but there are no more items") - item.type = UNSELECTED - } - else -> { - log("item-$index is adjacent to the lower edge") - item.type = UNSELECTED_SMALL - } - } + doOnNearToLowerEdge(visibleWindowState, log, index, item) } - //The adjacent to the higher edge may be small + visibleWindowState.window.isTheAdjacentToTheHigherEdge(index) -> { - val thereAreNoMoreItems = visibleWindowState.window.second == pagerCount - 1 - when { - thereAreNoMoreItems -> { - log("item-$index is unselected, because it's the adjacent to the edge, but there are no more items") - item.type = UNSELECTED - } - else -> { - log("item-$index is adjacent to the higher edge") - item.type = UNSELECTED_SMALL - } - } + doOnNearToHigherEdge(visibleWindowState, pagerCount, log, index, item) } - //The items in the lower edge can be regular, small or very small + visibleWindowState.window.isTheLowerEdge(index) -> { - val thereAreNoMoreItems = visibleWindowState.window.first == 0 - val isTheSelectedAdjacent = (index + 1) == currentSelected - when { - thereAreNoMoreItems -> { - log("item-$index is the lower edge and there are no more items") - item.type = UNSELECTED - } - isTheSelectedAdjacent -> { - log("item-$index is the lower edge and the selected is the adjacent") - item.type = UNSELECTED_SMALL - } - else -> { - log("item-$index is the lower edge and the selected is NOT adjacent") - item.type = UNSELECTED_VERY_SMALL - } - } + doOnLowerEdge(visibleWindowState, index, currentSelected, log, item) } - //The items in the higher edge can be regular, small or very small + visibleWindowState.window.isTheHigherEdge(index) -> { - val thereAreNoMoreItems = visibleWindowState.window.second == pagerCount - 1 - val isTheSelectedAdjacent = (index - 1) == currentSelected - when { - thereAreNoMoreItems -> { - log("item-$index is the higher edge and there are no more items") - item.type = UNSELECTED - } - isTheSelectedAdjacent -> { - log("item-$index is the higher edge and the selected is the adjacent") - item.type = UNSELECTED_SMALL - } - else -> { - log("item-$index is the higher edge and the selected is NOT adjacent") - item.type = UNSELECTED_VERY_SMALL - } - } + doOnHigherEdge(visibleWindowState, pagerCount, index, currentSelected, log, item) } else -> { log("item-$index is unselected") @@ -251,7 +198,106 @@ internal fun calculateItems( } } -@ExperimentalPagerApi +//The adjacent to the lower edge may be small +private fun doOnNearToLowerEdge( + visibleWindowState: VisibleWindowState, + log: (String) -> Unit, + index: Int, + item: Item, +) { + val thereAreNoMoreItems = visibleWindowState.window.first == 0 + when { + thereAreNoMoreItems -> { + log("item-$index is unselected, because it's the adjacent to the edge, but there are no more items") + item.type = UNSELECTED + } + + else -> { + log("item-$index is adjacent to the lower edge") + item.type = UNSELECTED_SMALL + } + } +} + +//The adjacent to the higher edge may be small +private fun doOnNearToHigherEdge( + visibleWindowState: VisibleWindowState, + pagerCount: Int, + log: (String) -> Unit, + index: Int, + item: Item, +) { + val thereAreNoMoreItems = visibleWindowState.window.second == pagerCount - 1 + when { + thereAreNoMoreItems -> { + log("item-$index is unselected, because it's the adjacent to the edge, but there are no more items") + item.type = UNSELECTED + } + + else -> { + log("item-$index is adjacent to the higher edge") + item.type = UNSELECTED_SMALL + } + } +} + +//The items in the lower edge can be regular, small or very small +private fun doOnLowerEdge( + visibleWindowState: VisibleWindowState, + index: Int, + currentSelected: Int, + log: (String) -> Unit, + item: Item, +) { + val thereAreNoMoreItems = visibleWindowState.window.first == 0 + val isTheSelectedAdjacent = (index + 1) == currentSelected + when { + thereAreNoMoreItems -> { + log("item-$index is the lower edge and there are no more items") + item.type = UNSELECTED + } + + isTheSelectedAdjacent -> { + log("item-$index is the lower edge and the selected is the adjacent") + item.type = UNSELECTED_SMALL + } + + else -> { + log("item-$index is the lower edge and the selected is NOT adjacent") + item.type = UNSELECTED_VERY_SMALL + } + } +} + +//The items in the higher edge can be regular, small or very small +private fun doOnHigherEdge( + visibleWindowState: VisibleWindowState, + pagerCount: Int, + index: Int, + currentSelected: Int, + log: (String) -> Unit, + item: Item, +) { + val thereAreNoMoreItems = visibleWindowState.window.second == pagerCount - 1 + val isTheSelectedAdjacent = (index - 1) == currentSelected + when { + thereAreNoMoreItems -> { + log("item-$index is the higher edge and there are no more items") + item.type = UNSELECTED + } + + isTheSelectedAdjacent -> { + log("item-$index is the higher edge and the selected is the adjacent") + item.type = UNSELECTED_SMALL + } + + else -> { + log("item-$index is the higher edge and the selected is NOT adjacent") + item.type = UNSELECTED_VERY_SMALL + } + } +} + internal fun calculateWindowPosition( movementDirection: MovementDirection, currentSelected: Int, @@ -312,7 +358,6 @@ internal fun calculateWindowPosition( } } -@ExperimentalPagerApi private fun calculateDirection( carouselState: CarouselState, currentlySelected: Int, @@ -325,7 +370,6 @@ private fun calculateDirection( return movementDirection } -@ExperimentalPagerApi @Composable @Suppress("CyclomaticComplexMethod") private fun PagerIndicatorBox( diff --git a/library/src/test/java/com/telefonica/mistica/compose/carousel/CalculateItemsTest.kt b/library/src/test/java/com/telefonica/mistica/compose/carousel/CalculateItemsTest.kt index dddf88135..92bb47af5 100644 --- a/library/src/test/java/com/telefonica/mistica/compose/carousel/CalculateItemsTest.kt +++ b/library/src/test/java/com/telefonica/mistica/compose/carousel/CalculateItemsTest.kt @@ -1,10 +1,8 @@ package com.telefonica.mistica.compose.carousel -import com.google.accompanist.pager.ExperimentalPagerApi import junit.framework.TestCase.assertEquals import org.junit.Test -@ExperimentalPagerApi class CalculateItemsTest { @Test diff --git a/library/src/test/java/com/telefonica/mistica/compose/carousel/CalculateWindowPositionTest.kt b/library/src/test/java/com/telefonica/mistica/compose/carousel/CalculateWindowPositionTest.kt index a703f8889..22228b6e3 100644 --- a/library/src/test/java/com/telefonica/mistica/compose/carousel/CalculateWindowPositionTest.kt +++ b/library/src/test/java/com/telefonica/mistica/compose/carousel/CalculateWindowPositionTest.kt @@ -1,10 +1,8 @@ package com.telefonica.mistica.compose.carousel -import com.google.accompanist.pager.ExperimentalPagerApi import junit.framework.TestCase.assertEquals import org.junit.Test -@ExperimentalPagerApi class CalculateWindowPositionTest { @Test