11package to.bitkit.ui.components
22
3+ import androidx.compose.animation.AnimatedContent
34import androidx.compose.foundation.layout.Arrangement
45import androidx.compose.foundation.layout.Column
56import androidx.compose.foundation.layout.Row
67import androidx.compose.foundation.layout.Spacer
78import androidx.compose.foundation.layout.fillMaxWidth
89import androidx.compose.foundation.layout.height
910import androidx.compose.foundation.layout.padding
11+ import androidx.compose.foundation.layout.size
12+ import androidx.compose.material3.Icon
1013import androidx.compose.runtime.Composable
14+ import androidx.compose.runtime.getValue
1115import androidx.compose.ui.Alignment
1216import androidx.compose.ui.Modifier
1317import androidx.compose.ui.platform.LocalInspectionMode
18+ import androidx.compose.ui.res.painterResource
1419import androidx.compose.ui.tooling.preview.Preview
1520import androidx.compose.ui.unit.dp
21+ import androidx.lifecycle.compose.collectAsStateWithLifecycle
22+ import to.bitkit.R
1623import to.bitkit.models.BITCOIN_SYMBOL
1724import to.bitkit.models.ConvertedAmount
1825import to.bitkit.models.PrimaryDisplay
1926import to.bitkit.ui.LocalCurrencies
2027import to.bitkit.ui.currencyViewModel
28+ import to.bitkit.ui.settingsViewModel
29+ import to.bitkit.ui.shared.animations.BalanceAnimations
30+ import to.bitkit.ui.shared.modifiers.swipeToHide
31+ import to.bitkit.ui.shared.UiConstants
2132import to.bitkit.ui.shared.util.clickableAlpha
2233import to.bitkit.ui.theme.AppThemeSurface
2334import to.bitkit.ui.theme.Colors
@@ -28,8 +39,11 @@ fun BalanceHeaderView(
2839 modifier : Modifier = Modifier ,
2940 prefix : String? = null,
3041 showBitcoinSymbol : Boolean = true,
42+ forceShowBalance : Boolean = false,
43+ showEyeIcon : Boolean = false,
3144) {
3245 val isPreview = LocalInspectionMode .current
46+
3347 if (isPreview) {
3448 BalanceHeader (
3549 modifier = modifier,
@@ -39,14 +53,23 @@ fun BalanceHeaderView(
3953 largeRowText = " $sats " ,
4054 largeRowSymbol = BITCOIN_SYMBOL ,
4155 showSymbol = showBitcoinSymbol,
56+ hideBalance = false ,
57+ isSwipeToHideEnabled = false ,
58+ showEyeIcon = showEyeIcon,
4259 onClick = {},
60+ onToggleHideBalance = {},
4361 )
4462 return
4563 }
4664
65+ val settings = settingsViewModel ? : return
4766 val currency = currencyViewModel ? : return
48- val (rates, _, _, _, displayUnit, primaryDisplay) = LocalCurrencies .current
49- val converted: ConvertedAmount ? = if (rates.isNotEmpty()) currency.convert(sats = sats) else null
67+ val (_, _, _, _, displayUnit, primaryDisplay) = LocalCurrencies .current
68+ val converted: ConvertedAmount ? = currency.convert(sats = sats)
69+
70+ val isSwipeToHideEnabled by settings.enableSwipeToHideBalance.collectAsStateWithLifecycle()
71+ val hideBalance by settings.hideBalance.collectAsStateWithLifecycle()
72+ val shouldHideBalance = hideBalance && ! forceShowBalance
5073
5174 converted?.let { converted ->
5275 val btcComponents = converted.bitcoinDisplay(displayUnit)
@@ -60,7 +83,11 @@ fun BalanceHeaderView(
6083 largeRowText = btcComponents.value,
6184 largeRowSymbol = btcComponents.symbol,
6285 showSymbol = showBitcoinSymbol,
63- onClick = { currency.togglePrimaryDisplay() }
86+ hideBalance = shouldHideBalance,
87+ isSwipeToHideEnabled = isSwipeToHideEnabled,
88+ showEyeIcon = showEyeIcon,
89+ onClick = { currency.togglePrimaryDisplay() },
90+ onToggleHideBalance = { settings.setHideBalance(! hideBalance) },
6491 )
6592 } else {
6693 BalanceHeader (
@@ -71,7 +98,11 @@ fun BalanceHeaderView(
7198 largeRowText = converted.formatted,
7299 largeRowSymbol = converted.symbol,
73100 showSymbol = true ,
74- onClick = { currency.togglePrimaryDisplay() }
101+ hideBalance = shouldHideBalance,
102+ isSwipeToHideEnabled = isSwipeToHideEnabled,
103+ showEyeIcon = showEyeIcon,
104+ onClick = { currency.togglePrimaryDisplay() },
105+ onToggleHideBalance = { settings.setHideBalance(! hideBalance) },
75106 )
76107 }
77108 }
@@ -86,35 +117,77 @@ fun BalanceHeader(
86117 largeRowText : String ,
87118 largeRowSymbol : String ,
88119 showSymbol : Boolean ,
89- onClick : () -> Unit
120+ hideBalance : Boolean = false,
121+ isSwipeToHideEnabled : Boolean = false,
122+ showEyeIcon : Boolean = false,
123+ onClick : () -> Unit ,
124+ onToggleHideBalance : () -> Unit = {},
90125) {
91126 Column (
92127 verticalArrangement = Arrangement .Center ,
93128 horizontalAlignment = Alignment .Start ,
94- modifier = modifier.clickableAlpha { onClick() }
129+ modifier = modifier
130+ .swipeToHide(
131+ enabled = isSwipeToHideEnabled,
132+ onSwipe = onToggleHideBalance,
133+ )
134+ .clickableAlpha { onClick() }
95135 ) {
96136 SmallRow (
97137 symbol = smallRowSymbol,
98- text = smallRowText
138+ text = smallRowText,
139+ hideBalance = hideBalance
99140 )
100141
101142 Spacer (modifier = Modifier .height(12 .dp))
102143
103- LargeRow (
104- prefix = largeRowPrefix,
105- text = largeRowText,
106- symbol = largeRowSymbol,
107- showSymbol = showSymbol
108- )
144+ Row (
145+ verticalAlignment = Alignment .CenterVertically ,
146+ ) {
147+ LargeRow (
148+ prefix = largeRowPrefix,
149+ text = largeRowText,
150+ symbol = largeRowSymbol,
151+ showSymbol = showSymbol,
152+ hideBalance = hideBalance
153+ )
154+
155+ if (showEyeIcon) {
156+ Spacer (modifier = Modifier .weight(1f ))
157+ AnimatedContent (
158+ targetState = hideBalance,
159+ transitionSpec = { BalanceAnimations .eyeIconTransition },
160+ label = " eyeIconAnimation" ,
161+ modifier = Modifier .size(24 .dp)
162+ ) { isHidden ->
163+ if (isHidden) {
164+ Icon (
165+ painter = painterResource(R .drawable.ic_eye),
166+ contentDescription = null ,
167+ tint = Colors .White64 ,
168+ modifier = Modifier
169+ .size(24 .dp)
170+ .clickableAlpha { onToggleHideBalance() }
171+ )
172+ }
173+ }
174+ }
175+ }
109176 }
110177}
111178
112179@Composable
113- fun LargeRow (prefix : String? , text : String , symbol : String , showSymbol : Boolean ) {
180+ fun LargeRow (
181+ prefix : String? ,
182+ text : String ,
183+ symbol : String ,
184+ showSymbol : Boolean ,
185+ hideBalance : Boolean = false
186+ ) {
114187 Row (
115188 verticalAlignment = Alignment .CenterVertically ,
116189 ) {
117- if (prefix != null ) {
190+ if (! hideBalance && prefix != null ) {
118191 Display (
119192 text = prefix,
120193 color = Colors .White64 ,
@@ -128,12 +201,18 @@ fun LargeRow(prefix: String?, text: String, symbol: String, showSymbol: Boolean)
128201 modifier = Modifier .padding(end = 8 .dp)
129202 )
130203 }
131- Display (text = text)
204+ AnimatedContent (
205+ targetState = hideBalance,
206+ transitionSpec = { BalanceAnimations .mainBalanceTransition },
207+ label = " largeRowTextAnimation"
208+ ) { isHidden ->
209+ Display (text = if (isHidden) UiConstants .HIDE_BALANCE_LONG else text)
210+ }
132211 }
133212}
134213
135214@Composable
136- private fun SmallRow (symbol : String? , text : String ) {
215+ private fun SmallRow (symbol : String? , text : String , hideBalance : Boolean = false ) {
137216 Row (
138217 verticalAlignment = Alignment .Bottom ,
139218 horizontalArrangement = Arrangement .spacedBy(4 .dp),
@@ -144,10 +223,16 @@ private fun SmallRow(symbol: String?, text: String) {
144223 color = Colors .White64 ,
145224 )
146225 }
147- Caption13Up (
148- text = text,
149- color = Colors .White64 ,
150- )
226+ AnimatedContent (
227+ targetState = hideBalance,
228+ transitionSpec = { BalanceAnimations .secondaryBalanceTransition },
229+ label = " smallRowTextAnimation"
230+ ) { isHidden ->
231+ Caption13Up (
232+ text = if (isHidden) UiConstants .HIDE_BALANCE_SHORT else text,
233+ color = Colors .White64 ,
234+ )
235+ }
151236 }
152237}
153238
@@ -167,3 +252,23 @@ private fun Preview() {
167252 )
168253 }
169254}
255+
256+ @Preview(showBackground = true )
257+ @Composable
258+ private fun PreviewHidden () {
259+ AppThemeSurface {
260+ BalanceHeader (
261+ smallRowSymbol = " $" ,
262+ smallRowText = " 27.36" ,
263+ largeRowPrefix = " +" ,
264+ largeRowText = " 136 825" ,
265+ largeRowSymbol = " ₿" ,
266+ showSymbol = true ,
267+ hideBalance = true ,
268+ isSwipeToHideEnabled = true ,
269+ modifier = Modifier .fillMaxWidth(),
270+ onClick = {},
271+ onToggleHideBalance = {}
272+ )
273+ }
274+ }
0 commit comments