change linter rules

This commit is contained in:
greenart7c3
2024-05-08 08:13:46 -03:00
parent 62e24a6384
commit 0f021d19a5
35 changed files with 622 additions and 723 deletions
+3 -1
View File
@@ -12,7 +12,9 @@ ij_kotlin_name_count_to_use_star_import = 999
ij_kotlin_name_count_to_use_star_import_for_members = 999
max_line_length = off
ktlint_function_naming_ignore_when_annotated_with = Composable
ktlint_code_style = ktlint_official
ktlint_code_style = android_studio
ij_kotlin_allow_trailing_comma_on_call_site = true
ij_kotlin_allow_trailing_comma = true
[*.{yml,yaml}]
indent_size = 2
@@ -17,11 +17,11 @@ import com.vitorpamplona.quartz.encoders.hexToByteArray
import com.vitorpamplona.quartz.encoders.toHexKey
import com.vitorpamplona.quartz.encoders.toNpub
import fr.acinq.secp256k1.jni.BuildConfig
import java.io.File
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.withContext
import org.json.JSONObject
import java.io.File
// Release mode (!BuildConfig.DEBUG) always uses encrypted preferences
// To use plaintext SharedPreferences for debugging, set this to true
@@ -61,15 +61,13 @@ data class BunkerRequest(
return BunkerRequest(
id = jsonObject.get("id").asText().intern(),
method = jsonObject.get("method").asText().intern(),
params =
jsonObject.get("params").asIterable().toList().map {
it.asText().intern()
}.toTypedArray(),
params = jsonObject.get("params").asIterable().toList().map {
it.asText().intern()
}.toTypedArray(),
localKey = jsonObject.get("localKey")?.asText()?.intern() ?: "",
relays =
jsonObject.get("relays")?.asIterable()?.toList()?.map {
it.asText().intern()
} ?: listOf(),
relays = jsonObject.get("relays")?.asIterable()?.toList()?.map {
it.asText().intern()
} ?: listOf(),
secret = jsonObject.get("secret")?.asText()?.intern() ?: "",
currentAccount = jsonObject.get("currentAccount")?.asText()?.intern() ?: "",
)
@@ -24,12 +24,12 @@ import android.util.Log
import com.greenart7c3.nostrsigner.checkNotInMainThread
import com.vitorpamplona.quartz.events.Event
import com.vitorpamplona.quartz.events.EventInterface
import java.util.UUID
import kotlinx.coroutines.DelicateCoroutinesApi
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import java.util.UUID
/**
* The Nostr Client manages multiple personae the user may switch between. Events are received and
@@ -30,12 +30,12 @@ import com.vitorpamplona.quartz.events.EventInterface
import com.vitorpamplona.quartz.events.RelayAuthEvent
import com.vitorpamplona.quartz.events.bytesUsedInMemory
import com.vitorpamplona.quartz.utils.TimeUtils
import java.util.concurrent.atomic.AtomicBoolean
import kotlinx.coroutines.CancellationException
import okhttp3.Request
import okhttp3.Response
import okhttp3.WebSocket
import okhttp3.WebSocketListener
import java.util.concurrent.atomic.AtomicBoolean
enum class FeedType {
FOLLOWS,
@@ -152,19 +152,18 @@ object AmberUtils {
database
.applicationDao()
.getByKey(key) ?: ApplicationWithPermissions(
application =
ApplicationEntity(
key,
appName,
listOf(),
"",
"",
"",
account.keyPair.pubKey.toHexKey(),
true,
intentData.bunkerRequest?.secret ?: "",
intentData.bunkerRequest?.secret != null,
),
application = ApplicationEntity(
key,
appName,
listOf(),
"",
"",
"",
account.keyPair.pubKey.toHexKey(),
true,
intentData.bunkerRequest?.secret ?: "",
intentData.bunkerRequest?.secret != null,
),
permissions = mutableListOf(),
)
@@ -21,6 +21,7 @@
package com.greenart7c3.nostrsigner.service
import androidx.compose.runtime.Stable
import java.util.concurrent.atomic.AtomicBoolean
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
@@ -30,7 +31,6 @@ import kotlinx.coroutines.cancel
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.util.concurrent.atomic.AtomicBoolean
/** This class is designed to have a waiting time between two calls of invalidate */
@Stable
@@ -22,15 +22,15 @@ package com.greenart7c3.nostrsigner.service
import android.util.Log
import com.greenart7c3.nostrsigner.BuildConfig
import okhttp3.Interceptor
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.Response
import java.io.IOException
import java.net.InetSocketAddress
import java.net.Proxy
import java.time.Duration
import kotlin.properties.Delegates
import okhttp3.Interceptor
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.Response
object HttpClientManager {
val DEFAULT_TIMEOUT_ON_WIFI: Duration = Duration.ofSeconds(10L)
@@ -32,14 +32,14 @@ import com.vitorpamplona.quartz.encoders.toHexKey
import com.vitorpamplona.quartz.encoders.toNpub
import com.vitorpamplona.quartz.events.Event
import fr.acinq.secp256k1.Hex
import java.net.URLDecoder
import java.util.UUID
import java.util.concurrent.ConcurrentHashMap
import kotlinx.coroutines.DelicateCoroutinesApi
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import java.net.URLDecoder
import java.util.UUID
import java.util.concurrent.ConcurrentHashMap
data class BunkerMetadata(
val name: String,
@@ -27,12 +27,12 @@ import com.greenart7c3.nostrsigner.relays.Relay
import com.greenart7c3.nostrsigner.relays.Subscription
import com.vitorpamplona.quartz.events.Event
import com.vitorpamplona.quartz.utils.TimeUtils
import java.util.UUID
import java.util.concurrent.atomic.AtomicBoolean
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.launch
import java.util.UUID
import java.util.concurrent.atomic.AtomicBoolean
abstract class NostrDataSource(val debugName: String) {
private val scope = CoroutineScope(Dispatchers.IO + SupervisorJob())
@@ -59,13 +59,12 @@ object NotificationDataSource : NostrDataSource("AccountData") {
return TypedFilter(
types = setOf(FeedType.FOLLOWS),
filter =
JsonFilter(
kinds = listOf(24133),
tags = mapOf("p" to pubKeys),
limit = 1,
since = eoses,
),
filter = JsonFilter(
kinds = listOf(24133),
tags = mapOf("p" to pubKeys),
limit = 1,
since = eoses,
),
)
}
@@ -38,10 +38,9 @@ open class AmberEvent(
pubKey = jsonObject.get("pubkey")?.asString ?: "",
createdAt = jsonObject.get("created_at")?.asLong ?: TimeUtils.now(),
kind = jsonObject.get("kind").asInt,
tags =
jsonObject.get("tags")?.asJsonArray?.map {
it.asJsonArray.mapNotNull { s -> if (s.isJsonNull) null else s.asString }.toTypedArray()
}?.toTypedArray() ?: emptyArray(),
tags = jsonObject.get("tags")?.asJsonArray?.map {
it.asJsonArray.mapNotNull { s -> if (s.isJsonNull) null else s.asString }.toTypedArray()
}?.toTypedArray() ?: emptyArray(),
content = jsonObject.get("content").asString,
sig = jsonObject.get("sig")?.asString ?: "",
)
@@ -74,13 +74,13 @@ import com.greenart7c3.nostrsigner.ui.components.PostButton
import com.greenart7c3.nostrsigner.ui.navigation.Route
import com.vitorpamplona.quartz.encoders.toHexKey
import com.vitorpamplona.quartz.encoders.toNpub
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import java.time.Instant
import java.time.LocalDateTime
import java.time.ZoneId
import java.time.format.DateTimeFormatter
import java.time.format.FormatStyle
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
fun convertLongToDateTime(longValue: Long): String {
val dateTime =
@@ -124,20 +124,18 @@ fun ActivityDialog(
) {
Surface(
modifier =
Modifier
.fillMaxSize(),
Modifier
.fillMaxSize(),
) {
Column(
modifier =
Modifier
.background(MaterialTheme.colorScheme.background)
.fillMaxSize(),
modifier = Modifier
.background(MaterialTheme.colorScheme.background)
.fillMaxSize(),
) {
Row(
modifier =
Modifier
.fillMaxWidth()
.padding(10.dp),
modifier = Modifier
.fillMaxWidth()
.padding(10.dp),
horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically,
) {
@@ -273,21 +271,18 @@ fun EditPermission(
properties = DialogProperties(usePlatformDefaultWidth = false),
) {
Surface(
modifier =
Modifier
.fillMaxSize(),
modifier = Modifier
.fillMaxSize(),
) {
Column(
modifier =
Modifier
.background(MaterialTheme.colorScheme.background)
.fillMaxSize(),
modifier = Modifier
.background(MaterialTheme.colorScheme.background)
.fillMaxSize(),
) {
Row(
modifier =
Modifier
.fillMaxWidth()
.padding(10.dp),
modifier = Modifier
.fillMaxWidth()
.padding(10.dp),
horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically,
) {
@@ -345,15 +340,13 @@ fun EditPermission(
) {
OutlinedTextField(
enabled = !applicationData.isConnected,
modifier =
Modifier
.fillMaxWidth(0.9f)
.padding(horizontal = 16.dp),
modifier = Modifier
.fillMaxWidth(0.9f)
.padding(horizontal = 16.dp),
value = textFieldRelay.text,
keyboardOptions =
KeyboardOptions(
imeAction = ImeAction.Done,
),
keyboardOptions = KeyboardOptions(
imeAction = ImeAction.Done,
),
onValueChange = {
textFieldRelay = TextFieldValue(it)
},
@@ -500,15 +493,14 @@ fun EditPermission(
Row(
horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically,
modifier =
Modifier
.padding(horizontal = 8.dp)
.clickable {
checked = !checked
val relays = applicationData.relays.joinToString(separator = "&") { "relay=$it" }
val localSecret = if (checked) "&secret=${applicationData.secret}" else ""
bunkerUri = "bunker://${account.keyPair.pubKey.toHexKey()}?$relays$localSecret"
},
modifier = Modifier
.padding(horizontal = 8.dp)
.clickable {
checked = !checked
val relays = applicationData.relays.joinToString(separator = "&") { "relay=$it" }
val localSecret = if (checked) "&secret=${applicationData.secret}" else ""
bunkerUri = "bunker://${account.keyPair.pubKey.toHexKey()}?$relays$localSecret"
},
) {
Text(
modifier = Modifier.weight(1f),
@@ -523,15 +515,13 @@ fun EditPermission(
}
}
OutlinedTextField(
modifier =
Modifier
.fillMaxWidth()
.padding(horizontal = 16.dp),
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 16.dp),
value = textFieldvalue.text,
keyboardOptions =
KeyboardOptions(
imeAction = ImeAction.Done,
),
keyboardOptions = KeyboardOptions(
imeAction = ImeAction.Done,
),
onValueChange = {
textFieldvalue = TextFieldValue(it)
},
@@ -590,36 +580,33 @@ fun EditPermission(
localPermission.toString()
}
Row(
modifier =
Modifier
.padding(vertical = 15.dp, horizontal = 25.dp)
.fillMaxWidth(),
modifier = Modifier
.padding(vertical = 15.dp, horizontal = 25.dp)
.fillMaxWidth(),
) {
Icon(
if (permission.acceptable) Icons.Default.Check else Icons.Default.Close,
null,
modifier =
Modifier
.size(22.dp)
.padding(end = 4.dp)
.clickable {
val localPermissions =
permissions.map {
if (it.id == permission.id) {
it.copy(acceptable = !permission.acceptable)
} else {
it.copy()
}
modifier = Modifier
.size(22.dp)
.padding(end = 4.dp)
.clickable {
val localPermissions =
permissions.map {
if (it.id == permission.id) {
it.copy(acceptable = !permission.acceptable)
} else {
it.copy()
}
permissions.clear()
permissions.addAll(localPermissions)
},
}
permissions.clear()
permissions.addAll(localPermissions)
},
tint = if (permission.acceptable) Color.Green else Color.Red,
)
Row(
modifier =
Modifier
.weight(1f),
modifier = Modifier
.weight(1f),
verticalAlignment = Alignment.CenterVertically,
) {
Text(
@@ -630,12 +617,11 @@ fun EditPermission(
Icon(
Icons.Default.Delete,
null,
modifier =
Modifier
.size(22.dp)
.clickable {
permissions.remove(permission)
},
modifier = Modifier
.size(22.dp)
.clickable {
permissions.remove(permission)
},
tint = Color.Red,
)
}
@@ -84,11 +84,10 @@ fun LoginPage(accountViewModel: AccountStateViewModel) {
val scope = rememberCoroutineScope()
Column(
modifier =
Modifier
.fillMaxSize()
.navigationBarsPadding()
.verticalScroll(rememberScrollState()),
modifier = Modifier
.fillMaxSize()
.navigationBarsPadding()
.verticalScroll(rememberScrollState()),
verticalArrangement = Arrangement.Center,
) {
// The first child is glued to the top.
@@ -97,10 +96,9 @@ fun LoginPage(accountViewModel: AccountStateViewModel) {
// The second child, this column, is centered vertically.
Column(
modifier =
Modifier
.padding(20.dp)
.fillMaxSize(),
modifier = Modifier
.padding(20.dp)
.fillMaxSize(),
horizontalAlignment = Alignment.CenterHorizontally,
) {
Spacer(modifier = Modifier.height(40.dp))
@@ -128,28 +126,26 @@ fun LoginPage(accountViewModel: AccountStateViewModel) {
LocalAutofillTree.current += autofillNodePassword
OutlinedTextField(
modifier =
Modifier
.onGloballyPositioned { coordinates ->
autofillNodeKey.boundingBox = coordinates.boundsInWindow()
}
.onFocusChanged { focusState ->
autofill?.run {
if (focusState.isFocused) {
requestAutofillForNode(autofillNodeKey)
} else {
cancelAutofillForNode(autofillNodeKey)
}
modifier = Modifier
.onGloballyPositioned { coordinates ->
autofillNodeKey.boundingBox = coordinates.boundsInWindow()
}
.onFocusChanged { focusState ->
autofill?.run {
if (focusState.isFocused) {
requestAutofillForNode(autofillNodeKey)
} else {
cancelAutofillForNode(autofillNodeKey)
}
},
}
},
value = key.value,
onValueChange = { key.value = it },
keyboardOptions =
KeyboardOptions(
autoCorrect = false,
keyboardType = KeyboardType.Password,
imeAction = ImeAction.Go,
),
keyboardOptions = KeyboardOptions(
autoCorrect = false,
keyboardType = KeyboardType.Password,
imeAction = ImeAction.Go,
),
placeholder = {
Text(
text = stringResource(R.string.nsec),
@@ -160,12 +156,11 @@ fun LoginPage(accountViewModel: AccountStateViewModel) {
IconButton(onClick = { showPassword = !showPassword }) {
Icon(
imageVector = if (showPassword) Icons.Outlined.VisibilityOff else Icons.Outlined.Visibility,
contentDescription =
if (showPassword) {
stringResource(R.string.show_password)
} else {
stringResource(R.string.hide_password)
},
contentDescription = if (showPassword) {
stringResource(R.string.show_password)
} else {
stringResource(R.string.hide_password)
},
)
}
}
@@ -189,8 +184,93 @@ fun LoginPage(accountViewModel: AccountStateViewModel) {
}
},
visualTransformation = if (showPassword) VisualTransformation.None else PasswordVisualTransformation(),
keyboardActions =
KeyboardActions(
keyboardActions = KeyboardActions(
onGo = {
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())) {
try {
accountViewModel.startUI(
key.value.text,
password.value.text,
null,
useProxy = useProxy.value,
proxyPort = proxyPort.value.toInt(),
)
} catch (e: Exception) {
Log.e("Login", "Could not sign in", e)
errorMessage = context.getString(R.string.invalid_key)
}
}
},
),
)
if (errorMessage.isNotBlank()) {
Text(
text = errorMessage,
color = MaterialTheme.colorScheme.error,
style = MaterialTheme.typography.bodySmall,
)
}
Spacer(modifier = Modifier.height(20.dp))
if (needsPassword.value) {
OutlinedTextField(
modifier = Modifier
.onGloballyPositioned { coordinates ->
autofillNodePassword.boundingBox = coordinates.boundsInWindow()
}
.onFocusChanged { focusState ->
autofill?.run {
if (focusState.isFocused) {
requestAutofillForNode(autofillNodePassword)
} else {
cancelAutofillForNode(autofillNodePassword)
}
}
},
value = password.value,
onValueChange = {
password.value = it
if (errorMessage.isNotEmpty()) {
errorMessage = ""
}
},
keyboardOptions = KeyboardOptions(
autoCorrect = false,
keyboardType = KeyboardType.Password,
imeAction = ImeAction.Go,
),
placeholder = {
Text(
text = stringResource(R.string.ncryptsec_password),
)
},
trailingIcon = {
Row {
IconButton(onClick = { showCharsPassword = !showCharsPassword }) {
Icon(
imageVector = if (showCharsPassword) Icons.Outlined.VisibilityOff else Icons.Outlined.Visibility,
contentDescription = if (showCharsPassword) {
stringResource(R.string.show_password)
} else {
stringResource(
R.string.hide_password,
)
},
)
}
}
},
visualTransformation = if (showCharsPassword) VisualTransformation.None else PasswordVisualTransformation(),
keyboardActions = KeyboardActions(
onGo = {
if (key.value.text.isBlank()) {
errorMessage = context.getString(R.string.key_is_required)
@@ -216,98 +296,6 @@ fun LoginPage(accountViewModel: AccountStateViewModel) {
}
},
),
)
if (errorMessage.isNotBlank()) {
Text(
text = errorMessage,
color = MaterialTheme.colorScheme.error,
style = MaterialTheme.typography.bodySmall,
)
}
Spacer(modifier = Modifier.height(20.dp))
if (needsPassword.value) {
OutlinedTextField(
modifier =
Modifier
.onGloballyPositioned { coordinates ->
autofillNodePassword.boundingBox = coordinates.boundsInWindow()
}
.onFocusChanged { focusState ->
autofill?.run {
if (focusState.isFocused) {
requestAutofillForNode(autofillNodePassword)
} else {
cancelAutofillForNode(autofillNodePassword)
}
}
},
value = password.value,
onValueChange = {
password.value = it
if (errorMessage.isNotEmpty()) {
errorMessage = ""
}
},
keyboardOptions =
KeyboardOptions(
autoCorrect = false,
keyboardType = KeyboardType.Password,
imeAction = ImeAction.Go,
),
placeholder = {
Text(
text = stringResource(R.string.ncryptsec_password),
)
},
trailingIcon = {
Row {
IconButton(onClick = { showCharsPassword = !showCharsPassword }) {
Icon(
imageVector =
if (showCharsPassword) Icons.Outlined.VisibilityOff else Icons.Outlined.Visibility,
contentDescription =
if (showCharsPassword) {
stringResource(R.string.show_password)
} else {
stringResource(
R.string.hide_password,
)
},
)
}
}
},
visualTransformation =
if (showCharsPassword) VisualTransformation.None else PasswordVisualTransformation(),
keyboardActions =
KeyboardActions(
onGo = {
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())) {
try {
accountViewModel.startUI(
key.value.text,
password.value.text,
null,
useProxy = useProxy.value,
proxyPort = proxyPort.value.toInt(),
)
} catch (e: Exception) {
Log.e("Login", "Could not sign in", e)
errorMessage = context.getString(R.string.invalid_key)
}
}
},
),
)
}
@@ -381,10 +369,9 @@ fun LoginPage(accountViewModel: AccountStateViewModel) {
}
},
shape = RoundedCornerShape(Size35dp),
modifier =
Modifier
.fillMaxWidth()
.height(50.dp),
modifier = Modifier
.fillMaxWidth()
.height(50.dp),
) {
Text(text = stringResource(R.string.login))
}
@@ -393,10 +380,9 @@ fun LoginPage(accountViewModel: AccountStateViewModel) {
Spacer(modifier = Modifier.height(10.dp))
TextButton(
modifier =
Modifier
.padding(30.dp)
.fillMaxWidth(),
modifier = Modifier
.padding(30.dp)
.fillMaxWidth(),
onClick = {
accountViewModel.newKey(useProxy.value, proxyPort.value.toInt())
},
@@ -107,14 +107,14 @@ import com.greenart7c3.nostrsigner.ui.navigation.Route
import com.greenart7c3.nostrsigner.ui.theme.ButtonBorder
import com.vitorpamplona.quartz.encoders.toHexKey
import com.vitorpamplona.quartz.encoders.toNpub
import kotlinx.coroutines.DelicateCoroutinesApi
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import java.io.ByteArrayOutputStream
import java.util.Base64
import java.util.UUID
import java.util.zip.GZIPOutputStream
import kotlinx.coroutines.DelicateCoroutinesApi
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
@OptIn(DelicateCoroutinesApi::class)
fun sendResult(
@@ -179,19 +179,18 @@ fun sendResult(
val application =
savedApplication ?: ApplicationWithPermissions(
application =
ApplicationEntity(
key,
appName ?: localAppName ?: "",
relays,
"",
"",
"",
account.keyPair.pubKey.toHexKey(),
true,
intentData.bunkerRequest?.secret ?: "",
intentData.bunkerRequest?.secret != null,
),
application = ApplicationEntity(
key,
appName ?: localAppName ?: "",
relays,
"",
"",
"",
account.keyPair.pubKey.toHexKey(),
true,
intentData.bunkerRequest?.secret ?: "",
intentData.bunkerRequest?.secret != null,
),
permissions = mutableListOf(),
)
application.application.isConnected = true
@@ -436,11 +435,10 @@ fun PermissionsFloatingActionButton(
val rotation by animateFloatAsState(
targetValue = if (expanded) 0f else 180f,
animationSpec =
tween(
durationMillis = 150,
easing = LinearEasing,
),
animationSpec = tween(
durationMillis = 150,
easing = LinearEasing,
),
label = "rotation",
)
@@ -732,10 +730,9 @@ fun MainScreen(
Route.Permissions.route,
content = {
PermissionsScreen(
modifier =
Modifier
.fillMaxSize()
.padding(padding),
modifier = Modifier
.fillMaxSize()
.padding(padding),
account = account,
accountStateViewModel = accountStateViewModel,
navController = navController,
@@ -763,9 +760,9 @@ fun MainScreen(
content = {
EditPermission(
modifier =
Modifier
.fillMaxSize()
.padding(padding),
Modifier
.fillMaxSize()
.padding(padding),
account = account,
accountStateViewModel = accountStateViewModel,
selectedPackage = it.arguments?.getString("packageName")!!,
@@ -40,11 +40,10 @@ fun QrCodeDrawer(
val foregroundColor = Color.Black
Box(
modifier =
modifier
.defaultMinSize(48.dp, 48.dp)
.aspectRatio(1f)
.background(Color.White),
modifier = modifier
.defaultMinSize(48.dp, 48.dp)
.aspectRatio(1f)
.background(Color.White),
) {
Canvas(modifier = Modifier.fillMaxSize()) {
// Calculate the height and width of each column/row
@@ -55,22 +54,20 @@ fun QrCodeDrawer(
// of the number of rows/columns to the width and height
drawQrCodeFinders(
sideLength = size.width,
finderPatternSize =
Size(
width = columnWidth * FINDER_PATTERN_ROW_COUNT,
height = rowHeight * FINDER_PATTERN_ROW_COUNT,
),
finderPatternSize = Size(
width = columnWidth * FINDER_PATTERN_ROW_COUNT,
height = rowHeight * FINDER_PATTERN_ROW_COUNT,
),
color = foregroundColor,
)
// Draw data bits (encoded data part)
drawAllQrCodeDataBits(
bytes = qrCode.matrix,
size =
Size(
width = columnWidth,
height = rowHeight,
),
size = Size(
width = columnWidth,
height = rowHeight,
),
color = foregroundColor,
)
}
@@ -108,33 +105,29 @@ fun DrawScope.drawAllQrCodeDataBits(
// data bits between top left finder pattern and top right finder pattern.
Pair(
first = Coordinate(first = FINDER_PATTERN_ROW_COUNT, second = 0),
second =
Coordinate(
first = (bytes.width - FINDER_PATTERN_ROW_COUNT),
second = FINDER_PATTERN_ROW_COUNT,
),
second = Coordinate(
first = (bytes.width - FINDER_PATTERN_ROW_COUNT),
second = FINDER_PATTERN_ROW_COUNT,
),
),
// data bits below top left finder pattern and above bottom left finder pattern.
Pair(
first = Coordinate(first = 0, second = FINDER_PATTERN_ROW_COUNT),
second =
Coordinate(
first = bytes.width,
second = bytes.height - FINDER_PATTERN_ROW_COUNT,
),
second = Coordinate(
first = bytes.width,
second = bytes.height - FINDER_PATTERN_ROW_COUNT,
),
),
// data bits to the right of the bottom left finder pattern.
Pair(
first =
Coordinate(
first = FINDER_PATTERN_ROW_COUNT,
second = (bytes.height - FINDER_PATTERN_ROW_COUNT),
),
second =
Coordinate(
first = bytes.width,
second = bytes.height,
),
first = Coordinate(
first = FINDER_PATTERN_ROW_COUNT,
second = (bytes.height - FINDER_PATTERN_ROW_COUNT),
),
second = Coordinate(
first = bytes.width,
second = bytes.height,
),
),
).forEach { section ->
for (y in section.first.second until section.second.second) {
@@ -142,20 +135,19 @@ fun DrawScope.drawAllQrCodeDataBits(
if (bytes[x, y] == 1.toByte()) {
drawPath(
color = color,
path =
newPath {
addRect(
rect =
Rect(
offset =
Offset(
x = QR_MARGIN_PX + x * size.width,
y = QR_MARGIN_PX + y * size.height,
),
size = size,
),
)
},
path = newPath {
addRect(
rect =
Rect(
offset =
Offset(
x = QR_MARGIN_PX + x * size.width,
y = QR_MARGIN_PX + y * size.height,
),
size = size,
),
)
},
)
}
}
@@ -210,56 +202,55 @@ private fun DrawScope.drawQrCodeFinder(
) {
drawPath(
color = color,
path =
newPath {
// Draw the outer rectangle for the finder pattern.
addRoundRect(
roundRect =
RoundRect(
rect =
Rect(
offset = topLeft,
size = finderPatternSize,
),
cornerRadius = cornerRadius,
),
)
path = newPath {
// Draw the outer rectangle for the finder pattern.
addRoundRect(
roundRect =
RoundRect(
rect =
Rect(
offset = topLeft,
size = finderPatternSize,
),
cornerRadius = cornerRadius,
),
)
// Draw background for the finder pattern interior (this keeps the arc ratio consistent).
val innerBackgroundOffset =
Offset(
x = finderPatternSize.width * INTERIOR_BACKGROUND_EXTERIOR_OFFSET_RATIO,
y = finderPatternSize.height * INTERIOR_BACKGROUND_EXTERIOR_OFFSET_RATIO,
)
addRoundRect(
roundRect =
RoundRect(
rect =
Rect(
offset = topLeft + innerBackgroundOffset,
size = finderPatternSize * INTERIOR_BACKGROUND_EXTERIOR_SHAPE_RATIO,
),
cornerRadius = cornerRadius * INTERIOR_BACKGROUND_EXTERIOR_SHAPE_CORNER_RADIUS,
),
// Draw background for the finder pattern interior (this keeps the arc ratio consistent).
val innerBackgroundOffset =
Offset(
x = finderPatternSize.width * INTERIOR_BACKGROUND_EXTERIOR_OFFSET_RATIO,
y = finderPatternSize.height * INTERIOR_BACKGROUND_EXTERIOR_OFFSET_RATIO,
)
addRoundRect(
roundRect =
RoundRect(
rect =
Rect(
offset = topLeft + innerBackgroundOffset,
size = finderPatternSize * INTERIOR_BACKGROUND_EXTERIOR_SHAPE_RATIO,
),
cornerRadius = cornerRadius * INTERIOR_BACKGROUND_EXTERIOR_SHAPE_CORNER_RADIUS,
),
)
// Draw the inner rectangle for the finder pattern.
val innerRectOffset =
Offset(
x = finderPatternSize.width * INTERIOR_EXTERIOR_OFFSET_RATIO,
y = finderPatternSize.height * INTERIOR_EXTERIOR_OFFSET_RATIO,
)
addRoundRect(
roundRect =
RoundRect(
rect =
Rect(
offset = topLeft + innerRectOffset,
size = finderPatternSize * INTERIOR_EXTERIOR_SHAPE_RATIO,
),
cornerRadius = cornerRadius * INTERIOR_EXTERIOR_SHAPE_CORNER_RADIUS,
),
// Draw the inner rectangle for the finder pattern.
val innerRectOffset =
Offset(
x = finderPatternSize.width * INTERIOR_EXTERIOR_OFFSET_RATIO,
y = finderPatternSize.height * INTERIOR_EXTERIOR_OFFSET_RATIO,
)
},
addRoundRect(
roundRect =
RoundRect(
rect =
Rect(
offset = topLeft + innerRectOffset,
size = finderPatternSize * INTERIOR_EXTERIOR_SHAPE_RATIO,
),
cornerRadius = cornerRadius * INTERIOR_EXTERIOR_SHAPE_CORNER_RADIUS,
),
)
},
)
}
@@ -70,6 +70,7 @@ import com.greenart7c3.nostrsigner.ui.components.PostButton
import com.greenart7c3.nostrsigner.ui.components.TextSpinner
import com.greenart7c3.nostrsigner.ui.components.TitleExplainer
import com.vitorpamplona.quartz.encoders.toNpub
import java.io.IOException
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.ImmutableMap
import kotlinx.collections.immutable.persistentListOf
@@ -79,7 +80,6 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import org.xmlpull.v1.XmlPullParser
import org.xmlpull.v1.XmlPullParserException
import java.io.IOException
fun Context.getLocaleListFromXml(): LocaleListCompat {
val tagsList = mutableListOf<CharSequence>()
@@ -377,12 +377,11 @@ fun SettingsScreen(
.padding(16.dp),
) {
IconRow(
title =
if (checked) {
stringResource(R.string.disconnect_from_your_orbot_setup)
} else {
stringResource(R.string.connect_via_tor_short)
},
title = if (checked) {
stringResource(R.string.disconnect_from_your_orbot_setup)
} else {
stringResource(R.string.connect_via_tor_short)
},
icon = R.drawable.ic_tor,
tint = MaterialTheme.colorScheme.onBackground,
onLongClick = {
@@ -408,16 +407,14 @@ fun SettingsScreen(
fullText = "v${BuildConfig.VERSION_NAME}\n\n${context.getString(
R.string.support_development,
)}\n\n${context.getString(R.string.source_code)}",
hyperLinks =
mutableMapOf(
stringResource(R.string.source_code) to stringResource(R.string.amber_github_uri),
stringResource(R.string.support_development) to stringResource(R.string.support_development_uri),
),
textStyle =
TextStyle(
textAlign = TextAlign.Center,
color = MaterialTheme.colorScheme.inverseSurface,
),
hyperLinks = mutableMapOf(
stringResource(R.string.source_code) to stringResource(R.string.amber_github_uri),
stringResource(R.string.support_development) to stringResource(R.string.support_development_uri),
),
textStyle = TextStyle(
textAlign = TextAlign.Center,
color = MaterialTheme.colorScheme.inverseSurface,
),
linkTextColor = MaterialTheme.colorScheme.primary,
linkTextDecoration = TextDecoration.Underline,
fontSize = 18.sp,
@@ -512,10 +509,9 @@ fun SettingsRow(
placeholder = selectedItems[selectedIndex].title,
options = selectedItems,
onSelect = onSelect,
modifier =
Modifier
.windowInsetsPadding(WindowInsets(0.dp, 0.dp, 0.dp, 0.dp))
.weight(1f),
modifier = Modifier
.windowInsetsPadding(WindowInsets(0.dp, 0.dp, 0.dp, 0.dp))
.weight(1f),
)
}
}
@@ -93,20 +93,20 @@ fun AccountBackupDialog(
) {
Surface(
modifier =
Modifier
.fillMaxSize(),
Modifier
.fillMaxSize(),
) {
Column(
modifier =
Modifier
.background(MaterialTheme.colorScheme.background)
.fillMaxSize(),
Modifier
.background(MaterialTheme.colorScheme.background)
.fillMaxSize(),
) {
Row(
modifier =
Modifier
.fillMaxWidth()
.padding(10.dp),
Modifier
.fillMaxWidth()
.padding(10.dp),
horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically,
) {
@@ -115,9 +115,9 @@ fun AccountBackupDialog(
Column(
modifier =
Modifier
.padding(horizontal = 30.dp)
.verticalScroll(rememberScrollState()),
Modifier
.padding(horizontal = 30.dp)
.verticalScroll(rememberScrollState()),
horizontalAlignment = Alignment.CenterHorizontally,
) {
val content = stringResource(R.string.account_backup_tips_md)
@@ -168,20 +168,19 @@ fun AccountBackupDialog(
LocalAutofillTree.current += autofillNode
OutlinedTextField(
modifier =
Modifier
.onGloballyPositioned { coordinates ->
autofillNode.boundingBox = coordinates.boundsInWindow()
}
.onFocusChanged { focusState ->
autofill?.run {
if (focusState.isFocused) {
requestAutofillForNode(autofillNode)
} else {
cancelAutofillForNode(autofillNode)
}
modifier = Modifier
.onGloballyPositioned { coordinates ->
autofillNode.boundingBox = coordinates.boundsInWindow()
}
.onFocusChanged { focusState ->
autofill?.run {
if (focusState.isFocused) {
requestAutofillForNode(autofillNode)
} else {
cancelAutofillForNode(autofillNode)
}
},
}
},
value = password.value,
onValueChange = {
password.value = it
@@ -189,12 +188,11 @@ fun AccountBackupDialog(
errorMessage = ""
}
},
keyboardOptions =
KeyboardOptions(
autoCorrect = false,
keyboardType = KeyboardType.Password,
imeAction = ImeAction.Go,
),
keyboardOptions = KeyboardOptions(
autoCorrect = false,
keyboardType = KeyboardType.Password,
imeAction = ImeAction.Go,
),
placeholder = {
Text(
text = stringResource(R.string.ncryptsec_password),
@@ -204,22 +202,19 @@ fun AccountBackupDialog(
Row {
IconButton(onClick = { showCharsPassword = !showCharsPassword }) {
Icon(
imageVector =
if (showCharsPassword) Icons.Outlined.VisibilityOff else Icons.Outlined.Visibility,
contentDescription =
if (showCharsPassword) {
stringResource(R.string.show_password)
} else {
stringResource(
R.string.hide_password,
)
},
imageVector = if (showCharsPassword) Icons.Outlined.VisibilityOff else Icons.Outlined.Visibility,
contentDescription = if (showCharsPassword) {
stringResource(R.string.show_password)
} else {
stringResource(
R.string.hide_password,
)
},
)
}
}
},
visualTransformation =
if (showCharsPassword) VisualTransformation.None else PasswordVisualTransformation(),
visualTransformation = if (showCharsPassword) VisualTransformation.None else PasswordVisualTransformation(),
)
if (errorMessage.isNotBlank()) {
@@ -311,16 +306,14 @@ fun QrCodeDialog(
) {
Surface(modifier = Modifier.fillMaxSize()) {
Column(
modifier =
Modifier
.background(MaterialTheme.colorScheme.background)
.fillMaxSize(),
modifier = Modifier
.background(MaterialTheme.colorScheme.background)
.fillMaxSize(),
) {
Row(
modifier =
Modifier
.fillMaxWidth()
.padding(10.dp),
modifier = Modifier
.fillMaxWidth()
.padding(10.dp),
horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically,
) {
@@ -328,19 +321,17 @@ fun QrCodeDialog(
}
Column(
modifier =
Modifier
.fillMaxSize()
.padding(horizontal = 30.dp),
modifier = Modifier
.fillMaxSize()
.padding(horizontal = 30.dp),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center,
) {
Row(
horizontalArrangement = Arrangement.Center,
modifier =
Modifier
.fillMaxWidth()
.padding(horizontal = Size35dp),
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = Size35dp),
) {
QrCodeDrawer(content)
}
@@ -452,18 +443,16 @@ private fun EncryptNSecCopyButton(
)
},
shape = ButtonBorder,
colors =
ButtonDefaults.buttonColors(
containerColor = MaterialTheme.colorScheme.primary,
),
colors = ButtonDefaults.buttonColors(
containerColor = MaterialTheme.colorScheme.primary,
),
contentPadding = PaddingValues(vertical = 6.dp, horizontal = 16.dp),
enabled = password.value.text.isNotBlank(),
) {
Icon(
tint = MaterialTheme.colorScheme.onPrimary,
imageVector = Icons.Default.Key,
contentDescription =
stringResource(R.string.copies_the_nsec_id_your_password_to_the_clipboard_for_backup),
contentDescription = stringResource(R.string.copies_the_nsec_id_your_password_to_the_clipboard_for_backup),
modifier = Modifier.padding(end = 5.dp),
)
Text(
@@ -521,18 +510,16 @@ private fun EncryptNSecQRButton(
)
},
shape = ButtonBorder,
colors =
ButtonDefaults.buttonColors(
containerColor = MaterialTheme.colorScheme.primary,
),
colors = ButtonDefaults.buttonColors(
containerColor = MaterialTheme.colorScheme.primary,
),
contentPadding = PaddingValues(vertical = 6.dp, horizontal = 16.dp),
enabled = password.value.text.isNotBlank(),
) {
Icon(
tint = MaterialTheme.colorScheme.onPrimary,
imageVector = Icons.Default.QrCode,
contentDescription =
stringResource(R.string.shows_qr_code_with_you_private_key),
contentDescription = stringResource(R.string.shows_qr_code_with_you_private_key),
modifier = Modifier.padding(end = 5.dp),
)
Text(
@@ -76,10 +76,9 @@ fun AccountsBottomSheet(
Column(modifier = Modifier.verticalScroll(scrollState)) {
Row(
modifier =
Modifier
.fillMaxWidth()
.padding(16.dp),
modifier = Modifier
.fillMaxWidth()
.padding(16.dp),
horizontalArrangement = Arrangement.Center,
verticalAlignment = Alignment.CenterVertically,
) {
@@ -88,13 +87,12 @@ fun AccountsBottomSheet(
accounts.forEach { acc ->
val name = LocalPreferences.getAccountName(acc.npub)
Row(
modifier =
Modifier
.fillMaxWidth()
.clickable {
accountStateViewModel.switchUser(acc.npub, null)
}
.padding(16.dp, 16.dp),
modifier = Modifier
.fillMaxWidth()
.clickable {
accountStateViewModel.switchUser(acc.npub, null)
}
.padding(16.dp, 16.dp),
verticalAlignment = Alignment.CenterVertically,
) {
Row(
@@ -146,10 +144,9 @@ fun AccountsBottomSheet(
}
}
Row(
modifier =
Modifier
.fillMaxWidth()
.padding(16.dp),
modifier = Modifier
.fillMaxWidth()
.padding(16.dp),
horizontalArrangement = Arrangement.Center,
verticalAlignment = Alignment.CenterVertically,
) {
@@ -202,17 +199,15 @@ fun EditAccountDialog(
) {
Surface {
Column(
modifier =
Modifier
.background(MaterialTheme.colorScheme.background)
.fillMaxWidth()
.padding(8.dp),
modifier = Modifier
.background(MaterialTheme.colorScheme.background)
.fillMaxWidth()
.padding(8.dp),
) {
Row(
modifier =
Modifier
.fillMaxWidth()
.padding(10.dp),
modifier = Modifier
.fillMaxWidth()
.padding(10.dp),
horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically,
) {
@@ -230,9 +225,8 @@ fun EditAccountDialog(
}
Column(
modifier =
Modifier
.padding(horizontal = 30.dp),
modifier = Modifier
.padding(horizontal = 30.dp),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center,
) {
@@ -47,16 +47,14 @@ fun AdjustPermissionsDialog(
) {
Surface(modifier = Modifier.fillMaxSize()) {
Column(
modifier =
Modifier
.background(MaterialTheme.colorScheme.background)
.fillMaxSize(),
modifier = Modifier
.background(MaterialTheme.colorScheme.background)
.fillMaxSize(),
) {
Row(
modifier =
Modifier
.fillMaxWidth()
.padding(10.dp),
modifier = Modifier
.fillMaxWidth()
.padding(10.dp),
horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically,
) {
@@ -75,16 +73,15 @@ fun AdjustPermissionsDialog(
Row(
horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically,
modifier =
Modifier
.padding(horizontal = 8.dp)
.clickable {
selectAll = !selectAll
dialogPermissions =
dialogPermissions.map { item ->
item.copy(checked = selectAll)
}
},
modifier = Modifier
.padding(horizontal = 8.dp)
.clickable {
selectAll = !selectAll
dialogPermissions =
dialogPermissions.map { item ->
item.copy(checked = selectAll)
}
},
) {
Text(
modifier = Modifier.weight(1f),
@@ -110,18 +107,17 @@ fun AdjustPermissionsDialog(
Row(
horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically,
modifier =
Modifier
.clickable {
dialogPermissions =
dialogPermissions.mapIndexed { j, item ->
if (it == j) {
item.copy(checked = !item.checked)
} else {
item
}
modifier = Modifier
.clickable {
dialogPermissions =
dialogPermissions.mapIndexed { j, item ->
if (it == j) {
item.copy(checked = !item.checked)
} else {
item
}
},
}
},
) {
Text(
modifier = Modifier.weight(1f),
@@ -107,14 +107,13 @@ fun ConnectOrbotDialog(
) {
val myMarkDownStyle =
RichTextDefaults.copy(
stringStyle =
RichTextDefaults.stringStyle?.copy(
linkStyle =
SpanStyle(
textDecoration = TextDecoration.Underline,
color = MaterialTheme.colorScheme.primary,
),
stringStyle = RichTextDefaults.stringStyle?.copy(
linkStyle =
SpanStyle(
textDecoration = TextDecoration.Underline,
color = MaterialTheme.colorScheme.primary,
),
),
)
Row {
@@ -142,11 +141,10 @@ fun ConnectOrbotDialog(
OutlinedTextField(
value = portNumber.value,
onValueChange = { portNumber.value = it },
keyboardOptions =
KeyboardOptions.Default.copy(
capitalization = KeyboardCapitalization.None,
keyboardType = KeyboardType.Number,
),
keyboardOptions = KeyboardOptions.Default.copy(
capitalization = KeyboardCapitalization.None,
keyboardType = KeyboardType.Number,
),
label = { Text(text = stringResource(R.string.orbot_socks_port)) },
placeholder = {
Text(
@@ -175,10 +173,9 @@ fun UseOrbotButton(
}
},
shape = ButtonBorder,
colors =
ButtonDefaults.buttonColors(
containerColor = if (isActive) MaterialTheme.colorScheme.primary else Color.Gray,
),
colors = ButtonDefaults.buttonColors(
containerColor = if (isActive) MaterialTheme.colorScheme.primary else Color.Gray,
),
) {
Text(text = stringResource(R.string.use_orbot), color = Color.White)
}
@@ -18,10 +18,9 @@ fun LogoutDialog(
},
text = {
Text(
text =
stringResource(
R.string.logging_out_deletes_all_your_local_information_make_sure_to_have_your_private_keys_backed_up_to_avoid_losing_your_account_do_you_want_to_continue,
),
text = stringResource(
R.string.logging_out_deletes_all_your_local_information_make_sure_to_have_your_private_keys_backed_up_to_avoid_losing_your_account_do_you_want_to_continue,
),
)
},
onDismissRequest = {
@@ -31,10 +31,9 @@ fun AcceptRejectButtons(
Button(
shape = ButtonBorder,
onClick = onReject,
colors =
ButtonDefaults.buttonColors(
containerColor = Color(0xFF5A5554),
),
colors = ButtonDefaults.buttonColors(
containerColor = Color(0xFF5A5554),
),
) {
Text(stringResource(R.string.reject))
}
@@ -77,9 +77,8 @@ fun EncryptDecryptData(
Spacer(Modifier.size(4.dp))
if (!type.toString().contains("DECRYPT")) {
Card(
modifier =
Modifier
.fillMaxWidth(),
modifier = Modifier
.fillMaxWidth(),
) {
Column(Modifier.padding(6.dp)) {
Text(
@@ -91,10 +90,9 @@ fun EncryptDecryptData(
content,
maxLines = 1,
overflow = TextOverflow.Ellipsis,
modifier =
Modifier
.fillMaxWidth()
.padding(top = 8.dp),
modifier = Modifier
.fillMaxWidth()
.padding(top = 8.dp),
)
}
}
@@ -66,9 +66,8 @@ fun EventData(
val content = if (event.kind == 22242) AmberEvent.relay(event) else event.content
if (content.isNotBlank()) {
Card(
modifier =
Modifier
.fillMaxWidth(),
modifier = Modifier
.fillMaxWidth(),
) {
Column(Modifier.padding(16.dp)) {
Text(
@@ -79,10 +78,9 @@ fun EventData(
content,
maxLines = 1,
overflow = TextOverflow.Ellipsis,
modifier =
Modifier
.fillMaxWidth()
.padding(top = 8.dp),
modifier = Modifier
.fillMaxWidth()
.padding(top = 8.dp),
)
}
}
@@ -30,13 +30,12 @@ fun HyperlinkText(
val startIndex = fullText.indexOf(key)
val endIndex = startIndex + key.length
addStyle(
style =
SpanStyle(
color = linkTextColor,
fontSize = fontSize,
fontWeight = linkTextFontWeight,
textDecoration = linkTextDecoration,
),
style = SpanStyle(
color = linkTextColor,
fontSize = fontSize,
fontWeight = linkTextFontWeight,
textDecoration = linkTextDecoration,
),
start = startIndex,
end = endIndex,
)
@@ -48,10 +47,9 @@ fun HyperlinkText(
)
}
addStyle(
style =
SpanStyle(
fontSize = fontSize,
),
style = SpanStyle(
fontSize = fontSize,
),
start = 0,
end = fullText.length,
)
@@ -28,19 +28,17 @@ fun IconRow(
onLongClick: (() -> Unit)? = null,
) {
Row(
modifier =
Modifier
.fillMaxWidth()
.combinedClickable(
onClick = onClick,
onLongClick = onLongClick,
),
modifier = Modifier
.fillMaxWidth()
.combinedClickable(
onClick = onClick,
onLongClick = onLongClick,
),
) {
Row(
modifier =
Modifier
.fillMaxWidth()
.padding(vertical = 15.dp, horizontal = 25.dp),
modifier = Modifier
.fillMaxWidth()
.padding(vertical = 15.dp, horizontal = 25.dp),
verticalAlignment = Alignment.CenterVertically,
) {
Icon(
@@ -70,19 +68,17 @@ fun IconRow(
onLongClick: (() -> Unit)? = null,
) {
Row(
modifier =
Modifier
.fillMaxWidth()
.combinedClickable(
onClick = onClick,
onLongClick = onLongClick,
),
modifier = Modifier
.fillMaxWidth()
.combinedClickable(
onClick = onClick,
onLongClick = onLongClick,
),
) {
Row(
modifier =
Modifier
.fillMaxWidth()
.padding(vertical = 15.dp, horizontal = 25.dp),
modifier = Modifier
.fillMaxWidth()
.padding(vertical = 15.dp, horizontal = 25.dp),
verticalAlignment = Alignment.CenterVertically,
) {
Icon(
@@ -141,9 +141,8 @@ fun LoginWithPubKey(
onClick = {
showAdjustDialog = true
},
modifier =
Modifier
.padding(8.dp),
modifier = Modifier
.padding(8.dp),
) {
Text(text = stringResource(R.string.adjust))
}
@@ -151,10 +150,9 @@ fun LoginWithPubKey(
}
Button(
modifier =
Modifier
.fillMaxWidth(0.8f)
.padding(8.dp),
modifier = Modifier
.fillMaxWidth(0.8f)
.padding(8.dp),
shape = ButtonBorder,
onClick = {
onAccept(localPermissions)
@@ -165,14 +163,13 @@ fun LoginWithPubKey(
Spacer(modifier = Modifier.width(8.dp))
Button(
modifier =
Modifier
.padding(8.dp),
Modifier
.padding(8.dp),
shape = ButtonBorder,
onClick = onReject,
colors =
ButtonDefaults.buttonColors(
containerColor = Color(0xFF5A5554),
),
colors = ButtonDefaults.buttonColors(
containerColor = Color(0xFF5A5554),
),
) {
Text(stringResource(R.string.reject))
}
@@ -83,12 +83,11 @@ fun SelectAllButton(
Row(
horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically,
modifier =
Modifier
.padding(horizontal = 8.dp)
.clickable {
onSelected()
},
modifier = Modifier
.padding(horizontal = 8.dp)
.clickable {
onSelected()
},
) {
Text(
modifier = Modifier.weight(1f),
@@ -188,19 +187,18 @@ fun MultiEventHomeScreen(
database
.applicationDao()
.getByKey(key) ?: ApplicationWithPermissions(
application =
ApplicationEntity(
key,
applicationEntity?.application?.name?.ifBlank { applicationEntity.application.key.toShortenHex() } ?: "",
listOf(),
"",
"",
"",
localAccount.keyPair.pubKey.toHexKey(),
true,
intentData.bunkerRequest?.secret ?: "",
intentData.bunkerRequest?.secret != null,
),
application = ApplicationEntity(
key,
applicationEntity?.application?.name?.ifBlank { applicationEntity.application.key.toShortenHex() } ?: "",
listOf(),
"",
"",
"",
localAccount.keyPair.pubKey.toHexKey(),
true,
intentData.bunkerRequest?.secret ?: "",
intentData.bunkerRequest?.secret != null,
),
permissions = mutableListOf(),
)
@@ -260,19 +258,18 @@ fun MultiEventHomeScreen(
database
.applicationDao()
.getByKey(key) ?: ApplicationWithPermissions(
application =
ApplicationEntity(
key,
applicationEntity?.application?.name?.ifBlank { applicationEntity.application.key.toShortenHex() } ?: "",
listOf(),
"",
"",
"",
localAccount.keyPair.pubKey.toHexKey(),
true,
intentData.bunkerRequest?.secret ?: "",
intentData.bunkerRequest?.secret != null,
),
application = ApplicationEntity(
key,
applicationEntity?.application?.name?.ifBlank { applicationEntity.application.key.toShortenHex() } ?: "",
listOf(),
"",
"",
"",
localAccount.keyPair.pubKey.toHexKey(),
true,
intentData.bunkerRequest?.secret ?: "",
intentData.bunkerRequest?.secret != null,
),
permissions = mutableListOf(),
)
@@ -408,10 +405,9 @@ fun ListItem(
Row(
verticalAlignment = Alignment.CenterVertically,
modifier =
Modifier
.fillMaxWidth()
.padding(4.dp),
modifier = Modifier
.fillMaxWidth()
.padding(4.dp),
) {
Icon(
Icons.Default.run {
@@ -436,13 +432,12 @@ fun ListItem(
}
Text(
modifier = Modifier.weight(1f),
text =
buildAnnotatedString {
withStyle(style = SpanStyle(fontWeight = FontWeight.Bold)) {
append(appName)
}
append(" $text")
},
text = buildAnnotatedString {
withStyle(style = SpanStyle(fontWeight = FontWeight.Bold)) {
append(appName)
}
append(" $text")
},
fontSize = 18.sp,
)
@@ -476,10 +471,9 @@ fun ListItem(
content,
maxLines = 1,
overflow = TextOverflow.Ellipsis,
modifier =
Modifier
.fillMaxWidth()
.padding(top = 8.dp),
modifier = Modifier
.fillMaxWidth()
.padding(top = 8.dp),
)
RememberMyChoice(
shouldRunOnAccept = false,
@@ -41,9 +41,8 @@ fun RawJson(
}
OutlinedTextField(
modifier =
modifier
.fillMaxWidth(),
modifier = modifier
.fillMaxWidth(),
value = TextFieldValue(currentContent),
onValueChange = { },
readOnly = true,
@@ -29,11 +29,10 @@ fun RememberMyChoice(
Row(
horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically,
modifier =
Modifier
.clickable {
onChanged()
},
modifier = Modifier
.clickable {
onChanged()
},
) {
Text(
modifier = Modifier.weight(1f),
@@ -142,19 +142,18 @@ fun SingleEventHomeScreen(
val relays = intentData.bunkerRequest?.relays ?: listOf()
val application =
savedApplication ?: ApplicationWithPermissions(
application =
ApplicationEntity(
key,
appName,
relays,
"",
"",
"",
account.keyPair.pubKey.toHexKey(),
true,
intentData.bunkerRequest?.secret ?: "",
intentData.bunkerRequest?.secret != null,
),
application = ApplicationEntity(
key,
appName,
relays,
"",
"",
"",
account.keyPair.pubKey.toHexKey(),
true,
intentData.bunkerRequest?.secret ?: "",
intentData.bunkerRequest?.secret != null,
),
permissions = mutableListOf(),
)
@@ -264,19 +263,18 @@ fun SingleEventHomeScreen(
val relays = intentData.bunkerRequest?.relays ?: listOf()
val application =
savedApplication ?: ApplicationWithPermissions(
application =
ApplicationEntity(
key,
appName,
relays,
"",
"",
"",
account.keyPair.pubKey.toHexKey(),
true,
intentData.bunkerRequest?.secret ?: "",
intentData.bunkerRequest?.secret != null,
),
application = ApplicationEntity(
key,
appName,
relays,
"",
"",
"",
account.keyPair.pubKey.toHexKey(),
true,
intentData.bunkerRequest?.secret ?: "",
intentData.bunkerRequest?.secret != null,
),
permissions = mutableListOf(),
)
@@ -417,19 +415,18 @@ fun SingleEventHomeScreen(
val relays = intentData.bunkerRequest?.relays ?: listOf()
val application =
savedApplication ?: ApplicationWithPermissions(
application =
ApplicationEntity(
key,
appName,
relays,
"",
"",
"",
account.keyPair.pubKey.toHexKey(),
true,
intentData.bunkerRequest?.secret ?: "",
intentData.bunkerRequest?.secret != null,
),
application = ApplicationEntity(
key,
appName,
relays,
"",
"",
"",
account.keyPair.pubKey.toHexKey(),
true,
intentData.bunkerRequest?.secret ?: "",
intentData.bunkerRequest?.secret != null,
),
permissions = mutableListOf(),
)
@@ -102,14 +102,13 @@ fun TextSpinner(
remember { Modifier.fillMaxWidth().focusRequester(focusRequester) },
)
Box(
modifier =
Modifier.matchParentSize().clickable(
interactionSource = interactionSource,
indication = null,
) {
optionsShowing = true
focusRequester.requestFocus()
},
modifier = Modifier.matchParentSize().clickable(
interactionSource = interactionSource,
indication = null,
) {
optionsShowing = true
focusRequester.requestFocus()
},
)
}
@@ -9,10 +9,9 @@ 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,
),
bodyLarge = TextStyle(
fontFamily = FontFamily.Default,
fontWeight = FontWeight.Normal,
fontSize = 16.sp,
),
)
@@ -9,12 +9,12 @@ import com.greenart7c3.nostrsigner.LocalPreferences
import com.greenart7c3.nostrsigner.service.NotificationUtils.getOrCreateDMChannel
import com.vitorpamplona.quartz.events.Event
import com.vitorpamplona.quartz.events.GiftWrapEvent
import kotlin.time.measureTimedValue
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.cancel
import kotlinx.coroutines.launch
import kotlin.time.measureTimedValue
class Notifications : FirebaseMessagingService() {
private val scope = CoroutineScope(Dispatchers.IO + SupervisorJob())