mirror of
https://github.com/vitorpamplona/amethyst.git
synced 2025-09-26 18:56:27 +02:00
Saves a copy of the NIP65 and NIP17 relay lists locally
This commit is contained in:
@@ -42,6 +42,8 @@ import com.vitorpamplona.quartz.encoders.Nip47WalletConnect
|
|||||||
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.encoders.toNpub
|
import com.vitorpamplona.quartz.encoders.toNpub
|
||||||
|
import com.vitorpamplona.quartz.events.AdvertisedRelayListEvent
|
||||||
|
import com.vitorpamplona.quartz.events.ChatMessageRelayListEvent
|
||||||
import com.vitorpamplona.quartz.events.ContactListEvent
|
import com.vitorpamplona.quartz.events.ContactListEvent
|
||||||
import com.vitorpamplona.quartz.events.Event
|
import com.vitorpamplona.quartz.events.Event
|
||||||
import com.vitorpamplona.quartz.events.LnZapEvent
|
import com.vitorpamplona.quartz.events.LnZapEvent
|
||||||
@@ -90,6 +92,8 @@ private object PrefKeys {
|
|||||||
const val DEFAULT_DISCOVERY_FOLLOW_LIST = "defaultDiscoveryFollowList"
|
const val DEFAULT_DISCOVERY_FOLLOW_LIST = "defaultDiscoveryFollowList"
|
||||||
const val ZAP_PAYMENT_REQUEST_SERVER = "zapPaymentServer"
|
const val ZAP_PAYMENT_REQUEST_SERVER = "zapPaymentServer"
|
||||||
const val LATEST_CONTACT_LIST = "latestContactList"
|
const val LATEST_CONTACT_LIST = "latestContactList"
|
||||||
|
const val LATEST_DM_RELAY_LIST = "latestDMRelayList"
|
||||||
|
const val LATEST_NIP65_RELAY_LIST = "latestNIP65RelayList"
|
||||||
const val HIDE_DELETE_REQUEST_DIALOG = "hide_delete_request_dialog"
|
const val HIDE_DELETE_REQUEST_DIALOG = "hide_delete_request_dialog"
|
||||||
const val HIDE_BLOCK_ALERT_DIALOG = "hide_block_alert_dialog"
|
const val HIDE_BLOCK_ALERT_DIALOG = "hide_block_alert_dialog"
|
||||||
const val HIDE_NIP_17_WARNING_DIALOG = "hide_nip24_warning_dialog" // delete later
|
const val HIDE_NIP_17_WARNING_DIALOG = "hide_nip24_warning_dialog" // delete later
|
||||||
@@ -311,10 +315,33 @@ object LocalPreferences {
|
|||||||
PrefKeys.ZAP_PAYMENT_REQUEST_SERVER,
|
PrefKeys.ZAP_PAYMENT_REQUEST_SERVER,
|
||||||
Event.mapper.writeValueAsString(account.zapPaymentRequest),
|
Event.mapper.writeValueAsString(account.zapPaymentRequest),
|
||||||
)
|
)
|
||||||
|
if (account.backupContactList != null) {
|
||||||
putString(
|
putString(
|
||||||
PrefKeys.LATEST_CONTACT_LIST,
|
PrefKeys.LATEST_CONTACT_LIST,
|
||||||
Event.mapper.writeValueAsString(account.backupContactList),
|
Event.mapper.writeValueAsString(account.backupContactList),
|
||||||
)
|
)
|
||||||
|
} else {
|
||||||
|
remove(PrefKeys.LATEST_CONTACT_LIST)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (account.backupDMRelayList != null) {
|
||||||
|
putString(
|
||||||
|
PrefKeys.LATEST_DM_RELAY_LIST,
|
||||||
|
Event.mapper.writeValueAsString(account.backupDMRelayList),
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
remove(PrefKeys.LATEST_DM_RELAY_LIST)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (account.backupNIP65RelayList != null) {
|
||||||
|
putString(
|
||||||
|
PrefKeys.LATEST_NIP65_RELAY_LIST,
|
||||||
|
Event.mapper.writeValueAsString(account.backupNIP65RelayList),
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
remove(PrefKeys.LATEST_NIP65_RELAY_LIST)
|
||||||
|
}
|
||||||
|
|
||||||
putBoolean(PrefKeys.HIDE_DELETE_REQUEST_DIALOG, account.hideDeleteRequestDialog)
|
putBoolean(PrefKeys.HIDE_DELETE_REQUEST_DIALOG, account.hideDeleteRequestDialog)
|
||||||
putBoolean(PrefKeys.HIDE_NIP_17_WARNING_DIALOG, account.hideNIP17WarningDialog)
|
putBoolean(PrefKeys.HIDE_NIP_17_WARNING_DIALOG, account.hideNIP17WarningDialog)
|
||||||
putBoolean(PrefKeys.HIDE_BLOCK_ALERT_DIALOG, account.hideBlockAlertDialog)
|
putBoolean(PrefKeys.HIDE_BLOCK_ALERT_DIALOG, account.hideBlockAlertDialog)
|
||||||
@@ -471,8 +498,8 @@ object LocalPreferences {
|
|||||||
val latestContactList =
|
val latestContactList =
|
||||||
try {
|
try {
|
||||||
getString(PrefKeys.LATEST_CONTACT_LIST, null)?.let {
|
getString(PrefKeys.LATEST_CONTACT_LIST, null)?.let {
|
||||||
println("Decoding Contact List: " + it)
|
if (it != "null") {
|
||||||
if (it != null) {
|
println("Decoding Contact List: $it")
|
||||||
Event.fromJson(it) as ContactListEvent?
|
Event.fromJson(it) as ContactListEvent?
|
||||||
} else {
|
} else {
|
||||||
null
|
null
|
||||||
@@ -488,6 +515,46 @@ object LocalPreferences {
|
|||||||
null
|
null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val latestDmRelayList =
|
||||||
|
try {
|
||||||
|
getString(PrefKeys.LATEST_DM_RELAY_LIST, null)?.let {
|
||||||
|
if (it != "null") {
|
||||||
|
println("Decoding DM Relay List: $it")
|
||||||
|
Event.fromJson(it) as ChatMessageRelayListEvent?
|
||||||
|
} else {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e: Throwable) {
|
||||||
|
if (e is CancellationException) throw e
|
||||||
|
Log.w(
|
||||||
|
"LocalPreferences",
|
||||||
|
"Error Decoding DM Relay List ${getString(PrefKeys.LATEST_DM_RELAY_LIST, null)}",
|
||||||
|
e,
|
||||||
|
)
|
||||||
|
null
|
||||||
|
}
|
||||||
|
|
||||||
|
val latestNip65RelayList =
|
||||||
|
try {
|
||||||
|
getString(PrefKeys.LATEST_NIP65_RELAY_LIST, null)?.let {
|
||||||
|
if (it != "null") {
|
||||||
|
println("Decoding NIP65 Relay List: $it")
|
||||||
|
Event.fromJson(it) as AdvertisedRelayListEvent?
|
||||||
|
} else {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e: Throwable) {
|
||||||
|
if (e is CancellationException) throw e
|
||||||
|
Log.w(
|
||||||
|
"LocalPreferences",
|
||||||
|
"Error Decoding NIP65 Relay List ${getString(PrefKeys.LATEST_NIP65_RELAY_LIST, null)}",
|
||||||
|
e,
|
||||||
|
)
|
||||||
|
null
|
||||||
|
}
|
||||||
|
|
||||||
val pendingAttestations =
|
val pendingAttestations =
|
||||||
try {
|
try {
|
||||||
getString(PrefKeys.PENDING_ATTESTATIONS, null)?.let {
|
getString(PrefKeys.PENDING_ATTESTATIONS, null)?.let {
|
||||||
@@ -502,7 +569,7 @@ object LocalPreferences {
|
|||||||
if (e is CancellationException) throw e
|
if (e is CancellationException) throw e
|
||||||
Log.w(
|
Log.w(
|
||||||
"LocalPreferences",
|
"LocalPreferences",
|
||||||
"Error Decoding Contact List ${getString(PrefKeys.LATEST_CONTACT_LIST, null)}",
|
"Error Decoding Contact List ${getString(PrefKeys.PENDING_ATTESTATIONS, null)}",
|
||||||
e,
|
e,
|
||||||
)
|
)
|
||||||
null
|
null
|
||||||
@@ -595,6 +662,8 @@ object LocalPreferences {
|
|||||||
hideBlockAlertDialog = hideBlockAlertDialog,
|
hideBlockAlertDialog = hideBlockAlertDialog,
|
||||||
hideNIP17WarningDialog = hideNIP17WarningDialog,
|
hideNIP17WarningDialog = hideNIP17WarningDialog,
|
||||||
backupContactList = latestContactList,
|
backupContactList = latestContactList,
|
||||||
|
backupNIP65RelayList = latestNip65RelayList,
|
||||||
|
backupDMRelayList = latestDmRelayList,
|
||||||
proxy = proxy,
|
proxy = proxy,
|
||||||
proxyPort = proxyPort,
|
proxyPort = proxyPort,
|
||||||
showSensitiveContent = MutableStateFlow(showSensitiveContent),
|
showSensitiveContent = MutableStateFlow(showSensitiveContent),
|
||||||
|
@@ -116,6 +116,7 @@ import kotlinx.coroutines.flow.Flow
|
|||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
import kotlinx.coroutines.flow.SharingStarted
|
import kotlinx.coroutines.flow.SharingStarted
|
||||||
import kotlinx.coroutines.flow.StateFlow
|
import kotlinx.coroutines.flow.StateFlow
|
||||||
|
import kotlinx.coroutines.flow.collect
|
||||||
import kotlinx.coroutines.flow.combineTransform
|
import kotlinx.coroutines.flow.combineTransform
|
||||||
import kotlinx.coroutines.flow.flatMapLatest
|
import kotlinx.coroutines.flow.flatMapLatest
|
||||||
import kotlinx.coroutines.flow.flattenMerge
|
import kotlinx.coroutines.flow.flattenMerge
|
||||||
@@ -192,6 +193,8 @@ class Account(
|
|||||||
var hideBlockAlertDialog: Boolean = false,
|
var hideBlockAlertDialog: Boolean = false,
|
||||||
var hideNIP17WarningDialog: Boolean = false,
|
var hideNIP17WarningDialog: Boolean = false,
|
||||||
var backupContactList: ContactListEvent? = null,
|
var backupContactList: ContactListEvent? = null,
|
||||||
|
var backupDMRelayList: ChatMessageRelayListEvent? = null,
|
||||||
|
var backupNIP65RelayList: AdvertisedRelayListEvent? = null,
|
||||||
var proxy: Proxy? = null,
|
var proxy: Proxy? = null,
|
||||||
var proxyPort: Int = 9050,
|
var proxyPort: Int = 9050,
|
||||||
var showSensitiveContent: MutableStateFlow<Boolean?> = MutableStateFlow(null),
|
var showSensitiveContent: MutableStateFlow<Boolean?> = MutableStateFlow(null),
|
||||||
@@ -269,7 +272,9 @@ class Account(
|
|||||||
if (mappedRelaySet.none { it.url == newUrl }) {
|
if (mappedRelaySet.none { it.url == newUrl }) {
|
||||||
mappedRelaySet = mappedRelaySet +
|
mappedRelaySet = mappedRelaySet +
|
||||||
RelaySetupInfo(
|
RelaySetupInfo(
|
||||||
newUrl, true, true,
|
newUrl,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
setOf(
|
setOf(
|
||||||
FeedType.PRIVATE_DMS,
|
FeedType.PRIVATE_DMS,
|
||||||
),
|
),
|
||||||
@@ -294,7 +299,9 @@ class Account(
|
|||||||
if (mappedRelaySet.none { it.url == newUrl }) {
|
if (mappedRelaySet.none { it.url == newUrl }) {
|
||||||
mappedRelaySet = mappedRelaySet +
|
mappedRelaySet = mappedRelaySet +
|
||||||
RelaySetupInfo(
|
RelaySetupInfo(
|
||||||
newUrl, true, false,
|
newUrl,
|
||||||
|
true,
|
||||||
|
false,
|
||||||
setOf(
|
setOf(
|
||||||
FeedType.SEARCH,
|
FeedType.SEARCH,
|
||||||
),
|
),
|
||||||
@@ -319,9 +326,14 @@ class Account(
|
|||||||
if (mappedRelaySet.none { it.url == newUrl }) {
|
if (mappedRelaySet.none { it.url == newUrl }) {
|
||||||
mappedRelaySet = mappedRelaySet +
|
mappedRelaySet = mappedRelaySet +
|
||||||
RelaySetupInfo(
|
RelaySetupInfo(
|
||||||
newUrl, true, true,
|
newUrl,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
setOf(
|
setOf(
|
||||||
FeedType.FOLLOWS, FeedType.PUBLIC_CHATS, FeedType.GLOBAL, FeedType.PRIVATE_DMS,
|
FeedType.FOLLOWS,
|
||||||
|
FeedType.PUBLIC_CHATS,
|
||||||
|
FeedType.GLOBAL,
|
||||||
|
FeedType.PRIVATE_DMS,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -344,9 +356,14 @@ class Account(
|
|||||||
if (mappedRelaySet.none { it.url == newUrl }) {
|
if (mappedRelaySet.none { it.url == newUrl }) {
|
||||||
mappedRelaySet = mappedRelaySet +
|
mappedRelaySet = mappedRelaySet +
|
||||||
RelaySetupInfo(
|
RelaySetupInfo(
|
||||||
newUrl, true, true,
|
newUrl,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
setOf(
|
setOf(
|
||||||
FeedType.FOLLOWS, FeedType.PUBLIC_CHATS, FeedType.GLOBAL, FeedType.PRIVATE_DMS,
|
FeedType.FOLLOWS,
|
||||||
|
FeedType.PUBLIC_CHATS,
|
||||||
|
FeedType.GLOBAL,
|
||||||
|
FeedType.PRIVATE_DMS,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -363,10 +380,14 @@ class Account(
|
|||||||
val write = nip65setup.type == AdvertisedRelayListEvent.AdvertisedRelayType.BOTH || nip65setup.type == AdvertisedRelayListEvent.AdvertisedRelayType.READ
|
val write = nip65setup.type == AdvertisedRelayListEvent.AdvertisedRelayType.BOTH || nip65setup.type == AdvertisedRelayListEvent.AdvertisedRelayType.READ
|
||||||
|
|
||||||
RelaySetupInfo(
|
RelaySetupInfo(
|
||||||
relay.url, true, relay.write || write,
|
relay.url,
|
||||||
|
true,
|
||||||
|
relay.write || write,
|
||||||
relay.feedTypes +
|
relay.feedTypes +
|
||||||
setOf(
|
setOf(
|
||||||
FeedType.FOLLOWS, FeedType.GLOBAL, FeedType.PUBLIC_CHATS,
|
FeedType.FOLLOWS,
|
||||||
|
FeedType.GLOBAL,
|
||||||
|
FeedType.PUBLIC_CHATS,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
@@ -380,9 +401,12 @@ class Account(
|
|||||||
|
|
||||||
mappedRelaySet = mappedRelaySet +
|
mappedRelaySet = mappedRelaySet +
|
||||||
RelaySetupInfo(
|
RelaySetupInfo(
|
||||||
newNip65Setup.relayUrl, true, write,
|
newNip65Setup.relayUrl,
|
||||||
|
true,
|
||||||
|
write,
|
||||||
setOf(
|
setOf(
|
||||||
FeedType.FOLLOWS, FeedType.PUBLIC_CHATS,
|
FeedType.FOLLOWS,
|
||||||
|
FeedType.PUBLIC_CHATS,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -2635,6 +2659,26 @@ class Account(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun updateDMRelayList(newDMRelayList: ChatMessageRelayListEvent?) {
|
||||||
|
if (newDMRelayList == null || newDMRelayList.tags.isEmpty()) return
|
||||||
|
|
||||||
|
// Events might be different objects, we have to compare their ids.
|
||||||
|
if (backupDMRelayList?.id != newDMRelayList.id) {
|
||||||
|
backupDMRelayList = newDMRelayList
|
||||||
|
saveable.invalidateData()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun updateNIP65RelayList(newNIP65RelayList: AdvertisedRelayListEvent?) {
|
||||||
|
if (newNIP65RelayList == null || newNIP65RelayList.tags.isEmpty()) return
|
||||||
|
|
||||||
|
// Events might be different objects, we have to compare their ids.
|
||||||
|
if (backupNIP65RelayList?.id != newNIP65RelayList.id) {
|
||||||
|
backupNIP65RelayList = newNIP65RelayList
|
||||||
|
saveable.invalidateData()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Takes a User's relay list and adds the types of feeds they are active for.
|
// Takes a User's relay list and adds the types of feeds they are active for.
|
||||||
fun activeRelays(): Array<RelaySetupInfo>? {
|
fun activeRelays(): Array<RelaySetupInfo>? {
|
||||||
val usersRelayList =
|
val usersRelayList =
|
||||||
@@ -2968,8 +3012,32 @@ class Account(
|
|||||||
suspend fun registerObservers() =
|
suspend fun registerObservers() =
|
||||||
withContext(Dispatchers.Main) {
|
withContext(Dispatchers.Main) {
|
||||||
// saves contact list for the next time.
|
// saves contact list for the next time.
|
||||||
userProfile().live().follows.observeForever {
|
scope.launch {
|
||||||
GlobalScope.launch(Dispatchers.IO) { updateContactListTo(userProfile().latestContactList) }
|
Log.d("AccountRegisterObservers", "Kind 3 Collector Start")
|
||||||
|
userProfile().flow().follows.stateFlow.collect {
|
||||||
|
Log.d("AccountRegisterObservers", "Updating Kind 3 ${userProfile().toBestDisplayName()}")
|
||||||
|
updateContactListTo(userProfile().latestContactList)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
scope.launch {
|
||||||
|
Log.d("AccountRegisterObservers", "NIP-17 Relay List Collector Start")
|
||||||
|
getDMRelayListFlow().collect {
|
||||||
|
Log.d("AccountRegisterObservers", "Updating DM Relay List for ${userProfile().toBestDisplayName()}")
|
||||||
|
(it.note.event as? ChatMessageRelayListEvent)?.let {
|
||||||
|
updateDMRelayList(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
scope.launch {
|
||||||
|
Log.d("AccountRegisterObservers", "NIP-65 Relay List Collector Start")
|
||||||
|
getNIP65RelayListFlow().collect {
|
||||||
|
Log.d("AccountRegisterObservers", "Updating NIP-65 List for ${userProfile().toBestDisplayName()}")
|
||||||
|
(it.note.event as? AdvertisedRelayListEvent)?.let {
|
||||||
|
updateNIP65RelayList(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// imports transient blocks due to spam.
|
// imports transient blocks due to spam.
|
||||||
@@ -2990,7 +3058,7 @@ class Account(
|
|||||||
}
|
}
|
||||||
|
|
||||||
init {
|
init {
|
||||||
Log.d("Init", "Account")
|
Log.d("Account", "Init")
|
||||||
backupContactList?.let {
|
backupContactList?.let {
|
||||||
println("Loading saved contacts ${it.toJson()}")
|
println("Loading saved contacts ${it.toJson()}")
|
||||||
|
|
||||||
@@ -2998,6 +3066,16 @@ class Account(
|
|||||||
GlobalScope.launch(Dispatchers.IO) { LocalCache.consume(it) }
|
GlobalScope.launch(Dispatchers.IO) { LocalCache.consume(it) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
backupDMRelayList?.let {
|
||||||
|
println("Loading DM Relay List ${it.toJson()}")
|
||||||
|
GlobalScope.launch(Dispatchers.IO) { LocalCache.verifyAndConsume(it, null) }
|
||||||
|
}
|
||||||
|
|
||||||
|
backupNIP65RelayList?.let {
|
||||||
|
println("Loading saved contacts ${it.toJson()}")
|
||||||
|
GlobalScope.launch(Dispatchers.IO) { LocalCache.verifyAndConsume(it, null) }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user