Use same styles across the app

This commit is contained in:
greenart7c3
2024-10-28 11:50:48 -03:00
parent 4b9a598f6f
commit aebcd9a15d
34 changed files with 705 additions and 692 deletions
@@ -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,
@@ -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)
},
)
}
}
}
@@ -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))
@@ -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,
+2 -2
View File
@@ -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>
+1 -1
View File
@@ -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>