mirror of
https://github.com/greenart7c3/Amber.git
synced 2026-10-05 19:08:23 +00:00
code cleanup
This commit is contained in:
+9
@@ -3,30 +3,39 @@
|
||||
<option name="myName" value="Project Default" />
|
||||
<inspection_tool class="PreviewAnnotationInFunctionWithParameters" enabled="true" level="ERROR" enabled_by_default="true">
|
||||
<option name="composableFile" value="true" />
|
||||
<option name="previewFile" value="true" />
|
||||
</inspection_tool>
|
||||
<inspection_tool class="PreviewApiLevelMustBeValid" enabled="true" level="ERROR" enabled_by_default="true">
|
||||
<option name="composableFile" value="true" />
|
||||
<option name="previewFile" value="true" />
|
||||
</inspection_tool>
|
||||
<inspection_tool class="PreviewDimensionRespectsLimit" enabled="true" level="WARNING" enabled_by_default="true">
|
||||
<option name="composableFile" value="true" />
|
||||
<option name="previewFile" value="true" />
|
||||
</inspection_tool>
|
||||
<inspection_tool class="PreviewFontScaleMustBeGreaterThanZero" enabled="true" level="ERROR" enabled_by_default="true">
|
||||
<option name="composableFile" value="true" />
|
||||
<option name="previewFile" value="true" />
|
||||
</inspection_tool>
|
||||
<inspection_tool class="PreviewMultipleParameterProviders" enabled="true" level="ERROR" enabled_by_default="true">
|
||||
<option name="composableFile" value="true" />
|
||||
<option name="previewFile" value="true" />
|
||||
</inspection_tool>
|
||||
<inspection_tool class="PreviewMustBeTopLevelFunction" enabled="true" level="ERROR" enabled_by_default="true">
|
||||
<option name="composableFile" value="true" />
|
||||
<option name="previewFile" value="true" />
|
||||
</inspection_tool>
|
||||
<inspection_tool class="PreviewNeedsComposableAnnotation" enabled="true" level="ERROR" enabled_by_default="true">
|
||||
<option name="composableFile" value="true" />
|
||||
<option name="previewFile" value="true" />
|
||||
</inspection_tool>
|
||||
<inspection_tool class="PreviewNotSupportedInUnitTestFiles" enabled="true" level="ERROR" enabled_by_default="true">
|
||||
<option name="composableFile" value="true" />
|
||||
<option name="previewFile" value="true" />
|
||||
</inspection_tool>
|
||||
<inspection_tool class="PreviewPickerAnnotation" enabled="true" level="ERROR" enabled_by_default="true">
|
||||
<option name="composableFile" value="true" />
|
||||
<option name="previewFile" value="true" />
|
||||
</inspection_tool>
|
||||
</profile>
|
||||
</component>
|
||||
@@ -3,7 +3,7 @@
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
|
||||
<application
|
||||
android:name=".nostrsigner"
|
||||
android:name=".Nostrsigner"
|
||||
android:allowBackup="false"
|
||||
android:configChanges="orientation|screenSize|screenLayout"
|
||||
android:dataExtractionRules="@xml/data_extraction_rules"
|
||||
|
||||
@@ -6,12 +6,12 @@ import androidx.security.crypto.MasterKey
|
||||
object EncryptedStorage {
|
||||
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"
|
||||
}
|
||||
|
||||
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)
|
||||
.setKeyScheme(MasterKey.KeyScheme.AES256_GCM)
|
||||
.build()
|
||||
|
||||
@@ -86,7 +86,7 @@ object LocalPreferences {
|
||||
}
|
||||
|
||||
private val prefsDirPath: String
|
||||
get() = "${nostrsigner.instance.filesDir.parent}/shared_prefs/"
|
||||
get() = "${Nostrsigner.instance.filesDir.parent}/shared_prefs/"
|
||||
|
||||
private fun addAccount(npub: String) {
|
||||
val accounts = savedAccounts().toMutableList()
|
||||
@@ -135,7 +135,7 @@ object LocalPreferences {
|
||||
private fun encryptedPreferences(npub: String? = null): SharedPreferences {
|
||||
return if (BuildConfig.DEBUG && DEBUG_PLAINTEXT_PREFERENCES) {
|
||||
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 {
|
||||
return EncryptedStorage.preferences(npub)
|
||||
}
|
||||
|
||||
+2
-2
@@ -2,14 +2,14 @@ package com.greenart7c3.nostrsigner
|
||||
|
||||
import android.app.Application
|
||||
|
||||
class nostrsigner : Application() {
|
||||
class Nostrsigner : Application() {
|
||||
override fun onCreate() {
|
||||
super.onCreate()
|
||||
instance = this
|
||||
}
|
||||
|
||||
companion object {
|
||||
lateinit var instance: nostrsigner
|
||||
lateinit var instance: Nostrsigner
|
||||
private set
|
||||
}
|
||||
}
|
||||
@@ -7,13 +7,6 @@ import com.vitorpamplona.quartz.crypto.KeyPair
|
||||
import com.vitorpamplona.quartz.signers.NostrSigner
|
||||
import com.vitorpamplona.quartz.signers.NostrSignerInternal
|
||||
|
||||
class History(
|
||||
val appName: String,
|
||||
val type: String,
|
||||
val time: Long,
|
||||
val kind: Int?
|
||||
)
|
||||
|
||||
@Stable
|
||||
class Account(
|
||||
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
|
||||
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.Date
|
||||
import java.util.Locale
|
||||
import java.util.TimeZone
|
||||
|
||||
object TimeUtils {
|
||||
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.decodeNIP44
|
||||
import com.vitorpamplona.quartz.crypto.encodeNIP44
|
||||
import com.vitorpamplona.quartz.encoders.Bech32
|
||||
import com.vitorpamplona.quartz.encoders.HexKey
|
||||
import com.vitorpamplona.quartz.encoders.hexToByteArray
|
||||
import com.vitorpamplona.quartz.encoders.toHexKey
|
||||
import com.vitorpamplona.quartz.events.Event
|
||||
import com.vitorpamplona.quartz.events.LnZapRequestEvent
|
||||
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 {
|
||||
fun encryptOrDecryptData(data: String, type: SignerType, account: Account, pubKey: HexKey): String? {
|
||||
@@ -124,25 +118,6 @@ object AmberUtils {
|
||||
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 {
|
||||
|
||||
@@ -80,7 +80,7 @@ open class AmberEvent(
|
||||
}
|
||||
|
||||
companion object {
|
||||
val gson: Gson = GsonBuilder()
|
||||
private val gson: Gson = GsonBuilder()
|
||||
.disableHtmlEscaping()
|
||||
.registerTypeAdapter(AmberEvent::class.java, EventSerializer())
|
||||
.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
|
||||
|
||||
sealed class AccountState {
|
||||
object LoggedOff : AccountState()
|
||||
data object LoggedOff : 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.Intent
|
||||
import android.net.Uri
|
||||
import android.text.format.DateUtils
|
||||
import android.widget.Toast
|
||||
import androidx.compose.animation.core.tween
|
||||
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
|
||||
intents.filter { it ->
|
||||
intentData.type == it.type
|
||||
}.forEach { it ->
|
||||
it.rememberMyChoice.value = intentData.rememberMyChoice.value
|
||||
intents.filter { item ->
|
||||
intentData.type == item.type
|
||||
}.forEach { item ->
|
||||
item.rememberMyChoice.value = intentData.rememberMyChoice.value
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
package com.greenart7c3.nostrsigner.ui.navigation
|
||||
|
||||
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.Settings
|
||||
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.Settings
|
||||
import androidx.compose.material.icons.outlined.ViewList
|
||||
@@ -41,10 +39,4 @@ sealed class Route(
|
||||
icon = Icons.Outlined.ViewList,
|
||||
selectedIcon = Icons.Default.ViewList
|
||||
)
|
||||
|
||||
data object History : Route(
|
||||
route = "History",
|
||||
icon = Icons.Outlined.History,
|
||||
selectedIcon = Icons.Default.History
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,11 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<color name="purple_200">#FFBB86FC</color>
|
||||
<color name="purple_500">#FF6200EE</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="white">#FFFFFFFF</color>
|
||||
<color name="amber">#FFBF00</color>
|
||||
</resources>
|
||||
@@ -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="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="scan_qr">Scan QR</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="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="cancel">Cancel</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="could_not_decrypt_the_message">Could not decrypt the message</string>
|
||||
<string name="nsec">nsec..</string>
|
||||
<string name="show_password">Show 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="no_permissions_granted">No permissions granted</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="reject">Reject</string>
|
||||
<string name="accept">Accept</string>
|
||||
@@ -54,17 +49,9 @@
|
||||
<string name="decrypt_nip04">decrypt nip04</string>
|
||||
<string name="decrypt_zap_event">decrypt zap event</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="decrypt">decrypt</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="hide_details">Hide Details</string>
|
||||
<string name="copy_raw_json">Raw json</string>
|
||||
@@ -72,13 +59,10 @@
|
||||
<string name="select_account">Select Account</string>
|
||||
<string name="active_account">Active Account</string>
|
||||
<string name="edit_name">Edit name</string>
|
||||
<string name="copy_to_clipboard">Copy to clipboard</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="data_copied_to_the_clipboard">Data copied to the clipboard</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="event_copied_to_the_clipboard">Event copied to the clipboard</string>
|
||||
<string name="select_deselect_all">Select/Deselect all</string>
|
||||
|
||||
Reference in New Issue
Block a user