.
This commit is contained in:
@@ -100,8 +100,8 @@ fun RelayScreen(viewModel: AccountViewModel) {
|
|||||||
viewModel.loadCurrentUserMsgRelayList()
|
viewModel.loadCurrentUserMsgRelayList()
|
||||||
}
|
}
|
||||||
|
|
||||||
val loadedRelayList by viewModel.currentUserRelayList.collectAsStateWithLifecycle()
|
val loadedRelayList by viewModel.userRelayList.collectAsStateWithLifecycle()
|
||||||
val loadedMsgRelayList by viewModel.currentUserMsgRelayList.collectAsStateWithLifecycle()
|
val loadedMsgRelayList by viewModel.userMsgRelayList.collectAsStateWithLifecycle()
|
||||||
|
|
||||||
LaunchedEffect(loadedRelayList) {
|
LaunchedEffect(loadedRelayList) {
|
||||||
if (loadedRelayList.isNotEmpty()) {
|
if (loadedRelayList.isNotEmpty()) {
|
||||||
|
|||||||
@@ -13,7 +13,6 @@ import kotlinx.coroutines.flow.collectLatest
|
|||||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||||
import kotlinx.coroutines.flow.filter
|
import kotlinx.coroutines.flow.filter
|
||||||
import kotlinx.coroutines.flow.filterNotNull
|
import kotlinx.coroutines.flow.filterNotNull
|
||||||
import kotlinx.coroutines.flow.first
|
|
||||||
import kotlinx.coroutines.flow.flatMapLatest
|
import kotlinx.coroutines.flow.flatMapLatest
|
||||||
import kotlinx.coroutines.flow.flow
|
import kotlinx.coroutines.flow.flow
|
||||||
import kotlinx.coroutines.flow.flowOf
|
import kotlinx.coroutines.flow.flowOf
|
||||||
@@ -84,12 +83,11 @@ class AccountRepository(
|
|||||||
private val _isRelayListEmpty = MutableStateFlow(false)
|
private val _isRelayListEmpty = MutableStateFlow(false)
|
||||||
val isRelayListEmpty: StateFlow<Boolean> = _isRelayListEmpty.asStateFlow()
|
val isRelayListEmpty: StateFlow<Boolean> = _isRelayListEmpty.asStateFlow()
|
||||||
|
|
||||||
private val _currentUserRelayList = MutableStateFlow<Map<RelayUrl, RelayMetadata?>>(emptyMap())
|
private val _userRelayList = MutableStateFlow<Map<RelayUrl, RelayMetadata?>>(emptyMap())
|
||||||
val currentUserRelayList: StateFlow<Map<RelayUrl, RelayMetadata?>> =
|
val userRelayList: StateFlow<Map<RelayUrl, RelayMetadata?>> = _userRelayList.asStateFlow()
|
||||||
_currentUserRelayList.asStateFlow()
|
|
||||||
|
|
||||||
private val _currentUserMsgRelayList = MutableStateFlow<List<RelayUrl>>(emptyList())
|
private val _userMsgRelayList = MutableStateFlow<List<RelayUrl>>(emptyList())
|
||||||
val currentUserMsgRelayList: StateFlow<List<RelayUrl>> = _currentUserMsgRelayList.asStateFlow()
|
val userMsgRelayList: StateFlow<List<RelayUrl>> = _userMsgRelayList.asStateFlow()
|
||||||
|
|
||||||
init {
|
init {
|
||||||
checkNotificationBannerDismissedStatus()
|
checkNotificationBannerDismissedStatus()
|
||||||
@@ -103,9 +101,22 @@ class AccountRepository(
|
|||||||
nostr.signer.publicKeyFlow
|
nostr.signer.publicKeyFlow
|
||||||
.filterNotNull()
|
.filterNotNull()
|
||||||
.distinctUntilChanged()
|
.distinctUntilChanged()
|
||||||
.collectLatest {
|
.collectLatest { pubkey ->
|
||||||
getUserMetadata()
|
// Refresh metadata
|
||||||
checkRelayList()
|
nostr.profiles.getUserMetadata()
|
||||||
|
|
||||||
|
// Verify messaging relays exist (wait up to 10s for initial fetch)
|
||||||
|
val relays = withTimeoutOrNull(10.seconds) {
|
||||||
|
var list = nostr.relays.getMsgRelays(pubkey)
|
||||||
|
while (list.isEmpty()) {
|
||||||
|
delay(500.milliseconds)
|
||||||
|
list = nostr.relays.getMsgRelays(pubkey)
|
||||||
|
}
|
||||||
|
list
|
||||||
|
} ?: emptyList()
|
||||||
|
|
||||||
|
// Automatically update the warning state
|
||||||
|
_isRelayListEmpty.value = relays.isEmpty()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -315,12 +326,6 @@ class AccountRepository(
|
|||||||
.map { (p, m) -> Profile(p, m) }
|
.map { (p, m) -> Profile(p, m) }
|
||||||
)
|
)
|
||||||
|
|
||||||
private fun getUserMetadata() {
|
|
||||||
scope.launch {
|
|
||||||
nostr.profiles.getUserMetadata()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun updateProfile(
|
fun updateProfile(
|
||||||
name: String? = null,
|
name: String? = null,
|
||||||
bio: String? = null,
|
bio: String? = null,
|
||||||
@@ -454,24 +459,6 @@ class AccountRepository(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@OptIn(ExperimentalCoroutinesApi::class)
|
|
||||||
private fun checkRelayList() {
|
|
||||||
scope.launch {
|
|
||||||
val currentUser = nostr.signer.publicKeyFlow.filterNotNull().first()
|
|
||||||
|
|
||||||
val relays = withTimeoutOrNull(10.seconds) {
|
|
||||||
var result = nostr.relays.getMsgRelays(currentUser)
|
|
||||||
while (result.isEmpty()) {
|
|
||||||
delay(500.milliseconds)
|
|
||||||
result = nostr.relays.getMsgRelays(currentUser)
|
|
||||||
}
|
|
||||||
result
|
|
||||||
} ?: emptyList()
|
|
||||||
|
|
||||||
if (relays.isEmpty()) _isRelayListEmpty.value = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun dismissRelayWarning() {
|
fun dismissRelayWarning() {
|
||||||
_isRelayListEmpty.value = false
|
_isRelayListEmpty.value = false
|
||||||
}
|
}
|
||||||
@@ -499,9 +486,8 @@ class AccountRepository(
|
|||||||
fun loadCurrentUserRelayList() {
|
fun loadCurrentUserRelayList() {
|
||||||
scope.launch {
|
scope.launch {
|
||||||
try {
|
try {
|
||||||
val currentUser =
|
val user = nostr.signer.getPublicKeyAsync() ?: throw Exception("User not found")
|
||||||
nostr.signer.getPublicKeyAsync() ?: throw Exception("User not found")
|
_userRelayList.value = nostr.relays.getRelayList(user)
|
||||||
_currentUserRelayList.value = nostr.relays.getRelayList(currentUser)
|
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
showError("Error: ${e.message}")
|
showError("Error: ${e.message}")
|
||||||
}
|
}
|
||||||
@@ -563,16 +549,15 @@ class AccountRepository(
|
|||||||
fun loadCurrentUserMsgRelayList() {
|
fun loadCurrentUserMsgRelayList() {
|
||||||
scope.launch {
|
scope.launch {
|
||||||
try {
|
try {
|
||||||
val currentUser =
|
val user = nostr.signer.getPublicKeyAsync() ?: throw Exception("User not found")
|
||||||
nostr.signer.getPublicKeyAsync() ?: throw Exception("User not found")
|
_userMsgRelayList.value = nostr.relays.getMsgRelays(user)
|
||||||
_currentUserMsgRelayList.value = nostr.relays.getMsgRelays(currentUser)
|
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
showError("Error: ${e.message}")
|
showError("Error: ${e.message}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun currentUserMsgRelayListInternal(): List<RelayUrl> {
|
private suspend fun userLatestMsgRelayList(): List<RelayUrl> {
|
||||||
try {
|
try {
|
||||||
val currentUser = nostr.signer.getPublicKeyAsync() ?: throw Exception("User not found")
|
val currentUser = nostr.signer.getPublicKeyAsync() ?: throw Exception("User not found")
|
||||||
return nostr.relays.getMsgRelays(currentUser)
|
return nostr.relays.getMsgRelays(currentUser)
|
||||||
@@ -586,7 +571,7 @@ class AccountRepository(
|
|||||||
scope.launch {
|
scope.launch {
|
||||||
try {
|
try {
|
||||||
val relayUrl = RelayUrl.parse(relay)
|
val relayUrl = RelayUrl.parse(relay)
|
||||||
val relays = currentUserMsgRelayListInternal().toMutableSet()
|
val relays = userLatestMsgRelayList().toMutableSet()
|
||||||
relays.add(relayUrl)
|
relays.add(relayUrl)
|
||||||
|
|
||||||
nostr.relays.setMsgRelays(relays.toList())
|
nostr.relays.setMsgRelays(relays.toList())
|
||||||
@@ -600,7 +585,7 @@ class AccountRepository(
|
|||||||
scope.launch {
|
scope.launch {
|
||||||
try {
|
try {
|
||||||
val relayUrl = RelayUrl.parse(relay)
|
val relayUrl = RelayUrl.parse(relay)
|
||||||
val relays = currentUserMsgRelayListInternal().toMutableSet()
|
val relays = userLatestMsgRelayList().toMutableSet()
|
||||||
relays.remove(relayUrl)
|
relays.remove(relayUrl)
|
||||||
|
|
||||||
nostr.relays.setMsgRelays(relays.toList())
|
nostr.relays.setMsgRelays(relays.toList())
|
||||||
|
|||||||
@@ -19,9 +19,8 @@ class AccountViewModel(
|
|||||||
val currentUserProfile: StateFlow<Profile?> = repository.currentUserProfile
|
val currentUserProfile: StateFlow<Profile?> = repository.currentUserProfile
|
||||||
val contactList: StateFlow<Set<PublicKey>> = repository.contactList
|
val contactList: StateFlow<Set<PublicKey>> = repository.contactList
|
||||||
val isRelayListEmpty: StateFlow<Boolean> = repository.isRelayListEmpty
|
val isRelayListEmpty: StateFlow<Boolean> = repository.isRelayListEmpty
|
||||||
val currentUserRelayList: StateFlow<Map<RelayUrl, RelayMetadata?>> =
|
val userRelayList: StateFlow<Map<RelayUrl, RelayMetadata?>> = repository.userRelayList
|
||||||
repository.currentUserRelayList
|
val userMsgRelayList: StateFlow<List<RelayUrl>> = repository.userMsgRelayList
|
||||||
val currentUserMsgRelayList: StateFlow<List<RelayUrl>> = repository.currentUserMsgRelayList
|
|
||||||
|
|
||||||
fun logout(onLogout: () -> Unit = {}) = repository.logout(onLogout)
|
fun logout(onLogout: () -> Unit = {}) = repository.logout(onLogout)
|
||||||
fun dismissNotificationBanner() = repository.dismissNotificationBanner()
|
fun dismissNotificationBanner() = repository.dismissNotificationBanner()
|
||||||
@@ -35,16 +34,14 @@ class AccountViewModel(
|
|||||||
bio: String?,
|
bio: String?,
|
||||||
picture: ByteArray?,
|
picture: ByteArray?,
|
||||||
contentType: String? = null
|
contentType: String? = null
|
||||||
) =
|
) = repository.createIdentity(name, bio, picture, contentType)
|
||||||
repository.createIdentity(name, bio, picture, contentType)
|
|
||||||
|
|
||||||
fun updateProfile(
|
fun updateProfile(
|
||||||
name: String? = null,
|
name: String? = null,
|
||||||
bio: String? = null,
|
bio: String? = null,
|
||||||
picture: ByteArray? = null,
|
picture: ByteArray? = null,
|
||||||
contentType: String? = null
|
contentType: String? = null
|
||||||
) =
|
) = repository.updateProfile(name, bio, picture, contentType)
|
||||||
repository.updateProfile(name, bio, picture, contentType)
|
|
||||||
|
|
||||||
fun resetInternalState() = repository.resetInternalState()
|
fun resetInternalState() = repository.resetInternalState()
|
||||||
fun addContact(address: String) = repository.addContact(address)
|
fun addContact(address: String) = repository.addContact(address)
|
||||||
|
|||||||
@@ -29,7 +29,6 @@ class ChatScreenViewModel(
|
|||||||
var loading by mutableStateOf(true)
|
var loading by mutableStateOf(true)
|
||||||
var newOtherMessages by mutableIntStateOf(0)
|
var newOtherMessages by mutableIntStateOf(0)
|
||||||
var requireScreening by mutableStateOf(screening)
|
var requireScreening by mutableStateOf(screening)
|
||||||
|
|
||||||
val messages = mutableStateListOf<UnsignedEvent>()
|
val messages = mutableStateListOf<UnsignedEvent>()
|
||||||
|
|
||||||
init {
|
init {
|
||||||
|
|||||||
Reference in New Issue
Block a user