Skip to content

Commit

Permalink
Merge pull request #5 from gaiuszzang/release/1.2.2
Browse files Browse the repository at this point in the history
Release/1.2.2
  • Loading branch information
gaiuszzang authored Apr 6, 2024
2 parents 97583d8 + 7e321bb commit d2e4746
Show file tree
Hide file tree
Showing 10 changed files with 192 additions and 108 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ This library offers a Box Composable that can be expanded/reduced through up/dow

| MusicPlayer Sample | Article Page Sample | Map Sample |
|:---------------------------------------------------------------------------------------------------------------------------------------------------------:|:---------------------------------------------------------------------------------------------------------------------------------------------------------:|:-------------------------------------------------------------------------------------------------------------------------------------------------:|
| <img src="https://github.com/gaiuszzang/GroovinExpandableBox/assets/15318053/5cca2871-b694-4002-955a-26f51385c0b6" alt="MusicPlayerSample" width="240px"> | <img src="https://github.com/gaiuszzang/GroovinExpandableBox/assets/15318053/78bdc12b-6884-4d4b-9470-76440474d461" alt="ArticlePageSample" width="240px"> | <img src="https://github.com/gaiuszzang/GroovinExpandableBox/assets/15318053/233f2b70-f706-45fc-89b4-d92227b6467e" alt="MapSample" width="240px"> |
| <img src="https://github.com/gaiuszzang/GroovinExpandableBox/assets/15318053/66df4c2e-c4f6-498b-8522-61497cef70a4" alt="MusicPlayerSample" width="240px"> | <img src="https://github.com/gaiuszzang/GroovinExpandableBox/assets/15318053/78bdc12b-6884-4d4b-9470-76440474d461" alt="ArticlePageSample" width="240px"> | <img src="https://github.com/gaiuszzang/GroovinExpandableBox/assets/15318053/233f2b70-f706-45fc-89b4-d92227b6467e" alt="MapSample" width="240px"> |


## Including in your project
Expand Down
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
buildscript {
ext {
androidx_core_version = '1.12.0'
compose_bom_version = '2024.02.02'
compose_bom_version = '2024.04.00'
compose_compiler_version = '1.5.8'
kotlin_plugin_version = '1.9.22'
}
Expand Down
2 changes: 1 addition & 1 deletion expandablebox/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ afterEvaluate {
from components.release
groupId = 'io.groovin'
artifactId = 'groovinexpandablebox'
version = '1.2.1'
version = '1.2.2'
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.Stable
import androidx.compose.runtime.State
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableFloatStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.saveable.Saver
Expand Down Expand Up @@ -72,9 +73,9 @@ open class ExpandableBoxState(
val offset: State<Float> get() = offsetState
val overflow: State<Float> get() = overflowState

private val offsetState = mutableStateOf(0f)
private val overflowState = mutableStateOf(0f)
private val absoluteOffset = mutableStateOf(0f)
private val offsetState = mutableFloatStateOf(0f)
private val overflowState = mutableFloatStateOf(0f)
private val absoluteOffset = mutableFloatStateOf(0f)
private val animationTarget = mutableStateOf<Float?>(null)

internal var anchors by mutableStateOf(emptyMap<Float, ExpandableBoxStateValue>())
Expand All @@ -94,8 +95,8 @@ open class ExpandableBoxState(
requireNotNull(initialOffset) {
"The initial value must have an associated anchor."
}
offsetState.value = initialOffset
absoluteOffset.value = initialOffset
offsetState.floatValue = initialOffset
absoluteOffset.floatValue = initialOffset
}
}

Expand Down Expand Up @@ -150,29 +151,29 @@ open class ExpandableBoxState(

internal var thresholds: (Float, Float) -> Float by mutableStateOf({ _, _ -> 0f })

internal var velocityThreshold by mutableStateOf(0f)
internal var velocityThreshold by mutableFloatStateOf(0f)

internal var resistance: ResistanceConfig? by mutableStateOf(null)

internal val draggableState = DraggableState {
val newAbsolute = absoluteOffset.value + it
val newAbsolute = absoluteOffset.floatValue + it
val clamped = newAbsolute.coerceIn(minBound, maxBound)
val overflow = newAbsolute - clamped
val resistanceDelta = resistance?.computeResistance(overflow) ?: 0f
offsetState.value = clamped + resistanceDelta
overflowState.value = overflow
absoluteOffset.value = newAbsolute
offsetState.floatValue = clamped + resistanceDelta
overflowState.floatValue = overflow
absoluteOffset.floatValue = newAbsolute
}

private suspend fun snapInternalToOffset(target: Float) {
draggableState.drag {
dragBy(target - absoluteOffset.value)
dragBy(target - absoluteOffset.floatValue)
}
}

private suspend fun animateInternalToOffset(target: Float, spec: AnimationSpec<Float>) {
draggableState.drag {
var prevValue = absoluteOffset.value
var prevValue = absoluteOffset.floatValue
animationTarget.value = target
isAnimationRunning = true
try {
Expand Down Expand Up @@ -206,17 +207,17 @@ open class ExpandableBoxState(
val bounds = findBounds(offset.value, anchors.keys)
val from: ExpandableBoxStateValue
val to: ExpandableBoxStateValue
val fraction: Float
val fromToProgress: Float
when (bounds.size) {
0 -> {
from = completedValue
to = completedValue
fraction = 1f
fromToProgress = 1f
}
1 -> {
from = anchors.getValue(bounds[0])
to = anchors.getValue(bounds[0])
fraction = 1f
fromToProgress = 1f
}
else -> {
val (a, b) =
Expand All @@ -227,10 +228,10 @@ open class ExpandableBoxState(
}
from = anchors.getValue(a)
to = anchors.getValue(b)
fraction = (offset.value - a) / (b - a)
fromToProgress = (offset.value - a) / (b - a)
}
}
return ExpandableBoxSwipeProgress(from, to, fraction)
return ExpandableBoxSwipeProgress(from, to, fromToProgress)
}

val direction: Float
Expand All @@ -256,7 +257,7 @@ open class ExpandableBoxState(
}
animateInternalToOffset(targetOffset, anim)
} finally {
val endOffset = absoluteOffset.value
val endOffset = absoluteOffset.floatValue
val endValue = anchors
// fighting rounding error once again, anchor should be as close as 0.5 pixels
.filterKeys { anchorOffset -> abs(anchorOffset - endOffset) < 0.5f }
Expand Down Expand Up @@ -285,9 +286,9 @@ open class ExpandableBoxState(
}

fun performDrag(delta: Float): Float {
val potentiallyConsumed = absoluteOffset.value + delta
val potentiallyConsumed = absoluteOffset.floatValue + delta
val clamped = potentiallyConsumed.coerceIn(minBound, maxBound)
val deltaToConsume = clamped - absoluteOffset.value
val deltaToConsume = clamped - absoluteOffset.floatValue
if (abs(deltaToConsume) > 0) {
draggableState.dispatchRawDelta(deltaToConsume)
}
Expand All @@ -310,23 +311,23 @@ class ExpandableBoxSwipeProgress(
val from: ExpandableBoxStateValue,
val to: ExpandableBoxStateValue,
/*@FloatRange(from = 0.0, to = 1.0)*/
val fraction: Float
val fromToProgress: Float
) {
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other !is ExpandableBoxSwipeProgress) return false
return !(from != other.from || to != other.to || fraction != other.fraction)
return !(from != other.from || to != other.to || fromToProgress != other.fromToProgress)
}

override fun hashCode(): Int {
var result = from.hashCode()
result = 31 * result + (to.hashCode())
result = 31 * result + fraction.hashCode()
result = 31 * result + fromToProgress.hashCode()
return result
}

override fun toString(): String {
return "ExpandableBoxSwipeProgress(from=$from, to=$to, fraction=$fraction)"
return "ExpandableBoxSwipeProgress(from=$from, to=$to, fromToProgress=$fromToProgress)"
}
}

Expand Down Expand Up @@ -404,7 +405,7 @@ internal fun Modifier.expandableBoxSwipeable(
state.processNewAnchors(oldAnchors, anchors)
}

Modifier.draggable(
this.draggable(
orientation = orientation,
enabled = enabled,
reverseDirection = reverseDirection,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,10 @@ import io.groovin.expandablebox.sampleapp.music.MusicSampleScreen


object GroovinDestination {
const val Main = "Main"
const val MusicBottomExpandBox = "MusicBottomExpandBox"
const val MusicUpExpandBox = "MusicUpExpandBox"
const val ArticleExpandBox = "ArticleExpandBox"
const val MapExpandBox = "MapExpandBox"
const val MAIN = "Main"
const val MUSIC_SAMPLE = "MusicSample"
const val ARTICLE_SAMPLE = "ArticleSample"
const val MAP_SAMPLE = "MapSample"
}

val LocalNavAction = compositionLocalOf<GroovinAction> { error("can't find GroovinAction") }
Expand All @@ -33,7 +32,7 @@ fun GroovinNavGraph(
) {
NavHost(
navController = navController,
startDestination = GroovinDestination.Main,
startDestination = GroovinDestination.MAIN,
enterTransition = {
fadeIn(animationSpec = tween(700)) + slideIntoContainer(
towards = AnimatedContentTransitionScope.SlideDirection.Companion.Up,
Expand All @@ -53,20 +52,17 @@ fun GroovinNavGraph(
)
}
) {
composable(GroovinDestination.Main) {
composable(GroovinDestination.MAIN) {
MainScreen()
}
composable(GroovinDestination.MusicBottomExpandBox) {
MusicSampleScreen(false)
composable(GroovinDestination.MUSIC_SAMPLE) {
MusicSampleScreen()
}
composable(GroovinDestination.MusicUpExpandBox) {
MusicSampleScreen(true)
}
composable(GroovinDestination.ArticleExpandBox) {
composable(GroovinDestination.ARTICLE_SAMPLE) {
ArticleSampleScreen()
}
composable(
route = "${GroovinDestination.MapExpandBox}?" +
route = "${GroovinDestination.MAP_SAMPLE}?" +
"nestedScrollOption={nestedScrollOption}",
arguments = listOf(
navArgument("nestedScrollOption") { defaultValue = 0 }
Expand All @@ -80,16 +76,13 @@ fun GroovinNavGraph(

class GroovinAction(private val navController: NavHostController?) {
val moveToMusicBottomExpandBox: () -> Unit = {
navController?.navigate(GroovinDestination.MusicBottomExpandBox)
}
val moveToMusicUpExpandBox: () -> Unit = {
navController?.navigate(GroovinDestination.MusicUpExpandBox)
navController?.navigate(GroovinDestination.MUSIC_SAMPLE)
}
val moveToArticleExpandBox: () -> Unit = {
navController?.navigate(GroovinDestination.ArticleExpandBox)
navController?.navigate(GroovinDestination.ARTICLE_SAMPLE)
}
val moveToMapExpandBox: (Int) -> Unit = { nestedScrollOption ->
navController?.navigate(GroovinDestination.MapExpandBox + "?nestedScrollOption=$nestedScrollOption")
navController?.navigate(GroovinDestination.MAP_SAMPLE + "?nestedScrollOption=$nestedScrollOption")
}
val moveToBack: () -> Unit = {
navController?.popBackStack()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,18 +37,11 @@ fun MainScreen() {
) {
MainHeader()
MainItem(
text = "Sample 1 : Music Player (Downside)",
text = "Sample 1 : Music Player",
onClick = {
navAction.moveToMusicBottomExpandBox()
}
)
MainItem(
text = "Sample 2 : Music Player (Upside)",
onClick = {
navAction.moveToMusicUpExpandBox()
}
)

MainItem(
text = "Sample 2 : Article Page",
onClick = {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package io.groovin.expandablebox.sampleapp.music

import androidx.compose.foundation.Image
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.RowScope
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.size
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.AccountCircle
import androidx.compose.material.icons.filled.Favorite
import androidx.compose.material.icons.filled.PlayArrow
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.unit.dp


@Composable
fun MusicBottomBar(
modifier: Modifier = Modifier,
onMenuClick: ((Int) -> Unit)? = null
) {
Row(
modifier = modifier
) {
MusicBottomBarItem(imageVector = Icons.Default.PlayArrow) {
onMenuClick?.invoke(0)
}
MusicBottomBarItem(imageVector = Icons.Default.Favorite) {
onMenuClick?.invoke(1)
}
MusicBottomBarItem(imageVector = Icons.Default.AccountCircle) {
onMenuClick?.invoke(2)
}
}
}

@Composable
private fun RowScope.MusicBottomBarItem(
imageVector: ImageVector,
onClick: () -> Unit
) {
Column(
modifier = Modifier
.weight(1f)
.fillMaxHeight()
.clickable {
onClick()
},
verticalArrangement = Arrangement.Center
) {
Image(
modifier = Modifier
.size(24.dp)
.align(Alignment.CenterHorizontally),
imageVector = imageVector,
contentDescription = null
)
}
}
Loading

0 comments on commit d2e4746

Please sign in to comment.