Skip to content

Commit 4b98964

Browse files
authored
Merge pull request #95 from synonymdev/feat/receive-polish
Receive flow polish
2 parents d9779b6 + 98645c1 commit 4b98964

40 files changed

+1349
-550
lines changed

app/build.gradle.kts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,15 @@ android {
110110
lint {
111111
abortOnError = false
112112
}
113+
applicationVariants.all {
114+
val variant = this
115+
outputs
116+
.map { it as com.android.build.gradle.internal.api.BaseVariantOutputImpl }
117+
.forEach { output ->
118+
val apkName = "bitkit-android-${defaultConfig.versionCode}-${variant.name}.apk"
119+
output.outputFileName = apkName
120+
}
121+
}
113122
}
114123
composeCompiler {
115124
featureFlags = setOf(

app/src/main/java/to/bitkit/data/keychain/Keychain.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ class Keychain @Inject constructor(
7676
fun observeExists(key: Key): Flow<Boolean> = context.keychain.data.map { it.contains(key.name.indexed) }
7777

7878
suspend fun wipe() {
79-
if (!Env.isDebug || Env.network != Network.REGTEST) throw KeychainError.KeychainWipeNotAllowed()
79+
if (Env.network != Network.REGTEST) throw KeychainError.KeychainWipeNotAllowed()
8080

8181
val keys = snapshot.asMap().keys
8282
context.keychain.edit { it.clear() }

app/src/main/java/to/bitkit/di/HttpModule.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ object HttpModule {
4444
}
4545
install(Logging) {
4646
logger = Logger.ANDROID
47-
level = LogLevel.BODY
47+
level = LogLevel.INFO
4848
}
4949
install(ContentNegotiation) {
5050
json(json = json)

app/src/main/java/to/bitkit/env/Env.kt

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,17 +14,13 @@ internal object Env {
1414
val isUnitTest = System.getProperty("java.class.path")?.contains("junit") == true
1515
val network = Network.REGTEST
1616
val defaultWalletWordCount = 12
17-
val onchainWalletStopGap = 20_UL
18-
val walletSyncIntervalSecs = 60_UL
19-
val feeRateCacheUpdateIntervalSecs = 60_UL
17+
val walletSyncIntervalSecs = 10_uL // TODO review
18+
val ldkNodeSyncIntervalSecs = 60_uL // TODO review
2019
val esploraParallelRequests = 6
2120
val trustedLnPeers
2221
get() = when (network) {
2322
Network.REGTEST -> listOf(
2423
Peers.btStaging,
25-
// Peers.btStagingOld,
26-
// Peers.polarToRegtest,
27-
// Peers.local,
2824
)
2925

3026
else -> TODO("Not yet implemented")
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
package to.bitkit.ext
2+
3+
import uniffi.bitkitcore.BtBolt11InvoiceState
4+
import uniffi.bitkitcore.CJitStateEnum
5+
import uniffi.bitkitcore.IBtBolt11Invoice
6+
import uniffi.bitkitcore.IBtChannel
7+
import uniffi.bitkitcore.ILspNode
8+
import uniffi.bitkitcore.IcJitEntry
9+
10+
fun IcJitEntry.Companion.mock(
11+
state: CJitStateEnum = CJitStateEnum.CREATED,
12+
channelSizeSat: ULong = 100_000u,
13+
feeSat: ULong = 1000u,
14+
channelExpiryWeeks: UInt = 6u,
15+
channel: IBtChannel? = null
16+
) = IcJitEntry(
17+
id = "test-cjit-id",
18+
state = state,
19+
feeSat = feeSat,
20+
networkFeeSat = 500u,
21+
serviceFeeSat = 500u,
22+
channelSizeSat = channelSizeSat,
23+
channelExpiryWeeks = channelExpiryWeeks,
24+
channelOpenError = null,
25+
nodeId = "node-id-123456",
26+
invoice = IBtBolt11Invoice(
27+
request = "lnbc100000...",
28+
state = BtBolt11InvoiceState.PENDING,
29+
expiresAt = "2024-10-28T12:00:00Z",
30+
updatedAt = "2024-10-21T12:00:00Z"
31+
),
32+
channel = channel,
33+
lspNode = ILspNode(
34+
alias = "Test LSP",
35+
pubkey = "lsp-pubkey-123456",
36+
connectionStrings = listOf("127.0.0.1:9735"),
37+
readonly = null
38+
),
39+
couponCode = "",
40+
source = "bitkit-android",
41+
discount = null,
42+
expiresAt = "2024-10-28T12:00:00Z",
43+
updatedAt = "2024-10-21T12:00:00Z",
44+
createdAt = "2024-10-21T12:00:00Z"
45+
)

app/src/main/java/to/bitkit/services/LightningService.kt

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ class LightningService @Inject constructor(
8484
config = EsploraSyncConfig(
8585
onchainWalletSyncIntervalSecs = Env.walletSyncIntervalSecs,
8686
lightningWalletSyncIntervalSecs = Env.walletSyncIntervalSecs,
87-
feeRateCacheUpdateIntervalSecs = Env.feeRateCacheUpdateIntervalSecs,
87+
feeRateCacheUpdateIntervalSecs = Env.walletSyncIntervalSecs,
8888
),
8989
)
9090
if (Env.ldkRgsServerUrl != null) {
@@ -310,8 +310,10 @@ class LightningService @Inject constructor(
310310

311311
return ServiceQueue.LDK.background {
312312
if (sat != null) {
313+
Logger.debug("Creating bolt11 for $sat sats")
313314
node.bolt11Payment().receive(sat.millis, description, expirySecs)
314315
} else {
316+
Logger.debug("Creating bolt11 for variable amount")
315317
node.bolt11Payment().receiveVariableAmount(description, expirySecs)
316318
}
317319
}
@@ -447,7 +449,7 @@ class LightningService @Inject constructor(
447449
fun syncFlow(): Flow<Unit> = flow {
448450
while (currentCoroutineContext().isActive) {
449451
emit(Unit)
450-
delay(Env.walletSyncIntervalSecs.toLong().seconds)
452+
delay(Env.ldkNodeSyncIntervalSecs.toLong().seconds)
451453
}
452454
}.flowOn(bgDispatcher)
453455
// endregion

app/src/main/java/to/bitkit/ui/components/TransferAmount.kt renamed to app/src/main/java/to/bitkit/ui/components/AmountInput.kt

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
package to.bitkit.ui.components
22

33
import androidx.compose.foundation.layout.Box
4+
import androidx.compose.foundation.layout.Column
5+
import androidx.compose.foundation.layout.Spacer
46
import androidx.compose.foundation.layout.fillMaxWidth
7+
import androidx.compose.foundation.layout.height
58
import androidx.compose.foundation.layout.size
69
import androidx.compose.foundation.text.KeyboardOptions
710
import androidx.compose.material3.TextField
@@ -30,9 +33,10 @@ import to.bitkit.ui.theme.Colors
3033
import to.bitkit.ui.utils.withAccent
3134

3235
@Composable
33-
fun TransferAmount(
36+
fun AmountInput(
3437
defaultValue: Long = 0,
3538
primaryDisplay: PrimaryDisplay,
39+
showConversion: Boolean = false,
3640
overrideSats: Long? = null,
3741
onSatsChange: (Long) -> Unit,
3842
) {
@@ -184,18 +188,25 @@ fun TransferAmount(
184188

185189
// Visible balance display
186190
currency.convert(sats)?.let { converted ->
187-
val displayText = if (primaryDisplay == PrimaryDisplay.BITCOIN) {
188-
val btcComponents = converted.bitcoinDisplay(displayUnit)
189-
"<accent>${btcComponents.symbol}</accent> ${btcComponents.value}"
190-
} else {
191-
"<accent>${converted.symbol}</accent> ${fiatAmount.text.ifEmpty { "0" }}"
191+
Column(modifier = Modifier.clickableAlpha { currency.togglePrimaryDisplay() }) {
192+
if (showConversion) {
193+
val captionText = if (primaryDisplay == PrimaryDisplay.BITCOIN) {
194+
"${converted.symbol} ${converted.formatted}"
195+
} else {
196+
val btcComponents = converted.bitcoinDisplay(displayUnit)
197+
"${btcComponents.symbol} ${btcComponents.value}"
198+
}
199+
Caption13Up(text = captionText, color = Colors.White64)
200+
Spacer(modifier = Modifier.height(12.dp))
201+
}
202+
val displayText = if (primaryDisplay == PrimaryDisplay.BITCOIN) {
203+
val btcComponents = converted.bitcoinDisplay(displayUnit)
204+
"<accent>${btcComponents.symbol}</accent> ${btcComponents.value}"
205+
} else {
206+
"<accent>${converted.symbol}</accent> ${fiatAmount.text.ifEmpty { "0" }}"
207+
}
208+
Display(text = displayText.withAccent(accentColor = Colors.White64))
192209
}
193-
194-
Display(
195-
text = displayText.withAccent(accentColor = Colors.White64),
196-
modifier = Modifier
197-
.clickableAlpha { currency.togglePrimaryDisplay() }
198-
)
199210
}
200211
}
201212
}

app/src/main/java/to/bitkit/ui/components/Button.kt

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,11 +54,12 @@ fun PrimaryButton(
5454
size: ButtonSize = ButtonSize.Large,
5555
enabled: Boolean = true,
5656
fullWidth: Boolean = true,
57+
color: Color = Colors.White16,
5758
) {
5859
Button(
5960
onClick = onClick,
6061
enabled = enabled && !isLoading,
61-
colors = AppButtonDefaults.primaryColors,
62+
colors = AppButtonDefaults.primaryColors.copy(containerColor = color),
6263
contentPadding = PaddingValues(horizontal = size.horizontalPadding),
6364
modifier = Modifier
6465
.then(if (fullWidth) Modifier.fillMaxWidth() else Modifier)
@@ -206,6 +207,13 @@ private fun PrimaryButtonPreview() {
206207
size = ButtonSize.Small,
207208
onClick = {},
208209
)
210+
PrimaryButton(
211+
text = "Primary Small Color Not Full",
212+
size = ButtonSize.Small,
213+
onClick = {},
214+
fullWidth = false,
215+
color = Colors.Brand,
216+
)
209217
PrimaryButton(
210218
text = "Primary Small Loading",
211219
size = ButtonSize.Small,

app/src/main/java/to/bitkit/ui/components/QrCodeImage.kt

Lines changed: 49 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@ import androidx.compose.foundation.layout.aspectRatio
88
import androidx.compose.foundation.layout.fillMaxSize
99
import androidx.compose.foundation.layout.fillMaxWidth
1010
import androidx.compose.foundation.layout.padding
11+
import androidx.compose.foundation.layout.size
12+
import androidx.compose.foundation.shape.CircleShape
13+
import androidx.compose.foundation.shape.RoundedCornerShape
1114
import androidx.compose.material3.CircularProgressIndicator
1215
import androidx.compose.runtime.Composable
1316
import androidx.compose.runtime.LaunchedEffect
@@ -20,8 +23,12 @@ import androidx.compose.ui.Modifier
2023
import androidx.compose.ui.graphics.Color
2124
import androidx.compose.ui.graphics.asImageBitmap
2225
import androidx.compose.ui.graphics.painter.BitmapPainter
26+
import androidx.compose.ui.graphics.painter.Painter
27+
import androidx.compose.ui.layout.ContentScale
2328
import androidx.compose.ui.platform.LocalConfiguration
2429
import androidx.compose.ui.platform.LocalDensity
30+
import androidx.compose.ui.res.painterResource
31+
import androidx.compose.ui.tooling.preview.Preview
2532
import androidx.compose.ui.unit.Dp
2633
import androidx.compose.ui.unit.dp
2734
import com.google.zxing.BarcodeFormat
@@ -30,18 +37,23 @@ import com.google.zxing.WriterException
3037
import com.google.zxing.qrcode.QRCodeWriter
3138
import kotlinx.coroutines.Dispatchers
3239
import kotlinx.coroutines.launch
40+
import to.bitkit.R
41+
import to.bitkit.ui.theme.AppThemeSurface
42+
import to.bitkit.ui.theme.Colors
43+
import androidx.core.graphics.createBitmap
3344

3445
@Composable
3546
fun QrCodeImage(
3647
content: String,
3748
modifier: Modifier = Modifier,
49+
logoPainter: Painter? = null,
3850
size: Dp = LocalConfiguration.current.screenWidthDp.dp,
3951
) {
4052
Box(
4153
contentAlignment = Alignment.TopCenter,
4254
modifier = modifier
4355
.fillMaxWidth()
44-
.background(Color.White)
56+
.background(Color.White, RoundedCornerShape(8.dp))
4557
.aspectRatio(1f)
4658
.padding(16.dp)
4759
) {
@@ -53,8 +65,27 @@ fun QrCodeImage(
5365
contentDescription = null,
5466
modifier = Modifier.fillMaxSize(),
5567
)
68+
logoPainter?.let {
69+
Box(
70+
contentAlignment = Alignment.Center,
71+
modifier = Modifier
72+
.size(68.dp)
73+
.background(Color.White, shape = CircleShape)
74+
.align(Alignment.Center)
75+
) {
76+
Image(
77+
painter = it,
78+
contentDescription = null,
79+
modifier = Modifier.size(50.dp),
80+
contentScale = ContentScale.Fit
81+
)
82+
}
83+
}
5684
} else {
57-
CircularProgressIndicator()
85+
CircularProgressIndicator(
86+
color = Colors.Black,
87+
modifier = Modifier.align(Alignment.Center)
88+
)
5889
}
5990
}
6091
}
@@ -84,17 +115,16 @@ private fun rememberQrBitmap(content: String, size: Dp): Bitmap? {
84115
sizePx,
85116
encodeHints,
86117
)
87-
} catch (ex: WriterException) {
118+
} catch (_: WriterException) {
88119
null
89120
}
90121

91122
val matrixWidth = bitmapMatrix?.width ?: sizePx
92123
val matrixHeight = bitmapMatrix?.height ?: sizePx
93124

94-
val newBitmap = Bitmap.createBitmap(
95-
bitmapMatrix?.width ?: sizePx,
96-
bitmapMatrix?.height ?: sizePx,
97-
Bitmap.Config.ARGB_8888,
125+
val newBitmap = createBitmap(
126+
width = bitmapMatrix?.width ?: sizePx,
127+
height = bitmapMatrix?.height ?: sizePx
98128
)
99129

100130
val pixels = IntArray(matrixWidth * matrixHeight)
@@ -117,3 +147,15 @@ private fun rememberQrBitmap(content: String, size: Dp): Bitmap? {
117147
}
118148
return bitmap
119149
}
150+
151+
@Preview(showBackground = true)
152+
@Composable
153+
private fun Preview() {
154+
AppThemeSurface {
155+
QrCodeImage(
156+
content = "https://bitkit.to",
157+
logoPainter = painterResource(R.drawable.ic_btc_circle),
158+
modifier = Modifier.padding(16.dp)
159+
)
160+
}
161+
}

app/src/main/java/to/bitkit/ui/components/SyncNodeView.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,8 @@ private fun Preview() {
5757
SyncNodeView(
5858
modifier = Modifier
5959
.fillMaxSize()
60-
.padding(horizontal = 16.dp)
6160
.gradientBackground()
61+
.padding(horizontal = 16.dp)
6262
)
6363
}
6464
}

0 commit comments

Comments
 (0)