Skip to content
This repository has been archived by the owner on Oct 11, 2024. It is now read-only.

Commit

Permalink
add send screen
Browse files Browse the repository at this point in the history
  • Loading branch information
greenart7c3 committed Jul 29, 2024
1 parent 59dc5c1 commit 7c5cc2c
Show file tree
Hide file tree
Showing 20 changed files with 570 additions and 11 deletions.
16 changes: 16 additions & 0 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ plugins {
alias(libs.plugins.compose.compiler)
alias(libs.plugins.serialization)
alias(libs.plugins.ktlint)
kotlin("kapt") version "2.0.0"
}

android {
Expand Down Expand Up @@ -31,6 +32,13 @@ android {
"proguard-rules.pro",
)
}
debug {
debug {
applicationIdSuffix = ".debug"
versionNameSuffix = "-DEBUG"
resValue("string", "app_name", "@string/app_name_debug")
}
}
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_8
Expand All @@ -41,6 +49,8 @@ android {
}
buildFeatures {
compose = true
dataBinding = true
viewBinding = true
}
composeOptions {
kotlinCompilerExtensionVersion = "1.5.1"
Expand Down Expand Up @@ -69,6 +79,7 @@ dependencies {
implementation(libs.androidx.ui.graphics)
implementation(libs.androidx.ui.tooling.preview)
implementation(libs.androidx.material3)
implementation(libs.androidx.ui.viewbinding)
testImplementation(libs.junit)
androidTestImplementation(libs.androidx.junit)
androidTestImplementation(libs.androidx.espresso.core)
Expand All @@ -86,4 +97,9 @@ dependencies {
implementation(libs.ktor.cio)
implementation(libs.zxing.core)
implementation(libs.zxing.android.embedded)
implementation(libs.jna) {
artifact { type = "aar" }
}
implementation(libs.acinq.lightning.kmp)
implementation(libs.secp256k1.kmp)
}
4 changes: 4 additions & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name="com.journeyapps.barcodescanner.CaptureActivity"
android:screenOrientation="fullSensor"
tools:replace="screenOrientation" />
</application>

</manifest>
10 changes: 10 additions & 0 deletions app/src/main/java/com/greenart7c3/phoenixd/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,11 @@ import androidx.navigation.compose.rememberNavController
import com.greenart7c3.phoenixd.screens.LoginScreen
import com.greenart7c3.phoenixd.screens.MainScreen
import com.greenart7c3.phoenixd.screens.ReceiveScreen
import com.greenart7c3.phoenixd.screens.SendScreen
import com.greenart7c3.phoenixd.services.LocalPreferences
import com.greenart7c3.phoenixd.services.PhoenixdViewModel
import com.greenart7c3.phoenixd.services.ReceiveViewModel
import com.greenart7c3.phoenixd.services.SendViewModel
import com.greenart7c3.phoenixd.services.Settings
import com.greenart7c3.phoenixd.ui.theme.PhoenixdTheme
import kotlinx.coroutines.Dispatchers
Expand Down Expand Up @@ -74,6 +76,14 @@ class MainActivity : ComponentActivity() {
)
}

composable("send") {
val viewModel by viewModels<SendViewModel>()
SendScreen(
viewModel = viewModel,
navController = navController,
)
}

composable("main") {
val viewModel by viewModels<PhoenixdViewModel>()
MainScreen(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ fun LoginScreen(navController: NavController) {
var password by remember {
mutableStateOf(TextFieldValue(""))
}
var loading by remember { mutableStateOf(true) }
var loading by remember { mutableStateOf(false) }
var useSSL by remember { mutableStateOf(false) }
val scope = rememberCoroutineScope()
val clipboardManager = LocalClipboardManager.current
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ fun MainScreen(
Spacer(modifier = Modifier.size(16.dp))
ElevatedButton(
onClick = {
navController.navigate("send")
},
) {
Row(
Expand Down Expand Up @@ -181,8 +182,15 @@ fun MainScreen(
Column(
horizontalAlignment = Alignment.End,
) {
val fees = payment.fees ?: 0
val fee = if (fees > 0) fees / 1000 else 0
val sent = if (fees > 0) it - fee else it
Text(
text = "${DecimalFormat("#,###").format(it)} sat",
text = "${DecimalFormat("#,###").format(sent)} sat",
textAlign = TextAlign.End,
)
Text(
text = "Fee ${DecimalFormat("#,###").format(fee)} sat",
textAlign = TextAlign.End,
)
formatCreatedAt(payment.createdAt)?.let {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,9 @@ fun ReceiveScreen(
Scaffold(
topBar = {
TopAppBar(
title = { },
title = {
Text(text = "Receive")
},
navigationIcon = {
IconButton(
onClick = {
Expand Down Expand Up @@ -142,7 +144,7 @@ fun ReceiveScreen(
}
},
) {
Text(text = "Bolt12")
Text(text = "Offer")
}
}
}
Expand Down
111 changes: 111 additions & 0 deletions app/src/main/java/com/greenart7c3/phoenixd/screens/SendScreen.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
package com.greenart7c3.phoenixd.screens

import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.Send
import androidx.compose.material.icons.filled.Send
import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.ElevatedButton
import androidx.compose.material3.Icon
import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.text.input.TextFieldValue
import androidx.compose.ui.unit.dp
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.navigation.NavController
import com.greenart7c3.phoenixd.services.SendViewModel
import com.greenart7c3.phoenixd.ui.ScannerView
import com.journeyapps.barcodescanner.DecoratedBarcodeView

@Composable
fun SendScreen(
viewModel: SendViewModel,
navController: NavController,
) {
val state = viewModel.state.collectAsStateWithLifecycle()
var scanView by remember { mutableStateOf<DecoratedBarcodeView?>(null) }
val context = LocalContext.current

DisposableEffect(Unit) {
onDispose {
viewModel.clear()
}
}

Scaffold { innerPadding ->
Box(
Modifier
.fillMaxSize()
.padding(innerPadding),
) {
if (state.value.showScanner) {
ScannerView(
onScanViewBinding = {
scanView = it
},
onScannedText = {
viewModel.onScannedText(it)
},
)
} else {
var textInput by remember(state.value.amount) { mutableStateOf(TextFieldValue(state.value.amount.toString())) }
LaunchedEffect(Unit) {
viewModel.processInput()
}
Column(
Modifier
.fillMaxSize()
.padding(16.dp),
Arrangement.Center,
Alignment.CenterHorizontally,
) {
if (state.value.isLoading) {
CircularProgressIndicator()
} else {
OutlinedTextField(
modifier = Modifier.fillMaxWidth(),
value = textInput,
onValueChange = {
textInput = it
},
)
Spacer(modifier = Modifier.size(4.dp))
ElevatedButton(
onClick = {
viewModel.send(context, navController)
},
) {
Row {
Icon(
Icons.AutoMirrored.Filled.Send,
contentDescription = "Send",
)
Spacer(modifier = Modifier.size(4.dp))
Text("Send")
}
}
}
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -49,13 +49,16 @@ class CustomHttpClient {

suspend fun submitForm(
url: String,
parameters: List<Pair<String, String>>,
): HttpResponse {
val localUrl = if (url.startsWith("/")) url else "/$url"
val protocol = if (Settings.protocol == URLProtocol.HTTP) "http" else "https"
return httpClient.submitForm(
url = "$protocol://${Settings.host}:${Settings.port}$localUrl",
formParameters = parameters {
append("description", "")
parameters.forEach {
append(it.first, it.second)
}
},
) {
basicAuth("", Settings.password)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,11 @@ class PhoenixdViewModel : ViewModel() {
val response4 = httpClient.get("payments/outgoing")
val outgoingPayments = response4.body<List<Payment>>()

outgoingPayments.forEach {
Log.d("outgoingPayments", ((it.fees ?: 1) / 1000).toString())
Log.d("outgoingPayments", it.sent.toString())
}

localPayments.addAll(incomingPayments)
localPayments.addAll(outgoingPayments)
localPayments.sortByDescending { it.createdAt }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,13 @@ class ReceiveViewModel : ViewModel() {
qrCodeBolt12 = body,
)
}
val responseInvoice = httpClient.submitForm("createinvoice")
val responseInvoice = httpClient.submitForm(
url = "createinvoice",
parameters = listOf(
Pair("description", ""),
Pair("amountSat", "1000"),
),
)
val bodyInvoice = responseInvoice.body<GeneratedInvoice>()
state.value = state.value.copy(
qrCode = bodyInvoice.serialized,
Expand Down
Loading

0 comments on commit 7c5cc2c

Please sign in to comment.