Separates the Account's relay info to the UI component
This commit is contained in:
@@ -22,16 +22,11 @@ package com.vitorpamplona.amethyst.model
|
|||||||
|
|
||||||
import androidx.compose.runtime.Immutable
|
import androidx.compose.runtime.Immutable
|
||||||
import com.vitorpamplona.amethyst.service.relays.FeedType
|
import com.vitorpamplona.amethyst.service.relays.FeedType
|
||||||
import com.vitorpamplona.amethyst.service.relays.RelayStat
|
|
||||||
|
|
||||||
@Immutable
|
@Immutable
|
||||||
data class RelaySetupInfo(
|
data class RelaySetupInfo(
|
||||||
val url: String,
|
val url: String,
|
||||||
val read: Boolean,
|
val read: Boolean,
|
||||||
val write: Boolean,
|
val write: Boolean,
|
||||||
val relayStat: RelayStat = RelayStat(),
|
|
||||||
val feedTypes: Set<FeedType>,
|
val feedTypes: Set<FeedType>,
|
||||||
val paidRelay: Boolean = false,
|
)
|
||||||
) {
|
|
||||||
val briefInfo: RelayBriefInfoCache.RelayBriefInfo = RelayBriefInfoCache.RelayBriefInfo(url)
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -237,7 +237,7 @@ fun ResetKind3Relays(postViewModel: Kind3RelayListViewModel) {
|
|||||||
OutlinedButton(
|
OutlinedButton(
|
||||||
onClick = {
|
onClick = {
|
||||||
postViewModel.deleteAll()
|
postViewModel.deleteAll()
|
||||||
Constants.defaultRelays.forEach { postViewModel.addRelay(it) }
|
postViewModel.addAll(Constants.defaultRelays)
|
||||||
postViewModel.loadRelayDocuments()
|
postViewModel.loadRelayDocuments()
|
||||||
},
|
},
|
||||||
) {
|
) {
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ package com.vitorpamplona.amethyst.ui.actions.relays
|
|||||||
|
|
||||||
import androidx.compose.runtime.Immutable
|
import androidx.compose.runtime.Immutable
|
||||||
import com.vitorpamplona.amethyst.model.RelayBriefInfoCache
|
import com.vitorpamplona.amethyst.model.RelayBriefInfoCache
|
||||||
|
import com.vitorpamplona.amethyst.service.relays.FeedType
|
||||||
import com.vitorpamplona.amethyst.service.relays.RelayStat
|
import com.vitorpamplona.amethyst.service.relays.RelayStat
|
||||||
|
|
||||||
@Immutable
|
@Immutable
|
||||||
@@ -32,3 +33,15 @@ data class BasicRelaySetupInfo(
|
|||||||
) {
|
) {
|
||||||
val briefInfo: RelayBriefInfoCache.RelayBriefInfo = RelayBriefInfoCache.RelayBriefInfo(url)
|
val briefInfo: RelayBriefInfoCache.RelayBriefInfo = RelayBriefInfoCache.RelayBriefInfo(url)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Immutable
|
||||||
|
data class Kind3BasicRelaySetupInfo(
|
||||||
|
val url: String,
|
||||||
|
val read: Boolean,
|
||||||
|
val write: Boolean,
|
||||||
|
val feedTypes: Set<FeedType>,
|
||||||
|
val relayStat: RelayStat,
|
||||||
|
val paidRelay: Boolean = false,
|
||||||
|
) {
|
||||||
|
val briefInfo: RelayBriefInfoCache.RelayBriefInfo = RelayBriefInfoCache.RelayBriefInfo(url)
|
||||||
|
}
|
||||||
|
|||||||
+37
-37
@@ -68,7 +68,6 @@ import androidx.compose.ui.unit.dp
|
|||||||
import androidx.compose.ui.unit.sp
|
import androidx.compose.ui.unit.sp
|
||||||
import com.vitorpamplona.amethyst.R
|
import com.vitorpamplona.amethyst.R
|
||||||
import com.vitorpamplona.amethyst.model.RelayBriefInfoCache
|
import com.vitorpamplona.amethyst.model.RelayBriefInfoCache
|
||||||
import com.vitorpamplona.amethyst.model.RelaySetupInfo
|
|
||||||
import com.vitorpamplona.amethyst.service.Nip11CachedRetriever
|
import com.vitorpamplona.amethyst.service.Nip11CachedRetriever
|
||||||
import com.vitorpamplona.amethyst.service.Nip11Retriever
|
import com.vitorpamplona.amethyst.service.Nip11Retriever
|
||||||
import com.vitorpamplona.amethyst.service.relays.Constants
|
import com.vitorpamplona.amethyst.service.relays.Constants
|
||||||
@@ -96,7 +95,7 @@ import kotlinx.coroutines.launch
|
|||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun Kind3RelayListView(
|
fun Kind3RelayListView(
|
||||||
feedState: List<RelaySetupInfo>,
|
feedState: List<Kind3BasicRelaySetupInfo>,
|
||||||
postViewModel: Kind3RelayListViewModel,
|
postViewModel: Kind3RelayListViewModel,
|
||||||
accountViewModel: AccountViewModel,
|
accountViewModel: AccountViewModel,
|
||||||
onClose: () -> Unit,
|
onClose: () -> Unit,
|
||||||
@@ -111,7 +110,7 @@ fun Kind3RelayListView(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun LazyListScope.renderKind3Items(
|
fun LazyListScope.renderKind3Items(
|
||||||
feedState: List<RelaySetupInfo>,
|
feedState: List<Kind3BasicRelaySetupInfo>,
|
||||||
postViewModel: Kind3RelayListViewModel,
|
postViewModel: Kind3RelayListViewModel,
|
||||||
accountViewModel: AccountViewModel,
|
accountViewModel: AccountViewModel,
|
||||||
onClose: () -> Unit,
|
onClose: () -> Unit,
|
||||||
@@ -148,7 +147,7 @@ fun ServerConfigPreview() {
|
|||||||
ClickableRelayItem(
|
ClickableRelayItem(
|
||||||
loadProfilePicture = true,
|
loadProfilePicture = true,
|
||||||
item =
|
item =
|
||||||
RelaySetupInfo(
|
Kind3BasicRelaySetupInfo(
|
||||||
url = "nostr.mom",
|
url = "nostr.mom",
|
||||||
read = true,
|
read = true,
|
||||||
write = true,
|
write = true,
|
||||||
@@ -176,15 +175,15 @@ fun ServerConfigPreview() {
|
|||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun LoadRelayInfo(
|
fun LoadRelayInfo(
|
||||||
item: RelaySetupInfo,
|
item: Kind3BasicRelaySetupInfo,
|
||||||
onToggleDownload: (RelaySetupInfo) -> Unit,
|
onToggleDownload: (Kind3BasicRelaySetupInfo) -> Unit,
|
||||||
onToggleUpload: (RelaySetupInfo) -> Unit,
|
onToggleUpload: (Kind3BasicRelaySetupInfo) -> Unit,
|
||||||
onToggleFollows: (RelaySetupInfo) -> Unit,
|
onToggleFollows: (Kind3BasicRelaySetupInfo) -> Unit,
|
||||||
onTogglePrivateDMs: (RelaySetupInfo) -> Unit,
|
onTogglePrivateDMs: (Kind3BasicRelaySetupInfo) -> Unit,
|
||||||
onTogglePublicChats: (RelaySetupInfo) -> Unit,
|
onTogglePublicChats: (Kind3BasicRelaySetupInfo) -> Unit,
|
||||||
onToggleGlobal: (RelaySetupInfo) -> Unit,
|
onToggleGlobal: (Kind3BasicRelaySetupInfo) -> Unit,
|
||||||
onToggleSearch: (RelaySetupInfo) -> Unit,
|
onToggleSearch: (Kind3BasicRelaySetupInfo) -> Unit,
|
||||||
onDelete: (RelaySetupInfo) -> Unit,
|
onDelete: (Kind3BasicRelaySetupInfo) -> Unit,
|
||||||
accountViewModel: AccountViewModel,
|
accountViewModel: AccountViewModel,
|
||||||
nav: (String) -> Unit,
|
nav: (String) -> Unit,
|
||||||
) {
|
) {
|
||||||
@@ -267,16 +266,16 @@ fun LoadRelayInfo(
|
|||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun ClickableRelayItem(
|
fun ClickableRelayItem(
|
||||||
item: RelaySetupInfo,
|
item: Kind3BasicRelaySetupInfo,
|
||||||
loadProfilePicture: Boolean,
|
loadProfilePicture: Boolean,
|
||||||
onToggleDownload: (RelaySetupInfo) -> Unit,
|
onToggleDownload: (Kind3BasicRelaySetupInfo) -> Unit,
|
||||||
onToggleUpload: (RelaySetupInfo) -> Unit,
|
onToggleUpload: (Kind3BasicRelaySetupInfo) -> Unit,
|
||||||
onToggleFollows: (RelaySetupInfo) -> Unit,
|
onToggleFollows: (Kind3BasicRelaySetupInfo) -> Unit,
|
||||||
onTogglePrivateDMs: (RelaySetupInfo) -> Unit,
|
onTogglePrivateDMs: (Kind3BasicRelaySetupInfo) -> Unit,
|
||||||
onTogglePublicChats: (RelaySetupInfo) -> Unit,
|
onTogglePublicChats: (Kind3BasicRelaySetupInfo) -> Unit,
|
||||||
onToggleGlobal: (RelaySetupInfo) -> Unit,
|
onToggleGlobal: (Kind3BasicRelaySetupInfo) -> Unit,
|
||||||
onToggleSearch: (RelaySetupInfo) -> Unit,
|
onToggleSearch: (Kind3BasicRelaySetupInfo) -> Unit,
|
||||||
onDelete: (RelaySetupInfo) -> Unit,
|
onDelete: (Kind3BasicRelaySetupInfo) -> Unit,
|
||||||
onClick: () -> Unit,
|
onClick: () -> Unit,
|
||||||
) {
|
) {
|
||||||
Column(Modifier.fillMaxWidth()) {
|
Column(Modifier.fillMaxWidth()) {
|
||||||
@@ -337,9 +336,9 @@ fun ClickableRelayItem(
|
|||||||
@Composable
|
@Composable
|
||||||
@OptIn(ExperimentalFoundationApi::class)
|
@OptIn(ExperimentalFoundationApi::class)
|
||||||
private fun StatusRow(
|
private fun StatusRow(
|
||||||
item: RelaySetupInfo,
|
item: Kind3BasicRelaySetupInfo,
|
||||||
onToggleDownload: (RelaySetupInfo) -> Unit,
|
onToggleDownload: (Kind3BasicRelaySetupInfo) -> Unit,
|
||||||
onToggleUpload: (RelaySetupInfo) -> Unit,
|
onToggleUpload: (Kind3BasicRelaySetupInfo) -> Unit,
|
||||||
modifier: Modifier,
|
modifier: Modifier,
|
||||||
) {
|
) {
|
||||||
val scope = rememberCoroutineScope()
|
val scope = rememberCoroutineScope()
|
||||||
@@ -489,11 +488,11 @@ private fun StatusRow(
|
|||||||
@Composable
|
@Composable
|
||||||
@OptIn(ExperimentalFoundationApi::class)
|
@OptIn(ExperimentalFoundationApi::class)
|
||||||
private fun ActiveToggles(
|
private fun ActiveToggles(
|
||||||
item: RelaySetupInfo,
|
item: Kind3BasicRelaySetupInfo,
|
||||||
onToggleFollows: (RelaySetupInfo) -> Unit,
|
onToggleFollows: (Kind3BasicRelaySetupInfo) -> Unit,
|
||||||
onTogglePrivateDMs: (RelaySetupInfo) -> Unit,
|
onTogglePrivateDMs: (Kind3BasicRelaySetupInfo) -> Unit,
|
||||||
onTogglePublicChats: (RelaySetupInfo) -> Unit,
|
onTogglePublicChats: (Kind3BasicRelaySetupInfo) -> Unit,
|
||||||
onToggleGlobal: (RelaySetupInfo) -> Unit,
|
onToggleGlobal: (Kind3BasicRelaySetupInfo) -> Unit,
|
||||||
) {
|
) {
|
||||||
val scope = rememberCoroutineScope()
|
val scope = rememberCoroutineScope()
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
@@ -643,9 +642,9 @@ private fun ActiveToggles(
|
|||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun FirstLine(
|
private fun FirstLine(
|
||||||
item: RelaySetupInfo,
|
item: Kind3BasicRelaySetupInfo,
|
||||||
onClick: () -> Unit,
|
onClick: () -> Unit,
|
||||||
onDelete: (RelaySetupInfo) -> Unit,
|
onDelete: (Kind3BasicRelaySetupInfo) -> Unit,
|
||||||
modifier: Modifier,
|
modifier: Modifier,
|
||||||
) {
|
) {
|
||||||
Row(verticalAlignment = Alignment.CenterVertically, modifier = modifier) {
|
Row(verticalAlignment = Alignment.CenterVertically, modifier = modifier) {
|
||||||
@@ -684,7 +683,7 @@ private fun FirstLine(
|
|||||||
@Composable
|
@Composable
|
||||||
fun Kind3RelayEditBox(
|
fun Kind3RelayEditBox(
|
||||||
relayToAdd: String,
|
relayToAdd: String,
|
||||||
onNewRelay: (RelaySetupInfo) -> Unit,
|
onNewRelay: (Kind3BasicRelaySetupInfo) -> Unit,
|
||||||
) {
|
) {
|
||||||
var url by remember { mutableStateOf<String>(relayToAdd) }
|
var url by remember { mutableStateOf<String>(relayToAdd) }
|
||||||
var read by remember { mutableStateOf(true) }
|
var read by remember { mutableStateOf(true) }
|
||||||
@@ -739,11 +738,12 @@ fun Kind3RelayEditBox(
|
|||||||
if (url.isNotBlank() && url != "/") {
|
if (url.isNotBlank() && url != "/") {
|
||||||
val addedWSS = RelayUrlFormatter.normalize(url)
|
val addedWSS = RelayUrlFormatter.normalize(url)
|
||||||
onNewRelay(
|
onNewRelay(
|
||||||
RelaySetupInfo(
|
Kind3BasicRelaySetupInfo(
|
||||||
addedWSS,
|
url = addedWSS,
|
||||||
read,
|
read = read,
|
||||||
write,
|
write = write,
|
||||||
feedTypes = FeedType.entries.toSet(),
|
feedTypes = FeedType.entries.toSet(),
|
||||||
|
relayStat = RelayStat(),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
url = ""
|
url = ""
|
||||||
|
|||||||
+52
-24
@@ -38,7 +38,7 @@ import kotlinx.coroutines.launch
|
|||||||
class Kind3RelayListViewModel : ViewModel() {
|
class Kind3RelayListViewModel : ViewModel() {
|
||||||
private lateinit var account: Account
|
private lateinit var account: Account
|
||||||
|
|
||||||
private val _relays = MutableStateFlow<List<RelaySetupInfo>>(emptyList())
|
private val _relays = MutableStateFlow<List<Kind3BasicRelaySetupInfo>>(emptyList())
|
||||||
val relays = _relays.asStateFlow()
|
val relays = _relays.asStateFlow()
|
||||||
|
|
||||||
var hasModified = false
|
var hasModified = false
|
||||||
@@ -52,7 +52,16 @@ class Kind3RelayListViewModel : ViewModel() {
|
|||||||
fun create() {
|
fun create() {
|
||||||
if (hasModified) {
|
if (hasModified) {
|
||||||
viewModelScope.launch(Dispatchers.IO) {
|
viewModelScope.launch(Dispatchers.IO) {
|
||||||
account.saveKind3RelayList(relays.value)
|
account.saveKind3RelayList(
|
||||||
|
relays.value.map {
|
||||||
|
RelaySetupInfo(
|
||||||
|
it.url,
|
||||||
|
it.read,
|
||||||
|
it.write,
|
||||||
|
it.feedTypes,
|
||||||
|
)
|
||||||
|
},
|
||||||
|
)
|
||||||
clear()
|
clear()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -91,12 +100,12 @@ class Kind3RelayListViewModel : ViewModel() {
|
|||||||
?.feedTypes
|
?.feedTypes
|
||||||
?: FeedType.values().toSet().toImmutableSet()
|
?: FeedType.values().toSet().toImmutableSet()
|
||||||
|
|
||||||
RelaySetupInfo(
|
Kind3BasicRelaySetupInfo(
|
||||||
it.key,
|
url = it.key,
|
||||||
it.value.read,
|
read = it.value.read,
|
||||||
it.value.write,
|
write = it.value.write,
|
||||||
RelayStats.get(it.key),
|
feedTypes = localInfoFeedTypes,
|
||||||
localInfoFeedTypes,
|
relayStat = RelayStats.get(it.key),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
.distinctBy { it.url }
|
.distinctBy { it.url }
|
||||||
@@ -105,12 +114,12 @@ class Kind3RelayListViewModel : ViewModel() {
|
|||||||
} else {
|
} else {
|
||||||
account.localRelays
|
account.localRelays
|
||||||
.map {
|
.map {
|
||||||
RelaySetupInfo(
|
Kind3BasicRelaySetupInfo(
|
||||||
it.url,
|
url = it.url,
|
||||||
it.read,
|
read = it.read,
|
||||||
it.write,
|
write = it.write,
|
||||||
RelayStats.get(it.url),
|
feedTypes = it.feedTypes,
|
||||||
it.feedTypes,
|
relayStat = RelayStats.get(it.url),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
.distinctBy { it.url }
|
.distinctBy { it.url }
|
||||||
@@ -120,7 +129,26 @@ class Kind3RelayListViewModel : ViewModel() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun addRelay(relay: RelaySetupInfo) {
|
fun addAll(defaultRelays: Array<RelaySetupInfo>) {
|
||||||
|
hasModified = true
|
||||||
|
|
||||||
|
_relays.update {
|
||||||
|
defaultRelays.map {
|
||||||
|
Kind3BasicRelaySetupInfo(
|
||||||
|
url = it.url,
|
||||||
|
read = it.read,
|
||||||
|
write = it.write,
|
||||||
|
feedTypes = it.feedTypes,
|
||||||
|
relayStat = RelayStats.get(it.url),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
.distinctBy { it.url }
|
||||||
|
.sortedBy { it.relayStat.receivedBytes }
|
||||||
|
.reversed()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun addRelay(relay: Kind3BasicRelaySetupInfo) {
|
||||||
if (relays.value.any { it.url == relay.url }) return
|
if (relays.value.any { it.url == relay.url }) return
|
||||||
|
|
||||||
_relays.update { it.plus(relay) }
|
_relays.update { it.plus(relay) }
|
||||||
@@ -128,7 +156,7 @@ class Kind3RelayListViewModel : ViewModel() {
|
|||||||
hasModified = true
|
hasModified = true
|
||||||
}
|
}
|
||||||
|
|
||||||
fun deleteRelay(relay: RelaySetupInfo) {
|
fun deleteRelay(relay: Kind3BasicRelaySetupInfo) {
|
||||||
_relays.update { it.minus(relay) }
|
_relays.update { it.minus(relay) }
|
||||||
hasModified = true
|
hasModified = true
|
||||||
}
|
}
|
||||||
@@ -138,48 +166,48 @@ class Kind3RelayListViewModel : ViewModel() {
|
|||||||
hasModified = true
|
hasModified = true
|
||||||
}
|
}
|
||||||
|
|
||||||
fun toggleDownload(relay: RelaySetupInfo) {
|
fun toggleDownload(relay: Kind3BasicRelaySetupInfo) {
|
||||||
_relays.update { it.updated(relay, relay.copy(read = !relay.read)) }
|
_relays.update { it.updated(relay, relay.copy(read = !relay.read)) }
|
||||||
hasModified = true
|
hasModified = true
|
||||||
}
|
}
|
||||||
|
|
||||||
fun toggleUpload(relay: RelaySetupInfo) {
|
fun toggleUpload(relay: Kind3BasicRelaySetupInfo) {
|
||||||
_relays.update { it.updated(relay, relay.copy(write = !relay.write)) }
|
_relays.update { it.updated(relay, relay.copy(write = !relay.write)) }
|
||||||
hasModified = true
|
hasModified = true
|
||||||
}
|
}
|
||||||
|
|
||||||
fun toggleFollows(relay: RelaySetupInfo) {
|
fun toggleFollows(relay: Kind3BasicRelaySetupInfo) {
|
||||||
val newTypes = togglePresenceInSet(relay.feedTypes, FeedType.FOLLOWS)
|
val newTypes = togglePresenceInSet(relay.feedTypes, FeedType.FOLLOWS)
|
||||||
_relays.update { it.updated(relay, relay.copy(feedTypes = newTypes)) }
|
_relays.update { it.updated(relay, relay.copy(feedTypes = newTypes)) }
|
||||||
hasModified = true
|
hasModified = true
|
||||||
}
|
}
|
||||||
|
|
||||||
fun toggleMessages(relay: RelaySetupInfo) {
|
fun toggleMessages(relay: Kind3BasicRelaySetupInfo) {
|
||||||
val newTypes = togglePresenceInSet(relay.feedTypes, FeedType.PRIVATE_DMS)
|
val newTypes = togglePresenceInSet(relay.feedTypes, FeedType.PRIVATE_DMS)
|
||||||
_relays.update { it.updated(relay, relay.copy(feedTypes = newTypes)) }
|
_relays.update { it.updated(relay, relay.copy(feedTypes = newTypes)) }
|
||||||
hasModified = true
|
hasModified = true
|
||||||
}
|
}
|
||||||
|
|
||||||
fun togglePublicChats(relay: RelaySetupInfo) {
|
fun togglePublicChats(relay: Kind3BasicRelaySetupInfo) {
|
||||||
val newTypes = togglePresenceInSet(relay.feedTypes, FeedType.PUBLIC_CHATS)
|
val newTypes = togglePresenceInSet(relay.feedTypes, FeedType.PUBLIC_CHATS)
|
||||||
_relays.update { it.updated(relay, relay.copy(feedTypes = newTypes)) }
|
_relays.update { it.updated(relay, relay.copy(feedTypes = newTypes)) }
|
||||||
hasModified = true
|
hasModified = true
|
||||||
}
|
}
|
||||||
|
|
||||||
fun toggleGlobal(relay: RelaySetupInfo) {
|
fun toggleGlobal(relay: Kind3BasicRelaySetupInfo) {
|
||||||
val newTypes = togglePresenceInSet(relay.feedTypes, FeedType.GLOBAL)
|
val newTypes = togglePresenceInSet(relay.feedTypes, FeedType.GLOBAL)
|
||||||
_relays.update { it.updated(relay, relay.copy(feedTypes = newTypes)) }
|
_relays.update { it.updated(relay, relay.copy(feedTypes = newTypes)) }
|
||||||
hasModified = true
|
hasModified = true
|
||||||
}
|
}
|
||||||
|
|
||||||
fun toggleSearch(relay: RelaySetupInfo) {
|
fun toggleSearch(relay: Kind3BasicRelaySetupInfo) {
|
||||||
val newTypes = togglePresenceInSet(relay.feedTypes, FeedType.SEARCH)
|
val newTypes = togglePresenceInSet(relay.feedTypes, FeedType.SEARCH)
|
||||||
_relays.update { it.updated(relay, relay.copy(feedTypes = newTypes)) }
|
_relays.update { it.updated(relay, relay.copy(feedTypes = newTypes)) }
|
||||||
hasModified = true
|
hasModified = true
|
||||||
}
|
}
|
||||||
|
|
||||||
fun togglePaidRelay(
|
fun togglePaidRelay(
|
||||||
relay: RelaySetupInfo,
|
relay: Kind3BasicRelaySetupInfo,
|
||||||
paid: Boolean,
|
paid: Boolean,
|
||||||
) {
|
) {
|
||||||
_relays.update { it.updated(relay, relay.copy(paidRelay = paid)) }
|
_relays.update { it.updated(relay, relay.copy(paidRelay = paid)) }
|
||||||
|
|||||||
Reference in New Issue
Block a user