refactor PackageUtils.isAmberInstalled to account.loggedinwithamber

This commit is contained in:
greenart7c3
2023-08-25 11:51:22 -03:00
parent b2b7799a0f
commit df1a017eb3
12 changed files with 54 additions and 58 deletions

View File

@ -35,7 +35,8 @@ private const val DEBUG_PREFERENCES_NAME = "debug_prefs"
@Immutable @Immutable
data class AccountInfo( data class AccountInfo(
val npub: String, val npub: String,
val hasPrivKey: Boolean = false val hasPrivKey: Boolean,
val loggedInWithAmber: Boolean
) )
private object PrefKeys { private object PrefKeys {
@ -202,7 +203,11 @@ object LocalPreferences {
fun allSavedAccounts(): List<AccountInfo> { fun allSavedAccounts(): List<AccountInfo> {
return savedAccounts().map { npub -> return savedAccounts().map { npub ->
AccountInfo(npub = npub) AccountInfo(
npub,
hasPrivKey(npub),
getLoggedInWithAmber(npub)
)
} }
} }
@ -291,6 +296,22 @@ object LocalPreferences {
return language return language
} }
private fun getLoggedInWithAmber(npub: String): Boolean {
var loggedInWithAmber: Boolean
encryptedPreferences(npub).apply {
loggedInWithAmber = getBoolean(PrefKeys.LOGIN_WITH_AMBER, false)
}
return loggedInWithAmber
}
private fun hasPrivKey(npub: String): Boolean {
var hasPrivKey: Boolean
encryptedPreferences(npub).apply {
hasPrivKey = (getString(PrefKeys.NOSTR_PRIVKEY, "") ?: "").isNotBlank()
}
return hasPrivKey
}
fun loadFromEncryptedStorage(): Account? { fun loadFromEncryptedStorage(): Account? {
val acc = loadFromEncryptedStorage(currentAccount()) val acc = loadFromEncryptedStorage(currentAccount())
acc?.registerObservers() acc?.registerObservers()

View File

@ -202,7 +202,7 @@ class Account(
return null return null
} }
fun sendNewUserMetadata(toString: String, identities: List<IdentityClaim>, signEvent: Boolean = true): MetadataEvent? { fun sendNewUserMetadata(toString: String, identities: List<IdentityClaim>, signEvent: Boolean): MetadataEvent? {
if (!isWriteable() && signEvent) return null if (!isWriteable() && signEvent) return null
val event = MetadataEvent.create(toString, identities, keyPair.pubKey.toHexKey(), keyPair.privKey) val event = MetadataEvent.create(toString, identities, keyPair.pubKey.toHexKey(), keyPair.privKey)
@ -1438,8 +1438,8 @@ class Account(
LocalCache.consume(event) LocalCache.consume(event)
} }
fun createAuthEvent(relay: Relay, challenge: String, isAmberInstalled: Boolean): RelayAuthEvent? { fun createAuthEvent(relay: Relay, challenge: String, loggedInWithAmber: Boolean): RelayAuthEvent? {
if (!isWriteable() && !isAmberInstalled) return null if (!isWriteable() && !loggedInWithAmber) return null
return RelayAuthEvent.create(relay.url, challenge, keyPair.pubKey.toHexKey(), keyPair.privKey) return RelayAuthEvent.create(relay.url, challenge, keyPair.pubKey.toHexKey(), keyPair.privKey)
} }

View File

@ -193,10 +193,10 @@ object NostrAccountDataSource : NostrDataSource("AccountData") {
if (this::account.isInitialized) { if (this::account.isInitialized) {
val context = Amethyst.instance val context = Amethyst.instance
val isAmberInstalled = PackageUtils.isAmberInstalled(context) val loggedInWithAmber = account.loginWithAmber
val event = account.createAuthEvent(relay, challenge, isAmberInstalled) val event = account.createAuthEvent(relay, challenge, loggedInWithAmber)
if (isAmberInstalled && !account.isWriteable()) { if (loggedInWithAmber && !account.isWriteable()) {
if (event != null) { if (event != null) {
openAmber( openAmber(
event.toJson(), event.toJson(),

View File

@ -2,12 +2,10 @@ package com.vitorpamplona.amethyst.service.notifications
import android.util.Log import android.util.Log
import com.vitorpamplona.amethyst.AccountInfo import com.vitorpamplona.amethyst.AccountInfo
import com.vitorpamplona.amethyst.Amethyst
import com.vitorpamplona.amethyst.BuildConfig import com.vitorpamplona.amethyst.BuildConfig
import com.vitorpamplona.amethyst.LocalPreferences import com.vitorpamplona.amethyst.LocalPreferences
import com.vitorpamplona.amethyst.service.HttpClient import com.vitorpamplona.amethyst.service.HttpClient
import com.vitorpamplona.amethyst.service.IntentUtils import com.vitorpamplona.amethyst.service.IntentUtils
import com.vitorpamplona.amethyst.service.PackageUtils
import com.vitorpamplona.amethyst.ui.actions.SignerType import com.vitorpamplona.amethyst.ui.actions.SignerType
import com.vitorpamplona.amethyst.ui.actions.openAmber import com.vitorpamplona.amethyst.ui.actions.openAmber
import com.vitorpamplona.quartz.events.RelayAuthEvent import com.vitorpamplona.quartz.events.RelayAuthEvent
@ -25,14 +23,14 @@ class RegisterAccounts(
private fun signEventsToProveControlOfAccounts( private fun signEventsToProveControlOfAccounts(
accounts: List<AccountInfo>, accounts: List<AccountInfo>,
notificationToken: String, notificationToken: String,
isAmberInstalled: Boolean loggedInWithAmber: Boolean
): List<RelayAuthEvent> { ): List<RelayAuthEvent> {
return accounts.mapNotNull { return accounts.mapNotNull {
val acc = LocalPreferences.loadFromEncryptedStorage(it.npub) val acc = LocalPreferences.loadFromEncryptedStorage(it.npub)
if (acc != null) { if (acc != null) {
val relayToUse = acc.activeRelays()?.firstOrNull { it.read } val relayToUse = acc.activeRelays()?.firstOrNull { it.read }
if (relayToUse != null) { if (relayToUse != null) {
val event = acc.createAuthEvent(relayToUse, notificationToken, isAmberInstalled) val event = acc.createAuthEvent(relayToUse, notificationToken, loggedInWithAmber)
event event
} else { } else {
null null
@ -70,11 +68,11 @@ class RegisterAccounts(
} }
suspend fun go(notificationToken: String) = withContext(Dispatchers.IO) { suspend fun go(notificationToken: String) = withContext(Dispatchers.IO) {
val isAmberInstalled = PackageUtils.isAmberInstalled(Amethyst.instance)
val accountsWithoutPrivKey = accounts.filter { !it.hasPrivKey } val accountsWithoutPrivKey = accounts.filter { !it.hasPrivKey }
val accountsWithPrivKey = accounts.filter { it.hasPrivKey } val accountsWithPrivKey = accounts.filter { it.hasPrivKey }
accountsWithoutPrivKey.forEach { account -> accountsWithoutPrivKey.forEach { account ->
val events = signEventsToProveControlOfAccounts(listOf(account), notificationToken, isAmberInstalled) Log.d("fcm register", account.npub)
val events = signEventsToProveControlOfAccounts(listOf(account), notificationToken, account.loggedInWithAmber)
if (events.isNotEmpty()) { if (events.isNotEmpty()) {
openAmber( openAmber(
events.first().toJson(), events.first().toJson(),
@ -87,7 +85,7 @@ class RegisterAccounts(
if (accountsWithPrivKey.isNotEmpty()) { if (accountsWithPrivKey.isNotEmpty()) {
postRegistrationEvent( postRegistrationEvent(
signEventsToProveControlOfAccounts(accountsWithPrivKey, notificationToken, isAmberInstalled) signEventsToProveControlOfAccounts(accountsWithPrivKey, notificationToken, false)
) )
} }
} }

View File

@ -34,7 +34,6 @@ import androidx.lifecycle.viewmodel.compose.viewModel
import com.vitorpamplona.amethyst.R import com.vitorpamplona.amethyst.R
import com.vitorpamplona.amethyst.model.Account import com.vitorpamplona.amethyst.model.Account
import com.vitorpamplona.amethyst.model.LocalCache import com.vitorpamplona.amethyst.model.LocalCache
import com.vitorpamplona.amethyst.service.PackageUtils
import com.vitorpamplona.amethyst.service.relays.Client import com.vitorpamplona.amethyst.service.relays.Client
import com.vitorpamplona.amethyst.ui.theme.placeholderText import com.vitorpamplona.amethyst.ui.theme.placeholderText
import com.vitorpamplona.quartz.events.Event import com.vitorpamplona.quartz.events.Event
@ -104,9 +103,8 @@ fun NewUserMetadataView(onClose: () -> Unit, account: Account) {
PostButton( PostButton(
onPost = { onPost = {
if (PackageUtils.isAmberInstalled(context)) { if (account.loginWithAmber) {
event = postViewModel.create(false) event = postViewModel.create(false)
println(event)
} else { } else {
postViewModel.create(true) postViewModel.create(true)
onClose() onClose()

View File

@ -124,11 +124,11 @@ class NewUserMetadataViewModel : ViewModel() {
if (signEvent) { if (signEvent) {
viewModelScope.launch(Dispatchers.IO) { viewModelScope.launch(Dispatchers.IO) {
account.sendNewUserMetadata(writer.buffer.toString(), newClaims, signEvent) account.sendNewUserMetadata(writer.buffer.toString(), newClaims, true)
} }
clear() clear()
} else { } else {
return account.sendNewUserMetadata(writer.buffer.toString(), newClaims, signEvent) return account.sendNewUserMetadata(writer.buffer.toString(), newClaims, false)
} }
return null return null

View File

@ -35,7 +35,6 @@ import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.Shape import androidx.compose.ui.graphics.Shape
import androidx.compose.ui.graphics.compositeOver import androidx.compose.ui.graphics.compositeOver
import androidx.compose.ui.layout.onSizeChanged import androidx.compose.ui.layout.onSizeChanged
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
@ -45,7 +44,6 @@ import androidx.lifecycle.map
import com.vitorpamplona.amethyst.R import com.vitorpamplona.amethyst.R
import com.vitorpamplona.amethyst.model.Note import com.vitorpamplona.amethyst.model.Note
import com.vitorpamplona.amethyst.model.User import com.vitorpamplona.amethyst.model.User
import com.vitorpamplona.amethyst.service.PackageUtils
import com.vitorpamplona.amethyst.ui.actions.SignerDialog import com.vitorpamplona.amethyst.ui.actions.SignerDialog
import com.vitorpamplona.amethyst.ui.actions.SignerType import com.vitorpamplona.amethyst.ui.actions.SignerType
import com.vitorpamplona.amethyst.ui.components.CreateClickableTextWithEmoji import com.vitorpamplona.amethyst.ui.components.CreateClickableTextWithEmoji
@ -639,10 +637,9 @@ private fun RenderRegularTextNote(
val tags = remember(note.event) { note.event?.tags()?.toImmutableListOfLists() ?: ImmutableListOfLists() } val tags = remember(note.event) { note.event?.tags()?.toImmutableListOfLists() ?: ImmutableListOfLists() }
var eventContent by remember { mutableStateOf(accountViewModel.decrypt(note)) } var eventContent by remember { mutableStateOf(accountViewModel.decrypt(note)) }
val modifier = remember { Modifier.padding(top = 5.dp) } val modifier = remember { Modifier.padding(top = 5.dp) }
val context = LocalContext.current val loggedInWithAmber = accountViewModel.loggedInWithAmber()
val isAmberInstalled = PackageUtils.isAmberInstalled(context)
var triedToDecrypt by remember { mutableStateOf(false) } var triedToDecrypt by remember { mutableStateOf(false) }
if (isAmberInstalled && !triedToDecrypt && note.event is PrivateDmEvent) { if (loggedInWithAmber && !triedToDecrypt && note.event is PrivateDmEvent) {
SignerDialog( SignerDialog(
onClose = { onClose = {
triedToDecrypt = true triedToDecrypt = true

View File

@ -78,7 +78,6 @@ import coil.request.ImageRequest
import com.vitorpamplona.amethyst.R import com.vitorpamplona.amethyst.R
import com.vitorpamplona.amethyst.model.LocalCache import com.vitorpamplona.amethyst.model.LocalCache
import com.vitorpamplona.amethyst.model.Note import com.vitorpamplona.amethyst.model.Note
import com.vitorpamplona.amethyst.service.PackageUtils
import com.vitorpamplona.amethyst.service.relays.Client import com.vitorpamplona.amethyst.service.relays.Client
import com.vitorpamplona.amethyst.ui.actions.NewPostView import com.vitorpamplona.amethyst.ui.actions.NewPostView
import com.vitorpamplona.amethyst.ui.actions.SignerDialog import com.vitorpamplona.amethyst.ui.actions.SignerDialog
@ -572,7 +571,7 @@ fun ReplyReaction(
if (accountViewModel.isWriteable()) { if (accountViewModel.isWriteable()) {
onPress() onPress()
} else { } else {
if (PackageUtils.isAmberInstalled(context)) { if (accountViewModel.loggedInWithAmber()) {
onPress() onPress()
} else { } else {
scope.launch { scope.launch {
@ -705,7 +704,7 @@ fun BoostReaction(
wantsToBoost = true wantsToBoost = true
} }
} else { } else {
if (PackageUtils.isAmberInstalled(context)) { if (accountViewModel.loggedInWithAmber()) {
if (accountViewModel.hasBoosted(baseNote)) { if (accountViewModel.hasBoosted(baseNote)) {
scope.launch(Dispatchers.IO) { scope.launch(Dispatchers.IO) {
event = accountViewModel.deleteBoostsTo(baseNote, false) event = accountViewModel.deleteBoostsTo(baseNote, false)
@ -995,7 +994,7 @@ private fun likeClick(
.show() .show()
} }
} else if (!accountViewModel.isWriteable()) { } else if (!accountViewModel.isWriteable()) {
if (PackageUtils.isAmberInstalled(context)) { if (accountViewModel.loggedInWithAmber()) {
onWantsToSignReaction() onWantsToSignReaction()
} else { } else {
scope.launch { scope.launch {
@ -1420,14 +1419,14 @@ private fun ActionableReactionButton(
Button( Button(
modifier = Modifier.padding(horizontal = 3.dp), modifier = Modifier.padding(horizontal = 3.dp),
onClick = { onClick = {
val isAmberInstalled = PackageUtils.isAmberInstalled(context) val loggedInWithAmber = accountViewModel.loggedInWithAmber()
scope.launch(Dispatchers.IO) { scope.launch(Dispatchers.IO) {
event = accountViewModel.reactToOrDelete( event = accountViewModel.reactToOrDelete(
baseNote, baseNote,
reactionType, reactionType,
!isAmberInstalled !loggedInWithAmber
) )
if (!isAmberInstalled) { if (!loggedInWithAmber) {
onDismiss() onDismiss()
} }
} }
@ -1441,14 +1440,14 @@ private fun ActionableReactionButton(
val thisModifier = remember(reactionType) { val thisModifier = remember(reactionType) {
Modifier.combinedClickable( Modifier.combinedClickable(
onClick = { onClick = {
val isAmberInstalled = PackageUtils.isAmberInstalled(context) val loggedInWithAmber = accountViewModel.loggedInWithAmber()
scope.launch(Dispatchers.IO) { scope.launch(Dispatchers.IO) {
event = accountViewModel.reactToOrDelete( event = accountViewModel.reactToOrDelete(
baseNote, baseNote,
reactionType, reactionType,
!isAmberInstalled !loggedInWithAmber
) )
if (!isAmberInstalled) { if (!loggedInWithAmber) {
onDismiss() onDismiss()
} }
} }

View File

@ -68,7 +68,6 @@ import com.vitorpamplona.amethyst.model.Note
import com.vitorpamplona.amethyst.model.ServersAvailable import com.vitorpamplona.amethyst.model.ServersAvailable
import com.vitorpamplona.amethyst.model.User import com.vitorpamplona.amethyst.model.User
import com.vitorpamplona.amethyst.service.NostrChatroomDataSource import com.vitorpamplona.amethyst.service.NostrChatroomDataSource
import com.vitorpamplona.amethyst.service.PackageUtils
import com.vitorpamplona.amethyst.service.relays.Client import com.vitorpamplona.amethyst.service.relays.Client
import com.vitorpamplona.amethyst.ui.actions.CloseButton import com.vitorpamplona.amethyst.ui.actions.CloseButton
import com.vitorpamplona.amethyst.ui.actions.NewPostViewModel import com.vitorpamplona.amethyst.ui.actions.NewPostViewModel
@ -338,7 +337,7 @@ fun ChatroomScreen(
wantsToMarkAsSensitive = false wantsToMarkAsSensitive = false
) )
} else { } else {
if (!accountViewModel.isWriteable() && PackageUtils.isAmberInstalled(context)) { if (!accountViewModel.isWriteable() && accountViewModel.loggedInWithAmber()) {
message = newPostModel.message.text message = newPostModel.message.text
} else { } else {
accountViewModel.account.sendPrivateMessage( accountViewModel.account.sendPrivateMessage(

View File

@ -9,15 +9,6 @@ import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.statusBarsPadding import androidx.compose.foundation.layout.statusBarsPadding
import androidx.compose.material.* import androidx.compose.material.*
import androidx.compose.material.DrawerValue
import androidx.compose.material.ExperimentalMaterialApi
import androidx.compose.material.MaterialTheme
import androidx.compose.material.ModalBottomSheetLayout
import androidx.compose.material.ModalBottomSheetValue
import androidx.compose.material.Scaffold
import androidx.compose.material.rememberDrawerState
import androidx.compose.material.rememberModalBottomSheetState
import androidx.compose.material.rememberScaffoldState
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.State import androidx.compose.runtime.State
@ -33,18 +24,11 @@ import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.navigation.NavBackStackEntry import androidx.navigation.NavBackStackEntry
import androidx.navigation.compose.currentBackStackEntryAsState import androidx.navigation.compose.currentBackStackEntryAsState
import androidx.navigation.compose.rememberNavController import androidx.navigation.compose.rememberNavController
import com.vitorpamplona.amethyst.service.PackageUtils
import com.vitorpamplona.amethyst.ui.buttons.ChannelFabColumn import com.vitorpamplona.amethyst.ui.buttons.ChannelFabColumn
import com.vitorpamplona.amethyst.ui.buttons.NewCommunityNoteButton import com.vitorpamplona.amethyst.ui.buttons.NewCommunityNoteButton
import com.vitorpamplona.amethyst.ui.buttons.NewImageButton import com.vitorpamplona.amethyst.ui.buttons.NewImageButton
import com.vitorpamplona.amethyst.ui.buttons.NewNoteButton import com.vitorpamplona.amethyst.ui.buttons.NewNoteButton
import com.vitorpamplona.amethyst.ui.navigation.* import com.vitorpamplona.amethyst.ui.navigation.*
import com.vitorpamplona.amethyst.ui.navigation.AccountSwitchBottomSheet
import com.vitorpamplona.amethyst.ui.navigation.AppBottomBar
import com.vitorpamplona.amethyst.ui.navigation.AppNavigation
import com.vitorpamplona.amethyst.ui.navigation.AppTopBar
import com.vitorpamplona.amethyst.ui.navigation.DrawerContent
import com.vitorpamplona.amethyst.ui.navigation.Route
import com.vitorpamplona.amethyst.ui.note.UserReactionsViewModel import com.vitorpamplona.amethyst.ui.note.UserReactionsViewModel
import com.vitorpamplona.amethyst.ui.screen.AccountState import com.vitorpamplona.amethyst.ui.screen.AccountState
import com.vitorpamplona.amethyst.ui.screen.AccountStateViewModel import com.vitorpamplona.amethyst.ui.screen.AccountStateViewModel
@ -258,7 +242,7 @@ fun FloatingButtons(
Crossfade(targetState = accountState, animationSpec = tween(durationMillis = 100)) { state -> Crossfade(targetState = accountState, animationSpec = tween(durationMillis = 100)) { state ->
when (state) { when (state) {
is AccountState.LoggedInViewOnly -> { is AccountState.LoggedInViewOnly -> {
if (PackageUtils.isAmberInstalled(context)) { if (accountViewModel.loggedInWithAmber()) {
WritePermissionButtons(navEntryState, accountViewModel, nav, navScrollToTop) WritePermissionButtons(navEntryState, accountViewModel, nav, navScrollToTop)
} }
} }

View File

@ -58,7 +58,6 @@ import com.vitorpamplona.amethyst.model.LocalCache
import com.vitorpamplona.amethyst.model.Note import com.vitorpamplona.amethyst.model.Note
import com.vitorpamplona.amethyst.model.User import com.vitorpamplona.amethyst.model.User
import com.vitorpamplona.amethyst.service.NostrUserProfileDataSource import com.vitorpamplona.amethyst.service.NostrUserProfileDataSource
import com.vitorpamplona.amethyst.service.PackageUtils
import com.vitorpamplona.amethyst.service.relays.Client import com.vitorpamplona.amethyst.service.relays.Client
import com.vitorpamplona.amethyst.ui.actions.NewUserMetadataView import com.vitorpamplona.amethyst.ui.actions.NewUserMetadataView
import com.vitorpamplona.amethyst.ui.actions.SignerDialog import com.vitorpamplona.amethyst.ui.actions.SignerDialog
@ -768,7 +767,7 @@ private fun DisplayFollowUnfollowButton(
if (isLoggedInFollowingUser) { if (isLoggedInFollowingUser) {
UnfollowButton { UnfollowButton {
if (!accountViewModel.isWriteable()) { if (!accountViewModel.isWriteable()) {
if (PackageUtils.isAmberInstalled(context)) { if (accountViewModel.loggedInWithAmber()) {
event = accountViewModel.account.unfollow(baseUser, false) event = accountViewModel.account.unfollow(baseUser, false)
} else { } else {
scope.launch { scope.launch {

View File

@ -27,9 +27,10 @@ class RelayAuthEvent(
listOf("relay", relay), listOf("relay", relay),
listOf("challenge", challenge) listOf("challenge", challenge)
) )
val id = generateId(pubKey, createdAt, kind, tags, content) val localPubKey = if (pubKey.isBlank() && privateKey != null) CryptoUtils.pubkeyCreate(privateKey).toHexKey() else pubKey
val id = generateId(localPubKey, createdAt, kind, tags, content)
val sig = if (privateKey == null) null else CryptoUtils.sign(id, privateKey) val sig = if (privateKey == null) null else CryptoUtils.sign(id, privateKey)
return RelayAuthEvent(id.toHexKey(), pubKey, createdAt, tags, content, sig?.toHexKey() ?: "") return RelayAuthEvent(id.toHexKey(), localPubKey, createdAt, tags, content, sig?.toHexKey() ?: "")
} }
} }
} }