mirror of
https://github.com/greenart7c3/Amber.git
synced 2026-10-06 03:18:23 +00:00
Use same styles across the app
This commit is contained in:
@@ -14,6 +14,7 @@ import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material3.CircularProgressIndicator
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Surface
|
||||
@@ -26,6 +27,7 @@ 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.unit.dp
|
||||
import androidx.compose.ui.window.Dialog
|
||||
import androidx.compose.ui.window.DialogProperties
|
||||
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
|
||||
@@ -160,30 +162,35 @@ class MainActivity : AppCompatActivity() {
|
||||
},
|
||||
) {
|
||||
Surface(
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
modifier = Modifier
|
||||
.fillMaxSize(),
|
||||
color = MaterialTheme.colorScheme.background,
|
||||
) {
|
||||
RandomPinInput(
|
||||
text = getString(R.string.enter_pin),
|
||||
onPinEntered = {
|
||||
val pin = LocalPreferences.loadPinFromEncryptedStorage()
|
||||
if (it == pin) {
|
||||
NostrSigner.getInstance().settings = NostrSigner.getInstance().settings.copy(
|
||||
lastBiometricsTime = System.currentTimeMillis(),
|
||||
)
|
||||
Box(
|
||||
Modifier.padding(40.dp),
|
||||
) {
|
||||
RandomPinInput(
|
||||
text = getString(R.string.enter_pin),
|
||||
onPinEntered = {
|
||||
val pin = LocalPreferences.loadPinFromEncryptedStorage()
|
||||
if (it == pin) {
|
||||
NostrSigner.getInstance().settings = NostrSigner.getInstance().settings.copy(
|
||||
lastBiometricsTime = System.currentTimeMillis(),
|
||||
)
|
||||
|
||||
LocalPreferences.saveSettingsToEncryptedStorage(NostrSigner.getInstance().settings)
|
||||
isAuthenticated = true
|
||||
showPinDialog = false
|
||||
} else {
|
||||
Toast.makeText(
|
||||
context,
|
||||
getString(R.string.pin_does_not_match),
|
||||
Toast.LENGTH_SHORT,
|
||||
).show()
|
||||
}
|
||||
},
|
||||
)
|
||||
LocalPreferences.saveSettingsToEncryptedStorage(NostrSigner.getInstance().settings)
|
||||
isAuthenticated = true
|
||||
showPinDialog = false
|
||||
} else {
|
||||
Toast.makeText(
|
||||
context,
|
||||
getString(R.string.pin_does_not_match),
|
||||
Toast.LENGTH_SHORT,
|
||||
).show()
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,6 +19,8 @@ import androidx.compose.material3.AlertDialog
|
||||
import androidx.compose.material3.Button
|
||||
import androidx.compose.material3.ButtonColors
|
||||
import androidx.compose.material3.ButtonDefaults
|
||||
import androidx.compose.material3.CenterAlignedTopAppBar
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.Scaffold
|
||||
import androidx.compose.material3.Text
|
||||
@@ -32,6 +34,7 @@ import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
@@ -53,6 +56,7 @@ import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@SuppressLint("StateFlowValueCalledInComposition", "UnrememberedMutableState")
|
||||
@Composable
|
||||
fun AccountScreen(
|
||||
@@ -166,11 +170,20 @@ fun AccountScreen(
|
||||
} else {
|
||||
AmberListenerSingleton.accountStateViewModel = accountStateViewModel
|
||||
DisplayErrorMessages(accountStateViewModel)
|
||||
Scaffold { innerPadding ->
|
||||
Scaffold(
|
||||
topBar = {
|
||||
CenterAlignedTopAppBar(
|
||||
title = {
|
||||
Text(stringResource(R.string.notification_type))
|
||||
},
|
||||
)
|
||||
},
|
||||
) { innerPadding ->
|
||||
NotificationTypeScreen(
|
||||
Modifier
|
||||
.fillMaxSize()
|
||||
.padding(innerPadding),
|
||||
.padding(innerPadding)
|
||||
.padding(40.dp),
|
||||
onDone = {
|
||||
isNotificationsConfigured = true
|
||||
},
|
||||
@@ -250,6 +263,7 @@ fun InformationDialog(
|
||||
Icon(
|
||||
imageVector = Icons.Outlined.Done,
|
||||
contentDescription = null,
|
||||
tint = Color.Black,
|
||||
)
|
||||
Spacer(Modifier.width(5.dp))
|
||||
Text(stringResource(R.string.ok))
|
||||
|
||||
@@ -13,7 +13,6 @@ import androidx.compose.foundation.text.KeyboardActions
|
||||
import androidx.compose.foundation.text.KeyboardOptions
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.Delete
|
||||
import androidx.compose.material3.Button
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.IconButton
|
||||
import androidx.compose.material3.OutlinedTextField
|
||||
@@ -87,8 +86,7 @@ fun EditConfigurationScreen(
|
||||
} else {
|
||||
Column(
|
||||
modifier
|
||||
.fillMaxSize()
|
||||
.padding(16.dp),
|
||||
.fillMaxSize(),
|
||||
) {
|
||||
Text(stringResource(R.string.edit_configuration_description))
|
||||
|
||||
@@ -125,21 +123,62 @@ fun EditConfigurationScreen(
|
||||
)
|
||||
|
||||
Spacer(modifier = Modifier.height(16.dp))
|
||||
if (application?.application?.shouldShowRelays() == true) {
|
||||
OutlinedTextField(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth(),
|
||||
value = textFieldRelay.value.text,
|
||||
keyboardOptions = KeyboardOptions(
|
||||
capitalization = KeyboardCapitalization.None,
|
||||
autoCorrectEnabled = false,
|
||||
imeAction = ImeAction.Done,
|
||||
),
|
||||
onValueChange = {
|
||||
textFieldRelay.value = TextFieldValue(it)
|
||||
},
|
||||
keyboardActions = KeyboardActions(
|
||||
onDone = {
|
||||
scope.launch(Dispatchers.IO) {
|
||||
onAddRelay(
|
||||
textFieldRelay,
|
||||
isLoading,
|
||||
relays,
|
||||
scope,
|
||||
accountStateViewModel,
|
||||
account,
|
||||
context,
|
||||
onDone = {
|
||||
scope.launch(Dispatchers.IO) {
|
||||
application?.let {
|
||||
val localApplicationData =
|
||||
it.application.copy(
|
||||
name = name.text,
|
||||
relays = relays,
|
||||
)
|
||||
database.applicationDao().delete(it.application)
|
||||
database.applicationDao().insertApplicationWithPermissions(
|
||||
ApplicationWithPermissions(
|
||||
localApplicationData,
|
||||
it.permissions,
|
||||
),
|
||||
)
|
||||
if (NostrSigner.getInstance().settings.notificationType == NotificationType.DIRECT) {
|
||||
NostrSigner.getInstance().checkForNewRelays()
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
},
|
||||
),
|
||||
label = {
|
||||
Text(stringResource(R.string.wss))
|
||||
},
|
||||
)
|
||||
|
||||
OutlinedTextField(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth(),
|
||||
value = textFieldRelay.value.text,
|
||||
keyboardOptions = KeyboardOptions(
|
||||
capitalization = KeyboardCapitalization.None,
|
||||
autoCorrectEnabled = false,
|
||||
imeAction = ImeAction.Done,
|
||||
),
|
||||
onValueChange = {
|
||||
textFieldRelay.value = TextFieldValue(it)
|
||||
},
|
||||
keyboardActions = KeyboardActions(
|
||||
onDone = {
|
||||
AmberButton(
|
||||
onClick = {
|
||||
scope.launch(Dispatchers.IO) {
|
||||
onAddRelay(
|
||||
textFieldRelay,
|
||||
@@ -173,55 +212,13 @@ fun EditConfigurationScreen(
|
||||
)
|
||||
}
|
||||
},
|
||||
),
|
||||
label = {
|
||||
Text(stringResource(R.string.wss))
|
||||
},
|
||||
)
|
||||
content = {
|
||||
Text(stringResource(R.string.add))
|
||||
},
|
||||
)
|
||||
|
||||
AmberButton(
|
||||
onClick = {
|
||||
scope.launch(Dispatchers.IO) {
|
||||
onAddRelay(
|
||||
textFieldRelay,
|
||||
isLoading,
|
||||
relays,
|
||||
scope,
|
||||
accountStateViewModel,
|
||||
account,
|
||||
context,
|
||||
onDone = {
|
||||
scope.launch(Dispatchers.IO) {
|
||||
application?.let {
|
||||
val localApplicationData =
|
||||
it.application.copy(
|
||||
name = name.text,
|
||||
relays = relays,
|
||||
)
|
||||
database.applicationDao().delete(it.application)
|
||||
database.applicationDao().insertApplicationWithPermissions(
|
||||
ApplicationWithPermissions(
|
||||
localApplicationData,
|
||||
it.permissions,
|
||||
),
|
||||
)
|
||||
if (NostrSigner.getInstance().settings.notificationType == NotificationType.DIRECT) {
|
||||
NostrSigner.getInstance().checkForNewRelays()
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
},
|
||||
content = {
|
||||
Text(stringResource(R.string.add))
|
||||
},
|
||||
)
|
||||
Spacer(modifier = Modifier.height(16.dp))
|
||||
|
||||
Spacer(modifier = Modifier.height(16.dp))
|
||||
|
||||
if (application?.application?.shouldShowRelays() == true) {
|
||||
LazyColumn(
|
||||
Modifier.weight(1f),
|
||||
) {
|
||||
@@ -277,36 +274,28 @@ fun EditConfigurationScreen(
|
||||
|
||||
Spacer(modifier = Modifier.height(16.dp))
|
||||
|
||||
Row(
|
||||
Modifier.fillMaxWidth(),
|
||||
horizontalArrangement = Arrangement.Center,
|
||||
) {
|
||||
Button(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(8.dp),
|
||||
onClick = {
|
||||
application?.let {
|
||||
scope.launch(Dispatchers.IO) {
|
||||
database.applicationDao().delete(it.application)
|
||||
AmberButton(
|
||||
onClick = {
|
||||
application?.let {
|
||||
scope.launch(Dispatchers.IO) {
|
||||
database.applicationDao().delete(it.application)
|
||||
|
||||
if (NostrSigner.getInstance().settings.notificationType == NotificationType.DIRECT) {
|
||||
NostrSigner.getInstance().checkForNewRelays()
|
||||
}
|
||||
if (NostrSigner.getInstance().settings.notificationType == NotificationType.DIRECT) {
|
||||
NostrSigner.getInstance().checkForNewRelays()
|
||||
}
|
||||
|
||||
scope.launch(Dispatchers.Main) {
|
||||
navController.navigate(Route.Applications.route) {
|
||||
popUpTo(0)
|
||||
}
|
||||
scope.launch(Dispatchers.Main) {
|
||||
navController.navigate(Route.Applications.route) {
|
||||
popUpTo(0)
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
content = {
|
||||
Text(stringResource(R.string.delete_application))
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
},
|
||||
content = {
|
||||
Text(stringResource(R.string.delete_application))
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package com.greenart7c3.nostrsigner.ui
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.widget.Toast
|
||||
import androidx.compose.foundation.BorderStroke
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
@@ -16,10 +17,11 @@ import androidx.compose.foundation.lazy.itemsIndexed
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.Delete
|
||||
import androidx.compose.material.icons.filled.Info
|
||||
import androidx.compose.material3.Button
|
||||
import androidx.compose.material3.ElevatedCard
|
||||
import androidx.compose.material3.Card
|
||||
import androidx.compose.material3.CardDefaults
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.IconButton
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Switch
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
@@ -120,8 +122,7 @@ fun EditPermission(
|
||||
}
|
||||
|
||||
Column(
|
||||
modifier = modifier
|
||||
.padding(8.dp),
|
||||
modifier = modifier,
|
||||
) {
|
||||
if (!applicationData.isConnected) {
|
||||
Text(
|
||||
@@ -132,10 +133,9 @@ fun EditPermission(
|
||||
fontSize = 18.sp,
|
||||
)
|
||||
|
||||
Button(
|
||||
AmberButton(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(8.dp),
|
||||
.fillMaxWidth(),
|
||||
onClick = {
|
||||
clipboardManager.setText(AnnotatedString(bunkerUri))
|
||||
},
|
||||
@@ -190,10 +190,14 @@ fun EditPermission(
|
||||
} else {
|
||||
localPermission.toLocalizedString(context)
|
||||
}
|
||||
ElevatedCard(
|
||||
Card(
|
||||
modifier = Modifier
|
||||
.padding(4.dp)
|
||||
.fillMaxWidth(),
|
||||
border = BorderStroke(1.dp, Color.Gray),
|
||||
colors = CardDefaults.cardColors().copy(
|
||||
containerColor = MaterialTheme.colorScheme.background,
|
||||
),
|
||||
) {
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
|
||||
+1
-1
@@ -35,7 +35,7 @@ import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
@Composable
|
||||
fun HomeScreen(
|
||||
fun IncomingRequestScreen(
|
||||
modifier: Modifier,
|
||||
intents: List<IntentData>,
|
||||
packageName: String?,
|
||||
@@ -36,8 +36,7 @@ fun LanguageScreen(
|
||||
|
||||
Column(
|
||||
modifier = modifier
|
||||
.fillMaxSize()
|
||||
.padding(10.dp),
|
||||
.fillMaxSize(),
|
||||
) {
|
||||
Column {
|
||||
Box(
|
||||
|
||||
@@ -30,13 +30,15 @@ import androidx.compose.foundation.verticalScroll
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.outlined.Visibility
|
||||
import androidx.compose.material.icons.outlined.VisibilityOff
|
||||
import androidx.compose.material3.Button
|
||||
import androidx.compose.material3.CenterAlignedTopAppBar
|
||||
import androidx.compose.material3.Checkbox
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.IconButton
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.OutlinedTextField
|
||||
import androidx.compose.material3.RadioButton
|
||||
import androidx.compose.material3.Scaffold
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
@@ -125,14 +127,6 @@ fun MainPage(
|
||||
|
||||
Spacer(modifier = Modifier.height(40.dp))
|
||||
|
||||
Text(
|
||||
text = stringResource(R.string.app_name),
|
||||
fontSize = 24.sp,
|
||||
fontWeight = FontWeight.Bold,
|
||||
)
|
||||
|
||||
Spacer(modifier = Modifier.height(40.dp))
|
||||
|
||||
Column(
|
||||
modifier = Modifier.padding(40.dp, 0.dp, 40.dp, 0.dp),
|
||||
verticalArrangement = Arrangement.spacedBy(8.dp),
|
||||
@@ -144,16 +138,11 @@ fun MainPage(
|
||||
state.animateScrollToPage(1)
|
||||
}
|
||||
},
|
||||
|
||||
modifier = Modifier
|
||||
.height(50.dp),
|
||||
) {
|
||||
Text(text = stringResource(R.string.add_a_key))
|
||||
}
|
||||
|
||||
AmberButton(
|
||||
modifier = Modifier
|
||||
.height(50.dp),
|
||||
onClick = {
|
||||
scope.launch {
|
||||
state.animateScrollToPage(2)
|
||||
@@ -167,6 +156,7 @@ fun MainPage(
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
fun MainLoginPage(
|
||||
accountViewModel: AccountStateViewModel,
|
||||
@@ -176,28 +166,41 @@ fun MainLoginPage(
|
||||
3
|
||||
}
|
||||
|
||||
HorizontalPager(
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
state = state,
|
||||
userScrollEnabled = false,
|
||||
) {
|
||||
when (it) {
|
||||
0 -> {
|
||||
MainPage(
|
||||
scope = scope,
|
||||
state = state,
|
||||
)
|
||||
}
|
||||
1 -> {
|
||||
LoginPage(
|
||||
accountViewModel = accountViewModel,
|
||||
)
|
||||
}
|
||||
2 -> {
|
||||
SignUpPage(
|
||||
accountViewModel = accountViewModel,
|
||||
scope = scope,
|
||||
)
|
||||
Scaffold(
|
||||
topBar = {
|
||||
CenterAlignedTopAppBar(
|
||||
title = {
|
||||
Text(text = stringResource(R.string.app_name))
|
||||
},
|
||||
)
|
||||
},
|
||||
) { innerPadding ->
|
||||
HorizontalPager(
|
||||
modifier = Modifier
|
||||
.padding(innerPadding)
|
||||
.padding(40.dp)
|
||||
.fillMaxSize(),
|
||||
state = state,
|
||||
userScrollEnabled = false,
|
||||
) {
|
||||
when (it) {
|
||||
0 -> {
|
||||
MainPage(
|
||||
scope = scope,
|
||||
state = state,
|
||||
)
|
||||
}
|
||||
1 -> {
|
||||
LoginPage(
|
||||
accountViewModel = accountViewModel,
|
||||
)
|
||||
}
|
||||
2 -> {
|
||||
SignUpPage(
|
||||
accountViewModel = accountViewModel,
|
||||
scope = scope,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -341,8 +344,6 @@ fun OrbotPage(
|
||||
Spacer(modifier = Modifier.height(20.dp))
|
||||
|
||||
AmberButton(
|
||||
Modifier
|
||||
.padding(start = 40.dp, end = 40.dp),
|
||||
onClick = {
|
||||
scope.launch {
|
||||
pageState.animateScrollToPage(2)
|
||||
@@ -457,8 +458,6 @@ fun SignPolicyScreen(
|
||||
Spacer(modifier = Modifier.height(40.dp))
|
||||
|
||||
AmberButton(
|
||||
Modifier
|
||||
.padding(start = 40.dp, end = 40.dp),
|
||||
onClick = {
|
||||
if (key.isBlank()) {
|
||||
accountViewModel.newKey(
|
||||
@@ -577,6 +576,7 @@ fun LoginPage(accountViewModel: AccountStateViewModel) {
|
||||
|
||||
OutlinedTextField(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.onGloballyPositioned { coordinates ->
|
||||
autofillNodeKey.boundingBox = coordinates.boundsInWindow()
|
||||
}
|
||||
@@ -670,6 +670,7 @@ fun LoginPage(accountViewModel: AccountStateViewModel) {
|
||||
if (needsPassword.value) {
|
||||
OutlinedTextField(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.onGloballyPositioned { coordinates ->
|
||||
autofillNodePassword.boundingBox = coordinates.boundsInWindow()
|
||||
}
|
||||
@@ -784,36 +785,30 @@ fun LoginPage(accountViewModel: AccountStateViewModel) {
|
||||
|
||||
Spacer(modifier = Modifier.height(10.dp))
|
||||
|
||||
Row(
|
||||
modifier = Modifier.padding(40.dp, 0.dp, 40.dp, 0.dp),
|
||||
horizontalArrangement = Arrangement.spacedBy(8.dp),
|
||||
) {
|
||||
Button(
|
||||
onClick = {
|
||||
if (key.value.text.isBlank()) {
|
||||
errorMessage = context.getString(R.string.key_is_required)
|
||||
}
|
||||
|
||||
if (needsPassword.value && password.value.text.isBlank()) {
|
||||
errorMessage = context.getString(R.string.password_is_required)
|
||||
}
|
||||
|
||||
if (key.value.text.isNotBlank() && !(needsPassword.value && password.value.text.isBlank())) {
|
||||
if (accountViewModel.isValidKey(key.value.text, password.value.text)) {
|
||||
scope.launch {
|
||||
pageState.animateScrollToPage(1)
|
||||
}
|
||||
} else {
|
||||
errorMessage = context.getString(R.string.invalid_key)
|
||||
}
|
||||
}
|
||||
},
|
||||
modifier = Modifier
|
||||
.height(50.dp),
|
||||
) {
|
||||
AmberButton(
|
||||
content = {
|
||||
Text(text = stringResource(R.string.next))
|
||||
}
|
||||
}
|
||||
},
|
||||
onClick = {
|
||||
if (key.value.text.isBlank()) {
|
||||
errorMessage = context.getString(R.string.key_is_required)
|
||||
}
|
||||
|
||||
if (needsPassword.value && password.value.text.isBlank()) {
|
||||
errorMessage = context.getString(R.string.password_is_required)
|
||||
}
|
||||
|
||||
if (key.value.text.isNotBlank() && !(needsPassword.value && password.value.text.isBlank())) {
|
||||
if (accountViewModel.isValidKey(key.value.text, password.value.text)) {
|
||||
scope.launch {
|
||||
pageState.animateScrollToPage(1)
|
||||
}
|
||||
} else {
|
||||
errorMessage = context.getString(R.string.invalid_key)
|
||||
}
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,15 +1,19 @@
|
||||
package com.greenart7c3.nostrsigner.ui
|
||||
|
||||
import androidx.compose.foundation.BorderStroke
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.material3.ElevatedCard
|
||||
import androidx.compose.material3.Card
|
||||
import androidx.compose.material3.CardDefaults
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.SpanStyle
|
||||
import androidx.compose.ui.text.buildAnnotatedString
|
||||
@@ -34,8 +38,7 @@ fun LogsScreen(
|
||||
val scope = rememberCoroutineScope()
|
||||
Column(
|
||||
modifier = modifier
|
||||
.fillMaxSize()
|
||||
.padding(10.dp),
|
||||
.fillMaxSize(),
|
||||
) {
|
||||
val logsFlow = NostrSigner.getInstance().getDatabase(account.keyPair.pubKey.toNpub()).applicationDao().getLogs()
|
||||
val logs = logsFlow.collectAsStateWithLifecycle(initialValue = emptyList())
|
||||
@@ -44,10 +47,14 @@ fun LogsScreen(
|
||||
Modifier.weight(1f),
|
||||
) {
|
||||
items(logs.value.size) { index ->
|
||||
ElevatedCard(
|
||||
Card(
|
||||
Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(6.dp),
|
||||
.padding(4.dp),
|
||||
border = BorderStroke(1.dp, Color.Gray),
|
||||
colors = CardDefaults.cardColors().copy(
|
||||
containerColor = MaterialTheme.colorScheme.background,
|
||||
),
|
||||
) {
|
||||
Column(Modifier.padding(6.dp)) {
|
||||
val log = logs.value[index]
|
||||
@@ -89,6 +96,7 @@ fun LogsScreen(
|
||||
}
|
||||
|
||||
AmberButton(
|
||||
modifier = Modifier.padding(top = 8.dp),
|
||||
onClick = {
|
||||
scope.launch(Dispatchers.IO) {
|
||||
NostrSigner.getInstance().getDatabase(account.keyPair.pubKey.toNpub()).applicationDao().clearLogs()
|
||||
|
||||
@@ -15,12 +15,14 @@ import androidx.compose.animation.core.tween
|
||||
import androidx.compose.animation.fadeIn
|
||||
import androidx.compose.animation.fadeOut
|
||||
import androidx.compose.foundation.border
|
||||
import androidx.compose.foundation.isSystemInDarkTheme
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.shape.CircleShape
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.automirrored.filled.ArrowBack
|
||||
import androidx.compose.material.icons.filled.Add
|
||||
@@ -355,12 +357,12 @@ fun PermissionsFloatingActionButton(
|
||||
) {
|
||||
FloatingActionButton(
|
||||
onClick = onClick,
|
||||
shape = CircleShape,
|
||||
shape = RoundedCornerShape(24),
|
||||
) {
|
||||
Icon(
|
||||
Icons.Default.Add,
|
||||
contentDescription = stringResource(R.string.connect_app),
|
||||
tint = Color.White,
|
||||
tint = Color.Black,
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -596,6 +598,7 @@ fun MainScreen(
|
||||
Icon(
|
||||
if (selected) it.selectedIcon else it.icon,
|
||||
it.route,
|
||||
tint = if (selected) Color.Black else if (isSystemInDarkTheme()) Color.White else Color.Black,
|
||||
)
|
||||
}
|
||||
},
|
||||
@@ -654,10 +657,11 @@ fun MainScreen(
|
||||
composable(
|
||||
Route.IncomingRequest.route,
|
||||
content = {
|
||||
HomeScreen(
|
||||
IncomingRequestScreen(
|
||||
Modifier
|
||||
.fillMaxSize()
|
||||
.padding(padding),
|
||||
.padding(padding)
|
||||
.padding(40.dp),
|
||||
intents,
|
||||
packageName,
|
||||
appName,
|
||||
@@ -673,7 +677,8 @@ fun MainScreen(
|
||||
PermissionsScreen(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.padding(padding),
|
||||
.padding(padding)
|
||||
.padding(24.dp),
|
||||
account = account,
|
||||
accountStateViewModel = accountStateViewModel,
|
||||
navController = navController,
|
||||
@@ -688,7 +693,8 @@ fun MainScreen(
|
||||
SettingsScreen(
|
||||
Modifier
|
||||
.fillMaxSize()
|
||||
.padding(padding),
|
||||
.padding(padding)
|
||||
.padding(40.dp),
|
||||
accountStateViewModel,
|
||||
account,
|
||||
navController,
|
||||
@@ -702,7 +708,8 @@ fun MainScreen(
|
||||
AccountBackupScreen(
|
||||
Modifier
|
||||
.fillMaxSize()
|
||||
.padding(padding),
|
||||
.padding(padding)
|
||||
.padding(40.dp),
|
||||
account,
|
||||
)
|
||||
},
|
||||
@@ -717,7 +724,8 @@ fun MainScreen(
|
||||
modifier =
|
||||
Modifier
|
||||
.fillMaxSize()
|
||||
.padding(padding),
|
||||
.padding(padding)
|
||||
.padding(40.dp),
|
||||
account = account,
|
||||
selectedPackage = packageName,
|
||||
navController = navController,
|
||||
@@ -734,7 +742,8 @@ fun MainScreen(
|
||||
modifier =
|
||||
Modifier
|
||||
.fillMaxSize()
|
||||
.padding(padding),
|
||||
.padding(padding)
|
||||
.padding(40.dp),
|
||||
account = account,
|
||||
)
|
||||
},
|
||||
@@ -748,7 +757,8 @@ fun MainScreen(
|
||||
modifier =
|
||||
Modifier
|
||||
.fillMaxSize()
|
||||
.padding(padding),
|
||||
.padding(padding)
|
||||
.padding(40.dp),
|
||||
)
|
||||
},
|
||||
)
|
||||
@@ -760,7 +770,8 @@ fun MainScreen(
|
||||
modifier =
|
||||
Modifier
|
||||
.fillMaxSize()
|
||||
.padding(padding),
|
||||
.padding(padding)
|
||||
.padding(40.dp),
|
||||
account = account,
|
||||
)
|
||||
},
|
||||
@@ -773,7 +784,8 @@ fun MainScreen(
|
||||
modifier =
|
||||
Modifier
|
||||
.fillMaxSize()
|
||||
.padding(padding),
|
||||
.padding(padding)
|
||||
.padding(40.dp),
|
||||
onDone = {
|
||||
navController.navigateUp()
|
||||
},
|
||||
@@ -788,8 +800,8 @@ fun MainScreen(
|
||||
modifier =
|
||||
Modifier
|
||||
.fillMaxSize()
|
||||
.padding(padding),
|
||||
navController = navController,
|
||||
.padding(padding)
|
||||
.padding(40.dp),
|
||||
accountStateViewModel = accountStateViewModel,
|
||||
account = account,
|
||||
)
|
||||
@@ -803,7 +815,8 @@ fun MainScreen(
|
||||
modifier =
|
||||
Modifier
|
||||
.fillMaxSize()
|
||||
.padding(padding),
|
||||
.padding(padding)
|
||||
.padding(40.dp),
|
||||
account = account,
|
||||
navController = navController,
|
||||
)
|
||||
@@ -817,7 +830,8 @@ fun MainScreen(
|
||||
modifier =
|
||||
Modifier
|
||||
.fillMaxSize()
|
||||
.padding(padding),
|
||||
.padding(padding)
|
||||
.padding(40.dp),
|
||||
navController = navController,
|
||||
)
|
||||
},
|
||||
@@ -833,7 +847,8 @@ fun MainScreen(
|
||||
modifier =
|
||||
Modifier
|
||||
.fillMaxSize()
|
||||
.padding(padding),
|
||||
.padding(padding)
|
||||
.padding(40.dp),
|
||||
)
|
||||
},
|
||||
)
|
||||
@@ -849,7 +864,8 @@ fun MainScreen(
|
||||
modifier =
|
||||
Modifier
|
||||
.fillMaxSize()
|
||||
.padding(padding),
|
||||
.padding(padding)
|
||||
.padding(40.dp),
|
||||
)
|
||||
},
|
||||
)
|
||||
@@ -866,7 +882,8 @@ fun MainScreen(
|
||||
modifier =
|
||||
Modifier
|
||||
.fillMaxSize()
|
||||
.padding(padding),
|
||||
.padding(padding)
|
||||
.padding(40.dp),
|
||||
)
|
||||
}
|
||||
},
|
||||
@@ -900,7 +917,8 @@ fun MainScreen(
|
||||
modifier =
|
||||
Modifier
|
||||
.fillMaxSize()
|
||||
.padding(padding),
|
||||
.padding(padding)
|
||||
.padding(40.dp),
|
||||
)
|
||||
}
|
||||
},
|
||||
@@ -914,7 +932,8 @@ fun MainScreen(
|
||||
EditConfigurationScreen(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.padding(padding),
|
||||
.padding(padding)
|
||||
.padding(40.dp),
|
||||
database = database,
|
||||
key = key,
|
||||
accountStateViewModel = accountStateViewModel,
|
||||
@@ -931,7 +950,8 @@ fun MainScreen(
|
||||
SetupPinScreen(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.padding(padding),
|
||||
.padding(padding)
|
||||
.padding(40.dp),
|
||||
navController = navController,
|
||||
)
|
||||
},
|
||||
@@ -945,7 +965,8 @@ fun MainScreen(
|
||||
ConfirmPinScreen(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.padding(padding),
|
||||
.padding(padding)
|
||||
.padding(40.dp),
|
||||
accountStateViewModel = accountStateViewModel,
|
||||
pin = pin,
|
||||
navController = navController,
|
||||
|
||||
@@ -52,10 +52,10 @@ fun NewApplicationScreen(
|
||||
Column(
|
||||
modifier =
|
||||
modifier
|
||||
.fillMaxSize()
|
||||
.padding(horizontal = 16.dp, vertical = 24.dp),
|
||||
.fillMaxSize(),
|
||||
) {
|
||||
Text(
|
||||
modifier = Modifier.padding(bottom = 20.dp),
|
||||
text = stringResource(R.string.new_app_description),
|
||||
)
|
||||
|
||||
@@ -92,7 +92,8 @@ fun NewApplicationScreen(
|
||||
)
|
||||
|
||||
Text(
|
||||
stringResource(R.string.nostr_connect_description),
|
||||
modifier = Modifier.padding(bottom = 20.dp),
|
||||
text = stringResource(R.string.nostr_connect_description),
|
||||
)
|
||||
|
||||
AmberButton(
|
||||
@@ -105,7 +106,8 @@ fun NewApplicationScreen(
|
||||
)
|
||||
|
||||
Text(
|
||||
stringResource(R.string.nostr_connect_qr_description),
|
||||
modifier = Modifier.padding(bottom = 20.dp),
|
||||
text = stringResource(R.string.nostr_connect_qr_description),
|
||||
)
|
||||
|
||||
AmberButton(
|
||||
|
||||
@@ -14,7 +14,6 @@ import androidx.compose.foundation.text.KeyboardOptions
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.Add
|
||||
import androidx.compose.material.icons.filled.Delete
|
||||
import androidx.compose.material3.Button
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.IconButton
|
||||
import androidx.compose.material3.OutlinedTextField
|
||||
@@ -46,6 +45,7 @@ import com.greenart7c3.nostrsigner.database.AppDatabase
|
||||
import com.greenart7c3.nostrsigner.database.ApplicationEntity
|
||||
import com.greenart7c3.nostrsigner.models.Account
|
||||
import com.greenart7c3.nostrsigner.ui.actions.onAddRelay
|
||||
import com.greenart7c3.nostrsigner.ui.components.AmberButton
|
||||
import com.vitorpamplona.ammolite.relays.RelaySetupInfo
|
||||
import com.vitorpamplona.quartz.encoders.toHexKey
|
||||
import java.util.UUID
|
||||
@@ -88,8 +88,7 @@ fun NewNsecBunkerScreen(
|
||||
} else {
|
||||
Column(
|
||||
modifier = modifier
|
||||
.fillMaxSize()
|
||||
.padding(16.dp),
|
||||
.fillMaxSize(),
|
||||
) {
|
||||
Text(stringResource(R.string.create_nsecbunker_description))
|
||||
|
||||
@@ -196,61 +195,54 @@ fun NewNsecBunkerScreen(
|
||||
}
|
||||
}
|
||||
|
||||
Row(
|
||||
Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(16.dp),
|
||||
horizontalArrangement = Arrangement.Center,
|
||||
) {
|
||||
Button(
|
||||
onClick = {
|
||||
if (relays.isEmpty()) {
|
||||
accountStateViewModel.toast(
|
||||
context.getString(R.string.relays),
|
||||
context.getString(R.string.no_relays_added),
|
||||
AmberButton(
|
||||
content = {
|
||||
Text(text = stringResource(R.string.create))
|
||||
},
|
||||
onClick = {
|
||||
if (relays.isEmpty()) {
|
||||
accountStateViewModel.toast(
|
||||
context.getString(R.string.relays),
|
||||
context.getString(R.string.no_relays_added),
|
||||
)
|
||||
|
||||
return@AmberButton
|
||||
}
|
||||
|
||||
if (name.text.isBlank()) {
|
||||
accountStateViewModel.toast(
|
||||
context.getString(R.string.name),
|
||||
context.getString(R.string.name_cannot_be_empty),
|
||||
)
|
||||
|
||||
return@AmberButton
|
||||
}
|
||||
|
||||
scope.launch(Dispatchers.IO) {
|
||||
val application =
|
||||
ApplicationEntity(
|
||||
secret.value,
|
||||
name.text,
|
||||
relays,
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
account.keyPair.pubKey.toHexKey(),
|
||||
false,
|
||||
secret.value,
|
||||
true,
|
||||
account.signPolicy,
|
||||
)
|
||||
|
||||
return@Button
|
||||
database.applicationDao().insertApplication(
|
||||
application,
|
||||
)
|
||||
scope.launch(Dispatchers.Main) {
|
||||
navController.navigate("NewNsecBunkerCreated/${secret.value}")
|
||||
}
|
||||
|
||||
if (name.text.isBlank()) {
|
||||
accountStateViewModel.toast(
|
||||
context.getString(R.string.name),
|
||||
context.getString(R.string.name_cannot_be_empty),
|
||||
)
|
||||
|
||||
return@Button
|
||||
}
|
||||
|
||||
scope.launch(Dispatchers.IO) {
|
||||
val application =
|
||||
ApplicationEntity(
|
||||
secret.value,
|
||||
name.text,
|
||||
relays,
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
account.keyPair.pubKey.toHexKey(),
|
||||
false,
|
||||
secret.value,
|
||||
true,
|
||||
account.signPolicy,
|
||||
)
|
||||
|
||||
database.applicationDao().insertApplication(
|
||||
application,
|
||||
)
|
||||
scope.launch(Dispatchers.Main) {
|
||||
navController.navigate("NewNsecBunkerCreated/${secret.value}")
|
||||
}
|
||||
}
|
||||
},
|
||||
content = {
|
||||
Text(text = stringResource(R.string.create))
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -285,8 +277,7 @@ fun NewNsecBunkerCreatedScreen(
|
||||
|
||||
Column(
|
||||
modifier = modifier
|
||||
.fillMaxSize()
|
||||
.padding(16.dp),
|
||||
.fillMaxSize(),
|
||||
) {
|
||||
Row(
|
||||
Modifier.fillMaxWidth(),
|
||||
@@ -317,19 +308,14 @@ fun NewNsecBunkerCreatedScreen(
|
||||
|
||||
Spacer(modifier = Modifier.height(8.dp))
|
||||
|
||||
Row(
|
||||
Modifier.fillMaxWidth(),
|
||||
horizontalArrangement = Arrangement.Center,
|
||||
) {
|
||||
Button(
|
||||
onClick = {
|
||||
clipboardManager.setText(AnnotatedString(bunkerUri))
|
||||
},
|
||||
content = {
|
||||
Text(text = stringResource(R.string.copy_to_clipboard))
|
||||
},
|
||||
)
|
||||
}
|
||||
AmberButton(
|
||||
onClick = {
|
||||
clipboardManager.setText(AnnotatedString(bunkerUri))
|
||||
},
|
||||
content = {
|
||||
Text(text = stringResource(R.string.copy_to_clipboard))
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -67,8 +67,7 @@ fun NotificationTypeScreen(
|
||||
)
|
||||
Column(
|
||||
modifier = modifier
|
||||
.fillMaxSize()
|
||||
.padding(10.dp),
|
||||
.fillMaxSize(),
|
||||
) {
|
||||
Column(
|
||||
Modifier.weight(1f),
|
||||
|
||||
@@ -4,10 +4,12 @@ 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.Spacer
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.material3.ElevatedCard
|
||||
import androidx.compose.material3.HorizontalDivider
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
@@ -99,38 +101,40 @@ fun PermissionsScreen(
|
||||
// }
|
||||
// }
|
||||
items(applications.size) {
|
||||
ElevatedCard(
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.padding(4.dp)
|
||||
.fillMaxSize(),
|
||||
) {
|
||||
Row(
|
||||
modifier = Modifier.clickable {
|
||||
.fillMaxSize()
|
||||
.padding(vertical = 4.dp)
|
||||
.clickable {
|
||||
navController.navigate("Permission/${applications.elementAt(it).key}")
|
||||
},
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
Column(
|
||||
Modifier
|
||||
.fillMaxSize(),
|
||||
verticalArrangement = Arrangement.Center,
|
||||
) {
|
||||
Column(
|
||||
Modifier
|
||||
.padding(16.dp)
|
||||
.weight(0.9f),
|
||||
) {
|
||||
val localPermission = applications.elementAt(it)
|
||||
Text(
|
||||
modifier = Modifier.padding(start = 16.dp),
|
||||
text = localPermission.name.ifBlank { localPermission.key.toShortenHex() },
|
||||
fontSize = 24.sp,
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
)
|
||||
Text(
|
||||
modifier = Modifier.padding(start = 16.dp, top = 4.dp),
|
||||
text = localPermission.key,
|
||||
fontSize = 18.sp,
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
)
|
||||
}
|
||||
val localPermission = applications.elementAt(it)
|
||||
Text(
|
||||
modifier = Modifier.padding(top = 16.dp),
|
||||
text = localPermission.name.ifBlank { localPermission.key.toShortenHex() },
|
||||
fontSize = 24.sp,
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
)
|
||||
Text(
|
||||
modifier = Modifier.padding(top = 4.dp, bottom = 16.dp),
|
||||
text = localPermission.key,
|
||||
fontSize = 18.sp,
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
)
|
||||
Spacer(Modifier.weight(1f))
|
||||
HorizontalDivider(
|
||||
|
||||
color = MaterialTheme.colorScheme.primary,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,7 +46,7 @@ fun SecurityScreen(
|
||||
TitleExplainer(stringResource(BiometricsTimeType.TEN_MINUTES.resourceId)),
|
||||
)
|
||||
var enableBiometrics by remember { mutableStateOf(NostrSigner.getInstance().settings.useAuth) }
|
||||
var setupPin by remember { mutableStateOf(NostrSigner.getInstance().settings.usePin) }
|
||||
val setupPin by remember { mutableStateOf(NostrSigner.getInstance().settings.usePin) }
|
||||
var biometricsIndex by remember {
|
||||
mutableIntStateOf(NostrSigner.getInstance().settings.biometricsTimeType.screenCode)
|
||||
}
|
||||
@@ -57,8 +57,7 @@ fun SecurityScreen(
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.padding(10.dp),
|
||||
.fillMaxSize(),
|
||||
) {
|
||||
Column(
|
||||
Modifier.weight(1f),
|
||||
|
||||
@@ -211,6 +211,13 @@ fun SettingsScreen(
|
||||
account.allowNewConnections = allowNewConnections
|
||||
LocalPreferences.saveToEncryptedStorage(context, account)
|
||||
},
|
||||
onLongClick = {
|
||||
Toast.makeText(
|
||||
context,
|
||||
if (allowNewConnections) context.getString(R.string.disable_listening_for_new_connections) else context.getString(R.string.enable_listening_for_new_connections),
|
||||
Toast.LENGTH_LONG,
|
||||
).show()
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
package com.greenart7c3.nostrsigner.ui
|
||||
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.navigation.NavController
|
||||
import com.greenart7c3.nostrsigner.LocalPreferences
|
||||
import com.greenart7c3.nostrsigner.NostrSigner
|
||||
@@ -19,8 +17,7 @@ fun SetupPinScreen(
|
||||
navController: NavController,
|
||||
) {
|
||||
Column(
|
||||
modifier
|
||||
.padding(16.dp),
|
||||
modifier,
|
||||
) {
|
||||
RandomPinInput { pin ->
|
||||
navController.navigate("${Route.ConfirmPin.route.split("/")[0]}/$pin")
|
||||
@@ -37,8 +34,7 @@ fun ConfirmPinScreen(
|
||||
) {
|
||||
val context = LocalContext.current
|
||||
Column(
|
||||
modifier
|
||||
.padding(16.dp),
|
||||
modifier,
|
||||
) {
|
||||
RandomPinInput(
|
||||
onPinEntered = { enteredPin ->
|
||||
|
||||
@@ -57,8 +57,7 @@ fun SignPolicySettingsScreen(
|
||||
|
||||
Column(
|
||||
modifier = modifier
|
||||
.fillMaxSize()
|
||||
.padding(10.dp),
|
||||
.fillMaxSize(),
|
||||
) {
|
||||
LazyColumn(
|
||||
modifier = Modifier.weight(1f),
|
||||
|
||||
@@ -54,6 +54,7 @@ import androidx.compose.ui.text.input.KeyboardType
|
||||
import androidx.compose.ui.text.input.PasswordVisualTransformation
|
||||
import androidx.compose.ui.text.input.TextFieldValue
|
||||
import androidx.compose.ui.text.input.VisualTransformation
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.window.Dialog
|
||||
import androidx.compose.ui.window.DialogProperties
|
||||
@@ -327,7 +328,6 @@ private fun NSecQrButton(account: Account) {
|
||||
content = {
|
||||
Text(
|
||||
stringResource(id = R.string.show_qr_code),
|
||||
color = MaterialTheme.colorScheme.onPrimary,
|
||||
)
|
||||
},
|
||||
)
|
||||
@@ -475,7 +475,8 @@ private fun EncryptNSecCopyButton(
|
||||
content = {
|
||||
Text(
|
||||
stringResource(id = R.string.encrypt_and_copy_my_secret_key),
|
||||
color = MaterialTheme.colorScheme.onPrimary,
|
||||
maxLines = 1,
|
||||
textAlign = TextAlign.Center,
|
||||
)
|
||||
},
|
||||
)
|
||||
@@ -531,7 +532,6 @@ private fun EncryptNSecQRButton(
|
||||
content = {
|
||||
Text(
|
||||
stringResource(id = R.string.show_qr_code),
|
||||
color = MaterialTheme.colorScheme.onPrimary,
|
||||
)
|
||||
},
|
||||
)
|
||||
|
||||
@@ -179,6 +179,6 @@ fun UseOrbotButton(
|
||||
containerColor = if (isActive) MaterialTheme.colorScheme.primary else Color.Gray,
|
||||
),
|
||||
) {
|
||||
Text(text = stringResource(R.string.use_orbot), color = Color.White)
|
||||
Text(text = stringResource(R.string.use_orbot), color = Color.Black)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.greenart7c3.nostrsigner.ui.actions
|
||||
|
||||
import android.content.Context
|
||||
import androidx.compose.foundation.BorderStroke
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Column
|
||||
@@ -16,7 +17,8 @@ import androidx.compose.foundation.text.KeyboardOptions
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.Circle
|
||||
import androidx.compose.material.icons.filled.Delete
|
||||
import androidx.compose.material3.ElevatedCard
|
||||
import androidx.compose.material3.Card
|
||||
import androidx.compose.material3.CardDefaults
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.IconButton
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
@@ -80,7 +82,6 @@ fun DefaultRelaysScreen(
|
||||
modifier: Modifier,
|
||||
accountStateViewModel: AccountStateViewModel,
|
||||
account: Account,
|
||||
navController: NavController,
|
||||
) {
|
||||
val scope = rememberCoroutineScope()
|
||||
val context = LocalContext.current
|
||||
@@ -388,63 +389,58 @@ fun RelayLogScreen(
|
||||
) {
|
||||
val context = LocalContext.current
|
||||
|
||||
Surface(
|
||||
val flows = LocalPreferences.allSavedAccounts(context).map {
|
||||
NostrSigner.getInstance().getDatabase(it.npub).applicationDao().getLogsByUrl(url)
|
||||
}.merge()
|
||||
|
||||
val logs = flows.collectAsStateWithLifecycle(initialValue = emptyList())
|
||||
|
||||
LazyColumn(
|
||||
modifier.fillMaxSize(),
|
||||
color = MaterialTheme.colorScheme.background,
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier.padding(10.dp),
|
||||
) {
|
||||
val flows = LocalPreferences.allSavedAccounts(context).map {
|
||||
NostrSigner.getInstance().getDatabase(it.npub).applicationDao().getLogsByUrl(url)
|
||||
}.merge()
|
||||
|
||||
val logs = flows.collectAsStateWithLifecycle(initialValue = emptyList())
|
||||
|
||||
LazyColumn(
|
||||
Modifier.weight(1f),
|
||||
itemsIndexed(logs.value) { _, log ->
|
||||
Card(
|
||||
Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(4.dp),
|
||||
border = BorderStroke(1.dp, Color.Gray),
|
||||
colors = CardDefaults.cardColors().copy(
|
||||
containerColor = MaterialTheme.colorScheme.background,
|
||||
),
|
||||
) {
|
||||
itemsIndexed(logs.value) { _, log ->
|
||||
ElevatedCard(
|
||||
Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(6.dp),
|
||||
) {
|
||||
Column(Modifier.padding(6.dp)) {
|
||||
Text(
|
||||
buildAnnotatedString {
|
||||
withStyle(style = SpanStyle(fontWeight = FontWeight.Bold)) {
|
||||
append("Date: ")
|
||||
}
|
||||
append(TimeUtils.convertLongToDateTime(log.time))
|
||||
},
|
||||
)
|
||||
Text(
|
||||
buildAnnotatedString {
|
||||
withStyle(style = SpanStyle(fontWeight = FontWeight.Bold)) {
|
||||
append("URL: ")
|
||||
}
|
||||
append(log.url)
|
||||
},
|
||||
)
|
||||
Text(
|
||||
buildAnnotatedString {
|
||||
withStyle(style = SpanStyle(fontWeight = FontWeight.Bold)) {
|
||||
append("Type: ")
|
||||
}
|
||||
append(log.type)
|
||||
},
|
||||
)
|
||||
Text(
|
||||
buildAnnotatedString {
|
||||
withStyle(style = SpanStyle(fontWeight = FontWeight.Bold)) {
|
||||
append("Message: ")
|
||||
}
|
||||
append(log.message)
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
Column(Modifier.padding(6.dp)) {
|
||||
Text(
|
||||
buildAnnotatedString {
|
||||
withStyle(style = SpanStyle(fontWeight = FontWeight.Bold)) {
|
||||
append("Date: ")
|
||||
}
|
||||
append(TimeUtils.convertLongToDateTime(log.time))
|
||||
},
|
||||
)
|
||||
Text(
|
||||
buildAnnotatedString {
|
||||
withStyle(style = SpanStyle(fontWeight = FontWeight.Bold)) {
|
||||
append("URL: ")
|
||||
}
|
||||
append(log.url)
|
||||
},
|
||||
)
|
||||
Text(
|
||||
buildAnnotatedString {
|
||||
withStyle(style = SpanStyle(fontWeight = FontWeight.Bold)) {
|
||||
append("Type: ")
|
||||
}
|
||||
append(log.type)
|
||||
},
|
||||
)
|
||||
Text(
|
||||
buildAnnotatedString {
|
||||
withStyle(style = SpanStyle(fontWeight = FontWeight.Bold)) {
|
||||
append("Message: ")
|
||||
}
|
||||
append(log.message)
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+12
-22
@@ -1,12 +1,10 @@
|
||||
package com.greenart7c3.nostrsigner.ui.components
|
||||
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.material3.Button
|
||||
import androidx.compose.material3.ButtonDefaults
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
@@ -15,39 +13,31 @@ import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.greenart7c3.nostrsigner.R
|
||||
import com.greenart7c3.nostrsigner.ui.theme.ButtonBorder
|
||||
|
||||
@Composable
|
||||
fun AcceptRejectButtons(
|
||||
onAccept: () -> Unit,
|
||||
onReject: () -> Unit,
|
||||
) {
|
||||
Row(
|
||||
Column(
|
||||
Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(10.dp),
|
||||
.fillMaxWidth(),
|
||||
Arrangement.Center,
|
||||
) {
|
||||
Button(
|
||||
shape = ButtonBorder,
|
||||
AmberButton(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
onClick = onAccept,
|
||||
) {
|
||||
Text(stringResource(R.string.accept))
|
||||
}
|
||||
Spacer(modifier = Modifier.width(20.dp))
|
||||
AmberButton(
|
||||
onClick = onReject,
|
||||
colors = ButtonDefaults.buttonColors(
|
||||
containerColor = Color(0xFF5A5554),
|
||||
containerColor = Color(0xFFFF6B00),
|
||||
),
|
||||
) {
|
||||
Text(stringResource(R.string.reject))
|
||||
}
|
||||
Spacer(modifier = Modifier.width(8.dp))
|
||||
Row(
|
||||
Modifier.weight(0.8f),
|
||||
) {
|
||||
Button(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
shape = ButtonBorder,
|
||||
onClick = onAccept,
|
||||
) {
|
||||
Text(stringResource(R.string.accept))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ fun ActiveMarker(
|
||||
Icon(
|
||||
imageVector = Icons.Default.RadioButtonChecked,
|
||||
contentDescription = stringResource(R.string.active_account),
|
||||
tint = MaterialTheme.colorScheme.secondary,
|
||||
tint = MaterialTheme.colorScheme.primary,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,15 +1,18 @@
|
||||
package com.greenart7c3.nostrsigner.ui.components
|
||||
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.PaddingValues
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material3.Button
|
||||
import androidx.compose.material3.ButtonColors
|
||||
import androidx.compose.material3.ButtonDefaults
|
||||
import androidx.compose.material3.ElevatedButton
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.unit.dp
|
||||
|
||||
@Composable
|
||||
@@ -17,7 +20,9 @@ fun AmberButton(
|
||||
modifier: Modifier = Modifier,
|
||||
onClick: () -> Unit,
|
||||
enabled: Boolean = true,
|
||||
colors: ButtonColors = ButtonDefaults.buttonColors(),
|
||||
colors: ButtonColors = ButtonDefaults.buttonColors().copy(
|
||||
contentColor = Color.Black,
|
||||
),
|
||||
content: @Composable () -> Unit,
|
||||
) {
|
||||
Row(
|
||||
@@ -25,12 +30,14 @@ fun AmberButton(
|
||||
horizontalArrangement = Arrangement.Center,
|
||||
) {
|
||||
Button(
|
||||
shape = RoundedCornerShape(20),
|
||||
enabled = enabled,
|
||||
onClick = onClick,
|
||||
colors = colors,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(6.dp),
|
||||
.padding(vertical = 6.dp),
|
||||
contentPadding = PaddingValues(vertical = 14.dp),
|
||||
) {
|
||||
content()
|
||||
}
|
||||
@@ -49,11 +56,13 @@ fun AmberElevatedButton(
|
||||
horizontalArrangement = Arrangement.Center,
|
||||
) {
|
||||
ElevatedButton(
|
||||
shape = RoundedCornerShape(20),
|
||||
enabled = enabled,
|
||||
onClick = onClick,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(6.dp),
|
||||
.padding(vertical = 6.dp),
|
||||
contentPadding = PaddingValues(vertical = 14.dp),
|
||||
) {
|
||||
content()
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.outlined.Close
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import com.greenart7c3.nostrsigner.ui.theme.Size20Modifier
|
||||
|
||||
@Composable
|
||||
@@ -12,5 +13,6 @@ fun CloseIcon() {
|
||||
Icons.Outlined.Close,
|
||||
contentDescription = "Cancel",
|
||||
modifier = Size20Modifier,
|
||||
tint = Color.Black,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -64,7 +64,6 @@ fun LoginWithPubKey(
|
||||
Column(
|
||||
Modifier
|
||||
.fillMaxSize()
|
||||
.padding(16.dp)
|
||||
.verticalScroll(rememberScrollState()),
|
||||
) {
|
||||
packageName?.let {
|
||||
@@ -251,7 +250,7 @@ fun LoginWithPubKey(
|
||||
AmberButton(
|
||||
onClick = onReject,
|
||||
colors = ButtonDefaults.buttonColors(
|
||||
containerColor = Color(0xFF5A5554),
|
||||
containerColor = Color(0xFFFF6B00),
|
||||
),
|
||||
content = {
|
||||
Text(stringResource(R.string.reject))
|
||||
|
||||
+226
-250
@@ -16,7 +16,6 @@ import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.KeyboardArrowDown
|
||||
import androidx.compose.material.icons.filled.KeyboardArrowUp
|
||||
import androidx.compose.material3.Button
|
||||
import androidx.compose.material3.Card
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.Switch
|
||||
@@ -64,7 +63,6 @@ import com.greenart7c3.nostrsigner.service.model.AmberEvent
|
||||
import com.greenart7c3.nostrsigner.service.toShortenHex
|
||||
import com.greenart7c3.nostrsigner.ui.NotificationType
|
||||
import com.greenart7c3.nostrsigner.ui.Result
|
||||
import com.greenart7c3.nostrsigner.ui.theme.ButtonBorder
|
||||
import com.vitorpamplona.quartz.crypto.CryptoUtils
|
||||
import com.vitorpamplona.quartz.encoders.toHexKey
|
||||
import com.vitorpamplona.quartz.encoders.toNpub
|
||||
@@ -153,6 +151,7 @@ fun MultiEventHomeScreen(
|
||||
) {
|
||||
selectAll = !selectAll
|
||||
acceptEventsGroup1.forEach { it.value = selectAll }
|
||||
acceptEventsGroup2.forEach { it.value = selectAll }
|
||||
intents.forEach {
|
||||
it.checked.value = selectAll
|
||||
}
|
||||
@@ -229,22 +228,14 @@ fun MultiEventHomeScreen(
|
||||
}
|
||||
}
|
||||
|
||||
Row(
|
||||
Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(top = 8.dp),
|
||||
horizontalArrangement = Arrangement.Center,
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
Button(
|
||||
onClick = {
|
||||
showItemsGroup1[index].value = !showItemsGroup1[index].value
|
||||
},
|
||||
content = {
|
||||
Text(if (showItemsGroup1[index].value) context.getString(R.string.hide_details) else context.getString(R.string.show_details))
|
||||
},
|
||||
)
|
||||
}
|
||||
AmberButton(
|
||||
onClick = {
|
||||
showItemsGroup1[index].value = !showItemsGroup1[index].value
|
||||
},
|
||||
content = {
|
||||
Text(if (showItemsGroup1[index].value) context.getString(R.string.hide_details) else context.getString(R.string.show_details))
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -320,22 +311,14 @@ fun MultiEventHomeScreen(
|
||||
}
|
||||
}
|
||||
|
||||
Row(
|
||||
Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(top = 8.dp),
|
||||
horizontalArrangement = Arrangement.Center,
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
Button(
|
||||
onClick = {
|
||||
showItemsGroup2[index].value = !showItemsGroup2[index].value
|
||||
},
|
||||
content = {
|
||||
Text(if (showItemsGroup2[index].value) context.getString(R.string.hide_details) else context.getString(R.string.show_details))
|
||||
},
|
||||
)
|
||||
}
|
||||
AmberButton(
|
||||
onClick = {
|
||||
showItemsGroup2[index].value = !showItemsGroup2[index].value
|
||||
},
|
||||
content = {
|
||||
Text(if (showItemsGroup2[index].value) context.getString(R.string.hide_details) else context.getString(R.string.show_details))
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -348,237 +331,230 @@ fun MultiEventHomeScreen(
|
||||
}
|
||||
}
|
||||
}
|
||||
Row(
|
||||
Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(10.dp),
|
||||
Arrangement.Center,
|
||||
) {
|
||||
Button(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
shape = ButtonBorder,
|
||||
onClick = {
|
||||
onLoading(true)
|
||||
coroutineScope.launch(Dispatchers.IO) {
|
||||
try {
|
||||
val activity = context.getAppCompatActivity()
|
||||
val results = mutableListOf<Result>()
|
||||
reconnectToRelays(intents)
|
||||
|
||||
for (intentData in intents) {
|
||||
val localAccount =
|
||||
if (intentData.currentAccount.isNotBlank()) {
|
||||
LocalPreferences.loadFromEncryptedStorage(
|
||||
context,
|
||||
intentData.currentAccount,
|
||||
)
|
||||
} else {
|
||||
accountParam
|
||||
} ?: continue
|
||||
AmberButton(
|
||||
content = {
|
||||
Text(stringResource(R.string.confirm))
|
||||
},
|
||||
onClick = {
|
||||
onLoading(true)
|
||||
coroutineScope.launch(Dispatchers.IO) {
|
||||
try {
|
||||
val activity = context.getAppCompatActivity()
|
||||
val results = mutableListOf<Result>()
|
||||
reconnectToRelays(intents)
|
||||
|
||||
val key = intentData.bunkerRequest?.localKey ?: packageName ?: continue
|
||||
|
||||
val database = NostrSigner.getInstance().getDatabase(localAccount.keyPair.pubKey.toNpub())
|
||||
|
||||
val application =
|
||||
database
|
||||
.applicationDao()
|
||||
.getByKey(key) ?: ApplicationWithPermissions(
|
||||
application = ApplicationEntity(
|
||||
key,
|
||||
"",
|
||||
listOf(),
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
localAccount.keyPair.pubKey.toHexKey(),
|
||||
true,
|
||||
intentData.bunkerRequest?.secret ?: "",
|
||||
intentData.bunkerRequest?.secret != null,
|
||||
localAccount.signPolicy,
|
||||
),
|
||||
permissions = mutableListOf(),
|
||||
for (intentData in intents) {
|
||||
val localAccount =
|
||||
if (intentData.currentAccount.isNotBlank()) {
|
||||
LocalPreferences.loadFromEncryptedStorage(
|
||||
context,
|
||||
intentData.currentAccount,
|
||||
)
|
||||
|
||||
if (intentData.type == SignerType.SIGN_EVENT) {
|
||||
val localEvent = intentData.event!!
|
||||
|
||||
if (intentData.rememberMyChoice.value) {
|
||||
AmberUtils.acceptOrRejectPermission(
|
||||
application,
|
||||
key,
|
||||
intentData,
|
||||
localEvent.kind,
|
||||
intentData.rememberMyChoice.value,
|
||||
database,
|
||||
)
|
||||
}
|
||||
|
||||
database.applicationDao().insertApplicationWithPermissions(application)
|
||||
|
||||
database.applicationDao().addHistory(
|
||||
HistoryEntity(
|
||||
0,
|
||||
key,
|
||||
intentData.type.toString(),
|
||||
localEvent.kind,
|
||||
TimeUtils.now(),
|
||||
true,
|
||||
),
|
||||
)
|
||||
|
||||
if (intentData.bunkerRequest != null) {
|
||||
IntentUtils.sendBunkerResponse(
|
||||
context,
|
||||
localAccount,
|
||||
intentData.bunkerRequest,
|
||||
BunkerResponse(intentData.bunkerRequest.id, localEvent.toJson(), null),
|
||||
application.application.relays,
|
||||
onLoading = {},
|
||||
onDone = {},
|
||||
)
|
||||
} else {
|
||||
results.add(
|
||||
Result(
|
||||
null,
|
||||
signature = if (localEvent is LnZapRequestEvent &&
|
||||
localEvent.tags.any {
|
||||
tag ->
|
||||
tag.any { t -> t == "anon" }
|
||||
}
|
||||
) {
|
||||
localEvent.toJson()
|
||||
} else {
|
||||
localEvent.sig
|
||||
},
|
||||
result = if (localEvent is LnZapRequestEvent &&
|
||||
localEvent.tags.any {
|
||||
tag ->
|
||||
tag.any { t -> t == "anon" }
|
||||
}
|
||||
) {
|
||||
localEvent.toJson()
|
||||
} else {
|
||||
localEvent.sig
|
||||
},
|
||||
id = intentData.id,
|
||||
),
|
||||
)
|
||||
}
|
||||
} else if (intentData.type == SignerType.SIGN_MESSAGE) {
|
||||
if (intentData.rememberMyChoice.value) {
|
||||
AmberUtils.acceptOrRejectPermission(
|
||||
application,
|
||||
key,
|
||||
intentData,
|
||||
null,
|
||||
intentData.rememberMyChoice.value,
|
||||
database,
|
||||
)
|
||||
}
|
||||
|
||||
database.applicationDao().insertApplicationWithPermissions(application)
|
||||
database.applicationDao().addHistory(
|
||||
HistoryEntity(
|
||||
0,
|
||||
key,
|
||||
intentData.type.toString(),
|
||||
null,
|
||||
TimeUtils.now(),
|
||||
true,
|
||||
),
|
||||
)
|
||||
|
||||
val signedMessage = CryptoUtils.signString(intentData.data, localAccount.keyPair.privKey!!).toHexKey()
|
||||
|
||||
if (intentData.bunkerRequest != null) {
|
||||
IntentUtils.sendBunkerResponse(
|
||||
context,
|
||||
localAccount,
|
||||
intentData.bunkerRequest,
|
||||
BunkerResponse(intentData.bunkerRequest.id, signedMessage, null),
|
||||
application.application.relays,
|
||||
onLoading = {},
|
||||
onDone = {},
|
||||
)
|
||||
} else {
|
||||
results.add(
|
||||
Result(
|
||||
null,
|
||||
signature = signedMessage,
|
||||
result = signedMessage,
|
||||
id = intentData.id,
|
||||
),
|
||||
)
|
||||
}
|
||||
} else {
|
||||
if (intentData.rememberMyChoice.value) {
|
||||
AmberUtils.acceptOrRejectPermission(
|
||||
application,
|
||||
key,
|
||||
intentData,
|
||||
null,
|
||||
intentData.rememberMyChoice.value,
|
||||
database,
|
||||
)
|
||||
}
|
||||
accountParam
|
||||
} ?: continue
|
||||
|
||||
database.applicationDao().insertApplicationWithPermissions(application)
|
||||
val key = intentData.bunkerRequest?.localKey ?: packageName ?: continue
|
||||
|
||||
database.applicationDao().addHistory(
|
||||
HistoryEntity(
|
||||
0,
|
||||
key,
|
||||
intentData.type.toString(),
|
||||
val database = NostrSigner.getInstance().getDatabase(localAccount.keyPair.pubKey.toNpub())
|
||||
|
||||
val application =
|
||||
database
|
||||
.applicationDao()
|
||||
.getByKey(key) ?: ApplicationWithPermissions(
|
||||
application = ApplicationEntity(
|
||||
key,
|
||||
"",
|
||||
listOf(),
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
localAccount.keyPair.pubKey.toHexKey(),
|
||||
true,
|
||||
intentData.bunkerRequest?.secret ?: "",
|
||||
intentData.bunkerRequest?.secret != null,
|
||||
localAccount.signPolicy,
|
||||
),
|
||||
permissions = mutableListOf(),
|
||||
)
|
||||
|
||||
if (intentData.type == SignerType.SIGN_EVENT) {
|
||||
val localEvent = intentData.event!!
|
||||
|
||||
if (intentData.rememberMyChoice.value) {
|
||||
AmberUtils.acceptOrRejectPermission(
|
||||
application,
|
||||
key,
|
||||
intentData,
|
||||
localEvent.kind,
|
||||
intentData.rememberMyChoice.value,
|
||||
database,
|
||||
)
|
||||
}
|
||||
|
||||
database.applicationDao().insertApplicationWithPermissions(application)
|
||||
|
||||
database.applicationDao().addHistory(
|
||||
HistoryEntity(
|
||||
0,
|
||||
key,
|
||||
intentData.type.toString(),
|
||||
localEvent.kind,
|
||||
TimeUtils.now(),
|
||||
true,
|
||||
),
|
||||
)
|
||||
|
||||
if (intentData.bunkerRequest != null) {
|
||||
IntentUtils.sendBunkerResponse(
|
||||
context,
|
||||
localAccount,
|
||||
intentData.bunkerRequest,
|
||||
BunkerResponse(intentData.bunkerRequest.id, localEvent.toJson(), null),
|
||||
application.application.relays,
|
||||
onLoading = {},
|
||||
onDone = {},
|
||||
)
|
||||
} else {
|
||||
results.add(
|
||||
Result(
|
||||
null,
|
||||
TimeUtils.now(),
|
||||
true,
|
||||
signature = if (localEvent is LnZapRequestEvent &&
|
||||
localEvent.tags.any {
|
||||
tag ->
|
||||
tag.any { t -> t == "anon" }
|
||||
}
|
||||
) {
|
||||
localEvent.toJson()
|
||||
} else {
|
||||
localEvent.sig
|
||||
},
|
||||
result = if (localEvent is LnZapRequestEvent &&
|
||||
localEvent.tags.any {
|
||||
tag ->
|
||||
tag.any { t -> t == "anon" }
|
||||
}
|
||||
) {
|
||||
localEvent.toJson()
|
||||
} else {
|
||||
localEvent.sig
|
||||
},
|
||||
id = intentData.id,
|
||||
),
|
||||
)
|
||||
}
|
||||
} else if (intentData.type == SignerType.SIGN_MESSAGE) {
|
||||
if (intentData.rememberMyChoice.value) {
|
||||
AmberUtils.acceptOrRejectPermission(
|
||||
application,
|
||||
key,
|
||||
intentData,
|
||||
null,
|
||||
intentData.rememberMyChoice.value,
|
||||
database,
|
||||
)
|
||||
}
|
||||
|
||||
val signature = intentData.encryptedData ?: continue
|
||||
database.applicationDao().insertApplicationWithPermissions(application)
|
||||
database.applicationDao().addHistory(
|
||||
HistoryEntity(
|
||||
0,
|
||||
key,
|
||||
intentData.type.toString(),
|
||||
null,
|
||||
TimeUtils.now(),
|
||||
true,
|
||||
),
|
||||
)
|
||||
|
||||
if (intentData.bunkerRequest != null) {
|
||||
IntentUtils.sendBunkerResponse(
|
||||
context,
|
||||
localAccount,
|
||||
intentData.bunkerRequest,
|
||||
BunkerResponse(intentData.bunkerRequest.id, signature, null),
|
||||
application.application.relays,
|
||||
onLoading = {},
|
||||
onDone = {},
|
||||
)
|
||||
} else {
|
||||
results.add(
|
||||
Result(
|
||||
null,
|
||||
signature = signature,
|
||||
result = signature,
|
||||
id = intentData.id,
|
||||
),
|
||||
)
|
||||
}
|
||||
val signedMessage = CryptoUtils.signString(intentData.data, localAccount.keyPair.privKey!!).toHexKey()
|
||||
|
||||
if (intentData.bunkerRequest != null) {
|
||||
IntentUtils.sendBunkerResponse(
|
||||
context,
|
||||
localAccount,
|
||||
intentData.bunkerRequest,
|
||||
BunkerResponse(intentData.bunkerRequest.id, signedMessage, null),
|
||||
application.application.relays,
|
||||
onLoading = {},
|
||||
onDone = {},
|
||||
)
|
||||
} else {
|
||||
results.add(
|
||||
Result(
|
||||
null,
|
||||
signature = signedMessage,
|
||||
result = signedMessage,
|
||||
id = intentData.id,
|
||||
),
|
||||
)
|
||||
}
|
||||
} else {
|
||||
if (intentData.rememberMyChoice.value) {
|
||||
AmberUtils.acceptOrRejectPermission(
|
||||
application,
|
||||
key,
|
||||
intentData,
|
||||
null,
|
||||
intentData.rememberMyChoice.value,
|
||||
database,
|
||||
)
|
||||
}
|
||||
|
||||
database.applicationDao().insertApplicationWithPermissions(application)
|
||||
|
||||
database.applicationDao().addHistory(
|
||||
HistoryEntity(
|
||||
0,
|
||||
key,
|
||||
intentData.type.toString(),
|
||||
null,
|
||||
TimeUtils.now(),
|
||||
true,
|
||||
),
|
||||
)
|
||||
|
||||
val signature = intentData.encryptedData ?: continue
|
||||
|
||||
if (intentData.bunkerRequest != null) {
|
||||
IntentUtils.sendBunkerResponse(
|
||||
context,
|
||||
localAccount,
|
||||
intentData.bunkerRequest,
|
||||
BunkerResponse(intentData.bunkerRequest.id, signature, null),
|
||||
application.application.relays,
|
||||
onLoading = {},
|
||||
onDone = {},
|
||||
)
|
||||
} else {
|
||||
results.add(
|
||||
Result(
|
||||
null,
|
||||
signature = signature,
|
||||
result = signature,
|
||||
id = intentData.id,
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
if (results.isNotEmpty()) {
|
||||
sendResultIntent(results, activity)
|
||||
}
|
||||
if (intents.any { it.bunkerRequest != null }) {
|
||||
EventNotificationConsumer(context).notificationManager().cancelAll()
|
||||
finishActivity(activity)
|
||||
} else {
|
||||
finishActivity(activity)
|
||||
}
|
||||
} finally {
|
||||
onLoading(false)
|
||||
}
|
||||
|
||||
if (results.isNotEmpty()) {
|
||||
sendResultIntent(results, activity)
|
||||
}
|
||||
if (intents.any { it.bunkerRequest != null }) {
|
||||
EventNotificationConsumer(context).notificationManager().cancelAll()
|
||||
finishActivity(activity)
|
||||
} else {
|
||||
finishActivity(activity)
|
||||
}
|
||||
} finally {
|
||||
onLoading(false)
|
||||
}
|
||||
},
|
||||
) {
|
||||
Text("Confirm")
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -29,6 +29,7 @@ import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.unit.dp
|
||||
@@ -73,8 +74,7 @@ fun RandomPinInput(
|
||||
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.padding(16.dp),
|
||||
.fillMaxSize(),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
verticalArrangement = Arrangement.Center,
|
||||
) {
|
||||
@@ -122,7 +122,7 @@ fun RandomPinInput(
|
||||
},
|
||||
modifier = Modifier.padding(8.dp),
|
||||
) {
|
||||
Text(number.toString())
|
||||
Text(number.toString(), color = Color.Black)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -138,6 +138,7 @@ fun RandomPinInput(
|
||||
Icon(
|
||||
Icons.AutoMirrored.Filled.Backspace,
|
||||
contentDescription = "Erase",
|
||||
tint = Color.Black,
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -151,7 +152,7 @@ fun RandomPinInput(
|
||||
},
|
||||
modifier = Modifier.weight(1f).padding(8.dp),
|
||||
) {
|
||||
Text(randomNumbers.last().toString())
|
||||
Text(randomNumbers.last().toString(), color = Color.Black)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -168,6 +169,7 @@ fun RandomPinInput(
|
||||
Icon(
|
||||
Icons.Default.Done,
|
||||
contentDescription = "Done",
|
||||
tint = Color.Black,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -68,11 +68,11 @@ fun RawJson(
|
||||
}
|
||||
}
|
||||
Row(
|
||||
Modifier.fillMaxWidth(),
|
||||
Modifier
|
||||
.fillMaxWidth(),
|
||||
horizontalArrangement = Arrangement.Center,
|
||||
) {
|
||||
Button(
|
||||
shape = ButtonBorder,
|
||||
AmberButton(
|
||||
onClick = {
|
||||
if (onCopy != null) {
|
||||
onCopy()
|
||||
|
||||
@@ -3,6 +3,7 @@ package com.greenart7c3.nostrsigner.ui.components
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material3.Switch
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
@@ -10,6 +11,7 @@ import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.greenart7c3.nostrsigner.R
|
||||
|
||||
@Composable
|
||||
@@ -36,6 +38,7 @@ fun RememberMyChoice(
|
||||
horizontalArrangement = Arrangement.SpaceBetween,
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
modifier = Modifier
|
||||
.padding(vertical = 8.dp)
|
||||
.clickable {
|
||||
onChanged()
|
||||
},
|
||||
|
||||
@@ -58,8 +58,6 @@ fun SeedWordsPage(
|
||||
Spacer(modifier = Modifier.height(20.dp))
|
||||
|
||||
AmberButton(
|
||||
Modifier
|
||||
.padding(start = 40.dp, end = 40.dp),
|
||||
onClick = {
|
||||
clipboardManager.setText(AnnotatedString(seedWords.joinToString(" ")))
|
||||
},
|
||||
@@ -128,9 +126,6 @@ fun SeedWordsPage(
|
||||
}
|
||||
if (showNextButton) {
|
||||
AmberButton(
|
||||
Modifier
|
||||
.padding(start = 40.dp, end = 40.dp)
|
||||
.height(50.dp),
|
||||
onClick = onNextPage,
|
||||
content = {
|
||||
Text(text = stringResource(R.string.next))
|
||||
|
||||
@@ -31,9 +31,9 @@ val Size35dp = 35.dp
|
||||
val ButtonBorder = RoundedCornerShape(20.dp)
|
||||
val Size20Modifier = Modifier.size(20.dp)
|
||||
|
||||
val primaryColor = Color(0xFFF16F26)
|
||||
val primaryColor = Color(0xFFFFCA62)
|
||||
val primaryVariant = Color(0xFFC8541A)
|
||||
val secondaryColor = Color(0xFFFF8E4C)
|
||||
val secondaryColor = Color(0xFFFFCA62)
|
||||
|
||||
val RichTextDefaults = RichTextStyle().resolveDefaults()
|
||||
|
||||
@@ -64,10 +64,11 @@ fun NostrSignerTheme(
|
||||
content: @Composable () -> Unit,
|
||||
) {
|
||||
val colors = if (darkTheme) DarkColorPalette else LightColorPalette
|
||||
val typography = if (darkTheme) TypographyDark else Typography
|
||||
|
||||
MaterialTheme(
|
||||
colorScheme = colors,
|
||||
typography = Typography,
|
||||
typography = typography,
|
||||
shapes = Shapes,
|
||||
content = content,
|
||||
)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.greenart7c3.nostrsigner.ui.theme
|
||||
|
||||
import androidx.compose.material3.Typography
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.text.TextStyle
|
||||
import androidx.compose.ui.text.font.FontFamily
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
@@ -8,6 +9,16 @@ import androidx.compose.ui.unit.sp
|
||||
|
||||
// Set of Material typography styles to start with
|
||||
val Typography =
|
||||
Typography(
|
||||
bodyLarge = TextStyle(
|
||||
fontFamily = FontFamily.Default,
|
||||
fontWeight = FontWeight.Normal,
|
||||
fontSize = 16.sp,
|
||||
color = Color.Black,
|
||||
),
|
||||
)
|
||||
|
||||
val TypographyDark =
|
||||
Typography(
|
||||
bodyLarge = TextStyle(
|
||||
fontFamily = FontFamily.Default,
|
||||
|
||||
@@ -38,12 +38,12 @@
|
||||
<string name="encrypt_decrypt">criptografar/descriptografar</string>
|
||||
<string name="show_details">Mostrar detalhes</string>
|
||||
<string name="hide_details">Ocultar detalhes</string>
|
||||
<string name="copy_raw_json">Mostrar json</string>
|
||||
<string name="copy_raw_json">json</string>
|
||||
<string name="add_new_account">Adicionar nova conta</string>
|
||||
<string name="select_account">Selecionar conta</string>
|
||||
<string name="active_account">Conta ativa</string>
|
||||
<string name="edit_name">Editar nome</string>
|
||||
<string name="copy">"Copiar"</string>
|
||||
<string name="copy">"Copiar "</string>
|
||||
<string name="encrypted_decrypted_data">Dados criptografados/descriptografados</string>
|
||||
<string name="data_copied_to_the_clipboard">Dados copiados para a área de transferência</string>
|
||||
<string name="connect_app">Conectar aplicativo</string>
|
||||
|
||||
@@ -2,5 +2,5 @@
|
||||
<resources>
|
||||
<color name="purple_700">#FF3700B3</color>
|
||||
<color name="black">#FF000000</color>
|
||||
<color name="amber">#FFBF00</color>
|
||||
<color name="amber">#FFFFCA62</color>
|
||||
</resources>
|
||||
|
||||
Reference in New Issue
Block a user