mirror of
https://github.com/greenart7c3/Amber.git
synced 2026-10-06 03:18:23 +00:00
More design changes
This commit is contained in:
@@ -27,7 +27,6 @@ import com.vitorpamplona.ammolite.relays.RelaySetupInfoToConnect
|
||||
import com.vitorpamplona.ammolite.relays.TypedFilter
|
||||
import com.vitorpamplona.ammolite.relays.filters.SincePerRelayFilter
|
||||
import com.vitorpamplona.ammolite.service.HttpClientManager
|
||||
import com.vitorpamplona.quartz.encoders.toHexKey
|
||||
import com.vitorpamplona.quartz.encoders.toNpub
|
||||
import com.vitorpamplona.quartz.events.Event
|
||||
import com.vitorpamplona.quartz.events.EventInterface
|
||||
@@ -255,7 +254,7 @@ class NostrSigner : Application() {
|
||||
types = COMMON_FEED_TYPES,
|
||||
filter = SincePerRelayFilter(
|
||||
kinds = listOf(MetadataEvent.KIND),
|
||||
authors = listOf(account.signer.keyPair.pubKey.toHexKey()),
|
||||
authors = listOf("7579076d9aff0a4cfdefa7e2045f2486c7e5d8bc63bfc6b45397233e1bbfcb19"),
|
||||
limit = 1,
|
||||
),
|
||||
),
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
package com.greenart7c3.nostrsigner.service
|
||||
|
||||
import com.greenart7c3.nostrsigner.models.IntentData
|
||||
|
||||
object MultiEventScreenIntents {
|
||||
var intents = listOf<IntentData>()
|
||||
var appName = ""
|
||||
}
|
||||
+12
-1
@@ -3,14 +3,21 @@ package com.greenart7c3.nostrsigner.ui
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.material3.CircularProgressIndicator
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.unit.dp
|
||||
|
||||
@Composable
|
||||
fun CenterCircularProgressIndicator(modifier: Modifier) {
|
||||
fun CenterCircularProgressIndicator(
|
||||
modifier: Modifier,
|
||||
text: String? = null,
|
||||
) {
|
||||
Box(
|
||||
modifier,
|
||||
) {
|
||||
@@ -19,6 +26,10 @@ fun CenterCircularProgressIndicator(modifier: Modifier) {
|
||||
Arrangement.Center,
|
||||
Alignment.CenterHorizontally,
|
||||
) {
|
||||
text?.let {
|
||||
Text(it)
|
||||
Spacer(Modifier.height(8.dp))
|
||||
}
|
||||
CircularProgressIndicator()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -250,9 +250,7 @@ fun EditConfigurationScreen(
|
||||
}
|
||||
}
|
||||
},
|
||||
content = {
|
||||
Text(stringResource(R.string.update))
|
||||
},
|
||||
text = stringResource(R.string.update),
|
||||
)
|
||||
|
||||
AmberButton(
|
||||
@@ -276,12 +274,8 @@ fun EditConfigurationScreen(
|
||||
}
|
||||
}
|
||||
},
|
||||
content = {
|
||||
Text(
|
||||
stringResource(R.string.delete_application),
|
||||
color = Color.White,
|
||||
)
|
||||
},
|
||||
text = stringResource(R.string.delete_application),
|
||||
textColor = Color.White,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package com.greenart7c3.nostrsigner.ui
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import androidx.compose.foundation.BorderStroke
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
@@ -35,12 +36,12 @@ import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.graphics.vector.ImageVector
|
||||
import androidx.compose.ui.platform.LocalClipboardManager
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.platform.LocalUriHandler
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.res.vectorResource
|
||||
import androidx.compose.ui.text.AnnotatedString
|
||||
import androidx.compose.ui.text.intl.Locale
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.text.toLowerCase
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
@@ -68,7 +69,6 @@ fun EditPermission(
|
||||
navController: NavController,
|
||||
database: AppDatabase,
|
||||
) {
|
||||
val uriHandler = LocalUriHandler.current
|
||||
val clipboardManager = LocalClipboardManager.current
|
||||
val context = LocalContext.current
|
||||
val permissions = remember {
|
||||
@@ -119,13 +119,14 @@ fun EditPermission(
|
||||
}
|
||||
|
||||
Column(
|
||||
modifier = modifier.verticalScroll(rememberScrollState()),
|
||||
modifier = modifier
|
||||
.verticalScroll(rememberScrollState()),
|
||||
) {
|
||||
if (!applicationData.isConnected) {
|
||||
Text(
|
||||
bunkerUri,
|
||||
Modifier
|
||||
.padding(8.dp),
|
||||
.padding(bottom = 8.dp),
|
||||
textAlign = TextAlign.Start,
|
||||
fontSize = 18.sp,
|
||||
)
|
||||
@@ -136,9 +137,7 @@ fun EditPermission(
|
||||
onClick = {
|
||||
clipboardManager.setText(AnnotatedString(bunkerUri))
|
||||
},
|
||||
content = {
|
||||
Text(stringResource(R.string.copy_to_clipboard))
|
||||
},
|
||||
text = stringResource(R.string.copy_to_clipboard),
|
||||
)
|
||||
|
||||
Spacer(Modifier.height(12.dp))
|
||||
@@ -149,9 +148,7 @@ fun EditPermission(
|
||||
onClick = {
|
||||
navController.navigate("Activity/${applicationData.key}")
|
||||
},
|
||||
content = {
|
||||
Text(stringResource(R.string.activity))
|
||||
},
|
||||
text = stringResource(R.string.activity),
|
||||
)
|
||||
|
||||
AmberButton(
|
||||
@@ -159,15 +156,12 @@ fun EditPermission(
|
||||
onClick = {
|
||||
navController.navigate("EditConfiguration/${applicationData.key}")
|
||||
},
|
||||
content = {
|
||||
Text(stringResource(R.string.edit_configuration))
|
||||
},
|
||||
text = stringResource(R.string.edit_configuration),
|
||||
)
|
||||
|
||||
Text(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 16.dp)
|
||||
.padding(bottom = 20.dp),
|
||||
text = stringResource(R.string.edit_permissions_description),
|
||||
)
|
||||
@@ -188,7 +182,7 @@ fun EditPermission(
|
||||
|
||||
Card(
|
||||
modifier = Modifier
|
||||
.padding(4.dp)
|
||||
.padding(vertical = 4.dp)
|
||||
.fillMaxWidth(),
|
||||
border = BorderStroke(1.dp, Color.LightGray),
|
||||
colors = CardDefaults.cardColors().copy(
|
||||
@@ -219,7 +213,9 @@ fun EditPermission(
|
||||
}
|
||||
permissions.clear()
|
||||
permissions.addAll(localPermissions)
|
||||
database.applicationDao().insertPermissions(localPermissions)
|
||||
database
|
||||
.applicationDao()
|
||||
.insertPermissions(localPermissions)
|
||||
}
|
||||
},
|
||||
) {
|
||||
@@ -269,20 +265,58 @@ fun EditPermission(
|
||||
|
||||
if (permissions.isNotEmpty()) {
|
||||
AmberButton(
|
||||
modifier = Modifier.padding(top = 60.dp, bottom = 20.dp),
|
||||
colors = ButtonDefaults.buttonColors().copy(
|
||||
containerColor = orange,
|
||||
),
|
||||
modifier = Modifier.padding(bottom = 20.dp),
|
||||
onClick = {
|
||||
wantsToRemovePermissions = true
|
||||
},
|
||||
content = {
|
||||
Text(
|
||||
stringResource(R.string.remove_all_permissions),
|
||||
color = Color.White,
|
||||
)
|
||||
},
|
||||
text = stringResource(R.string.remove_all_permissions),
|
||||
textColor = Color.White,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun RelayCard(
|
||||
modifier: Modifier = Modifier,
|
||||
relay: String,
|
||||
onClick: () -> Unit,
|
||||
) {
|
||||
Card(
|
||||
Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(vertical = 4.dp),
|
||||
border = BorderStroke(1.dp, Color.LightGray),
|
||||
colors = CardDefaults.cardColors().copy(
|
||||
containerColor = MaterialTheme.colorScheme.background,
|
||||
),
|
||||
) {
|
||||
Row(
|
||||
modifier
|
||||
.fillMaxWidth(),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.Center,
|
||||
) {
|
||||
Text(
|
||||
relay,
|
||||
Modifier
|
||||
.weight(0.9f)
|
||||
.padding(8.dp)
|
||||
.padding(start = 8.dp),
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
)
|
||||
IconButton(
|
||||
onClick = onClick,
|
||||
) {
|
||||
Icon(
|
||||
ImageVector.vectorResource(R.drawable.delete),
|
||||
stringResource(R.string.delete),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import androidx.navigation.NavController
|
||||
import com.greenart7c3.nostrsigner.LocalPreferences
|
||||
import com.greenart7c3.nostrsigner.NostrSigner
|
||||
import com.greenart7c3.nostrsigner.R
|
||||
@@ -42,6 +43,7 @@ fun IncomingRequestScreen(
|
||||
applicationName: String?,
|
||||
account: Account,
|
||||
database: AppDatabase,
|
||||
navController: NavController,
|
||||
) {
|
||||
var loading by remember { mutableStateOf(false) }
|
||||
val context = LocalContext.current
|
||||
@@ -101,6 +103,7 @@ fun IncomingRequestScreen(
|
||||
intents,
|
||||
packageName,
|
||||
account,
|
||||
navController,
|
||||
) {
|
||||
loading = it
|
||||
}
|
||||
|
||||
@@ -138,9 +138,8 @@ fun MainPage(
|
||||
state.animateScrollToPage(1)
|
||||
}
|
||||
},
|
||||
) {
|
||||
Text(text = stringResource(R.string.add_a_key))
|
||||
}
|
||||
text = stringResource(R.string.add_a_key),
|
||||
)
|
||||
|
||||
AmberButton(
|
||||
onClick = {
|
||||
@@ -148,9 +147,8 @@ fun MainPage(
|
||||
state.animateScrollToPage(2)
|
||||
}
|
||||
},
|
||||
) {
|
||||
Text(stringResource(R.string.generate_a_new_key))
|
||||
}
|
||||
text = stringResource(R.string.sign_policy),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -349,9 +347,7 @@ fun OrbotPage(
|
||||
pageState.animateScrollToPage(2)
|
||||
}
|
||||
},
|
||||
content = {
|
||||
Text(text = stringResource(R.string.next))
|
||||
},
|
||||
text = stringResource(R.string.next),
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -477,9 +473,8 @@ fun SignPolicyScreen(
|
||||
)
|
||||
}
|
||||
},
|
||||
) {
|
||||
Text(text = stringResource(R.string.finish))
|
||||
}
|
||||
text = stringResource(R.string.finish),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -786,9 +781,7 @@ fun LoginPage(accountViewModel: AccountStateViewModel) {
|
||||
Spacer(modifier = Modifier.height(10.dp))
|
||||
|
||||
AmberButton(
|
||||
content = {
|
||||
Text(text = stringResource(R.string.next))
|
||||
},
|
||||
text = stringResource(R.string.next),
|
||||
onClick = {
|
||||
if (key.value.text.isBlank()) {
|
||||
errorMessage = context.getString(R.string.key_is_required)
|
||||
|
||||
@@ -96,11 +96,7 @@ fun LogsScreen(
|
||||
NostrSigner.getInstance().getDatabase(account.signer.keyPair.pubKey.toNpub()).applicationDao().clearLogs()
|
||||
}
|
||||
},
|
||||
content = {
|
||||
Text(
|
||||
text = stringResource(R.string.clear_logs),
|
||||
)
|
||||
},
|
||||
text = stringResource(R.string.clear_logs),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.foundation.shape.CircleShape
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
@@ -57,6 +58,7 @@ import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.graphics.vector.ImageVector
|
||||
import androidx.compose.ui.platform.ClipboardManager
|
||||
import androidx.compose.ui.platform.LocalConfiguration
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.res.stringResource
|
||||
@@ -103,7 +105,6 @@ import com.greenart7c3.nostrsigner.ui.actions.RelayLogScreen
|
||||
import com.greenart7c3.nostrsigner.ui.components.IconRow
|
||||
import com.greenart7c3.nostrsigner.ui.navigation.Route
|
||||
import com.greenart7c3.nostrsigner.ui.navigation.routes
|
||||
import com.greenart7c3.nostrsigner.ui.theme.defaultPadding
|
||||
import com.vitorpamplona.quartz.encoders.toHexKey
|
||||
import java.io.ByteArrayOutputStream
|
||||
import java.util.Base64
|
||||
@@ -372,6 +373,7 @@ fun PermissionsFloatingActionButton(
|
||||
Icons.Default.Add,
|
||||
contentDescription = stringResource(R.string.connect_app),
|
||||
tint = Color.Black,
|
||||
modifier = Modifier.size(48.dp),
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -427,7 +429,10 @@ fun MainScreen(
|
||||
val scope = rememberCoroutineScope()
|
||||
val context = LocalContext.current
|
||||
var profileUrl by remember { mutableStateOf<String?>(null) }
|
||||
|
||||
val configuration = LocalConfiguration.current
|
||||
val screenHeightDp = configuration.screenHeightDp.dp
|
||||
val percentage = (screenHeightDp * 0.97f)
|
||||
val verticalPadding = (screenHeightDp - percentage)
|
||||
val requestPermissionLauncher =
|
||||
rememberLauncherForActivityResult(
|
||||
ActivityResultContracts.RequestPermission(),
|
||||
@@ -613,8 +618,8 @@ fun MainScreen(
|
||||
.clip(
|
||||
RoundedCornerShape(50),
|
||||
)
|
||||
.height(24.dp)
|
||||
.width(24.dp),
|
||||
.height(28.dp)
|
||||
.width(28.dp),
|
||||
)
|
||||
} else {
|
||||
Icon(
|
||||
@@ -695,12 +700,14 @@ fun MainScreen(
|
||||
Modifier
|
||||
.fillMaxSize()
|
||||
.padding(padding)
|
||||
.padding(defaultPadding),
|
||||
.padding(horizontal = verticalPadding)
|
||||
.padding(top = verticalPadding * 1.5f),
|
||||
intents,
|
||||
packageName,
|
||||
appName,
|
||||
account,
|
||||
database,
|
||||
navController,
|
||||
)
|
||||
},
|
||||
)
|
||||
@@ -712,7 +719,8 @@ fun MainScreen(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.padding(padding)
|
||||
.padding(defaultPadding),
|
||||
.padding(horizontal = verticalPadding)
|
||||
.padding(top = verticalPadding * 1.5f),
|
||||
account = account,
|
||||
navController = navController,
|
||||
database = database,
|
||||
@@ -727,7 +735,8 @@ fun MainScreen(
|
||||
Modifier
|
||||
.fillMaxSize()
|
||||
.padding(padding)
|
||||
.padding(defaultPadding),
|
||||
.padding(horizontal = verticalPadding)
|
||||
.padding(top = verticalPadding * 1.5f),
|
||||
accountStateViewModel,
|
||||
account,
|
||||
navController,
|
||||
@@ -742,7 +751,8 @@ fun MainScreen(
|
||||
Modifier
|
||||
.fillMaxSize()
|
||||
.padding(padding)
|
||||
.padding(defaultPadding),
|
||||
.padding(horizontal = verticalPadding)
|
||||
.padding(top = verticalPadding * 1.5f),
|
||||
account,
|
||||
)
|
||||
},
|
||||
@@ -758,7 +768,8 @@ fun MainScreen(
|
||||
Modifier
|
||||
.fillMaxSize()
|
||||
.padding(padding)
|
||||
.padding(defaultPadding),
|
||||
.padding(horizontal = verticalPadding)
|
||||
.padding(top = verticalPadding * 1.5f),
|
||||
account = account,
|
||||
selectedPackage = packageName,
|
||||
navController = navController,
|
||||
@@ -776,7 +787,8 @@ fun MainScreen(
|
||||
Modifier
|
||||
.fillMaxSize()
|
||||
.padding(padding)
|
||||
.padding(defaultPadding),
|
||||
.padding(horizontal = verticalPadding)
|
||||
.padding(top = verticalPadding * 1.5f),
|
||||
account = account,
|
||||
)
|
||||
},
|
||||
@@ -791,7 +803,8 @@ fun MainScreen(
|
||||
Modifier
|
||||
.fillMaxSize()
|
||||
.padding(padding)
|
||||
.padding(defaultPadding),
|
||||
.padding(horizontal = verticalPadding)
|
||||
.padding(top = verticalPadding * 1.5f),
|
||||
)
|
||||
},
|
||||
)
|
||||
@@ -804,7 +817,8 @@ fun MainScreen(
|
||||
Modifier
|
||||
.fillMaxSize()
|
||||
.padding(padding)
|
||||
.padding(defaultPadding),
|
||||
.padding(horizontal = verticalPadding)
|
||||
.padding(top = verticalPadding * 1.5f),
|
||||
account = account,
|
||||
)
|
||||
},
|
||||
@@ -818,7 +832,8 @@ fun MainScreen(
|
||||
Modifier
|
||||
.fillMaxSize()
|
||||
.padding(padding)
|
||||
.padding(defaultPadding),
|
||||
.padding(horizontal = verticalPadding)
|
||||
.padding(top = verticalPadding * 1.5f),
|
||||
accountStateViewModel = accountStateViewModel,
|
||||
account = account,
|
||||
)
|
||||
@@ -833,7 +848,8 @@ fun MainScreen(
|
||||
Modifier
|
||||
.fillMaxSize()
|
||||
.padding(padding)
|
||||
.padding(defaultPadding),
|
||||
.padding(horizontal = verticalPadding)
|
||||
.padding(top = verticalPadding * 1.5f),
|
||||
account = account,
|
||||
navController = navController,
|
||||
)
|
||||
@@ -848,7 +864,8 @@ fun MainScreen(
|
||||
Modifier
|
||||
.fillMaxSize()
|
||||
.padding(padding)
|
||||
.padding(defaultPadding),
|
||||
.padding(horizontal = verticalPadding)
|
||||
.padding(top = verticalPadding * 1.5f),
|
||||
navController = navController,
|
||||
)
|
||||
},
|
||||
@@ -865,7 +882,8 @@ fun MainScreen(
|
||||
Modifier
|
||||
.fillMaxSize()
|
||||
.padding(padding)
|
||||
.padding(defaultPadding),
|
||||
.padding(horizontal = verticalPadding)
|
||||
.padding(top = verticalPadding * 1.5f),
|
||||
)
|
||||
},
|
||||
)
|
||||
@@ -882,7 +900,8 @@ fun MainScreen(
|
||||
Modifier
|
||||
.fillMaxSize()
|
||||
.padding(padding)
|
||||
.padding(defaultPadding),
|
||||
.padding(horizontal = verticalPadding)
|
||||
.padding(top = verticalPadding * 1.5f),
|
||||
)
|
||||
},
|
||||
)
|
||||
@@ -900,7 +919,8 @@ fun MainScreen(
|
||||
Modifier
|
||||
.fillMaxSize()
|
||||
.padding(padding)
|
||||
.padding(defaultPadding),
|
||||
.padding(horizontal = verticalPadding)
|
||||
.padding(top = verticalPadding * 1.5f),
|
||||
)
|
||||
}
|
||||
},
|
||||
@@ -918,7 +938,8 @@ fun MainScreen(
|
||||
Modifier
|
||||
.fillMaxSize()
|
||||
.padding(padding)
|
||||
.padding(defaultPadding),
|
||||
.padding(horizontal = verticalPadding)
|
||||
.padding(top = verticalPadding * 1.5f),
|
||||
)
|
||||
}
|
||||
},
|
||||
@@ -936,7 +957,8 @@ fun MainScreen(
|
||||
Modifier
|
||||
.fillMaxSize()
|
||||
.padding(padding)
|
||||
.padding(defaultPadding),
|
||||
.padding(horizontal = verticalPadding)
|
||||
.padding(top = verticalPadding * 1.5f),
|
||||
)
|
||||
}
|
||||
},
|
||||
@@ -951,7 +973,8 @@ fun MainScreen(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.padding(padding)
|
||||
.padding(defaultPadding),
|
||||
.padding(horizontal = verticalPadding)
|
||||
.padding(top = verticalPadding * 1.5f),
|
||||
database = database,
|
||||
key = key,
|
||||
accountStateViewModel = accountStateViewModel,
|
||||
@@ -969,7 +992,8 @@ fun MainScreen(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.padding(padding)
|
||||
.padding(defaultPadding),
|
||||
.padding(horizontal = verticalPadding)
|
||||
.padding(top = verticalPadding * 1.5f),
|
||||
navController = navController,
|
||||
)
|
||||
},
|
||||
@@ -984,7 +1008,8 @@ fun MainScreen(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.padding(padding)
|
||||
.padding(defaultPadding),
|
||||
.padding(horizontal = verticalPadding)
|
||||
.padding(top = verticalPadding * 1.5f),
|
||||
accountStateViewModel = accountStateViewModel,
|
||||
pin = pin,
|
||||
navController = navController,
|
||||
@@ -992,6 +1017,19 @@ fun MainScreen(
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
composable(
|
||||
Route.SeeDetails.route,
|
||||
content = {
|
||||
SeeDetailsScreen(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.padding(padding)
|
||||
.padding(horizontal = verticalPadding)
|
||||
.padding(top = verticalPadding * 1.5f),
|
||||
)
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,6 @@ import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.scale
|
||||
import androidx.compose.ui.platform.LocalClipboardManager
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.stringResource
|
||||
@@ -91,12 +90,7 @@ fun NewApplicationScreen(
|
||||
context.getAppCompatActivity()?.startActivity(intent)
|
||||
accountStateViewModel.switchUser(account.signer.keyPair.pubKey.toNpub(), Route.IncomingRequest.route)
|
||||
},
|
||||
content = {
|
||||
Text(
|
||||
text = stringResource(R.string.paste_from_clipboard),
|
||||
Modifier.scale(1.25f),
|
||||
)
|
||||
},
|
||||
text = stringResource(R.string.paste_from_clipboard),
|
||||
)
|
||||
|
||||
Text(
|
||||
@@ -108,12 +102,7 @@ fun NewApplicationScreen(
|
||||
onClick = {
|
||||
dialogOpen = true
|
||||
},
|
||||
content = {
|
||||
Text(
|
||||
text = stringResource(R.string.scan_qr_code),
|
||||
Modifier.scale(1.25f),
|
||||
)
|
||||
},
|
||||
text = stringResource(R.string.scan_qr_code),
|
||||
)
|
||||
|
||||
Text(
|
||||
@@ -125,12 +114,7 @@ fun NewApplicationScreen(
|
||||
onClick = {
|
||||
navController.navigate(Route.NewNsecBunker.route)
|
||||
},
|
||||
content = {
|
||||
Text(
|
||||
text = stringResource(R.string.add_a_nsecbunker),
|
||||
Modifier.scale(1.25f),
|
||||
)
|
||||
},
|
||||
text = stringResource(R.string.add_a_nsecbunker),
|
||||
)
|
||||
|
||||
Text(
|
||||
|
||||
@@ -8,12 +8,10 @@ import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.text.KeyboardActions
|
||||
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.Icon
|
||||
import androidx.compose.material3.IconButton
|
||||
import androidx.compose.material3.IconButtonDefaults
|
||||
@@ -30,7 +28,6 @@ import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.scale
|
||||
import androidx.compose.ui.focus.FocusRequester
|
||||
import androidx.compose.ui.focus.focusRequester
|
||||
import androidx.compose.ui.platform.LocalClipboardManager
|
||||
@@ -40,7 +37,6 @@ import androidx.compose.ui.text.AnnotatedString
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.text.input.ImeAction
|
||||
import androidx.compose.ui.text.input.TextFieldValue
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import androidx.navigation.NavController
|
||||
@@ -93,7 +89,8 @@ fun NewNsecBunkerScreen(
|
||||
|
||||
if (isLoading.value) {
|
||||
CenterCircularProgressIndicator(
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
modifier = Modifier,
|
||||
text = "Testing the relay...",
|
||||
)
|
||||
} else {
|
||||
Column(
|
||||
@@ -181,47 +178,18 @@ fun NewNsecBunkerScreen(
|
||||
|
||||
Spacer(modifier = Modifier.height(16.dp))
|
||||
|
||||
LazyColumn(
|
||||
Modifier
|
||||
.padding(bottom = 20.dp),
|
||||
) {
|
||||
items(relays.size) {
|
||||
Row(
|
||||
Modifier.fillMaxWidth(),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.Center,
|
||||
) {
|
||||
Text(
|
||||
relays[it].url,
|
||||
Modifier
|
||||
.weight(0.9f)
|
||||
.padding(8.dp),
|
||||
fontWeight = FontWeight.Bold,
|
||||
fontSize = 18.sp,
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
)
|
||||
IconButton(
|
||||
onClick = {
|
||||
relays.removeAt(it)
|
||||
},
|
||||
) {
|
||||
Icon(
|
||||
Icons.Default.Delete,
|
||||
stringResource(R.string.delete),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
relays.forEachIndexed { index, relay ->
|
||||
RelayCard(
|
||||
relay = relay.url,
|
||||
onClick = {
|
||||
relays.removeAt(index)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
AmberButton(
|
||||
content = {
|
||||
Text(
|
||||
text = stringResource(R.string.create),
|
||||
Modifier.scale(1.25f),
|
||||
)
|
||||
},
|
||||
Modifier.padding(top = 20.dp),
|
||||
text = stringResource(R.string.create),
|
||||
onClick = {
|
||||
if (relays.isEmpty()) {
|
||||
accountStateViewModel.toast(
|
||||
@@ -335,12 +303,7 @@ fun NewNsecBunkerCreatedScreen(
|
||||
onClick = {
|
||||
clipboardManager.setText(AnnotatedString(bunkerUri))
|
||||
},
|
||||
content = {
|
||||
Text(
|
||||
text = stringResource(R.string.copy_to_clipboard),
|
||||
Modifier.scale(1.25f),
|
||||
)
|
||||
},
|
||||
text = stringResource(R.string.copy_to_clipboard),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,33 +52,8 @@ fun PermissionsScreen(
|
||||
} else {
|
||||
LazyColumn(
|
||||
Modifier
|
||||
.fillMaxSize()
|
||||
.padding(8.dp),
|
||||
.fillMaxSize(),
|
||||
) {
|
||||
// item {
|
||||
// Row(
|
||||
// Modifier
|
||||
// .fillMaxWidth()
|
||||
// .padding(8.dp)
|
||||
// .clickable {
|
||||
//
|
||||
// },
|
||||
// horizontalArrangement = Arrangement.End,
|
||||
// ) {
|
||||
// Icon(
|
||||
// Icons.AutoMirrored.Filled.Sort,
|
||||
// null,
|
||||
// modifier = Modifier.size(22.dp),
|
||||
// tint = MaterialTheme.colorScheme.onBackground,
|
||||
// )
|
||||
// Text(
|
||||
// modifier = Modifier.padding(start = 16.dp),
|
||||
// text = "Sort by $sortBy",
|
||||
// maxLines = 1,
|
||||
// overflow = TextOverflow.Ellipsis,
|
||||
// )
|
||||
// }
|
||||
// }
|
||||
itemsIndexed(applications.value) { _, applicationWithHistory ->
|
||||
Row(
|
||||
modifier = Modifier
|
||||
|
||||
@@ -142,11 +142,7 @@ fun SecurityScreen(
|
||||
}
|
||||
}
|
||||
},
|
||||
content = {
|
||||
Text(
|
||||
text = stringResource(R.string.save),
|
||||
)
|
||||
},
|
||||
text = stringResource(R.string.save),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,145 @@
|
||||
package com.greenart7c3.nostrsigner.ui
|
||||
|
||||
import androidx.compose.foundation.BorderStroke
|
||||
import androidx.compose.foundation.background
|
||||
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.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.foundation.verticalScroll
|
||||
import androidx.compose.material3.Card
|
||||
import androidx.compose.material3.CardDefaults
|
||||
import androidx.compose.material3.Checkbox
|
||||
import androidx.compose.material3.CheckboxDefaults
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Switch
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.scale
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.intl.Locale
|
||||
import androidx.compose.ui.text.toLowerCase
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.greenart7c3.nostrsigner.R
|
||||
import com.greenart7c3.nostrsigner.models.Permission
|
||||
import com.greenart7c3.nostrsigner.models.SignerType
|
||||
import com.greenart7c3.nostrsigner.service.MultiEventScreenIntents
|
||||
import com.greenart7c3.nostrsigner.service.model.AmberEvent
|
||||
|
||||
@Composable
|
||||
fun SeeDetailsScreen(
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
val context = LocalContext.current
|
||||
Column(
|
||||
modifier = modifier
|
||||
.fillMaxWidth()
|
||||
.verticalScroll(rememberScrollState()),
|
||||
) {
|
||||
var rememberMyChoice by remember { mutableStateOf(MultiEventScreenIntents.intents.first().rememberMyChoice.value) }
|
||||
val first = MultiEventScreenIntents.intents.first()
|
||||
val permission = if (first.type == SignerType.SIGN_EVENT) {
|
||||
Permission("sign_event", first.event!!.kind)
|
||||
} else {
|
||||
Permission(first.type.toString().toLowerCase(Locale.current), null)
|
||||
}
|
||||
|
||||
val message = if (first.type == SignerType.CONNECT) {
|
||||
stringResource(R.string.connect)
|
||||
} else {
|
||||
permission.toLocalizedString(context)
|
||||
}
|
||||
Text(
|
||||
stringResource(R.string.is_requiring_to_sign_these_events_related_to_permission, MultiEventScreenIntents.appName, message),
|
||||
Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(bottom = 20.dp),
|
||||
)
|
||||
|
||||
Row(
|
||||
horizontalArrangement = Arrangement.SpaceBetween,
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
modifier = Modifier
|
||||
.padding(vertical = 8.dp)
|
||||
.clickable {
|
||||
rememberMyChoice = !rememberMyChoice
|
||||
MultiEventScreenIntents.intents.forEach { intent ->
|
||||
intent.rememberMyChoice.value = rememberMyChoice
|
||||
}
|
||||
},
|
||||
) {
|
||||
Switch(
|
||||
modifier = Modifier.scale(0.85f),
|
||||
checked = rememberMyChoice,
|
||||
onCheckedChange = {
|
||||
rememberMyChoice = !rememberMyChoice
|
||||
MultiEventScreenIntents.intents.forEach { intent ->
|
||||
intent.rememberMyChoice.value = rememberMyChoice
|
||||
}
|
||||
},
|
||||
)
|
||||
Text(
|
||||
modifier = Modifier
|
||||
.weight(1f)
|
||||
.padding(start = 8.dp),
|
||||
text = stringResource(R.string.always_approve_this_permission),
|
||||
)
|
||||
}
|
||||
|
||||
MultiEventScreenIntents.intents.forEach { intent ->
|
||||
Card(
|
||||
Modifier
|
||||
.padding(4.dp),
|
||||
colors = CardDefaults.cardColors().copy(
|
||||
containerColor = MaterialTheme.colorScheme.background,
|
||||
),
|
||||
border = BorderStroke(1.dp, Color.Gray),
|
||||
) {
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.clickable {
|
||||
intent.checked.value = !intent.checked.value
|
||||
},
|
||||
) {
|
||||
Checkbox(
|
||||
checked = intent.checked.value,
|
||||
onCheckedChange = { _ ->
|
||||
intent.checked.value = !intent.checked.value
|
||||
},
|
||||
colors = CheckboxDefaults.colors().copy(
|
||||
uncheckedBorderColor = Color.Gray,
|
||||
),
|
||||
)
|
||||
|
||||
val data = if (intent.type == SignerType.SIGN_EVENT) {
|
||||
val event = intent.event!!
|
||||
if (event.kind == 22242) AmberEvent.relay(event) else event.content
|
||||
} else {
|
||||
intent.encryptedData ?: intent.data
|
||||
}
|
||||
|
||||
Text(
|
||||
modifier = Modifier
|
||||
.weight(1f)
|
||||
.padding(vertical = 8.dp),
|
||||
text = data.ifBlank { message },
|
||||
color = if (intent.checked.value) Color.Unspecified else Color.Gray,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -100,7 +100,7 @@ fun SettingsScreen(
|
||||
) {
|
||||
Box(
|
||||
Modifier
|
||||
.padding(vertical = 8.dp),
|
||||
.padding(bottom = 8.dp),
|
||||
) {
|
||||
IconRow(
|
||||
title = stringResource(R.string.security),
|
||||
|
||||
@@ -121,11 +121,7 @@ fun SignPolicySettingsScreen(
|
||||
}
|
||||
}
|
||||
},
|
||||
content = {
|
||||
Text(
|
||||
text = stringResource(R.string.save),
|
||||
)
|
||||
},
|
||||
text = stringResource(R.string.save),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -176,9 +176,7 @@ fun AccountBackupScreen(
|
||||
},
|
||||
)
|
||||
},
|
||||
content = {
|
||||
Text(text = stringResource(R.string.show_seed_words))
|
||||
},
|
||||
text = stringResource(R.string.show_seed_words),
|
||||
)
|
||||
}
|
||||
NSecCopyButton(account)
|
||||
@@ -324,11 +322,7 @@ private fun NSecQrButton(account: Account) {
|
||||
},
|
||||
)
|
||||
},
|
||||
content = {
|
||||
Text(
|
||||
stringResource(id = R.string.show_qr_code),
|
||||
)
|
||||
},
|
||||
text = stringResource(id = R.string.show_qr_code),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -411,9 +405,7 @@ private fun NSecCopyButton(account: Account) {
|
||||
},
|
||||
)
|
||||
},
|
||||
content = {
|
||||
Text(stringResource(id = R.string.copy_my_secret_key))
|
||||
},
|
||||
text = stringResource(id = R.string.copy_my_secret_key),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -471,13 +463,9 @@ private fun EncryptNSecCopyButton(
|
||||
)
|
||||
},
|
||||
enabled = password.value.text.isNotBlank(),
|
||||
content = {
|
||||
Text(
|
||||
stringResource(id = R.string.encrypt_and_copy_my_secret_key),
|
||||
maxLines = 1,
|
||||
textAlign = TextAlign.Center,
|
||||
)
|
||||
},
|
||||
text = stringResource(id = R.string.encrypt_and_copy_my_secret_key),
|
||||
maxLines = 1,
|
||||
textAlign = TextAlign.Center,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -528,11 +516,7 @@ private fun EncryptNSecQRButton(
|
||||
)
|
||||
},
|
||||
enabled = password.value.text.isNotBlank(),
|
||||
content = {
|
||||
Text(
|
||||
stringResource(id = R.string.show_qr_code),
|
||||
)
|
||||
},
|
||||
text = stringResource(id = R.string.show_qr_code),
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -124,7 +124,7 @@ fun ActivityScreen(
|
||||
if (activity.accepted) Icons.Default.Check else Icons.Default.Close,
|
||||
contentDescription = if (activity.accepted) stringResource(R.string.accepted) else stringResource(R.string.rejected),
|
||||
tint = if (activity.accepted) Color(0xFF1D8802) else Color(0xFFFF6B00),
|
||||
modifier = Modifier.padding(top = 4.dp, bottom = 16.dp),
|
||||
modifier = Modifier.padding(start = 10.dp, top = 4.dp, bottom = 16.dp),
|
||||
)
|
||||
}
|
||||
Spacer(Modifier.weight(1f))
|
||||
|
||||
@@ -15,11 +15,7 @@ import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.itemsIndexed
|
||||
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.HorizontalDivider
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.IconButton
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.OutlinedTextField
|
||||
import androidx.compose.material3.Surface
|
||||
@@ -37,7 +33,6 @@ 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.text.font.FontWeight
|
||||
import androidx.compose.ui.text.input.ImeAction
|
||||
import androidx.compose.ui.text.input.KeyboardCapitalization
|
||||
import androidx.compose.ui.text.input.TextFieldValue
|
||||
@@ -57,6 +52,7 @@ import com.greenart7c3.nostrsigner.service.Nip11Retriever
|
||||
import com.greenart7c3.nostrsigner.service.NotificationDataSource
|
||||
import com.greenart7c3.nostrsigner.ui.AccountStateViewModel
|
||||
import com.greenart7c3.nostrsigner.ui.CenterCircularProgressIndicator
|
||||
import com.greenart7c3.nostrsigner.ui.RelayCard
|
||||
import com.greenart7c3.nostrsigner.ui.components.AmberButton
|
||||
import com.vitorpamplona.ammolite.relays.COMMON_FEED_TYPES
|
||||
import com.vitorpamplona.ammolite.relays.Client
|
||||
@@ -108,7 +104,10 @@ fun DefaultRelaysScreen(
|
||||
.fillMaxSize(),
|
||||
) {
|
||||
if (isLoading.value) {
|
||||
CenterCircularProgressIndicator(Modifier)
|
||||
CenterCircularProgressIndicator(
|
||||
Modifier,
|
||||
text = "Testing relay...",
|
||||
)
|
||||
} else {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
@@ -117,8 +116,7 @@ fun DefaultRelaysScreen(
|
||||
) {
|
||||
OutlinedTextField(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 16.dp),
|
||||
.fillMaxWidth(),
|
||||
value = textFieldRelay.value.text,
|
||||
keyboardOptions = KeyboardOptions(
|
||||
capitalization = KeyboardCapitalization.None,
|
||||
@@ -168,8 +166,7 @@ fun DefaultRelaysScreen(
|
||||
|
||||
AmberButton(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 16.dp),
|
||||
.fillMaxWidth(),
|
||||
onClick = {
|
||||
scope.launch(Dispatchers.IO) {
|
||||
onAddRelay(
|
||||
@@ -202,9 +199,7 @@ fun DefaultRelaysScreen(
|
||||
)
|
||||
}
|
||||
},
|
||||
content = {
|
||||
Text(stringResource(R.string.add))
|
||||
},
|
||||
text = stringResource(R.string.add),
|
||||
)
|
||||
|
||||
LazyColumn(
|
||||
@@ -212,47 +207,29 @@ fun DefaultRelaysScreen(
|
||||
.weight(1f),
|
||||
) {
|
||||
items(relays2.size) {
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
Text(
|
||||
relays2[it].url,
|
||||
Modifier
|
||||
.weight(0.9f)
|
||||
.padding(16.dp),
|
||||
fontWeight = FontWeight.Bold,
|
||||
fontSize = 18.sp,
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
)
|
||||
IconButton(
|
||||
onClick = {
|
||||
isLoading.value = true
|
||||
relays2.removeAt(it)
|
||||
NostrSigner.getInstance().settings = NostrSigner.getInstance().settings.copy(
|
||||
defaultRelays = relays2,
|
||||
)
|
||||
LocalPreferences.saveSettingsToEncryptedStorage(NostrSigner.getInstance().settings)
|
||||
scope.launch(Dispatchers.IO) {
|
||||
@Suppress("KotlinConstantConditions")
|
||||
if (BuildConfig.FLAVOR != "offline") {
|
||||
NostrSigner.getInstance().checkForNewRelays()
|
||||
NotificationDataSource.stop()
|
||||
delay(2000)
|
||||
NotificationDataSource.start()
|
||||
isLoading.value = false
|
||||
} else {
|
||||
isLoading.value = false
|
||||
}
|
||||
}
|
||||
},
|
||||
) {
|
||||
Icon(
|
||||
Icons.Default.Delete,
|
||||
stringResource(R.string.delete),
|
||||
RelayCard(
|
||||
relay = relays2[it].url,
|
||||
onClick = {
|
||||
isLoading.value = true
|
||||
relays2.removeAt(it)
|
||||
NostrSigner.getInstance().settings = NostrSigner.getInstance().settings.copy(
|
||||
defaultRelays = relays2,
|
||||
)
|
||||
}
|
||||
}
|
||||
LocalPreferences.saveSettingsToEncryptedStorage(NostrSigner.getInstance().settings)
|
||||
scope.launch(Dispatchers.IO) {
|
||||
@Suppress("KotlinConstantConditions")
|
||||
if (BuildConfig.FLAVOR != "offline") {
|
||||
NostrSigner.getInstance().checkForNewRelays()
|
||||
NotificationDataSource.stop()
|
||||
delay(2000)
|
||||
NotificationDataSource.start()
|
||||
isLoading.value = false
|
||||
} else {
|
||||
isLoading.value = false
|
||||
}
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,6 @@ import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.material3.ButtonDefaults
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
@@ -27,17 +26,16 @@ fun AcceptRejectButtons(
|
||||
AmberButton(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
onClick = onAccept,
|
||||
) {
|
||||
Text(stringResource(R.string.accept))
|
||||
}
|
||||
text = stringResource(R.string.accept),
|
||||
)
|
||||
|
||||
Spacer(modifier = Modifier.width(20.dp))
|
||||
AmberButton(
|
||||
onClick = onReject,
|
||||
colors = ButtonDefaults.buttonColors(
|
||||
containerColor = Color(0xFFFF6B00),
|
||||
),
|
||||
) {
|
||||
Text(stringResource(R.string.reject))
|
||||
}
|
||||
text = stringResource(R.string.reject),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,9 +10,12 @@ import androidx.compose.material3.Button
|
||||
import androidx.compose.material3.ButtonColors
|
||||
import androidx.compose.material3.ButtonDefaults
|
||||
import androidx.compose.material3.ElevatedButton
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.scale
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.unit.dp
|
||||
|
||||
@Composable
|
||||
@@ -23,7 +26,10 @@ fun AmberButton(
|
||||
colors: ButtonColors = ButtonDefaults.buttonColors().copy(
|
||||
contentColor = Color.Black,
|
||||
),
|
||||
content: @Composable () -> Unit,
|
||||
textColor: Color = Color.Unspecified,
|
||||
text: String,
|
||||
textAlign: TextAlign? = null,
|
||||
maxLines: Int = Int.MAX_VALUE,
|
||||
) {
|
||||
Row(
|
||||
modifier.fillMaxWidth(),
|
||||
@@ -39,7 +45,13 @@ fun AmberButton(
|
||||
.padding(vertical = 6.dp),
|
||||
contentPadding = PaddingValues(vertical = 14.dp),
|
||||
) {
|
||||
content()
|
||||
Text(
|
||||
text = text,
|
||||
color = textColor,
|
||||
modifier = Modifier.scale(1.50f),
|
||||
textAlign = textAlign,
|
||||
maxLines = maxLines,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -49,7 +61,10 @@ fun AmberElevatedButton(
|
||||
modifier: Modifier = Modifier,
|
||||
onClick: () -> Unit,
|
||||
enabled: Boolean = true,
|
||||
content: @Composable () -> Unit,
|
||||
textColor: Color = Color.Unspecified,
|
||||
text: String,
|
||||
textAlign: TextAlign? = null,
|
||||
maxLines: Int = Int.MAX_VALUE,
|
||||
) {
|
||||
Row(
|
||||
modifier.fillMaxWidth(),
|
||||
@@ -64,7 +79,13 @@ fun AmberElevatedButton(
|
||||
.padding(vertical = 6.dp),
|
||||
contentPadding = PaddingValues(vertical = 14.dp),
|
||||
) {
|
||||
content()
|
||||
Text(
|
||||
text = text,
|
||||
color = textColor,
|
||||
modifier = Modifier.scale(1.50f),
|
||||
textAlign = textAlign,
|
||||
maxLines = maxLines,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ fun IconRow(
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(vertical = 15.dp, horizontal = 25.dp),
|
||||
.padding(vertical = 15.dp),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = if (center) Arrangement.Center else Arrangement.Start,
|
||||
) {
|
||||
@@ -81,7 +81,7 @@ fun IconRow(
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(vertical = 15.dp, horizontal = 25.dp),
|
||||
.padding(vertical = 15.dp),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
Icon(
|
||||
|
||||
@@ -224,9 +224,7 @@ fun LoginWithPubKey(
|
||||
onClick = {
|
||||
onAccept(localPermissions, selectedOption)
|
||||
},
|
||||
content = {
|
||||
Text(stringResource(R.string.grant_permissions))
|
||||
},
|
||||
text = stringResource(R.string.grant_permissions),
|
||||
)
|
||||
|
||||
AmberButton(
|
||||
@@ -235,9 +233,7 @@ fun LoginWithPubKey(
|
||||
colors = ButtonDefaults.buttonColors(
|
||||
containerColor = Color(0xFFFF6B00),
|
||||
),
|
||||
content = {
|
||||
Text(stringResource(R.string.reject))
|
||||
},
|
||||
text = stringResource(R.string.reject),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
+298
-442
@@ -5,6 +5,7 @@ import android.content.Context
|
||||
import android.content.Intent
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.compose.foundation.BorderStroke
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
@@ -14,17 +15,12 @@ import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.foundation.verticalScroll
|
||||
import androidx.compose.material3.BottomAppBar
|
||||
import androidx.compose.material3.ButtonDefaults
|
||||
import androidx.compose.material3.Card
|
||||
import androidx.compose.material3.CardDefaults
|
||||
import androidx.compose.material3.CenterAlignedTopAppBar
|
||||
import androidx.compose.material3.Checkbox
|
||||
import androidx.compose.material3.CheckboxDefaults
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Scaffold
|
||||
import androidx.compose.material3.Switch
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
@@ -36,12 +32,9 @@ import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.scale
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.graphics.vector.ImageVector
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.res.vectorResource
|
||||
import androidx.compose.ui.text.LinkAnnotation
|
||||
import androidx.compose.ui.text.SpanStyle
|
||||
import androidx.compose.ui.text.TextLinkStyles
|
||||
@@ -52,8 +45,7 @@ import androidx.compose.ui.text.toLowerCase
|
||||
import androidx.compose.ui.text.withLink
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import androidx.compose.ui.window.Dialog
|
||||
import androidx.compose.ui.window.DialogProperties
|
||||
import androidx.navigation.NavController
|
||||
import com.google.gson.GsonBuilder
|
||||
import com.greenart7c3.nostrsigner.LocalPreferences
|
||||
import com.greenart7c3.nostrsigner.NostrSigner
|
||||
@@ -71,8 +63,8 @@ import com.greenart7c3.nostrsigner.service.AmberUtils
|
||||
import com.greenart7c3.nostrsigner.service.ApplicationNameCache
|
||||
import com.greenart7c3.nostrsigner.service.EventNotificationConsumer
|
||||
import com.greenart7c3.nostrsigner.service.IntentUtils
|
||||
import com.greenart7c3.nostrsigner.service.MultiEventScreenIntents
|
||||
import com.greenart7c3.nostrsigner.service.getAppCompatActivity
|
||||
import com.greenart7c3.nostrsigner.service.model.AmberEvent
|
||||
import com.greenart7c3.nostrsigner.service.toShortenHex
|
||||
import com.greenart7c3.nostrsigner.ui.Result
|
||||
import com.greenart7c3.nostrsigner.ui.navigation.Route
|
||||
@@ -84,19 +76,18 @@ import com.vitorpamplona.quartz.events.LnZapRequestEvent
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
fun MultiEventHomeScreen(
|
||||
intents: List<IntentData>,
|
||||
packageName: String?,
|
||||
accountParam: Account,
|
||||
navController: NavController,
|
||||
onLoading: (Boolean) -> Unit,
|
||||
) {
|
||||
val coroutineScope = rememberCoroutineScope()
|
||||
val context = LocalContext.current
|
||||
val grouped = intents.groupBy { it.type }.filter { it.key != SignerType.SIGN_EVENT }
|
||||
val grouped2 = intents.filter { it.type == SignerType.SIGN_EVENT }.groupBy { it.event?.kind }
|
||||
var intentsDialog by remember { mutableStateOf<List<IntentData>?>(null) }
|
||||
val acceptEventsGroup1 = grouped.map {
|
||||
remember {
|
||||
mutableStateOf(true)
|
||||
@@ -121,453 +112,318 @@ fun MultiEventHomeScreen(
|
||||
|
||||
val appName = ApplicationNameCache.names["$localAccount-$key"] ?: key.toShortenHex()
|
||||
|
||||
if (intentsDialog != null) {
|
||||
Dialog(
|
||||
properties = DialogProperties(
|
||||
usePlatformDefaultWidth = false,
|
||||
),
|
||||
onDismissRequest = {
|
||||
intentsDialog = null
|
||||
},
|
||||
) {
|
||||
Scaffold(
|
||||
bottomBar = {
|
||||
BottomAppBar {
|
||||
IconRow(
|
||||
center = true,
|
||||
title = stringResource(R.string.back_to, Route.IncomingRequest.title),
|
||||
icon = ImageVector.vectorResource(R.drawable.back),
|
||||
onClick = {
|
||||
intentsDialog = null
|
||||
},
|
||||
tint = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
)
|
||||
}
|
||||
Column(
|
||||
Modifier
|
||||
.fillMaxSize()
|
||||
.verticalScroll(rememberScrollState()),
|
||||
) {
|
||||
Text(
|
||||
stringResource(R.string.is_requiring_some_permissions_please_review_them, appName),
|
||||
Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(bottom = 20.dp),
|
||||
)
|
||||
|
||||
grouped.toList().forEachIndexed { index, it ->
|
||||
PermissionCard(
|
||||
context = context,
|
||||
acceptEventsGroup = acceptEventsGroup1,
|
||||
index = index,
|
||||
item = it,
|
||||
onDetailsClick = {
|
||||
MultiEventScreenIntents.intents = it
|
||||
MultiEventScreenIntents.appName = appName
|
||||
navController.navigate(Route.SeeDetails.route)
|
||||
},
|
||||
topBar = {
|
||||
CenterAlignedTopAppBar(
|
||||
title = {
|
||||
Text(Route.IncomingRequest.title)
|
||||
},
|
||||
)
|
||||
)
|
||||
}
|
||||
grouped2.toList().forEachIndexed { index, it ->
|
||||
PermissionCard(
|
||||
context = context,
|
||||
acceptEventsGroup = acceptEventsGroup2,
|
||||
index = index,
|
||||
item = it,
|
||||
onDetailsClick = {
|
||||
MultiEventScreenIntents.intents = it
|
||||
MultiEventScreenIntents.appName = appName
|
||||
navController.navigate(Route.SeeDetails.route)
|
||||
},
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.padding(it)
|
||||
.padding(40.dp),
|
||||
) {
|
||||
var rememberMyChoice by remember { mutableStateOf(intentsDialog!!.first().rememberMyChoice.value) }
|
||||
val first = intentsDialog!!.first()
|
||||
val permission = if (first.type == SignerType.SIGN_EVENT) {
|
||||
Permission("sign_event", first.event!!.kind)
|
||||
} else {
|
||||
Permission(first.type.toString().toLowerCase(Locale.current), null)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
val message = if (first.type == SignerType.CONNECT) {
|
||||
stringResource(R.string.connect)
|
||||
} else {
|
||||
permission.toLocalizedString(context)
|
||||
}
|
||||
Text(
|
||||
stringResource(R.string.is_requiring_to_sign_these_events_related_to_permission, appName, message),
|
||||
Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(bottom = 20.dp),
|
||||
)
|
||||
AmberButton(
|
||||
Modifier.padding(vertical = 20.dp),
|
||||
text = stringResource(R.string.approve_selected),
|
||||
onClick = {
|
||||
onLoading(true)
|
||||
coroutineScope.launch(Dispatchers.IO) {
|
||||
try {
|
||||
val activity = context.getAppCompatActivity()
|
||||
val results = mutableListOf<Result>()
|
||||
reconnectToRelays(intents)
|
||||
|
||||
Row(
|
||||
horizontalArrangement = Arrangement.SpaceBetween,
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
modifier = Modifier
|
||||
.padding(vertical = 8.dp)
|
||||
.clickable {
|
||||
rememberMyChoice = !rememberMyChoice
|
||||
intentsDialog?.forEach { intent ->
|
||||
intent.rememberMyChoice.value = rememberMyChoice
|
||||
for (intentData in intents) {
|
||||
val localAccount =
|
||||
if (intentData.currentAccount.isNotBlank()) {
|
||||
LocalPreferences.loadFromEncryptedStorage(
|
||||
context,
|
||||
intentData.currentAccount,
|
||||
)
|
||||
} else {
|
||||
accountParam
|
||||
} ?: continue
|
||||
|
||||
val key = intentData.bunkerRequest?.localKey ?: packageName ?: continue
|
||||
|
||||
val database = NostrSigner.getInstance().getDatabase(localAccount.signer.keyPair.pubKey.toNpub())
|
||||
|
||||
val application =
|
||||
database
|
||||
.applicationDao()
|
||||
.getByKey(key) ?: ApplicationWithPermissions(
|
||||
application = ApplicationEntity(
|
||||
key,
|
||||
"",
|
||||
listOf(),
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
localAccount.signer.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 && intentData.checked.value) {
|
||||
AmberUtils.acceptOrRejectPermission(
|
||||
application,
|
||||
key,
|
||||
intentData,
|
||||
localEvent.kind,
|
||||
intentData.rememberMyChoice.value,
|
||||
database,
|
||||
)
|
||||
}
|
||||
},
|
||||
) {
|
||||
Switch(
|
||||
modifier = Modifier.scale(0.85f),
|
||||
checked = rememberMyChoice,
|
||||
onCheckedChange = {
|
||||
rememberMyChoice = !rememberMyChoice
|
||||
intentsDialog?.forEach { intent ->
|
||||
intent.rememberMyChoice.value = rememberMyChoice
|
||||
}
|
||||
},
|
||||
)
|
||||
Text(
|
||||
modifier = Modifier
|
||||
.weight(1f)
|
||||
.padding(start = 8.dp),
|
||||
text = stringResource(R.string.always_approve_this_permission),
|
||||
)
|
||||
}
|
||||
|
||||
intentsDialog?.forEach { intent ->
|
||||
Card(
|
||||
Modifier
|
||||
.padding(4.dp),
|
||||
colors = CardDefaults.cardColors().copy(
|
||||
containerColor = MaterialTheme.colorScheme.background,
|
||||
),
|
||||
border = BorderStroke(1.dp, Color.Gray),
|
||||
) {
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.clickable {
|
||||
intent.checked.value = !intent.checked.value
|
||||
},
|
||||
) {
|
||||
Checkbox(
|
||||
checked = intent.checked.value,
|
||||
onCheckedChange = { _ ->
|
||||
intent.checked.value = !intent.checked.value
|
||||
},
|
||||
colors = CheckboxDefaults.colors().copy(
|
||||
uncheckedBorderColor = Color.Gray,
|
||||
database.applicationDao().insertApplicationWithPermissions(application)
|
||||
|
||||
database.applicationDao().addHistory(
|
||||
HistoryEntity(
|
||||
0,
|
||||
key,
|
||||
intentData.type.toString(),
|
||||
localEvent.kind,
|
||||
TimeUtils.now(),
|
||||
intentData.checked.value,
|
||||
),
|
||||
)
|
||||
|
||||
val data = if (intent.type == SignerType.SIGN_EVENT) {
|
||||
val event = intent.event!!
|
||||
if (event.kind == 22242) AmberEvent.relay(event) else event.content
|
||||
if (intentData.bunkerRequest != null) {
|
||||
if (intentData.checked.value) {
|
||||
IntentUtils.sendBunkerResponse(
|
||||
context,
|
||||
localAccount,
|
||||
intentData.bunkerRequest,
|
||||
BunkerResponse(intentData.bunkerRequest.id, localEvent.toJson(), null),
|
||||
application.application.relays,
|
||||
onLoading = {},
|
||||
onDone = {},
|
||||
)
|
||||
} else {
|
||||
AmberUtils.sendBunkerError(
|
||||
localAccount,
|
||||
intentData.bunkerRequest,
|
||||
relays = application.application.relays,
|
||||
context = context,
|
||||
onLoading = {},
|
||||
)
|
||||
}
|
||||
} else {
|
||||
intent.encryptedData ?: intent.data
|
||||
if (intentData.checked.value) {
|
||||
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 && intentData.checked.value) {
|
||||
AmberUtils.acceptOrRejectPermission(
|
||||
application,
|
||||
key,
|
||||
intentData,
|
||||
null,
|
||||
intentData.rememberMyChoice.value,
|
||||
database,
|
||||
)
|
||||
}
|
||||
|
||||
Text(
|
||||
modifier = Modifier
|
||||
.weight(1f)
|
||||
.padding(vertical = 8.dp),
|
||||
text = data,
|
||||
color = if (intent.checked.value) Color.Unspecified else Color.Gray,
|
||||
database.applicationDao().insertApplicationWithPermissions(application)
|
||||
database.applicationDao().addHistory(
|
||||
HistoryEntity(
|
||||
0,
|
||||
key,
|
||||
intentData.type.toString(),
|
||||
null,
|
||||
TimeUtils.now(),
|
||||
intentData.checked.value,
|
||||
),
|
||||
)
|
||||
|
||||
val signedMessage = CryptoUtils.signString(intentData.data, localAccount.signer.keyPair.privKey!!).toHexKey()
|
||||
|
||||
if (intentData.bunkerRequest != null) {
|
||||
if (intentData.checked.value) {
|
||||
IntentUtils.sendBunkerResponse(
|
||||
context,
|
||||
localAccount,
|
||||
intentData.bunkerRequest,
|
||||
BunkerResponse(intentData.bunkerRequest.id, signedMessage, null),
|
||||
application.application.relays,
|
||||
onLoading = {},
|
||||
onDone = {},
|
||||
)
|
||||
} else {
|
||||
AmberUtils.sendBunkerError(
|
||||
localAccount,
|
||||
intentData.bunkerRequest,
|
||||
relays = application.application.relays,
|
||||
context = context,
|
||||
onLoading = {},
|
||||
)
|
||||
}
|
||||
} else {
|
||||
if (intentData.checked.value) {
|
||||
results.add(
|
||||
Result(
|
||||
null,
|
||||
signature = signedMessage,
|
||||
result = signedMessage,
|
||||
id = intentData.id,
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (intentData.rememberMyChoice.value && intentData.checked.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(),
|
||||
intentData.checked.value,
|
||||
),
|
||||
)
|
||||
|
||||
val signature = intentData.encryptedData ?: continue
|
||||
|
||||
if (intentData.bunkerRequest != null) {
|
||||
if (intentData.checked.value) {
|
||||
IntentUtils.sendBunkerResponse(
|
||||
context,
|
||||
localAccount,
|
||||
intentData.bunkerRequest,
|
||||
BunkerResponse(intentData.bunkerRequest.id, signature, null),
|
||||
application.application.relays,
|
||||
onLoading = {},
|
||||
onDone = {},
|
||||
)
|
||||
} else {
|
||||
AmberUtils.sendBunkerError(
|
||||
localAccount,
|
||||
intentData.bunkerRequest,
|
||||
relays = application.application.relays,
|
||||
context = context,
|
||||
onLoading = {},
|
||||
)
|
||||
}
|
||||
} else {
|
||||
if (intentData.checked.value) {
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Column(
|
||||
Modifier
|
||||
.fillMaxSize()
|
||||
.verticalScroll(rememberScrollState()),
|
||||
) {
|
||||
Text(
|
||||
stringResource(R.string.is_requiring_some_permissions_please_review_them, appName),
|
||||
Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(bottom = 20.dp),
|
||||
)
|
||||
},
|
||||
)
|
||||
|
||||
grouped.toList().forEachIndexed { index, it ->
|
||||
PermissionCard(
|
||||
context = context,
|
||||
acceptEventsGroup = acceptEventsGroup1,
|
||||
index = index,
|
||||
item = it,
|
||||
onDetailsClick = {
|
||||
intentsDialog = it
|
||||
},
|
||||
)
|
||||
}
|
||||
grouped2.toList().forEachIndexed { index, it ->
|
||||
PermissionCard(
|
||||
context = context,
|
||||
acceptEventsGroup = acceptEventsGroup2,
|
||||
index = index,
|
||||
item = it,
|
||||
onDetailsClick = {
|
||||
intentsDialog = it
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
AmberButton(
|
||||
Modifier.padding(vertical = 20.dp),
|
||||
content = {
|
||||
Text(stringResource(R.string.approve_selected))
|
||||
},
|
||||
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
|
||||
|
||||
val key = intentData.bunkerRequest?.localKey ?: packageName ?: continue
|
||||
|
||||
val database = NostrSigner.getInstance().getDatabase(localAccount.signer.keyPair.pubKey.toNpub())
|
||||
|
||||
val application =
|
||||
database
|
||||
.applicationDao()
|
||||
.getByKey(key) ?: ApplicationWithPermissions(
|
||||
application = ApplicationEntity(
|
||||
key,
|
||||
"",
|
||||
listOf(),
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
localAccount.signer.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 && intentData.checked.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(),
|
||||
intentData.checked.value,
|
||||
),
|
||||
)
|
||||
|
||||
if (intentData.bunkerRequest != null) {
|
||||
if (intentData.checked.value) {
|
||||
IntentUtils.sendBunkerResponse(
|
||||
context,
|
||||
localAccount,
|
||||
intentData.bunkerRequest,
|
||||
BunkerResponse(intentData.bunkerRequest.id, localEvent.toJson(), null),
|
||||
application.application.relays,
|
||||
onLoading = {},
|
||||
onDone = {},
|
||||
)
|
||||
} else {
|
||||
AmberUtils.sendBunkerError(
|
||||
localAccount,
|
||||
intentData.bunkerRequest,
|
||||
relays = application.application.relays,
|
||||
context = context,
|
||||
onLoading = {},
|
||||
)
|
||||
}
|
||||
} else {
|
||||
if (intentData.checked.value) {
|
||||
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 && intentData.checked.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(),
|
||||
intentData.checked.value,
|
||||
),
|
||||
)
|
||||
|
||||
val signedMessage = CryptoUtils.signString(intentData.data, localAccount.signer.keyPair.privKey!!).toHexKey()
|
||||
|
||||
if (intentData.bunkerRequest != null) {
|
||||
if (intentData.checked.value) {
|
||||
IntentUtils.sendBunkerResponse(
|
||||
context,
|
||||
localAccount,
|
||||
intentData.bunkerRequest,
|
||||
BunkerResponse(intentData.bunkerRequest.id, signedMessage, null),
|
||||
application.application.relays,
|
||||
onLoading = {},
|
||||
onDone = {},
|
||||
)
|
||||
} else {
|
||||
AmberUtils.sendBunkerError(
|
||||
localAccount,
|
||||
intentData.bunkerRequest,
|
||||
relays = application.application.relays,
|
||||
context = context,
|
||||
onLoading = {},
|
||||
)
|
||||
}
|
||||
} else {
|
||||
if (intentData.checked.value) {
|
||||
results.add(
|
||||
Result(
|
||||
null,
|
||||
signature = signedMessage,
|
||||
result = signedMessage,
|
||||
id = intentData.id,
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (intentData.rememberMyChoice.value && intentData.checked.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(),
|
||||
intentData.checked.value,
|
||||
),
|
||||
)
|
||||
|
||||
val signature = intentData.encryptedData ?: continue
|
||||
|
||||
if (intentData.bunkerRequest != null) {
|
||||
if (intentData.checked.value) {
|
||||
IntentUtils.sendBunkerResponse(
|
||||
context,
|
||||
localAccount,
|
||||
intentData.bunkerRequest,
|
||||
BunkerResponse(intentData.bunkerRequest.id, signature, null),
|
||||
application.application.relays,
|
||||
onLoading = {},
|
||||
onDone = {},
|
||||
)
|
||||
} else {
|
||||
AmberUtils.sendBunkerError(
|
||||
localAccount,
|
||||
intentData.bunkerRequest,
|
||||
relays = application.application.relays,
|
||||
context = context,
|
||||
onLoading = {},
|
||||
)
|
||||
}
|
||||
} else {
|
||||
if (intentData.checked.value) {
|
||||
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)
|
||||
}
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
AmberButton(
|
||||
Modifier.padding(vertical = 20.dp),
|
||||
colors = ButtonDefaults.buttonColors().copy(
|
||||
containerColor = orange,
|
||||
),
|
||||
onClick = {
|
||||
val activity = context.getAppCompatActivity()
|
||||
if (intents.any { it.bunkerRequest != null }) {
|
||||
EventNotificationConsumer(context).notificationManager().cancelAll()
|
||||
finishActivity(activity)
|
||||
} else {
|
||||
finishActivity(activity)
|
||||
}
|
||||
},
|
||||
content = {
|
||||
Text(stringResource(R.string.discard_all_requests))
|
||||
},
|
||||
)
|
||||
}
|
||||
AmberButton(
|
||||
Modifier.padding(vertical = 20.dp),
|
||||
colors = ButtonDefaults.buttonColors().copy(
|
||||
containerColor = orange,
|
||||
),
|
||||
onClick = {
|
||||
val activity = context.getAppCompatActivity()
|
||||
if (intents.any { it.bunkerRequest != null }) {
|
||||
EventNotificationConsumer(context).notificationManager().cancelAll()
|
||||
finishActivity(activity)
|
||||
} else {
|
||||
finishActivity(activity)
|
||||
}
|
||||
},
|
||||
text = stringResource(R.string.discard_all_requests),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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.draw.scale
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
@@ -123,7 +124,11 @@ fun RandomPinInput(
|
||||
},
|
||||
modifier = Modifier.padding(8.dp),
|
||||
) {
|
||||
Text(number.toString(), color = Color.Black)
|
||||
Text(
|
||||
number.toString(),
|
||||
color = Color.Black,
|
||||
modifier = Modifier.scale(1.50f),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -155,7 +160,11 @@ fun RandomPinInput(
|
||||
},
|
||||
modifier = Modifier.weight(1f).padding(8.dp),
|
||||
) {
|
||||
Text(randomNumbers.last().toString(), color = Color.Black)
|
||||
Text(
|
||||
randomNumbers.last().toString(),
|
||||
color = Color.Black,
|
||||
modifier = Modifier.scale(1.50f),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -88,8 +88,7 @@ fun RawJson(
|
||||
}
|
||||
}
|
||||
},
|
||||
) {
|
||||
Text(stringResource(R.string.copy) + label)
|
||||
}
|
||||
text = (stringResource(R.string.copy) + label),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -61,9 +61,7 @@ fun SeedWordsPage(
|
||||
onClick = {
|
||||
clipboardManager.setText(AnnotatedString(seedWords.joinToString(" ")))
|
||||
},
|
||||
content = {
|
||||
Text(text = stringResource(R.string.copy_to_clipboard))
|
||||
},
|
||||
text = stringResource(R.string.copy_to_clipboard),
|
||||
)
|
||||
|
||||
Row(
|
||||
@@ -127,9 +125,7 @@ fun SeedWordsPage(
|
||||
if (showNextButton) {
|
||||
AmberButton(
|
||||
onClick = onNextPage,
|
||||
content = {
|
||||
Text(text = stringResource(R.string.next))
|
||||
},
|
||||
text = stringResource(R.string.next),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -151,6 +151,13 @@ sealed class Route(
|
||||
icon = R.drawable.settings,
|
||||
selectedIcon = R.drawable.settings,
|
||||
)
|
||||
|
||||
data object SeeDetails : Route(
|
||||
title = NostrSigner.getInstance().getString(R.string.incoming_request),
|
||||
route = "SeeDetails",
|
||||
icon = R.drawable.settings,
|
||||
selectedIcon = R.drawable.settings,
|
||||
)
|
||||
}
|
||||
|
||||
val routes = listOf(
|
||||
@@ -174,4 +181,5 @@ val routes = listOf(
|
||||
Route.EditConfiguration,
|
||||
Route.SetupPin,
|
||||
Route.ConfirmPin,
|
||||
Route.SeeDetails,
|
||||
)
|
||||
|
||||
@@ -36,8 +36,7 @@ val primaryColor = Color(0xFFFFCA62)
|
||||
val primaryVariant = Color(0xFFC8541A)
|
||||
val secondaryColor = Color(0xFFFFCA62)
|
||||
val orange = Color(0xFFFF6B00)
|
||||
val defaultPadding = 40.dp
|
||||
|
||||
val defaultPadding = 35.dp
|
||||
val RichTextDefaults = RichTextStyle().resolveDefaults()
|
||||
|
||||
private val DarkColorPalette =
|
||||
|
||||
Reference in New Issue
Block a user