code cleanup

This commit is contained in:
greenart7c3
2023-12-20 13:50:32 -03:00
parent c3cc32857e
commit e98a2e8f5c
22 changed files with 22 additions and 571 deletions
+9
View File
@@ -3,30 +3,39 @@
<option name="myName" value="Project Default" /> <option name="myName" value="Project Default" />
<inspection_tool class="PreviewAnnotationInFunctionWithParameters" enabled="true" level="ERROR" enabled_by_default="true"> <inspection_tool class="PreviewAnnotationInFunctionWithParameters" enabled="true" level="ERROR" enabled_by_default="true">
<option name="composableFile" value="true" /> <option name="composableFile" value="true" />
<option name="previewFile" value="true" />
</inspection_tool> </inspection_tool>
<inspection_tool class="PreviewApiLevelMustBeValid" enabled="true" level="ERROR" enabled_by_default="true"> <inspection_tool class="PreviewApiLevelMustBeValid" enabled="true" level="ERROR" enabled_by_default="true">
<option name="composableFile" value="true" /> <option name="composableFile" value="true" />
<option name="previewFile" value="true" />
</inspection_tool> </inspection_tool>
<inspection_tool class="PreviewDimensionRespectsLimit" enabled="true" level="WARNING" enabled_by_default="true"> <inspection_tool class="PreviewDimensionRespectsLimit" enabled="true" level="WARNING" enabled_by_default="true">
<option name="composableFile" value="true" /> <option name="composableFile" value="true" />
<option name="previewFile" value="true" />
</inspection_tool> </inspection_tool>
<inspection_tool class="PreviewFontScaleMustBeGreaterThanZero" enabled="true" level="ERROR" enabled_by_default="true"> <inspection_tool class="PreviewFontScaleMustBeGreaterThanZero" enabled="true" level="ERROR" enabled_by_default="true">
<option name="composableFile" value="true" /> <option name="composableFile" value="true" />
<option name="previewFile" value="true" />
</inspection_tool> </inspection_tool>
<inspection_tool class="PreviewMultipleParameterProviders" enabled="true" level="ERROR" enabled_by_default="true"> <inspection_tool class="PreviewMultipleParameterProviders" enabled="true" level="ERROR" enabled_by_default="true">
<option name="composableFile" value="true" /> <option name="composableFile" value="true" />
<option name="previewFile" value="true" />
</inspection_tool> </inspection_tool>
<inspection_tool class="PreviewMustBeTopLevelFunction" enabled="true" level="ERROR" enabled_by_default="true"> <inspection_tool class="PreviewMustBeTopLevelFunction" enabled="true" level="ERROR" enabled_by_default="true">
<option name="composableFile" value="true" /> <option name="composableFile" value="true" />
<option name="previewFile" value="true" />
</inspection_tool> </inspection_tool>
<inspection_tool class="PreviewNeedsComposableAnnotation" enabled="true" level="ERROR" enabled_by_default="true"> <inspection_tool class="PreviewNeedsComposableAnnotation" enabled="true" level="ERROR" enabled_by_default="true">
<option name="composableFile" value="true" /> <option name="composableFile" value="true" />
<option name="previewFile" value="true" />
</inspection_tool> </inspection_tool>
<inspection_tool class="PreviewNotSupportedInUnitTestFiles" enabled="true" level="ERROR" enabled_by_default="true"> <inspection_tool class="PreviewNotSupportedInUnitTestFiles" enabled="true" level="ERROR" enabled_by_default="true">
<option name="composableFile" value="true" /> <option name="composableFile" value="true" />
<option name="previewFile" value="true" />
</inspection_tool> </inspection_tool>
<inspection_tool class="PreviewPickerAnnotation" enabled="true" level="ERROR" enabled_by_default="true"> <inspection_tool class="PreviewPickerAnnotation" enabled="true" level="ERROR" enabled_by_default="true">
<option name="composableFile" value="true" /> <option name="composableFile" value="true" />
<option name="previewFile" value="true" />
</inspection_tool> </inspection_tool>
</profile> </profile>
</component> </component>
+1 -1
View File
@@ -3,7 +3,7 @@
xmlns:tools="http://schemas.android.com/tools"> xmlns:tools="http://schemas.android.com/tools">
<application <application
android:name=".nostrsigner" android:name=".Nostrsigner"
android:allowBackup="false" android:allowBackup="false"
android:configChanges="orientation|screenSize|screenLayout" android:configChanges="orientation|screenSize|screenLayout"
android:dataExtractionRules="@xml/data_extraction_rules" android:dataExtractionRules="@xml/data_extraction_rules"
@@ -6,12 +6,12 @@ import androidx.security.crypto.MasterKey
object EncryptedStorage { object EncryptedStorage {
private const val PREFERENCES_NAME = "secret_keeper" private const val PREFERENCES_NAME = "secret_keeper"
fun prefsFileName(npub: String? = null): String { private fun prefsFileName(npub: String? = null): String {
return if (npub == null) PREFERENCES_NAME else "${PREFERENCES_NAME}_$npub" return if (npub == null) PREFERENCES_NAME else "${PREFERENCES_NAME}_$npub"
} }
fun preferences(npub: String? = null): EncryptedSharedPreferences { fun preferences(npub: String? = null): EncryptedSharedPreferences {
val context = nostrsigner.instance val context = Nostrsigner.instance
val masterKey: MasterKey = MasterKey.Builder(context, MasterKey.DEFAULT_MASTER_KEY_ALIAS) val masterKey: MasterKey = MasterKey.Builder(context, MasterKey.DEFAULT_MASTER_KEY_ALIAS)
.setKeyScheme(MasterKey.KeyScheme.AES256_GCM) .setKeyScheme(MasterKey.KeyScheme.AES256_GCM)
.build() .build()
@@ -86,7 +86,7 @@ object LocalPreferences {
} }
private val prefsDirPath: String private val prefsDirPath: String
get() = "${nostrsigner.instance.filesDir.parent}/shared_prefs/" get() = "${Nostrsigner.instance.filesDir.parent}/shared_prefs/"
private fun addAccount(npub: String) { private fun addAccount(npub: String) {
val accounts = savedAccounts().toMutableList() val accounts = savedAccounts().toMutableList()
@@ -135,7 +135,7 @@ object LocalPreferences {
private fun encryptedPreferences(npub: String? = null): SharedPreferences { private fun encryptedPreferences(npub: String? = null): SharedPreferences {
return if (BuildConfig.DEBUG && DEBUG_PLAINTEXT_PREFERENCES) { return if (BuildConfig.DEBUG && DEBUG_PLAINTEXT_PREFERENCES) {
val preferenceFile = if (npub == null) DEBUG_PREFERENCES_NAME else "${DEBUG_PREFERENCES_NAME}_$npub" val preferenceFile = if (npub == null) DEBUG_PREFERENCES_NAME else "${DEBUG_PREFERENCES_NAME}_$npub"
nostrsigner.instance.getSharedPreferences(preferenceFile, Context.MODE_PRIVATE) Nostrsigner.instance.getSharedPreferences(preferenceFile, Context.MODE_PRIVATE)
} else { } else {
return EncryptedStorage.preferences(npub) return EncryptedStorage.preferences(npub)
} }
@@ -2,14 +2,14 @@ package com.greenart7c3.nostrsigner
import android.app.Application import android.app.Application
class nostrsigner : Application() { class Nostrsigner : Application() {
override fun onCreate() { override fun onCreate() {
super.onCreate() super.onCreate()
instance = this instance = this
} }
companion object { companion object {
lateinit var instance: nostrsigner lateinit var instance: Nostrsigner
private set private set
} }
} }
@@ -7,13 +7,6 @@ import com.vitorpamplona.quartz.crypto.KeyPair
import com.vitorpamplona.quartz.signers.NostrSigner import com.vitorpamplona.quartz.signers.NostrSigner
import com.vitorpamplona.quartz.signers.NostrSignerInternal import com.vitorpamplona.quartz.signers.NostrSignerInternal
class History(
val appName: String,
val type: String,
val time: Long,
val kind: Int?
)
@Stable @Stable
class Account( class Account(
val keyPair: KeyPair, val keyPair: KeyPair,
@@ -1,10 +0,0 @@
package com.greenart7c3.nostrsigner.models
import androidx.compose.runtime.Stable
@Stable
data class ImmutableListOfLists<T>(val lists: List<List<T>> = emptyList())
fun List<List<String>>.toImmutableListOfLists(): ImmutableListOfLists<String> {
return ImmutableListOfLists(this)
}
@@ -1,18 +1,5 @@
package com.greenart7c3.nostrsigner.models package com.greenart7c3.nostrsigner.models
import java.text.SimpleDateFormat
import java.util.Date
import java.util.Locale
import java.util.TimeZone
object TimeUtils { object TimeUtils {
fun now() = System.currentTimeMillis() / 1000 fun now() = System.currentTimeMillis() / 1000
fun format(date: Long): String {
val sdf = SimpleDateFormat(
"dd/MM/yyyy HH:mm:ss",
Locale.getDefault()
)
sdf.timeZone = TimeZone.getDefault()
return sdf.format(Date(date * 1000))
}
} }
@@ -7,18 +7,12 @@ import com.vitorpamplona.quartz.crypto.CryptoUtils
import com.vitorpamplona.quartz.crypto.Nip44Version import com.vitorpamplona.quartz.crypto.Nip44Version
import com.vitorpamplona.quartz.crypto.decodeNIP44 import com.vitorpamplona.quartz.crypto.decodeNIP44
import com.vitorpamplona.quartz.crypto.encodeNIP44 import com.vitorpamplona.quartz.crypto.encodeNIP44
import com.vitorpamplona.quartz.encoders.Bech32
import com.vitorpamplona.quartz.encoders.HexKey import com.vitorpamplona.quartz.encoders.HexKey
import com.vitorpamplona.quartz.encoders.hexToByteArray import com.vitorpamplona.quartz.encoders.hexToByteArray
import com.vitorpamplona.quartz.encoders.toHexKey import com.vitorpamplona.quartz.encoders.toHexKey
import com.vitorpamplona.quartz.events.Event import com.vitorpamplona.quartz.events.Event
import com.vitorpamplona.quartz.events.LnZapRequestEvent import com.vitorpamplona.quartz.events.LnZapRequestEvent
import fr.acinq.secp256k1.Hex import fr.acinq.secp256k1.Hex
import java.nio.charset.Charset
import java.security.SecureRandom
import javax.crypto.Cipher
import javax.crypto.spec.IvParameterSpec
import javax.crypto.spec.SecretKeySpec
object AmberUtils { object AmberUtils {
fun encryptOrDecryptData(data: String, type: SignerType, account: Account, pubKey: HexKey): String? { fun encryptOrDecryptData(data: String, type: SignerType, account: Account, pubKey: HexKey): String? {
@@ -124,25 +118,6 @@ object AmberUtils {
null null
} }
} }
private fun encryptPrivateZapMessage(msg: String, privkey: ByteArray, pubkey: ByteArray): String {
val sharedSecret = CryptoUtils.getSharedSecretNIP04(privkey, pubkey)
val iv = ByteArray(16)
SecureRandom().nextBytes(iv)
val keySpec = SecretKeySpec(sharedSecret, "AES")
val ivSpec = IvParameterSpec(iv)
val utf8message = msg.toByteArray(Charset.forName("utf-8"))
val cipher = Cipher.getInstance("AES/CBC/PKCS5Padding")
cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec)
val encryptedMsg = cipher.doFinal(utf8message)
val encryptedMsgBech32 = Bech32.encode("pzap", Bech32.eight2five(encryptedMsg), Bech32.Encoding.Bech32)
val ivBech32 = Bech32.encode("iv", Bech32.eight2five(iv), Bech32.Encoding.Bech32)
return encryptedMsgBech32 + "_" + ivBech32
}
} }
fun String.toShortenHex(): String { fun String.toShortenHex(): String {
@@ -80,7 +80,7 @@ open class AmberEvent(
} }
companion object { companion object {
val gson: Gson = GsonBuilder() private val gson: Gson = GsonBuilder()
.disableHtmlEscaping() .disableHtmlEscaping()
.registerTypeAdapter(AmberEvent::class.java, EventSerializer()) .registerTypeAdapter(AmberEvent::class.java, EventSerializer())
.registerTypeAdapter(AmberEvent::class.java, EventDeserializer()) .registerTypeAdapter(AmberEvent::class.java, EventDeserializer())
@@ -1,70 +0,0 @@
package com.greenart7c3.nostrsigner.service.model
import androidx.compose.runtime.Immutable
import com.vitorpamplona.quartz.encoders.ATag
import com.vitorpamplona.quartz.encoders.HexKey
import com.vitorpamplona.quartz.events.EmojiUrl
import java.math.BigDecimal
@Immutable
interface AmberEventInterface {
fun id(): HexKey
fun pubKey(): HexKey
fun createdAt(): Long
fun kind(): Int
fun description(): String
fun tags(): Array<Array<String>>
fun content(): String
fun sig(): HexKey
fun toJson(): String
fun checkSignature()
fun hasValidSignature(): Boolean
fun isTaggedUser(idHex: String): Boolean
fun isTaggedEvent(idHex: String): Boolean
fun isTaggedAddressableNote(idHex: String): Boolean
fun isTaggedAddressableNotes(idHexes: Set<String>): Boolean
fun isTaggedHash(hashtag: String): Boolean
fun isTaggedGeoHash(hashtag: String): Boolean
fun isTaggedHashes(hashtags: Set<String>): Boolean
fun isTaggedGeoHashes(hashtags: Set<String>): Boolean
fun firstIsTaggedHashes(hashtags: Set<String>): String?
fun firstIsTaggedAddressableNote(addressableNotes: Set<String>): String?
fun isTaggedAddressableKind(kind: Int): Boolean
fun getTagOfAddressableKind(kind: Int): ATag?
fun hashtags(): List<String>
fun geohashes(): List<String>
fun getReward(): BigDecimal?
fun getPoWRank(): Int
fun getGeoHash(): String?
fun zapAddress(): String?
fun isSensitive(): Boolean
fun zapraiserAmount(): Long?
fun taggedAddresses(): List<ATag>
fun taggedUsers(): List<HexKey>
fun taggedEvents(): List<HexKey>
fun taggedUrls(): List<String>
fun taggedEmojis(): List<EmojiUrl>
fun matchTag1With(text: String): Boolean
}
@@ -3,6 +3,6 @@ package com.greenart7c3.nostrsigner.ui
import com.greenart7c3.nostrsigner.models.Account import com.greenart7c3.nostrsigner.models.Account
sealed class AccountState { sealed class AccountState {
object LoggedOff : AccountState() data object LoggedOff : AccountState()
class LoggedIn(val account: Account, val route: String?) : AccountState() class LoggedIn(val account: Account, val route: String?) : AccountState()
} }
@@ -4,7 +4,6 @@ import android.app.Activity.RESULT_OK
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.net.Uri import android.net.Uri
import android.text.format.DateUtils
import android.widget.Toast import android.widget.Toast
import androidx.compose.animation.core.tween import androidx.compose.animation.core.tween
import androidx.compose.animation.fadeIn import androidx.compose.animation.fadeIn
@@ -357,19 +356,3 @@ fun MainScreen(
} }
} }
} }
fun timeAgoShort(mills: Long?, stringForNow: String): String {
if (mills == null) return " "
var humanReadable = DateUtils.getRelativeTimeSpanString(
mills * 1000,
System.currentTimeMillis(),
DateUtils.MINUTE_IN_MILLIS,
DateUtils.FORMAT_ABBREV_ALL
).toString()
if (humanReadable.startsWith("In") || humanReadable.startsWith("0")) {
humanReadable = stringForNow
}
return humanReadable
}
@@ -1,63 +0,0 @@
package com.greenart7c3.nostrsigner.ui
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.Dialog
import androidx.compose.ui.window.DialogProperties
import com.greenart7c3.nostrsigner.models.Account
import com.greenart7c3.nostrsigner.ui.components.CloseButton
import com.greenart7c3.nostrsigner.ui.theme.Size35dp
import com.vitorpamplona.quartz.encoders.toNpub
@Composable
fun ShowQRDialog(account: Account, onClose: () -> Unit) {
Dialog(
onDismissRequest = onClose,
properties = DialogProperties(usePlatformDefaultWidth = false)
) {
Surface(modifier = Modifier.fillMaxSize()) {
Column(
modifier = Modifier
.background(MaterialTheme.colorScheme.background)
.fillMaxSize()
) {
Row(
modifier = Modifier
.fillMaxWidth()
.padding(10.dp),
horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically
) {
CloseButton(onCancel = onClose)
}
Column(
modifier = Modifier
.fillMaxSize()
.padding(horizontal = 10.dp),
verticalArrangement = Arrangement.SpaceAround
) {
Row(
horizontalArrangement = Arrangement.Center,
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = Size35dp)
) {
QrCodeDrawer("nostr:${account.keyPair.pubKey.toNpub()}")
}
}
}
}
}
}
@@ -1,18 +0,0 @@
package com.greenart7c3.nostrsigner.ui.components
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
@Composable
fun AppTitle(appName: String) {
Text(
modifier = Modifier.fillMaxWidth(),
text = appName,
fontWeight = FontWeight.Bold,
textAlign = TextAlign.Center
)
}
@@ -1,42 +0,0 @@
package com.greenart7c3.nostrsigner.ui.components
import androidx.activity.OnBackPressedCallback
import androidx.activity.compose.LocalOnBackPressedDispatcherOwner
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.SideEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberUpdatedState
import androidx.compose.ui.platform.LocalLifecycleOwner
@SuppressWarnings("MissingJvmstatic")
@Composable
fun BackHandler(enabled: Boolean = true, onBack: () -> Unit) {
// Safely update the current `onBack` lambda when a new one is provided
val currentOnBack by rememberUpdatedState(onBack)
// Remember in Composition a back callback that calls the `onBack` lambda
val backCallback = remember {
object : OnBackPressedCallback(enabled) {
override fun handleOnBackPressed() {
currentOnBack()
}
}
}
// On every successful composition, update the callback with the `enabled` value
SideEffect {
backCallback.isEnabled = enabled
}
val backDispatcher = checkNotNull(LocalOnBackPressedDispatcherOwner.current) {
"No OnBackPressedDispatcherOwner was provided via LocalOnBackPressedDispatcherOwner"
}.onBackPressedDispatcher
val lifecycleOwner = LocalLifecycleOwner.current
DisposableEffect(lifecycleOwner, backDispatcher) {
// Add callback to the backDispatcher
backDispatcher.addCallback(lifecycleOwner, backCallback)
// When the effect leaves the Composition, remove the callback
onDispose {
backCallback.remove()
}
}
}
@@ -1,211 +0,0 @@
package com.greenart7c3.nostrsigner.ui.components
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.ClearAll
import androidx.compose.material.icons.filled.Key
import androidx.compose.material.icons.filled.QrCode
import androidx.compose.material3.AlertDialog
import androidx.compose.material3.Divider
import androidx.compose.material3.DrawerState
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.greenart7c3.nostrsigner.BuildConfig
import com.greenart7c3.nostrsigner.LocalPreferences
import com.greenart7c3.nostrsigner.R
import com.greenart7c3.nostrsigner.models.Account
import com.greenart7c3.nostrsigner.ui.AccountStateViewModel
import com.greenart7c3.nostrsigner.ui.ShowQRDialog
import com.greenart7c3.nostrsigner.ui.actions.AccountBackupDialog
import com.vitorpamplona.quartz.encoders.toNpub
import kotlinx.coroutines.launch
@Composable
fun Drawer(
accountStateViewModel: AccountStateViewModel,
account: Account,
drawerState: DrawerState
) {
var logoutDialog by remember { mutableStateOf(false) }
var resetPermissions by remember { mutableStateOf(false) }
var backupDialogOpen by remember { mutableStateOf(false) }
val scope = rememberCoroutineScope()
if (logoutDialog) {
AlertDialog(
title = {
Text(text = stringResource(R.string.logout))
},
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))
},
onDismissRequest = {
logoutDialog = false
},
confirmButton = {
TextButton(
onClick = {
logoutDialog = false
accountStateViewModel.logOff(account.keyPair.pubKey.toNpub())
}
) {
Text(text = stringResource(R.string.logout))
}
},
dismissButton = {
TextButton(
onClick = {
logoutDialog = false
}
) {
Text(text = stringResource(R.string.cancel))
}
}
)
}
if (resetPermissions) {
AlertDialog(
title = {
Text(text = stringResource(R.string.reset_permissions))
},
text = {
Text(text = stringResource(R.string.do_you_want_to_reset_all_permissions))
},
onDismissRequest = {
resetPermissions = false
},
confirmButton = {
TextButton(
onClick = {
resetPermissions = false
scope.launch {
drawerState.close()
LocalPreferences.deleteSavedApps(account)
}
}
) {
Text(text = stringResource(R.string.confirm))
}
},
dismissButton = {
TextButton(
onClick = {
resetPermissions = false
}
) {
Text(text = stringResource(R.string.cancel))
}
}
)
}
Surface(
modifier = Modifier.fillMaxWidth(),
color = MaterialTheme.colorScheme.background
) {
Column {
Spacer(modifier = Modifier.weight(1f))
IconRow(
title = "Reset permissions",
icon = Icons.Default.ClearAll,
tint = MaterialTheme.colorScheme.onBackground,
onClick = {
resetPermissions = true
}
)
IconRow(
title = "Backup Keys",
icon = Icons.Default.Key,
tint = MaterialTheme.colorScheme.onBackground,
onClick = {
scope.launch {
drawerState.close()
}
backupDialogOpen = true
}
)
BottomContent(account, drawerState)
}
}
if (backupDialogOpen) {
AccountBackupDialog(account, onClose = { backupDialogOpen = false })
}
BackHandler(enabled = drawerState.isOpen) {
scope.launch { drawerState.close() }
}
}
@Composable
fun BottomContent(account: Account, drawerState: DrawerState) {
val coroutineScope = rememberCoroutineScope()
// store the dialog open or close state
var dialogOpen by remember {
mutableStateOf(false)
}
Column(modifier = Modifier) {
Divider(
modifier = Modifier.padding(top = 15.dp),
thickness = 0.25.dp
)
Row(
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 15.dp),
verticalAlignment = Alignment.CenterVertically
) {
Text(
modifier = Modifier.padding(start = 16.dp),
text = "v" + BuildConfig.VERSION_NAME,
fontSize = 12.sp,
fontWeight = FontWeight.Bold
)
Box(modifier = Modifier.weight(1F))
IconButton(onClick = {
dialogOpen = true
coroutineScope.launch {
drawerState.close()
}
}) {
Icon(
Icons.Default.QrCode,
null,
modifier = Modifier.size(24.dp),
tint = MaterialTheme.colorScheme.primary
)
}
}
}
if (dialogOpen) {
ShowQRDialog(
account,
onClose = { dialogOpen = false }
)
}
}
@@ -1,53 +0,0 @@
package com.greenart7c3.nostrsigner.ui.components
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Divider
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
@Composable
fun EventRow(
icon: ImageVector,
title: String,
content: String
) {
Divider(
modifier = Modifier.padding(vertical = 15.dp),
thickness = Dp.Hairline
)
Row(
Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.Start
) {
Icon(
icon,
null,
tint = MaterialTheme.colorScheme.onBackground
)
Text(
modifier = Modifier.padding(start = 8.dp),
text = "$title ",
fontWeight = FontWeight.Bold
)
Text(
content,
color = Color.Gray,
maxLines = 1,
overflow = TextOverflow.Ellipsis,
modifier = Modifier.fillMaxWidth()
)
}
}
@@ -209,10 +209,10 @@ fun MultiEventHomeScreen(
{ } { }
) { ) {
intentData.rememberMyChoice.value = !intentData.rememberMyChoice.value intentData.rememberMyChoice.value = !intentData.rememberMyChoice.value
intents.filter { it -> intents.filter { item ->
intentData.type == it.type intentData.type == item.type
}.forEach { it -> }.forEach { item ->
it.rememberMyChoice.value = intentData.rememberMyChoice.value item.rememberMyChoice.value = intentData.rememberMyChoice.value
} }
} }
} }
@@ -1,11 +1,9 @@
package com.greenart7c3.nostrsigner.ui.navigation package com.greenart7c3.nostrsigner.ui.navigation
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.History
import androidx.compose.material.icons.filled.Home import androidx.compose.material.icons.filled.Home
import androidx.compose.material.icons.filled.Settings import androidx.compose.material.icons.filled.Settings
import androidx.compose.material.icons.filled.ViewList import androidx.compose.material.icons.filled.ViewList
import androidx.compose.material.icons.outlined.History
import androidx.compose.material.icons.outlined.Home import androidx.compose.material.icons.outlined.Home
import androidx.compose.material.icons.outlined.Settings import androidx.compose.material.icons.outlined.Settings
import androidx.compose.material.icons.outlined.ViewList import androidx.compose.material.icons.outlined.ViewList
@@ -41,10 +39,4 @@ sealed class Route(
icon = Icons.Outlined.ViewList, icon = Icons.Outlined.ViewList,
selectedIcon = Icons.Default.ViewList selectedIcon = Icons.Default.ViewList
) )
data object History : Route(
route = "History",
icon = Icons.Outlined.History,
selectedIcon = Icons.Default.History
)
} }
-5
View File
@@ -1,11 +1,6 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<color name="purple_200">#FFBB86FC</color>
<color name="purple_500">#FF6200EE</color>
<color name="purple_700">#FF3700B3</color> <color name="purple_700">#FF3700B3</color>
<color name="teal_200">#FF03DAC5</color>
<color name="teal_700">#FF018786</color>
<color name="black">#FF000000</color> <color name="black">#FF000000</color>
<color name="white">#FFFFFFFF</color>
<color name="amber">#FFBF00</color> <color name="amber">#FFBF00</color>
</resources> </resources>
-16
View File
@@ -17,17 +17,13 @@
<string name="copies_the_npub_id_your_user_to_the_clipboard_for_backup">Copies the Npub ID (your user) to the clipboard for backup</string> <string name="copies_the_npub_id_your_user_to_the_clipboard_for_backup">Copies the Npub ID (your user) to the clipboard for backup</string>
<string name="copy_my_public_key">Copy my public key</string> <string name="copy_my_public_key">Copy my public key</string>
<string name="event_pubkey_is_not_equal_to_current_logged_in_user">Event pubkey is not equal to current logged in user</string> <string name="event_pubkey_is_not_equal_to_current_logged_in_user">Event pubkey is not equal to current logged in user</string>
<string name="scan_qr">Scan QR</string>
<string name="signature_copied_to_the_clipboard">Signature copied to the clipboard</string> <string name="signature_copied_to_the_clipboard">Signature copied to the clipboard</string>
<string name="sign">Sign</string>
<string name="raw_json_copied_to_the_clipboard"> copied to the clipboard</string>
<string name="reset_permissions">Reset permissions</string> <string name="reset_permissions">Reset permissions</string>
<string name="logout">Logout</string> <string name="logout">Logout</string>
<string name="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">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?</string> <string name="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">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?</string>
<string name="cancel">Cancel</string> <string name="cancel">Cancel</string>
<string name="do_you_want_to_reset_all_permissions">Do you want to reset all permissions?</string> <string name="do_you_want_to_reset_all_permissions">Do you want to reset all permissions?</string>
<string name="confirm">Confirm</string> <string name="confirm">Confirm</string>
<string name="could_not_decrypt_the_message">Could not decrypt the message</string>
<string name="nsec">nsec..</string> <string name="nsec">nsec..</string>
<string name="show_password">Show password</string> <string name="show_password">Show password</string>
<string name="hide_password">Hide password</string> <string name="hide_password">Hide password</string>
@@ -44,7 +40,6 @@
<string name="read_your_public_key">Read your public key</string> <string name="read_your_public_key">Read your public key</string>
<string name="no_permissions_granted">No permissions granted</string> <string name="no_permissions_granted">No permissions granted</string>
<string name="no_event_to_sign">No event to sign</string> <string name="no_event_to_sign">No event to sign</string>
<string name="wants_to_read_your_public_key">wants to read your public key</string>
<string name="remember_my_choice_and_don_t_ask_again">Remember my choice and don\'t ask again</string> <string name="remember_my_choice_and_don_t_ask_again">Remember my choice and don\'t ask again</string>
<string name="reject">Reject</string> <string name="reject">Reject</string>
<string name="accept">Accept</string> <string name="accept">Accept</string>
@@ -54,17 +49,9 @@
<string name="decrypt_nip04">decrypt nip04</string> <string name="decrypt_nip04">decrypt nip04</string>
<string name="decrypt_zap_event">decrypt zap event</string> <string name="decrypt_zap_event">decrypt zap event</string>
<string name="encrypt_decrypt">encrypt/decrypt</string> <string name="encrypt_decrypt">encrypt/decrypt</string>
<string name="wants_you_to_data">wants you to %1$s data</string>
<string name="encrypt">encrypt</string> <string name="encrypt">encrypt</string>
<string name="decrypt">decrypt</string> <string name="decrypt">decrypt</string>
<string name="error_to_data">Error to %1$s data</string> <string name="error_to_data">Error to %1$s data</string>
<string name="client_authentication">client authentication</string>
<string name="event">event</string>
<string name="wants_you_to_sign_a">wants you to sign a %1$s</string>
<string name="kind">"Kind "</string>
<string name="created_at">"Created at "</string>
<string name="signed_by">"Signed by "</string>
<string name="content">"Content "</string>
<string name="show_details">Show Details</string> <string name="show_details">Show Details</string>
<string name="hide_details">Hide Details</string> <string name="hide_details">Hide Details</string>
<string name="copy_raw_json">Raw json</string> <string name="copy_raw_json">Raw json</string>
@@ -72,13 +59,10 @@
<string name="select_account">Select Account</string> <string name="select_account">Select Account</string>
<string name="active_account">Active Account</string> <string name="active_account">Active Account</string>
<string name="edit_name">Edit name</string> <string name="edit_name">Edit name</string>
<string name="copy_to_clipboard">Copy to clipboard</string>
<string name="copy">"Copy "</string> <string name="copy">"Copy "</string>
<string name="my_public_key">my public key</string>
<string name="encrypted_decrypted_data">Encrypted/Decrypted data</string> <string name="encrypted_decrypted_data">Encrypted/Decrypted data</string>
<string name="data_copied_to_the_clipboard">Data copied to the clipboard</string> <string name="data_copied_to_the_clipboard">Data copied to the clipboard</string>
<string name="message_already_encrypted">Message already encrypted</string> <string name="message_already_encrypted">Message already encrypted</string>
<string name="relay">Relay</string>
<string name="go_to_top">go to top</string> <string name="go_to_top">go to top</string>
<string name="event_copied_to_the_clipboard">Event copied to the clipboard</string> <string name="event_copied_to_the_clipboard">Event copied to the clipboard</string>
<string name="select_deselect_all">Select/Deselect all</string> <string name="select_deselect_all">Select/Deselect all</string>