diff --git a/.editorconfig b/.editorconfig index 5cb1e52c..63241c4a 100644 --- a/.editorconfig +++ b/.editorconfig @@ -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 \ No newline at end of file diff --git a/app/src/main/java/com/greenart7c3/nostrsigner/LocalPreferences.kt b/app/src/main/java/com/greenart7c3/nostrsigner/LocalPreferences.kt index d34a9de7..d49f80b6 100644 --- a/app/src/main/java/com/greenart7c3/nostrsigner/LocalPreferences.kt +++ b/app/src/main/java/com/greenart7c3/nostrsigner/LocalPreferences.kt @@ -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 diff --git a/app/src/main/java/com/greenart7c3/nostrsigner/models/BunkerRequest.kt b/app/src/main/java/com/greenart7c3/nostrsigner/models/BunkerRequest.kt index e39b28fb..c0509824 100644 --- a/app/src/main/java/com/greenart7c3/nostrsigner/models/BunkerRequest.kt +++ b/app/src/main/java/com/greenart7c3/nostrsigner/models/BunkerRequest.kt @@ -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() ?: "", ) diff --git a/app/src/main/java/com/greenart7c3/nostrsigner/relays/Client.kt b/app/src/main/java/com/greenart7c3/nostrsigner/relays/Client.kt index d7468997..1eeef4a8 100644 --- a/app/src/main/java/com/greenart7c3/nostrsigner/relays/Client.kt +++ b/app/src/main/java/com/greenart7c3/nostrsigner/relays/Client.kt @@ -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 diff --git a/app/src/main/java/com/greenart7c3/nostrsigner/relays/Relay.kt b/app/src/main/java/com/greenart7c3/nostrsigner/relays/Relay.kt index 73ebcaa8..ee594ef4 100644 --- a/app/src/main/java/com/greenart7c3/nostrsigner/relays/Relay.kt +++ b/app/src/main/java/com/greenart7c3/nostrsigner/relays/Relay.kt @@ -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, diff --git a/app/src/main/java/com/greenart7c3/nostrsigner/service/AmberUtils.kt b/app/src/main/java/com/greenart7c3/nostrsigner/service/AmberUtils.kt index 78994f60..6e363527 100644 --- a/app/src/main/java/com/greenart7c3/nostrsigner/service/AmberUtils.kt +++ b/app/src/main/java/com/greenart7c3/nostrsigner/service/AmberUtils.kt @@ -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(), ) diff --git a/app/src/main/java/com/greenart7c3/nostrsigner/service/BundledUpdate.kt b/app/src/main/java/com/greenart7c3/nostrsigner/service/BundledUpdate.kt index 80ac916e..232263ea 100644 --- a/app/src/main/java/com/greenart7c3/nostrsigner/service/BundledUpdate.kt +++ b/app/src/main/java/com/greenart7c3/nostrsigner/service/BundledUpdate.kt @@ -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 diff --git a/app/src/main/java/com/greenart7c3/nostrsigner/service/HttpClientManager.kt b/app/src/main/java/com/greenart7c3/nostrsigner/service/HttpClientManager.kt index 4a9f7f59..abefe4dd 100644 --- a/app/src/main/java/com/greenart7c3/nostrsigner/service/HttpClientManager.kt +++ b/app/src/main/java/com/greenart7c3/nostrsigner/service/HttpClientManager.kt @@ -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) diff --git a/app/src/main/java/com/greenart7c3/nostrsigner/service/IntentUtils.kt b/app/src/main/java/com/greenart7c3/nostrsigner/service/IntentUtils.kt index 2488286b..7b2e1bd2 100644 --- a/app/src/main/java/com/greenart7c3/nostrsigner/service/IntentUtils.kt +++ b/app/src/main/java/com/greenart7c3/nostrsigner/service/IntentUtils.kt @@ -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, diff --git a/app/src/main/java/com/greenart7c3/nostrsigner/service/NostrDataSource.kt b/app/src/main/java/com/greenart7c3/nostrsigner/service/NostrDataSource.kt index 97f9b1d5..b48c434d 100644 --- a/app/src/main/java/com/greenart7c3/nostrsigner/service/NostrDataSource.kt +++ b/app/src/main/java/com/greenart7c3/nostrsigner/service/NostrDataSource.kt @@ -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()) diff --git a/app/src/main/java/com/greenart7c3/nostrsigner/service/NotificationDataSource.kt b/app/src/main/java/com/greenart7c3/nostrsigner/service/NotificationDataSource.kt index caf005e9..971cb88e 100644 --- a/app/src/main/java/com/greenart7c3/nostrsigner/service/NotificationDataSource.kt +++ b/app/src/main/java/com/greenart7c3/nostrsigner/service/NotificationDataSource.kt @@ -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, + ), ) } diff --git a/app/src/main/java/com/greenart7c3/nostrsigner/service/model/AmberEvent.kt b/app/src/main/java/com/greenart7c3/nostrsigner/service/model/AmberEvent.kt index 727bc4cf..067b6ee2 100644 --- a/app/src/main/java/com/greenart7c3/nostrsigner/service/model/AmberEvent.kt +++ b/app/src/main/java/com/greenart7c3/nostrsigner/service/model/AmberEvent.kt @@ -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 ?: "", ) diff --git a/app/src/main/java/com/greenart7c3/nostrsigner/ui/EditPermission.kt b/app/src/main/java/com/greenart7c3/nostrsigner/ui/EditPermission.kt index 80778963..d7b65724 100644 --- a/app/src/main/java/com/greenart7c3/nostrsigner/ui/EditPermission.kt +++ b/app/src/main/java/com/greenart7c3/nostrsigner/ui/EditPermission.kt @@ -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, ) } diff --git a/app/src/main/java/com/greenart7c3/nostrsigner/ui/LoginScreen.kt b/app/src/main/java/com/greenart7c3/nostrsigner/ui/LoginScreen.kt index d659188d..1ad834af 100644 --- a/app/src/main/java/com/greenart7c3/nostrsigner/ui/LoginScreen.kt +++ b/app/src/main/java/com/greenart7c3/nostrsigner/ui/LoginScreen.kt @@ -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()) }, diff --git a/app/src/main/java/com/greenart7c3/nostrsigner/ui/MainScreen.kt b/app/src/main/java/com/greenart7c3/nostrsigner/ui/MainScreen.kt index 03a7b671..7fd21b49 100644 --- a/app/src/main/java/com/greenart7c3/nostrsigner/ui/MainScreen.kt +++ b/app/src/main/java/com/greenart7c3/nostrsigner/ui/MainScreen.kt @@ -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")!!, diff --git a/app/src/main/java/com/greenart7c3/nostrsigner/ui/QrCodeDrawer.kt b/app/src/main/java/com/greenart7c3/nostrsigner/ui/QrCodeDrawer.kt index fb58821e..8226a753 100644 --- a/app/src/main/java/com/greenart7c3/nostrsigner/ui/QrCodeDrawer.kt +++ b/app/src/main/java/com/greenart7c3/nostrsigner/ui/QrCodeDrawer.kt @@ -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, + ), + ) + }, ) } diff --git a/app/src/main/java/com/greenart7c3/nostrsigner/ui/SettingsScreen.kt b/app/src/main/java/com/greenart7c3/nostrsigner/ui/SettingsScreen.kt index d8586aed..5690cca1 100644 --- a/app/src/main/java/com/greenart7c3/nostrsigner/ui/SettingsScreen.kt +++ b/app/src/main/java/com/greenart7c3/nostrsigner/ui/SettingsScreen.kt @@ -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() @@ -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), ) } } diff --git a/app/src/main/java/com/greenart7c3/nostrsigner/ui/actions/AccountBackupDialog.kt b/app/src/main/java/com/greenart7c3/nostrsigner/ui/actions/AccountBackupDialog.kt index 138a4086..c637c0fe 100644 --- a/app/src/main/java/com/greenart7c3/nostrsigner/ui/actions/AccountBackupDialog.kt +++ b/app/src/main/java/com/greenart7c3/nostrsigner/ui/actions/AccountBackupDialog.kt @@ -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( diff --git a/app/src/main/java/com/greenart7c3/nostrsigner/ui/actions/AccountsBottomSheet.kt b/app/src/main/java/com/greenart7c3/nostrsigner/ui/actions/AccountsBottomSheet.kt index fd4f03da..fc80c9d3 100644 --- a/app/src/main/java/com/greenart7c3/nostrsigner/ui/actions/AccountsBottomSheet.kt +++ b/app/src/main/java/com/greenart7c3/nostrsigner/ui/actions/AccountsBottomSheet.kt @@ -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, ) { diff --git a/app/src/main/java/com/greenart7c3/nostrsigner/ui/actions/AdjustPermissionsDialog.kt b/app/src/main/java/com/greenart7c3/nostrsigner/ui/actions/AdjustPermissionsDialog.kt index 885a02bc..fae709f7 100644 --- a/app/src/main/java/com/greenart7c3/nostrsigner/ui/actions/AdjustPermissionsDialog.kt +++ b/app/src/main/java/com/greenart7c3/nostrsigner/ui/actions/AdjustPermissionsDialog.kt @@ -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), diff --git a/app/src/main/java/com/greenart7c3/nostrsigner/ui/actions/ConnectOrbotDialog.kt b/app/src/main/java/com/greenart7c3/nostrsigner/ui/actions/ConnectOrbotDialog.kt index 07d05aef..78d64374 100644 --- a/app/src/main/java/com/greenart7c3/nostrsigner/ui/actions/ConnectOrbotDialog.kt +++ b/app/src/main/java/com/greenart7c3/nostrsigner/ui/actions/ConnectOrbotDialog.kt @@ -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) } diff --git a/app/src/main/java/com/greenart7c3/nostrsigner/ui/actions/LogoutDialog.kt b/app/src/main/java/com/greenart7c3/nostrsigner/ui/actions/LogoutDialog.kt index cde01ad5..fc49c44f 100644 --- a/app/src/main/java/com/greenart7c3/nostrsigner/ui/actions/LogoutDialog.kt +++ b/app/src/main/java/com/greenart7c3/nostrsigner/ui/actions/LogoutDialog.kt @@ -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 = { diff --git a/app/src/main/java/com/greenart7c3/nostrsigner/ui/components/AcceptRejectButtons.kt b/app/src/main/java/com/greenart7c3/nostrsigner/ui/components/AcceptRejectButtons.kt index cd72ab86..2fadceb9 100644 --- a/app/src/main/java/com/greenart7c3/nostrsigner/ui/components/AcceptRejectButtons.kt +++ b/app/src/main/java/com/greenart7c3/nostrsigner/ui/components/AcceptRejectButtons.kt @@ -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)) } diff --git a/app/src/main/java/com/greenart7c3/nostrsigner/ui/components/EncryptDecryptData.kt b/app/src/main/java/com/greenart7c3/nostrsigner/ui/components/EncryptDecryptData.kt index c5a0bf41..df64ec2b 100644 --- a/app/src/main/java/com/greenart7c3/nostrsigner/ui/components/EncryptDecryptData.kt +++ b/app/src/main/java/com/greenart7c3/nostrsigner/ui/components/EncryptDecryptData.kt @@ -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), ) } } diff --git a/app/src/main/java/com/greenart7c3/nostrsigner/ui/components/EventData.kt b/app/src/main/java/com/greenart7c3/nostrsigner/ui/components/EventData.kt index 96f9b499..cacff807 100644 --- a/app/src/main/java/com/greenart7c3/nostrsigner/ui/components/EventData.kt +++ b/app/src/main/java/com/greenart7c3/nostrsigner/ui/components/EventData.kt @@ -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), ) } } diff --git a/app/src/main/java/com/greenart7c3/nostrsigner/ui/components/HyperlinkText.kt b/app/src/main/java/com/greenart7c3/nostrsigner/ui/components/HyperlinkText.kt index d01e85fb..9beff856 100644 --- a/app/src/main/java/com/greenart7c3/nostrsigner/ui/components/HyperlinkText.kt +++ b/app/src/main/java/com/greenart7c3/nostrsigner/ui/components/HyperlinkText.kt @@ -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, ) diff --git a/app/src/main/java/com/greenart7c3/nostrsigner/ui/components/IconRow.kt b/app/src/main/java/com/greenart7c3/nostrsigner/ui/components/IconRow.kt index 9687191e..a641181d 100644 --- a/app/src/main/java/com/greenart7c3/nostrsigner/ui/components/IconRow.kt +++ b/app/src/main/java/com/greenart7c3/nostrsigner/ui/components/IconRow.kt @@ -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( diff --git a/app/src/main/java/com/greenart7c3/nostrsigner/ui/components/LoginWithPubKey.kt b/app/src/main/java/com/greenart7c3/nostrsigner/ui/components/LoginWithPubKey.kt index d6b7c097..5261f5df 100644 --- a/app/src/main/java/com/greenart7c3/nostrsigner/ui/components/LoginWithPubKey.kt +++ b/app/src/main/java/com/greenart7c3/nostrsigner/ui/components/LoginWithPubKey.kt @@ -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)) } diff --git a/app/src/main/java/com/greenart7c3/nostrsigner/ui/components/MultiEventHomeScreen.kt b/app/src/main/java/com/greenart7c3/nostrsigner/ui/components/MultiEventHomeScreen.kt index 4997fcfe..15da813f 100644 --- a/app/src/main/java/com/greenart7c3/nostrsigner/ui/components/MultiEventHomeScreen.kt +++ b/app/src/main/java/com/greenart7c3/nostrsigner/ui/components/MultiEventHomeScreen.kt @@ -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, diff --git a/app/src/main/java/com/greenart7c3/nostrsigner/ui/components/RawJson.kt b/app/src/main/java/com/greenart7c3/nostrsigner/ui/components/RawJson.kt index 534d6516..6736ff6c 100644 --- a/app/src/main/java/com/greenart7c3/nostrsigner/ui/components/RawJson.kt +++ b/app/src/main/java/com/greenart7c3/nostrsigner/ui/components/RawJson.kt @@ -41,9 +41,8 @@ fun RawJson( } OutlinedTextField( - modifier = - modifier - .fillMaxWidth(), + modifier = modifier + .fillMaxWidth(), value = TextFieldValue(currentContent), onValueChange = { }, readOnly = true, diff --git a/app/src/main/java/com/greenart7c3/nostrsigner/ui/components/RememberMyChoice.kt b/app/src/main/java/com/greenart7c3/nostrsigner/ui/components/RememberMyChoice.kt index c1ae1f62..d78cd080 100644 --- a/app/src/main/java/com/greenart7c3/nostrsigner/ui/components/RememberMyChoice.kt +++ b/app/src/main/java/com/greenart7c3/nostrsigner/ui/components/RememberMyChoice.kt @@ -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), diff --git a/app/src/main/java/com/greenart7c3/nostrsigner/ui/components/SingleEventHomeScreen.kt b/app/src/main/java/com/greenart7c3/nostrsigner/ui/components/SingleEventHomeScreen.kt index b0356054..3116a288 100644 --- a/app/src/main/java/com/greenart7c3/nostrsigner/ui/components/SingleEventHomeScreen.kt +++ b/app/src/main/java/com/greenart7c3/nostrsigner/ui/components/SingleEventHomeScreen.kt @@ -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(), ) diff --git a/app/src/main/java/com/greenart7c3/nostrsigner/ui/components/TextSpinner.kt b/app/src/main/java/com/greenart7c3/nostrsigner/ui/components/TextSpinner.kt index 0b765e59..0766e0be 100644 --- a/app/src/main/java/com/greenart7c3/nostrsigner/ui/components/TextSpinner.kt +++ b/app/src/main/java/com/greenart7c3/nostrsigner/ui/components/TextSpinner.kt @@ -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() + }, ) } diff --git a/app/src/main/java/com/greenart7c3/nostrsigner/ui/theme/Type.kt b/app/src/main/java/com/greenart7c3/nostrsigner/ui/theme/Type.kt index 019a63e8..0eec23ba 100644 --- a/app/src/main/java/com/greenart7c3/nostrsigner/ui/theme/Type.kt +++ b/app/src/main/java/com/greenart7c3/nostrsigner/ui/theme/Type.kt @@ -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, + ), ) diff --git a/app/src/play/java/com/greenart7c3/nostrsigner/service/Notifications.kt b/app/src/play/java/com/greenart7c3/nostrsigner/service/Notifications.kt index a4b86942..1b55abfa 100644 --- a/app/src/play/java/com/greenart7c3/nostrsigner/service/Notifications.kt +++ b/app/src/play/java/com/greenart7c3/nostrsigner/service/Notifications.kt @@ -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())