Skip to content

Commit

Permalink
- do not allow avatar click when user is already on settings
Browse files Browse the repository at this point in the history
 - visually show click is not avail by reducing oppacity
 - added avatar shining animation gradient

[Ticket: X]
  • Loading branch information
rodvar committed Dec 17, 2024
1 parent 62cce13 commit 81e2b77
Show file tree
Hide file tree
Showing 2 changed files with 93 additions and 5 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package network.bisq.mobile.presentation.ui.components.atoms.animations

import androidx.compose.animation.core.*
import androidx.compose.foundation.Canvas
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.layout.BoxScope
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.*
import kotlin.random.Random

const val INITIAL_SHINE = -1.0f
const val TARGET_SHINE = 3f
const val ANIMATION_INTERVAL = 5000
const val ANIMATION_MAX_INTERVAL = 10001
const val GRADIENT_OFFSET_FACTOR = 300f

fun nextDuration(): Int = Random.nextInt(ANIMATION_INTERVAL, ANIMATION_MAX_INTERVAL)

@Composable
fun ShineOverlay(
modifier: Modifier = Modifier,
content: @Composable BoxScope.() -> Unit
) {

val randomDuration = remember { mutableStateOf(nextDuration()) }

val infiniteTransition = rememberInfiniteTransition()
val gradientOffset by infiniteTransition.animateFloat(
initialValue = INITIAL_SHINE,
targetValue = TARGET_SHINE,
animationSpec = infiniteRepeatable(
animation = tween(durationMillis = randomDuration.value, easing = LinearEasing),
repeatMode = RepeatMode.Restart
)
)

LaunchedEffect(gradientOffset) {
if (gradientOffset == TARGET_SHINE) {
randomDuration.value = nextDuration()
}
}

// Gradient brush that moves across the composable
val gradientBrush = Brush.linearGradient(
colors = listOf(
Color.Transparent,
Color.White.copy(alpha = 0.3f), // Shine effect
Color.Transparent
),
start = Offset(gradientOffset * GRADIENT_OFFSET_FACTOR, gradientOffset * GRADIENT_OFFSET_FACTOR),
end = Offset((gradientOffset + 1) * GRADIENT_OFFSET_FACTOR, (gradientOffset + 1) * GRADIENT_OFFSET_FACTOR)
)

// Layer composable with shine overlay
Box(
modifier = modifier
.clip(CircleShape),
contentAlignment = Alignment.Center
) {
// UserIcon composable
content()

// Canvas for the moving shine gradient
Canvas(
modifier = Modifier
.matchParentSize()
.clip(CircleShape)) {
drawRect(brush = gradientBrush)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.IconButton
import androidx.compose.material3.TopAppBar
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.ui.draw.alpha
import androidx.navigation.compose.currentBackStackEntryAsState
import network.bisq.mobile.presentation.ui.components.atoms.animations.ShineOverlay
import network.bisq.mobile.presentation.ui.components.atoms.icons.BisqLogoSmall
import network.bisq.mobile.presentation.ui.components.atoms.icons.UserIcon
import network.bisq.mobile.presentation.ui.navigation.Routes
Expand All @@ -40,6 +43,9 @@ fun TopBar(
) {
val presenter: ITopBarPresenter = koinInject()
val navController: NavHostController = presenter.getRootNavController()
val tabNavController: NavHostController = presenter.getRootTabNavController()

val currentTab = tabNavController.currentBackStackEntryAsState().value?.destination?.route

val showBackButton = customBackButton == null && navController.previousBackStackEntry != null

Expand Down Expand Up @@ -101,11 +107,17 @@ fun TopBar(
// TODO implement full feature after MVP
// BellIcon()
Spacer(modifier = Modifier.width(12.dp))
UserIcon(presenter.uniqueAvatar.value,
modifier = Modifier.size(30.dp)
.clickable {
navController.navigate(Routes.UserProfileSettings.name)
})
ShineOverlay {
UserIcon(presenter.uniqueAvatar.value,
modifier = Modifier.size(30.dp)
// .fillMaxSize()
.alpha(if (currentTab == Routes.TabSettings.name) 0.5f else 1.0f)
.clickable {
if (currentTab != Routes.TabSettings.name) {
navController.navigate(Routes.UserProfileSettings.name)
}
})
}
}
},
)
Expand Down

0 comments on commit 81e2b77

Please sign in to comment.